VT: Adjust an anchor time if packet comes too early.

[Problem] video played out with delay consistently.
[Cause] an anchor time set with delay if a first rtp
  packet came with delay.
[Solution] adjust anchor time if packets are coming
  too early than expected.

Bug: 183578712

Signed-off-by: Byeongjo Park <bjo.park@samsung.com>
Change-Id: I49ad1ad7e728dbb1d4ddb6f82f9a8072ad9c867d
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index 5d3960a..3f4d662 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -138,7 +138,7 @@
     }
     source->putInterArrivalJitterData(rtpTime, nowTimeUs);
 
-    const int64_t startTimeMs = source->mFirstSysTime / 1000;
+    const int64_t startTimeMs = source->mSysAnchorTime / 1000;
     const int64_t nowTimeMs = nowTimeUs / 1000;
     const int32_t staticJitterTimeMs = source->getStaticJitterTimeMs();
     const int32_t baseJitterTimeMs = source->getBaseJitterTimeMs();
diff --git a/media/libstagefright/rtsp/AHEVCAssembler.cpp b/media/libstagefright/rtsp/AHEVCAssembler.cpp
index adc7ee2..b240339 100644
--- a/media/libstagefright/rtsp/AHEVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AHEVCAssembler.cpp
@@ -148,7 +148,7 @@
     }
     source->putInterArrivalJitterData(rtpTime, nowTimeUs);
 
-    const int64_t startTimeMs = source->mFirstSysTime / 1000;
+    const int64_t startTimeMs = source->mSysAnchorTime / 1000;
     const int64_t nowTimeMs = nowTimeUs / 1000;
     const int32_t staticJitterTimeMs = source->getStaticJitterTimeMs();
     const int32_t baseJitterTimeMs = source->getBaseJitterTimeMs();
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 8429c0d..38a370b 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -47,6 +47,8 @@
     : mFirstRtpTime(0),
       mFirstSysTime(0),
       mClockRate(0),
+      mSysAnchorTime(0),
+      mLastSysAnchorTimeUpdatedUs(0),
       mFirstSsrc(0),
       mHighestNackNumber(0),
       mID(id),
@@ -64,6 +66,7 @@
       mLastSrUpdateTimeUs(0),
       mIsFirstRtpRtcpGap(true),
       mAvgRtpRtcpGapMs(0),
+      mAvgUnderlineDelayMs(0),
       mIssueFIRRequests(false),
       mIssueFIRByAssembler(false),
       mLastFIRRequestUs(-1),
@@ -147,6 +150,8 @@
 void ARTPSource::timeReset() {
     mFirstRtpTime = 0;
     mFirstSysTime = 0;
+    mSysAnchorTime = 0;
+    mLastSysAnchorTimeUpdatedUs = 0;
     mFirstSsrc = 0;
     mHighestNackNumber = 0;
     mHighestSeqNumber = 0;
@@ -162,16 +167,17 @@
     mLastSrUpdateTimeUs = 0;
     mIsFirstRtpRtcpGap = true;
     mAvgRtpRtcpGapMs = 0;
+    mAvgUnderlineDelayMs = 0;
     mIssueFIRByAssembler = false;
     mLastFIRRequestUs = -1;
 }
 
-void ARTPSource::calcTimeGapRtpRtcp(const sp<ABuffer> &buffer) {
+void ARTPSource::calcTimeGapRtpRtcp(const sp<ABuffer> &buffer, int64_t nowUs) {
     if (mLastSrUpdateTimeUs == 0) {
         return;
     }
 
-    int64_t elapsedMs = (ALooper::GetNowUs() - mLastSrUpdateTimeUs) / 1000;
+    int64_t elapsedMs = (nowUs - mLastSrUpdateTimeUs) / 1000;
     int64_t elapsedRtpTime = (elapsedMs * (mClockRate / 1000));
     uint32_t rtpTime;
     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
@@ -201,17 +207,51 @@
     }
 }
 
-bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
-    calcTimeGapRtpRtcp(buffer);
-    uint32_t seqNum = (uint32_t)buffer->int32Data();
+void ARTPSource::calcUnderlineDelay(const sp<ABuffer> &buffer, int64_t nowUs) {
+    int64_t elapsedMs = (nowUs - mSysAnchorTime) / 1000;
+    int64_t elapsedRtpTime = (elapsedMs * (mClockRate / 1000));
+    int64_t expectedRtpTime = mFirstRtpTime + elapsedRtpTime;
 
+    int32_t rtpTime;
+    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+    int32_t delayMs = (expectedRtpTime - rtpTime) / (mClockRate / 1000);
+
+    mAvgUnderlineDelayMs = ((mAvgUnderlineDelayMs * 15) + delayMs) / 16;
+}
+
+void ARTPSource::adjustAnchorTimeIfRequired(int64_t nowUs) {
+    if (nowUs - mLastSysAnchorTimeUpdatedUs < 1000000L) {
+        return;
+    }
+
+    if (mAvgUnderlineDelayMs < -30) {
+        // adjust underline delay a quarter of desired delay like step by step.
+        mSysAnchorTime += (int64_t)(mAvgUnderlineDelayMs * 1000 / 4);
+        ALOGD("anchor time updated: original(%lld), anchor(%lld), diffMs(%lld)",
+                (long long)mFirstSysTime, (long long)mSysAnchorTime,
+                (long long)(mFirstSysTime - mSysAnchorTime) / 1000);
+
+        mAvgUnderlineDelayMs = 0;
+        mLastSysAnchorTimeUpdatedUs = nowUs;
+
+        // reset a jitter stastics since an anchor time adjusted.
+        mJitterCalc->init(mFirstRtpTime, mSysAnchorTime, 0, mStaticJbTimeMs * 1000);
+    }
+}
+
+bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
+    int64_t nowUs = ALooper::GetNowUs();
+    uint32_t seqNum = (uint32_t)buffer->int32Data();
     int32_t ssrc = 0, rtpTime = 0;
+
     buffer->meta()->findInt32("ssrc", &ssrc);
     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
     mLatestRtpTime = rtpTime;
 
     if (mNumBuffersReceived++ == 0 && mFirstSysTime == 0) {
-        mFirstSysTime = ALooper::GetNowUs();
+        mFirstSysTime = nowUs;
+        mSysAnchorTime = nowUs;
+        mLastSysAnchorTimeUpdatedUs = nowUs;
         mHighestSeqNumber = seqNum;
         mBaseSeqNumber = seqNum;
         mFirstRtpTime = rtpTime;
@@ -233,6 +273,10 @@
         return false;
     }
 
+    calcTimeGapRtpRtcp(buffer, nowUs);
+    calcUnderlineDelay(buffer, nowUs);
+    adjustAnchorTimeIfRequired(nowUs);
+
     // 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 97e6d77..c625204 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -94,6 +94,9 @@
     int64_t mFirstSysTime;
     int32_t mClockRate;
 
+    int64_t mSysAnchorTime;
+    int64_t mLastSysAnchorTimeUpdatedUs;
+
     int32_t mFirstSsrc;
     int32_t mHighestNackNumber;
 
@@ -134,6 +137,7 @@
 
     bool mIsFirstRtpRtcpGap;
     double mAvgRtpRtcpGapMs;
+    double mAvgUnderlineDelayMs;
     int64_t mLastJbAlarmTimeUs;
 
     bool mIssueFIRRequests;
@@ -143,7 +147,10 @@
 
     sp<AMessage> mNotify;
 
-    void calcTimeGapRtpRtcp(const sp<ABuffer> &buffer);
+    void calcTimeGapRtpRtcp(const sp<ABuffer> &buffer, int64_t nowUs);
+    void calcUnderlineDelay(const sp<ABuffer> &buffer, int64_t nowUs);
+    void adjustAnchorTimeIfRequired(int64_t nowUs);
+
     bool queuePacket(const sp<ABuffer> &buffer);
 
     DISALLOW_EVIL_CONSTRUCTORS(ARTPSource);