LiveSession: raise upwards adaptation constraint

Adjust bandwidth more conservatively when considering an upwards
adaptation. Also fixed an issue with kWhatCheckBandwidth messages
being accumulated across switch generations; this causes
onCheckBandwidth to be fired at a high frequency and LiveSession to
be too sensitive to network glitches.

Bug: 13743153
Change-Id: I1dec99cb5d123c6675abe0847fd12aab5178eefd
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 7b18348..02ebfc7 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -498,7 +498,7 @@
                 break;
             }
 
-            onCheckBandwidth();
+            onCheckBandwidth(msg);
             break;
         }
 
@@ -919,14 +919,22 @@
             }
         }
 
-        // Consider only 80% of the available bandwidth usable.
-        bandwidthBps = (bandwidthBps * 8) / 10;
-
         // Pick the highest bandwidth stream below or equal to estimated bandwidth.
 
         index = mBandwidthItems.size() - 1;
-        while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth
-                                > (size_t)bandwidthBps) {
+        while (index > 0) {
+            // consider only 80% of the available bandwidth, but if we are switching up,
+            // be even more conservative (70%) to avoid overestimating and immediately
+            // switching back.
+            size_t adjustedBandwidthBps = bandwidthBps;
+            if (index > mCurBandwidthIndex) {
+                adjustedBandwidthBps = adjustedBandwidthBps * 7 / 10;
+            } else {
+                adjustedBandwidthBps = adjustedBandwidthBps * 8 / 10;
+            }
+            if (mBandwidthItems.itemAt(index).mBandwidth <= adjustedBandwidthBps) {
+                break;
+            }
             --index;
         }
     }
@@ -1394,6 +1402,7 @@
     // All fetchers have now been started, the configuration change
     // has completed.
 
+    cancelCheckBandwidthEvent();
     scheduleCheckBandwidthEvent();
 
     ALOGV("XXX configuration change completed.");
@@ -1492,20 +1501,16 @@
     }
 }
 
-void LiveSession::onCheckBandwidth() {
+void LiveSession::onCheckBandwidth(const sp<AMessage> &msg) {
     size_t bandwidthIndex = getBandwidthIndex();
     if (canSwitchBandwidthTo(bandwidthIndex)) {
         changeConfiguration(-1ll /* timeUs */, bandwidthIndex);
     } else {
-        scheduleCheckBandwidthEvent();
+        // Come back and check again 10 seconds later in case there is nothing to do now.
+        // If we DO change configuration, once that completes it'll schedule a new
+        // check bandwidth event with an incremented mCheckBandwidthGeneration.
+        msg->post(10000000ll);
     }
-
-    // Handling the kWhatCheckBandwidth even here does _not_ automatically
-    // schedule another one on return, only an explicit call to
-    // scheduleCheckBandwidthEvent will do that.
-    // This ensures that only one configuration change is ongoing at any
-    // one time, once that completes it'll schedule another check bandwidth
-    // event.
 }
 
 void LiveSession::postPrepared(status_t err) {
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 5423f0f..aa06a3f 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -257,7 +257,7 @@
     void cancelBandwidthSwitch();
 
     bool canSwitchBandwidthTo(size_t bandwidthIndex);
-    void onCheckBandwidth();
+    void onCheckBandwidth(const sp<AMessage> &msg);
 
     void finishDisconnect();