Merge "VT: Add auto downgrade function" am: d5a24879c6

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/953058

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ia1cb6774ef0e5368f426eccf5b6b94e210a938b4
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 4d33b4e..44423f8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2848,6 +2848,7 @@
     switch (payloadType) {
         case NuPlayer::RTPSource::RTCP_TSFB:   // RTCP TSFB
         case NuPlayer::RTPSource::RTCP_PSFB:   // RTCP PSFB
+        case NuPlayer::RTPSource::RTP_AUTODOWN:
         {
             int32_t feedbackType, id;
             CHECK(msg->findInt32("feedback-type", &feedbackType));
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.h b/media/libmediaplayerservice/nuplayer/RTPSource.h
index d7084d4..efbf6d2 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.h
@@ -57,6 +57,7 @@
         RTCP_TSFB = 205,
         RTCP_PSFB = 206,
         RTP_CVO = 300,
+        RTP_AUTODOWN = 400,
     };
 
     virtual status_t getBufferingSettings(
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 90d1a8f..07ece6a 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -416,6 +416,12 @@
 
             if (err == -ECONNRESET) {
                 // socket failure, this stream is dead, Jim.
+                sp<AMessage> notify = it->mNotifyMsg->dup();
+                notify->setInt32("IMS-Rx-notice", 1);
+                notify->setInt32("payload-type", 400);
+                notify->setInt32("feedback-type", 1);
+                notify->setInt32("sender", it->mSources.valueAt(0)->getSelfID());
+                notify->post();
 
                 ALOGW("failed to receive RTP/RTCP datagram.");
                 it = mStreams.erase(it);
@@ -1016,8 +1022,17 @@
 
             for (size_t i = 0; i < s->mSources.size(); ++i) {
                 sp<ARTPSource> source = s->mSources.valueAt(i);
+                source->setBitrateData(bitrate, nowUs);
                 source->setTargetBitrate();
                 source->addTMMBR(buffer);
+                if (source->isNeedToDowngrade()) {
+                    sp<AMessage> notify = s->mNotifyMsg->dup();
+                    notify->setInt32("IMS-Rx-notice", 1);
+                    notify->setInt32("payload-type", 400);
+                    notify->setInt32("feedback-type", 1);
+                    notify->setInt32("sender", source->getSelfID());
+                    notify->post();
+                }
             }
             if (buffer->size() > 0) {
                 ALOGV("Sending TMMBR...");
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 33b1772..ee4b7c2 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -379,6 +379,10 @@
     mQualManager.setMinMaxBitrate(min, max);
 }
 
+void ARTPSource::setBitrateData(int32_t bitrate, int64_t time) {
+    mQualManager.setBitrateData(bitrate, time);
+}
+
 void ARTPSource::setTargetBitrate() {
     uint8_t fraction = 0;
 
@@ -403,6 +407,10 @@
     return (intervalReceived > 0) ? true : false;
 }
 
+bool ARTPSource::isNeedToDowngrade() {
+    return mQualManager.isNeedToDowngrade();
+}
+
 void ARTPSource::noticeAbandonBuffer(int cnt) {
     mNumBuffersReceived -= cnt;
 }
diff --git a/media/libstagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/ARTPSource.h
index 5b1ae73..652e753 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -50,9 +50,11 @@
     uint32_t getSelfID();
     void setSelfID(const uint32_t selfID);
     void setMinMaxBitrate(int32_t min, int32_t max);
+    void setBitrateData(int32_t bitrate, int64_t time);
     void setTargetBitrate();
 
     bool isNeedToReport();
+    bool isNeedToDowngrade();
 
     void noticeAbandonBuffer(int cnt=1);
 
diff --git a/media/libstagefright/rtsp/QualManager.h b/media/libstagefright/rtsp/QualManager.h
index f6671ba..ee2fb40 100644
--- a/media/libstagefright/rtsp/QualManager.h
+++ b/media/libstagefright/rtsp/QualManager.h
@@ -24,6 +24,7 @@
 public:
     QualManager() : mMinBitrate(-1), mMaxBitrate(-1), mTargetBitrate(512000),
                     mLastTargetBitrate(-1), mLastSetBitrateTime(0),
+                    mLowBitrateStartTime(0), mAutoDowngrade(false),
                     mIsNewTargetBitrate(false){};
 
     int32_t getTargetBitrate() {
@@ -36,6 +37,10 @@
         }
     }
 
+    bool isNeedToDowngrade() {
+        return mAutoDowngrade;
+    }
+
     void setTargetBitrate(uint8_t fraction, int64_t nowUs) {
         if (fraction <= (256 * 2 /100)) {           // loss less than 2%
             mTargetBitrate += mBitrateStep;
@@ -46,6 +51,9 @@
         if (mTargetBitrate > mMaxBitrate) {
             mTargetBitrate = mMaxBitrate;
         } else if (mTargetBitrate < mMinBitrate) {
+            if (mLowBitrateStartTime != 0) {
+                mLowBitrateStartTime = nowUs;
+            }
             mTargetBitrate = mMinBitrate;
         }
 
@@ -60,6 +68,25 @@
         mMaxBitrate = max;
         mBitrateStep = (max - min) / 8;
     };
+
+    void setBitrateData(int32_t bitrate, int64_t now) {
+        int64_t lowBitrateDuration = 0;
+        if (bitrate < mMinBitrate)
+        {
+            if (mLowBitrateStartTime == 0) {
+                mLowBitrateStartTime = now;
+            } else {
+                lowBitrateDuration = now - mLowBitrateStartTime;
+            }
+        } else {
+            mLowBitrateStartTime = 0;
+        }
+        if (lowBitrateDuration > mPatientTime) {
+            mAutoDowngrade = true;
+        } else {
+            mAutoDowngrade = false;
+        }
+    }
 private:
     int32_t mMinBitrate;
     int32_t mMaxBitrate;
@@ -70,6 +97,10 @@
 
     int64_t mLastSetBitrateTime;
 
+    const int64_t mPatientTime = 10000000ll;    // 10 sec
+    int64_t mLowBitrateStartTime;
+
+    bool mAutoDowngrade;
     bool mIsNewTargetBitrate;
 };