VT: Refine codes in AAVCAssembler.

 - Fixed a crash problem by overflow when rtp time hits 2^31
 - Code clean up for jitter buffer's logging.

Bug: 165061754
Merged-in: I1c9f39d8857870e1590d1f320f0385e0a500c7e6
Change-Id: I1c9f39d8857870e1590d1f320f0385e0a500c7e6
Signed-off-by: Kim Sungyeon <sy85.kim@samsung.com>
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index facff09..9d75828 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -109,35 +109,28 @@
     }
 
     sp<ABuffer> buffer = *queue->begin();
-    int32_t rtpTime;
-    CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+    uint32_t rtpTime;
+    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
     int64_t startTime = source->mFirstSysTime / 1000;
     int64_t nowTime = ALooper::GetNowUs() / 1000;
     int64_t playedTime = nowTime - startTime;
-    int32_t playedTimeRtp = source->mFirstRtpTime +
+    int64_t playedTimeRtp = source->mFirstRtpTime +
         (((uint32_t)playedTime) * (source->mClockRate / 1000));
-    const int32_t jitterTime = (int32_t)(source->mClockRate / ((float)1000 / (source->mJbTime)));
-    int32_t expiredTimeInJb = rtpTime + jitterTime;
+    const uint32_t jitterTime = (uint32_t)(source->mClockRate / ((float)1000 / (source->mJbTime)));
+    uint32_t expiredTimeInJb = rtpTime + jitterTime;
     bool isExpired = expiredTimeInJb <= (playedTimeRtp);
     bool isTooLate200 = expiredTimeInJb < (playedTimeRtp - jitterTime);
     bool isTooLate300 = expiredTimeInJb < (playedTimeRtp - (jitterTime * 3 / 2));
 
     if (mShowQueue && mShowQueueCnt < 20) {
         showCurrentQueue(queue);
-        ALOGD("start=%lld, now=%lld, played=%lld", (long long)startTime,
-                (long long)nowTime, (long long)playedTime);
-        ALOGD("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
-                rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
+        printNowTimeUs(startTime, nowTime, playedTime);
+        printRTPTime(rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
         mShowQueueCnt++;
     }
 
     AAVCAssembler::addNack(source);
 
-    ALOGV("start=%lld, now=%lld, played=%lld", (long long)startTime,
-            (long long)nowTime, (long long)playedTime);
-    ALOGV("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
-            rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
-
     if (!isExpired) {
         ALOGV("buffering in jitter buffer.");
         return NOT_ENOUGH_DATA;
@@ -147,42 +140,21 @@
         ALOGW("=== WARNING === buffer arrived 200ms late. === WARNING === ");
 
     if (isTooLate300) {
-        ALOGW("buffer arrived too late. 300ms..");
-        ALOGW("start=%lld, now=%lld, played=%lld", (long long)startTime,
-                (long long)nowTime, (long long)playedTime);
-        ALOGW("rtp-time(JB)=%d, plyed-rtp-time(JB)=%d, exp-rtp-time(JB)=%d diff=%lld isExpired=%d",
-                rtpTime, playedTimeRtp, expiredTimeInJb,
-                ((long long)playedTimeRtp) - expiredTimeInJb, isExpired);
-        ALOGW("expected Seq. NO =%d", buffer->int32Data());
+        ALOGW("buffer arrived after 300ms ... \t Diff in Jb=%lld \t Seq# %d",
+              ((long long)playedTimeRtp) - expiredTimeInJb, buffer->int32Data());
+        printNowTimeUs(startTime, nowTime, playedTime);
+        printRTPTime(rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
 
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            CHECK((*it)->meta()->findInt32("rtp-time", &rtpTime));
-            if (rtpTime + jitterTime >= playedTimeRtp) {
-                mNextExpectedSeqNo = (*it)->int32Data();
-                break;
-            }
-            it++;
-        }
-        source->noticeAbandonBuffer();
+        mNextExpectedSeqNo = pickProperSeq(queue, jitterTime, playedTimeRtp);
     }
 
     if (mNextExpectedSeqNoValid) {
         int32_t size = queue->size();
-        int32_t cnt = 0;
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
+        int32_t cntRemove = deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
 
-            it = queue->erase(it);
-            cnt++;
-        }
-
-        if (cnt > 0) {
-            source->noticeAbandonBuffer(cnt);
-            ALOGW("delete %d of %d buffers", cnt, size);
+        if (cntRemove > 0) {
+            source->noticeAbandonBuffer(cntRemove);
+            ALOGW("delete %d of %d buffers", cntRemove, size);
         }
         if (queue->empty()) {
             return NOT_ENOUGH_DATA;
@@ -339,8 +311,8 @@
     size_t totalCount = 1;
     bool complete = false;
 
-    int32_t rtpTimeStartAt;
-    CHECK(buffer->meta()->findInt32("rtp-time", &rtpTimeStartAt));
+    uint32_t rtpTimeStartAt;
+    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTimeStartAt));
     uint32_t startSeqNo = buffer->int32Data();
     bool pFrame = nalType == 0x1;
 
@@ -368,8 +340,8 @@
                     return WRONG_SEQUENCE_NUMBER;
             }
 
-            int32_t rtpTime;
-            CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+            uint32_t rtpTime;
+            CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
             if (size < 2
                     || data[0] != indicator
                     || (data[1] & 0x1f) != nalType
@@ -379,12 +351,8 @@
 
                 // Delete the whole start of the FU.
 
-                it = queue->begin();
-                for (size_t i = 0; i <= totalCount; ++i) {
-                    it = queue->erase(it);
-                }
-
                 mNextExpectedSeqNo = expectedSeqNo + 1;
+                deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
 
                 return MALFORMED_PACKET;
             }
@@ -395,22 +363,11 @@
             expectedSeqNo = buffer->int32Data() + 1;
 
             if (data[1] & 0x40) {
-                if (pFrame) {
-                    ALOGV("checking p-frame losses.. recvBufs %d diff %d drop? %d",
-                            (uint32_t)totalCount, expectedSeqNo - startSeqNo,
-                            totalCount < ((expectedSeqNo - startSeqNo) / 2));
-                    if (totalCount < ((expectedSeqNo - startSeqNo) / 2)) {
-                        ALOGI("drop p-frame. recvBufs %d lastSeq %d startSeq %d",
-                                (uint32_t)totalCount, expectedSeqNo - 1, startSeqNo);
-
-                        it = queue->begin();
-                        for (size_t i = 0; i <= totalCount; ++i) {
-                            it = queue->erase(it);
-                        }
+                if (pFrame && !recycleUnit(startSeqNo, expectedSeqNo, totalCount, 0.5f)) {
                         mNextExpectedSeqNo = expectedSeqNo;
+                        deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
 
                         return MALFORMED_PACKET;
-                    }
                 }
                 // This is the last fragment.
                 complete = true;
@@ -518,6 +475,58 @@
     msg->post();
 }
 
+int32_t AAVCAssembler::pickProperSeq(const Q *q, uint32_t jit, int64_t play) {
+    sp<ABuffer> buffer = *(q->begin());
+    uint32_t rtpTime;
+    int32_t nextSeqNo = buffer->int32Data();
+
+    Q::const_iterator it = q->begin();
+    while (it != q->end()) {
+        CHECK((*it)->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+        // if pkt in time exists, that should be the next pivot
+        if (rtpTime + jit >= play) {
+            nextSeqNo = (*it)->int32Data();
+            break;
+        }
+        it++;
+    }
+    return nextSeqNo;
+}
+
+bool AAVCAssembler::recycleUnit(uint32_t start, uint32_t end, size_t avail, float goodRatio) {
+    float total = end - start;
+    float exist = avail;
+    bool isRecycle = (exist / total) >= goodRatio;
+
+    ALOGV("checking p-frame losses.. recvBufs %f diff %f recycle? %d",
+            exist, total, isRecycle);
+
+    return isRecycle;
+}
+
+int32_t AAVCAssembler::deleteUnitUnderSeq(Q *q, uint32_t seq) {
+    int32_t initSize = q->size();
+    Q::iterator it = q->begin();
+    while (it != q->end()) {
+        if ((uint32_t)(*it)->int32Data() >= seq) {
+            break;
+        }
+        it++;
+    }
+    q->erase(q->begin(), it);
+    return initSize - q->size();
+}
+
+inline void AAVCAssembler::printNowTimeUs(int64_t start, int64_t now, int64_t play) {
+    ALOGD("start=%lld, now=%lld, played=%lld",
+            (long long)start, (long long)now, (long long)play);
+}
+
+inline void AAVCAssembler::printRTPTime(uint32_t rtp, int64_t play, uint32_t exp, bool isExp) {
+    ALOGD("rtp-time(JB)=%u, played-rtp-time(JB)=%lld, expired-rtp-time(JB)=%u isExpired=%d",
+            rtp, (long long)play, exp, isExp);
+}
+
 ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
         const sp<ARTPSource> &source) {
     AssemblyStatus status = addNALUnit(source);
diff --git a/media/libstagefright/rtsp/AAVCAssembler.h b/media/libstagefright/rtsp/AAVCAssembler.h
index 11ba08c..b9add64 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.h
+++ b/media/libstagefright/rtsp/AAVCAssembler.h
@@ -25,6 +25,8 @@
 
 namespace android {
 
+using Q = List<sp<ABuffer> >;
+
 struct ABuffer;
 struct AMessage;
 
@@ -55,6 +57,12 @@
 
     void submitAccessUnit();
 
+    int32_t pickProperSeq(const Q *q, uint32_t jit, int64_t play);
+    bool recycleUnit(uint32_t start, uint32_t end, size_t avail, float goodRatio);
+    int32_t deleteUnitUnderSeq(Q *q, uint32_t seq);
+    void printNowTimeUs(int64_t start, int64_t now, int64_t play);
+    void printRTPTime(uint32_t rtp, int64_t play, uint32_t exp, bool isExp);
+
     DISALLOW_EVIL_CONSTRUCTORS(AAVCAssembler);
 };
 
diff --git a/media/libstagefright/rtsp/AHEVCAssembler.cpp b/media/libstagefright/rtsp/AHEVCAssembler.cpp
index 7b9ccc1..2514c6b 100644
--- a/media/libstagefright/rtsp/AHEVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AHEVCAssembler.cpp
@@ -63,19 +63,19 @@
     }
 
     sp<ABuffer> buffer = *queue->begin();
-    int32_t rtpTime;
-    CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+    uint32_t rtpTime;
+    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
     int64_t startTime = source->mFirstSysTime / 1000;
     int64_t nowTime = ALooper::GetNowUs() / 1000;
     int64_t playedTime = nowTime - startTime;
-    int32_t playedTimeRtp = source->mFirstRtpTime +
+    int64_t playedTimeRtp = source->mFirstRtpTime +
         (((uint32_t)playedTime) * (source->mClockRate / 1000));
-    int32_t expiredTimeInJb = rtpTime + (source->mClockRate / 5);
+    const uint32_t expiredTimeInJb = rtpTime + (source->mClockRate / 5);
     bool isExpired = expiredTimeInJb <= (playedTimeRtp);
     ALOGV("start=%lld, now=%lld, played=%lld", (long long)startTime,
             (long long)nowTime, (long long)playedTime);
-    ALOGV("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
-            rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
+    ALOGV("rtp-time(JB)=%u, played-rtp-time(JB)=%lld, expired-rtp-time(JB)=%u isExpired=%d",
+            rtpTime, (long long)playedTimeRtp, expiredTimeInJb, isExpired);
 
     if (!isExpired) {
         ALOGV("buffering in jitter buffer.");
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 9ae00ac..5c8c71e 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -129,8 +129,8 @@
     buffer->meta()->findInt32("ssrc", &ssrc);
 
     if (mNumBuffersReceived++ == 0 && mFirstSysTime == 0) {
-        int32_t firstRtpTime;
-        CHECK(buffer->meta()->findInt32("rtp-time", &firstRtpTime));
+        uint32_t firstRtpTime;
+        CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&firstRtpTime));
         mFirstSysTime = ALooper::GetNowUs();
         mHighestSeqNumber = seqNum;
         mBaseSeqNumber = seqNum;
diff --git a/media/libstagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/ARTPSource.h
index 9f5c4b3..a68740e 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -59,7 +59,7 @@
     void noticeAbandonBuffer(int cnt=1);
 
     int32_t mFirstSeqNumber;
-    int32_t mFirstRtpTime;
+    uint32_t mFirstRtpTime;
     int64_t mFirstSysTime;
     int32_t mClockRate;