Merge changes from topic "New_IR94_AV_sync_solution" into tm-dev

* changes:
  VT: Add interarrival jitter time to RR
  VT: adding RR(Reception Report) logic
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c6b22a6..9b4fc8f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2893,6 +2893,38 @@
             in.writeInt32(recvTimeUs & 0xFFFFFFFF);
             break;
         }
+        case ARTPSource::RTCP_RR:
+        {
+            int64_t recvTimeUs;
+            int32_t senderId;
+            int32_t ssrc;
+            int32_t fraction;
+            int32_t lost;
+            int32_t lastSeq;
+            int32_t jitter;
+            int32_t lsr;
+            int32_t dlsr;
+            CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
+            CHECK(msg->findInt32("rtcp-rr-ssrc", &senderId));
+            CHECK(msg->findInt32("rtcp-rrb-ssrc", &ssrc));
+            CHECK(msg->findInt32("rtcp-rrb-fraction", &fraction));
+            CHECK(msg->findInt32("rtcp-rrb-lost", &lost));
+            CHECK(msg->findInt32("rtcp-rrb-lastSeq", &lastSeq));
+            CHECK(msg->findInt32("rtcp-rrb-jitter", &jitter));
+            CHECK(msg->findInt32("rtcp-rrb-lsr", &lsr));
+            CHECK(msg->findInt32("rtcp-rrb-dlsr", &dlsr));
+            in.writeInt32(recvTimeUs >> 32);
+            in.writeInt32(recvTimeUs & 0xFFFFFFFF);
+            in.writeInt32(senderId);
+            in.writeInt32(ssrc);
+            in.writeInt32(fraction);
+            in.writeInt32(lost);
+            in.writeInt32(lastSeq);
+            in.writeInt32(jitter);
+            in.writeInt32(lsr);
+            in.writeInt32(dlsr);
+            break;
+        }
         case ARTPSource::RTCP_TSFB:   // RTCP TSFB
         case ARTPSource::RTCP_PSFB:   // RTCP PSFB
         case ARTPSource::RTP_AUTODOWN:
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 7d72510..a61f48f 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "ARTPConnection"
 #include <utils/Log.h>
 
+#include <media/stagefright/rtsp/ARTPAssembler.h>
 #include <media/stagefright/rtsp/ARTPConnection.h>
 #include <media/stagefright/rtsp/ARTPSource.h>
 #include <media/stagefright/rtsp/ASessionDescription.h>
@@ -41,6 +42,10 @@
     return data[0] << 8 | data[1];
 }
 
+static uint32_t u24at(const uint8_t *data) {
+    return u16at(data) << 16 | data[2];
+}
+
 static uint32_t u32at(const uint8_t *data) {
     return u16at(data) << 16 | u16at(&data[2]);
 }
@@ -877,11 +882,15 @@
         switch (data[1]) {
             case 200:
             {
-                parseSR(s, data, headerLength);
+                parseSenderReport(s, data, headerLength);
                 break;
             }
 
             case 201:  // RR
+            {
+                parseReceiverReport(s, data, headerLength);
+                break;
+            }
             case 202:  // SDES
             case 204:  // APP
                 break;
@@ -940,18 +949,44 @@
     return OK;
 }
 
-status_t ARTPConnection::parseSR(
+status_t ARTPConnection::parseSenderReport(
         StreamInfo *s, const uint8_t *data, size_t size) {
-    size_t RC = data[0] & 0x1f;
-
-    if (size < (7 + RC * 6) * 4) {
-        // Packet too short for the minimal SR header.
+    ALOG_ASSERT(size >= 1, "parseSenderReport: invalid packet size.");
+    size_t receptionReportCount = data[0] & 0x1f;
+    if (size < (7 + (receptionReportCount * 6)) * 4) {
+        // Packet too short for the minimal sender report header.
         return -1;
     }
 
-    uint32_t id = u32at(&data[4]);
+    int64_t recvTimeUs = ALooper::GetNowUs();
+    uint32_t senderId = u32at(&data[4]);
     uint64_t ntpTime = u64at(&data[8]);
     uint32_t rtpTime = u32at(&data[16]);
+    uint32_t pktCount = u32at(&data[20]);
+    uint32_t octCount = u32at(&data[24]);
+
+    ALOGD("SR received: ssrc=0x%08x, rtpTime%u == ntpTime %llu, pkt=%u, oct=%u",
+            senderId, rtpTime, (unsigned long long)ntpTime, pktCount, octCount);
+
+    sp<ARTPSource> source = findSource(s, senderId);
+    source->timeUpdate(recvTimeUs, rtpTime, ntpTime);
+
+    for (int32_t i = 0; i < receptionReportCount; i++) {
+        int32_t offset = 28 + (i * 24);
+        parseReceptionReportBlock(s, recvTimeUs, senderId, data + offset, size - offset);
+    }
+
+    return 0;
+}
+
+status_t ARTPConnection::parseReceiverReport(
+        StreamInfo *s, const uint8_t *data, size_t size) {
+    ALOG_ASSERT(size >= 1, "parseReceiverReport: invalid packet size.");
+    size_t receptionReportCount = data[0] & 0x1f;
+    if (size < (2 + (receptionReportCount * 6)) * 4) {
+        // Packet too short for the minimal receiver report header.
+        return -1;
+    }
 
 #if 0
     ALOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
@@ -959,10 +994,40 @@
          rtpTime,
          (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
 #endif
+    int64_t recvTimeUs = ALooper::GetNowUs();
+    uint32_t senderId = u32at(&data[4]);
 
-    sp<ARTPSource> source = findSource(s, id);
+    for (int i = 0; i < receptionReportCount; i++) {
+        int32_t offset = 8 + (i * 24);
+        parseReceptionReportBlock(s, recvTimeUs, senderId, data + offset, size - offset);
+    }
 
-    source->timeUpdate(rtpTime, ntpTime);
+    return 0;
+}
+
+status_t ARTPConnection::parseReceptionReportBlock(
+        StreamInfo *s, int64_t recvTimeUs, uint32_t senderId, const uint8_t *data, size_t size) {
+    ALOG_ASSERT(size >= 24, "parseReceptionReportBlock: invalid packet size.");
+    if (size < 24) {
+        // remaining size is smaller than reception report block size.
+        return -1;
+    }
+
+    uint32_t rbId = u32at(&data[0]);
+    uint32_t fLost = data[4];
+    int32_t cumLost = u24at(&data[5]);
+    uint32_t ehSeq = u32at(&data[8]);
+    uint32_t jitter = u32at(&data[12]);
+    uint32_t lsr = u32at(&data[16]);
+    uint32_t dlsr = u32at(&data[20]);
+
+    ALOGD("Reception Report Block: t:%llu sid:%u rid:%u fl:%u cl:%u hs:%u jt:%u lsr:%u dlsr:%u",
+            (unsigned long long)recvTimeUs, senderId, rbId, fLost, cumLost,
+            ehSeq, jitter, lsr, dlsr);
+    sp<ARTPSource> source = findSource(s, senderId);
+    sp<ReceptionReportBlock> rrb = new ReceptionReportBlock(
+            rbId, fLost, cumLost, ehSeq, jitter, lsr, dlsr);
+    source->processReceptionReportBlock(recvTimeUs, senderId, rrb);
 
     return 0;
 }
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 5f62b9d..717d8af 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -132,10 +132,10 @@
     }
 }
 
-void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
+void ARTPSource::timeUpdate(int64_t recvTimeUs, uint32_t rtpTime, uint64_t ntpTime) {
     mLastSrRtpTime = rtpTime;
     mLastSrNtpTime = ntpTime;
-    mLastSrUpdateTimeUs = ALooper::GetNowUs();
+    mLastSrUpdateTimeUs = recvTimeUs;
 
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("time-update", true);
@@ -143,7 +143,30 @@
     notify->setInt64("ntp-time", ntpTime);
     notify->setInt32("rtcp-event", 1);
     notify->setInt32("payload-type", RTCP_SR);
-    notify->setInt64("recv-time-us", mLastSrUpdateTimeUs);
+    notify->setInt64("recv-time-us", recvTimeUs);
+    notify->post();
+}
+
+void ARTPSource::processReceptionReportBlock(
+        int64_t recvTimeUs, uint32_t senderId, sp<ReceptionReportBlock> rrb) {
+    mLastRrUpdateTimeUs = recvTimeUs;
+
+    sp<AMessage> notify = mNotify->dup();
+    notify->setInt32("rtcp-event", 1);
+    // A Reception Report Block (RRB) can be included in both Sender Report and Receiver Report.
+    // But it means 'Packet Reception Report' actually.
+    // So that, we will report RRB as RR since there is no meaning difference
+    // between RRB(Reception Report Block) and RR(Receiver Report).
+    notify->setInt32("payload-type", RTCP_RR);
+    notify->setInt64("recv-time-us", recvTimeUs);
+    notify->setInt32("rtcp-rr-ssrc", senderId);
+    notify->setInt32("rtcp-rrb-ssrc", rrb->ssrc);
+    notify->setInt32("rtcp-rrb-fraction", rrb->fraction);
+    notify->setInt32("rtcp-rrb-lost", rrb->lost);
+    notify->setInt32("rtcp-rrb-lastSeq", rrb->lastSeq);
+    notify->setInt32("rtcp-rrb-jitter", rrb->jitter);
+    notify->setInt32("rtcp-rrb-lsr", rrb->lsr);
+    notify->setInt32("rtcp-rrb-dlsr", rrb->dlsr);
     notify->post();
 }
 
@@ -453,7 +476,8 @@
     data[18] = (mHighestSeqNumber >> 8) & 0xff;
     data[19] = mHighestSeqNumber & 0xff;
 
-    uint32_t jitterTime = 0;
+    uint32_t jitterTimeMs = (uint32_t)getInterArrivalJitterTimeMs();
+    uint32_t jitterTime = jitterTimeMs * mClockRate / 1000;
     data[20] = jitterTime >> 24;    // Interarrival jitter
     data[21] = (jitterTime >> 16) & 0xff;
     data[22] = (jitterTime >> 8) & 0xff;
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
index f959c40..39161b6 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
@@ -105,6 +105,27 @@
             (long long)rtp, (long long)play, (long long)exp, isExp);
 }
 
+struct ReceptionReportBlock : public RefBase {
+    uint32_t ssrc;       // ssrc of data source being reported
+    uint32_t fraction;   // fraction lost since last SR/RR
+    int32_t lost;        // cumul. no. pkts lost (signed!)
+    uint32_t lastSeq;    // extended last seq. no. received
+    uint32_t jitter;     // interarrival jitter
+    uint32_t lsr;        // last SR packet from this source
+    uint32_t dlsr;       // delay since last SR packet
+
+    ReceptionReportBlock(uint32_t ssrc, uint32_t fraction, int32_t lost, uint32_t lastSeq,
+            uint32_t jitter, uint32_t lsr, uint32_t dlsr) {
+        this->ssrc = ssrc;
+        this->fraction = fraction;
+        this->lost = lost;
+        this->lastSeq = lastSeq;
+        this->jitter = jitter;
+        this->lsr = lsr;
+        this->dlsr = dlsr;
+    }
+};
+
 }  // namespace android
 
 #endif  // A_RTP_ASSEMBLER_H_
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
index 36cca31..73d2866 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
@@ -110,7 +110,10 @@
     status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer);
     status_t parseRTPExt(StreamInfo *s, const uint8_t *extData, size_t extLen, int32_t *cvoDegrees);
     status_t parseRTCP(StreamInfo *info, const sp<ABuffer> &buffer);
-    status_t parseSR(StreamInfo *info, const uint8_t *data, size_t size);
+    status_t parseSenderReport(StreamInfo *info, const uint8_t *data, size_t size);
+    status_t parseReceiverReport(StreamInfo *info, const uint8_t *data, size_t size);
+    status_t parseReceptionReportBlock(StreamInfo *info,
+            int64_t recvTimeUs, uint32_t senderId, const uint8_t *data, size_t size);
     status_t parseTSFB(StreamInfo *info, const uint8_t *data, size_t size);
     status_t parsePSFB(StreamInfo *info, const uint8_t *data, size_t size);
     status_t parseBYE(StreamInfo *info, const uint8_t *data, size_t size);
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
index 4984e91..e9b4942 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
@@ -36,6 +36,7 @@
 struct ABuffer;
 struct AMessage;
 struct ARTPAssembler;
+struct ReceptionReportBlock;
 struct ASessionDescription;
 
 struct ARTPSource : public RefBase {
@@ -59,8 +60,10 @@
 
     void processRTPPacket(const sp<ABuffer> &buffer);
     void processRTPPacket();
+    void processReceptionReportBlock(
+            int64_t recvTimeUs, uint32_t senderId, sp<ReceptionReportBlock> rrb);
     void timeReset();
-    void timeUpdate(uint32_t rtpTime, uint64_t ntpTime);
+    void timeUpdate(int64_t recvTimeUs, uint32_t rtpTime, uint64_t ntpTime);
     void byeReceived();
 
     List<sp<ABuffer> > *queue() { return &mQueue; }
@@ -135,6 +138,8 @@
     uint64_t mLastSrNtpTime;
     int64_t mLastSrUpdateTimeUs;
 
+    int64_t mLastRrUpdateTimeUs;
+
     bool mIsFirstRtpRtcpGap;
     double mAvgRtpRtcpGapMs;
     double mAvgUnderlineDelayMs;