VT: Enhancements on RTP depacketizer

 1) Do not merge FU pkts if rtptimes are different.
   [Problem] There was a case that Fragmented Units of RTP be merged as
     an one frame even Fragmented Units are has different timestamp.
   [Solution] Added a condition to check rtptime between Fragmented Units.

 2) Implementation of a new frame drop rule for p-frame.
   [Problem] P-frame should be dropped only if FU packets damaged
     more than half of amount of frame.
   [Solution] Implemented a rule for p-frame drop.

 3) Discards a rtp buffer that has unexpected ssrc.
   [Problem] so many packet loss observed and video loss because about
     4 different video stream coming at the same time.
   [Solution] Allow only one stream that matched SSRC of first stream.

Bug: 165061754
Change-Id: If840df274a6fc4b04910f9201359b7c09fd2bc85
Signed-off-by: Byeongjo Park <bjo.park@samsung.com>
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.cpp b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
index 3c3ad86..8072863 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
@@ -281,20 +281,19 @@
     }
 
     int32_t cvo;
-    if ((*accessUnit) != NULL && (*accessUnit)->meta()->findInt32("cvo", &cvo)) {
-        if (cvo != mLastCVOUpdated) {
-            sp<AMessage> msg = new AMessage();
-            msg->setInt32("payload-type", NuPlayer::RTPSource::RTP_CVO);
-            msg->setInt32("cvo", cvo);
+    if ((*accessUnit) != NULL && (*accessUnit)->meta()->findInt32("cvo", &cvo) &&
+            cvo != mLastCVOUpdated) {
+        sp<AMessage> msg = new AMessage();
+        msg->setInt32("payload-type", NuPlayer::RTPSource::RTP_CVO);
+        msg->setInt32("cvo", cvo);
 
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatIMSRxNotice);
-            notify->setMessage("message", msg);
-            notify->post();
+        sp<AMessage> notify = dupNotify();
+        notify->setInt32("what", kWhatIMSRxNotice);
+        notify->setMessage("message", msg);
+        notify->post();
 
-            ALOGV("notify cvo updated (%d)->(%d) to upper layer", mLastCVOUpdated, cvo);
-            mLastCVOUpdated = cvo;
-        }
+        ALOGV("notify cvo updated (%d)->(%d) to upper layer", mLastCVOUpdated, cvo);
+        mLastCVOUpdated = cvo;
     }
 
     return finalResult;
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index af82533..f0ee9b7 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -280,6 +280,11 @@
     size_t totalCount = 1;
     bool complete = false;
 
+    int32_t rtpTimeStartAt;
+    CHECK(buffer->meta()->findInt32("rtp-time", &rtpTimeStartAt));
+    uint32_t startSeqNo = buffer->int32Data();
+    bool pFrame = nalType == 0x1;
+
     if (data[1] & 0x40) {
         // Huh? End bit also set on the first buffer.
 
@@ -297,16 +302,20 @@
             size_t size = buffer->size();
 
             if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
-                ALOGV("sequence not complete, expected seqNo %d, got %d",
-                     expectedSeqNo, (uint32_t)buffer->int32Data());
+                ALOGV("sequence not complete, expected seqNo %d, got %d, pFrame %d",
+                     expectedSeqNo, (uint32_t)buffer->int32Data(), pFrame);
 
-                return WRONG_SEQUENCE_NUMBER;
+                if (!pFrame)
+                    return WRONG_SEQUENCE_NUMBER;
             }
 
+            int32_t rtpTime;
+            CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
             if (size < 2
                     || data[0] != indicator
                     || (data[1] & 0x1f) != nalType
-                    || (data[1] & 0x80)) {
+                    || (data[1] & 0x80)
+                    || rtpTime != rtpTimeStartAt) {
                 ALOGV("Ignoring malformed FU buffer.");
 
                 // Delete the whole start of the FU.
@@ -324,9 +333,26 @@
             totalSize += size - 2;
             ++totalCount;
 
-            expectedSeqNo = expectedSeqNo + 1;
+            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);
+                        }
+                        mNextExpectedSeqNo = expectedSeqNo;
+
+                        return MALFORMED_PACKET;
+                    }
+                }
                 // This is the last fragment.
                 complete = true;
                 break;
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 202e5d6..db5b9a8 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -47,6 +47,7 @@
       mFirstSysTime(0),
       mClockRate(0),
       mJbTime(300), // default jitter buffer time is 300ms.
+      mFirstSsrc(0),
       mID(id),
       mHighestSeqNumber(0),
       mPrevExpected(0),
@@ -121,6 +122,9 @@
 bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
     uint32_t seqNum = (uint32_t)buffer->int32Data();
 
+    int32_t ssrc = 0;
+    buffer->meta()->findInt32("ssrc", &ssrc);
+
     if (mNumBuffersReceived++ == 0 && mFirstSysTime == 0) {
         int32_t firstRtpTime;
         CHECK(buffer->meta()->findInt32("rtp-time", &firstRtpTime));
@@ -128,13 +132,19 @@
         mHighestSeqNumber = seqNum;
         mBaseSeqNumber = seqNum;
         mFirstRtpTime = firstRtpTime;
-        ALOGV("first-rtp arrived: first-rtp-time=%d, sys-time=%lld, seq-num=%u",
-                mFirstRtpTime, (long long)mFirstSysTime, mHighestSeqNumber);
+        mFirstSsrc = ssrc;
+        ALOGD("first-rtp arrived: first-rtp-time=%d, sys-time=%lld, seq-num=%u, ssrc=%d",
+                mFirstRtpTime, (long long)mFirstSysTime, mHighestSeqNumber, mFirstSsrc);
         mClockRate = 90000;
         mQueue.push_back(buffer);
         return true;
     }
 
+    if (mFirstSsrc != ssrc) {
+        ALOGW("Discarding a buffer due to unexpected ssrc");
+        return false;
+    }
+
     // Only the lower 16-bit of the sequence numbers are transmitted,
     // derive the high-order bits by choosing the candidate closest
     // to the highest sequence number (extended to 32 bits) received so far.
diff --git a/media/libstagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/ARTPSource.h
index 0d92720..8bbab7f 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -65,6 +65,7 @@
     int32_t mClockRate;
 
     uint32_t mJbTime;
+    int32_t mFirstSsrc;
 
 private: