VT: Increase TMMBR reaction speed

1. More immediate TMMBR sending as like NACK & FIR
2. RTP notification of packet info is sent immediately by a delicate bad N/W sign
    - The notification is independent of legacy regular notification
    - It's defined as 'early notification'
    - This early notification can derive faster reaction against the bad N/W
3. Change the place of definition of message type for RTP notifications
    - RTPSource.h -> ARTPSource.h

Bug: 175266635

Change-Id: I12af66ef3b4a150996990bb22640109953a8ec79
Signed-off-by: Kim Sungyeon <sy85.kim@samsung.com>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 47362ef..389249e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2858,23 +2858,24 @@
     in.writeInt32(payloadType);
 
     switch (payloadType) {
-        case NuPlayer::RTPSource::RTCP_TSFB:   // RTCP TSFB
-        case NuPlayer::RTPSource::RTCP_PSFB:   // RTCP PSFB
-        case NuPlayer::RTPSource::RTP_AUTODOWN:
+        case ARTPSource::RTCP_TSFB:   // RTCP TSFB
+        case ARTPSource::RTCP_PSFB:   // RTCP PSFB
+        case ARTPSource::RTP_AUTODOWN:
         {
             int32_t feedbackType, id;
             CHECK(msg->findInt32("feedback-type", &feedbackType));
             CHECK(msg->findInt32("sender", &id));
             in.writeInt32(feedbackType);
             in.writeInt32(id);
-            if (payloadType == NuPlayer::RTPSource::RTCP_TSFB) {
+            if (payloadType == ARTPSource::RTCP_TSFB) {
                 int32_t bitrate;
                 CHECK(msg->findInt32("bit-rate", &bitrate));
                 in.writeInt32(bitrate);
             }
             break;
         }
-        case NuPlayer::RTPSource::RTP_QUALITY:
+        case ARTPSource::RTP_QUALITY:
+        case ARTPSource::RTP_QUALITY_EMC:
         {
             int32_t feedbackType, bitrate;
             int32_t highestSeqNum, baseSeqNum, prevExpected;
@@ -2895,7 +2896,7 @@
             in.writeInt32(prevNumBufRecv);
             break;
         }
-        case NuPlayer::RTPSource::RTP_CVO:
+        case ARTPSource::RTP_CVO:
         {
             int32_t cvo;
             CHECK(msg->findInt32("cvo", &cvo));
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.cpp b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
index f87eece..b43df38 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
@@ -299,7 +299,7 @@
     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("payload-type", ARTPSource::RTP_CVO);
         msg->setInt32("cvo", cvo);
 
         sp<AMessage> notify = dupNotify();
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.h b/media/libmediaplayerservice/nuplayer/RTPSource.h
index fb2d3b9..3b4f9e9 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.h
@@ -33,6 +33,7 @@
 #include "AnotherPacketSource.h"
 #include "APacketSource.h"
 #include "ARTPConnection.h"
+#include "ARTPSource.h"
 #include "ASessionDescription.h"
 #include "NuPlayerSource.h"
 
@@ -51,16 +52,6 @@
             const sp<AMessage> &notify,
             const String8& rtpParams);
 
-    enum {
-        RTP_FIRST_PACKET = 100,
-        RTCP_FIRST_PACKET = 101,
-        RTP_QUALITY = 102,
-        RTCP_TSFB = 205,
-        RTCP_PSFB = 206,
-        RTP_CVO = 300,
-        RTP_AUTODOWN = 400,
-    };
-
     virtual status_t getBufferingSettings(
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 97a9bbb..73c94e8 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -464,6 +464,22 @@
                     ALOGD("Send FIR immediately for lost Packets");
                     send(&*it, buffer);
                 }
+
+                buffer->setRange(0, 0);
+                it->mSources.valueAt(i)->addTMMBR(buffer, mTargetBitrate);
+                mTargetBitrate = -1;
+                if (buffer->size() > 0) {
+                    ALOGV("Sending TMMBR...");
+                    ssize_t n = send(&*it, buffer);
+
+                    if (n != (ssize_t)buffer->size()) {
+                        ALOGW("failed to send RTCP TMMBR (%s).",
+                                n >= 0 ? "connection gone" : strerror(errno));
+
+                        it = mStreams.erase(it);
+                        continue;
+                    }
+                }
             }
 
             ++it;
@@ -509,16 +525,14 @@
 
                 ssize_t n = send(s, buffer);
 
-                if (n <= 0) {
+                if (n != (ssize_t)buffer->size()) {
                     ALOGW("failed to send RTCP receiver report (%s).",
-                         n == 0 ? "connection gone" : strerror(errno));
+                            n >= 0 ? "connection gone" : strerror(errno));
 
                     it = mStreams.erase(it);
                     continue;
                 }
 
-                CHECK_EQ(n, (ssize_t)buffer->size());
-
                 mLastReceiverReportTimeUs = nowUs;
             }
 
@@ -1079,6 +1093,28 @@
         mCumulativeBytes = 0;
         mLastBitrateReportTimeUs = nowUs;
     }
+    else if (mLastEarlyNotifyTimeUs + 100000ll <= nowUs) {
+        int32_t timeDiff = (nowUs - mLastBitrateReportTimeUs) / 1000000ll;
+        int32_t bitrate = mCumulativeBytes * 8 / timeDiff;
+        mLastEarlyNotifyTimeUs = nowUs;
+
+        List<StreamInfo>::iterator it = mStreams.begin();
+        while (it != mStreams.end()) {
+            StreamInfo *s = &*it;
+            if (s->mIsInjected) {
+                ++it;
+                continue;
+            }
+            for (size_t i = 0; i < s->mSources.size(); ++i) {
+                sp<ARTPSource> source = s->mSources.valueAt(i);
+                if (source->isNeedToEarlyNotify()) {
+                    source->notifyPktInfo(bitrate, false /* isRegular */);
+                    mLastEarlyNotifyTimeUs = nowUs + (1000000ll * 3600 * 24); // after 1 day
+                }
+            }
+            ++it;
+        }
+    }
     else if (mLastBitrateReportTimeUs + 1000000ll <= nowUs) {
         int32_t timeDiff = (nowUs - mLastBitrateReportTimeUs) / 1000000ll;
         int32_t bitrate = mCumulativeBytes * 8 / timeDiff;
@@ -1101,31 +1137,15 @@
             }
 
             buffer->setRange(0, 0);
-
             for (size_t i = 0; i < s->mSources.size(); ++i) {
                 sp<ARTPSource> source = s->mSources.valueAt(i);
-                source->notifyPktInfo(bitrate, nowUs);
-                source->addTMMBR(buffer, mTargetBitrate);
-            }
-            if (buffer->size() > 0) {
-                ALOGV("Sending TMMBR...");
-
-                ssize_t n = send(s, buffer);
-
-                if (n <= 0) {
-                    ALOGW("failed to send RTCP TMMBR (%s).",
-                         n == 0 ? "connection gone" : strerror(errno));
-
-                    it = mStreams.erase(it);
-                    continue;
-                }
-
-                CHECK_EQ(n, (ssize_t)buffer->size());
+                source->notifyPktInfo(bitrate, true /* isRegular */);
             }
             ++it;
         }
         mCumulativeBytes = 0;
         mLastBitrateReportTimeUs = nowUs;
+        mLastEarlyNotifyTimeUs = nowUs;
     }
 }
 void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h
index 7c8218f..a37ac0e 100644
--- a/media/libstagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/ARTPConnection.h
@@ -84,6 +84,7 @@
     bool mPollEventPending;
     int64_t mLastReceiverReportTimeUs;
     int64_t mLastBitrateReportTimeUs;
+    int64_t mLastEarlyNotifyTimeUs;
 
     int32_t mSelfID;
     int32_t mTargetBitrate;
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index c611f6f..25821c8 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -512,10 +512,22 @@
     mIssueFIRRequests = enable;
 }
 
-void ARTPSource::notifyPktInfo(int32_t bitrate, int64_t /*time*/) {
+bool ARTPSource::isNeedToEarlyNotify() {
+    uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
+    int32_t intervalExpectedInNow = expected - mPrevExpected;
+    int32_t intervalReceivedInNow = mNumBuffersReceived - mPrevNumBuffersReceived;
+
+    if (intervalExpectedInNow - intervalReceivedInNow > 5)
+        return true;
+    return false;
+}
+
+void ARTPSource::notifyPktInfo(int32_t bitrate, bool isRegular) {
+    int32_t payloadType = isRegular ? RTP_QUALITY : RTP_QUALITY_EMC;
+
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("rtcp-event", 1);
-    notify->setInt32("payload-type", 102);
+    notify->setInt32("payload-type", payloadType);
     notify->setInt32("feedback-type", 0);
     // sending target bitrate up to application to share rtp quality.
     notify->setInt32("bit-rate", bitrate);
@@ -526,9 +538,11 @@
     notify->setInt32("prev-num-buf-recv", mPrevNumBuffersReceived);
     notify->post();
 
-    uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
-    mPrevExpected = expected;
-    mPrevNumBuffersReceived = mNumBuffersReceived;
+    if (isRegular) {
+        uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
+        mPrevExpected = expected;
+        mPrevNumBuffersReceived = mNumBuffersReceived;
+    }
 }
 
 void ARTPSource::onIssueFIRByAssembler() {
diff --git a/media/libstagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/ARTPSource.h
index ea683a0..c51fd8a 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -40,6 +40,17 @@
             const sp<ASessionDescription> &sessionDesc, size_t index,
             const sp<AMessage> &notify);
 
+    enum {
+        RTP_FIRST_PACKET = 100,
+        RTCP_FIRST_PACKET = 101,
+        RTP_QUALITY = 102,
+        RTP_QUALITY_EMC = 103,
+        RTCP_TSFB = 205,
+        RTCP_PSFB = 206,
+        RTP_CVO = 300,
+        RTP_AUTODOWN = 400,
+    };
+
     void processRTPPacket(const sp<ABuffer> &buffer);
     void timeUpdate(uint32_t rtpTime, uint64_t ntpTime);
     void byeReceived();
@@ -55,7 +66,8 @@
     void setSelfID(const uint32_t selfID);
     void setJbTime(const uint32_t jbTimeMs);
     void setPeriodicFIR(bool enable);
-    void notifyPktInfo(int32_t bitrate, int64_t time);
+    bool isNeedToEarlyNotify();
+    void notifyPktInfo(int32_t bitrate, bool isRegular);
     // FIR needs to be sent by missing packet or broken video image.
     void onIssueFIRByAssembler();