Bug 1254187: Fix maxBitrate to respect simulcast. r=jesup draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Fri, 01 Apr 2016 15:10:47 -0500
changeset 346985 2b25f67832214cc9f6f816e9a70c119329a7b083
parent 346552 538d248fa252a4100082fd9bc3fdc08d322cda22
child 517524 90b5bc1005a962a734875e51a7dbe73d747f84e8
push id14466
push userbcampen@mozilla.com
push dateFri, 01 Apr 2016 20:11:14 +0000
reviewersjesup
bugs1254187
milestone48.0a1
Bug 1254187: Fix maxBitrate to respect simulcast. r=jesup MozReview-Commit-ID: 51dz5y0q6qQ
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -1283,16 +1283,23 @@ WebrtcVideoConduit::ReconfigureSendCodec
   vie_codec.height = height;
   vie_codec.maxFramerate = mSendingFramerate;
   SelectBitrates(vie_codec.width, vie_codec.height, 0,
                  mLastFramerateTenths,
                  vie_codec.minBitrate,
                  vie_codec.startBitrate,
                  vie_codec.maxBitrate);
 
+  // These are based on lowest-fidelity, because if there is insufficient
+  // bandwidth for all streams, only the lowest fidelity one will be sent.
+  uint32_t minMinBitrate = 0;
+  uint32_t minStartBitrate = 0;
+  // Total for all simulcast streams.
+  uint32_t totalMaxBitrate = 0;
+
   for (size_t i = vie_codec.numberOfSimulcastStreams; i > 0; --i) {
     webrtc::SimulcastStream& stream(vie_codec.simulcastStream[i - 1]);
     stream.width = width;
     stream.height = height;
     MOZ_ASSERT(stream.jsScaleDownBy >= 1.0);
     uint32_t new_width = uint32_t(width / stream.jsScaleDownBy);
     uint32_t new_height = uint32_t(height / stream.jsScaleDownBy);
     // TODO: If two layers are similar, only alloc bits to one (Bug 1249859)
@@ -1305,35 +1312,40 @@ WebrtcVideoConduit::ReconfigureSendCodec
         // webrtc.org supposedly won't tolerate simulcast unless every stream
         // is exactly the same aspect ratio. 320x240 / 3 = 80x60.
         ConstrainPreservingAspectRatioExact(new_width*new_height,
                                             &stream.width, &stream.height);
       }
     }
     // Give each layer default appropriate bandwidth limits based on the
     // resolution/framerate of that layer
-    SelectBitrates(stream.width, stream.height, stream.jsMaxBitrate,
+    SelectBitrates(stream.width, stream.height,
+                   MinIgnoreZero(stream.jsMaxBitrate, vie_codec.maxBitrate),
                    mLastFramerateTenths,
                    stream.minBitrate,
                    stream.targetBitrate,
                    stream.maxBitrate);
 
-    vie_codec.minBitrate = std::min(stream.minBitrate, vie_codec.minBitrate);
-    vie_codec.startBitrate += stream.targetBitrate;
-    vie_codec.maxBitrate = std::max(stream.maxBitrate, vie_codec.maxBitrate);
-
     // webrtc.org expects the last, highest fidelity, simulcast stream to
     // always have the same resolution as vie_codec
+    // Also set the least user-constrained of the stream bitrates on vie_codec.
     if (i == vie_codec.numberOfSimulcastStreams) {
       vie_codec.width = stream.width;
       vie_codec.height = stream.height;
     }
+    minMinBitrate = MinIgnoreZero(stream.minBitrate, minMinBitrate);
+    minStartBitrate = MinIgnoreZero(stream.targetBitrate, minStartBitrate);
+    totalMaxBitrate += stream.maxBitrate;
   }
   if (vie_codec.numberOfSimulcastStreams != 0) {
-    vie_codec.startBitrate /= vie_codec.numberOfSimulcastStreams;
+    vie_codec.minBitrate = std::max(minMinBitrate, vie_codec.minBitrate);
+    vie_codec.maxBitrate = std::min(totalMaxBitrate, vie_codec.maxBitrate);
+    vie_codec.startBitrate = std::max(vie_codec.minBitrate,
+                                      std::min(minStartBitrate,
+                                               vie_codec.maxBitrate));
   }
   if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0)
   {
     CSFLogError(logTag, "%s: SetSendCodec(%ux%u) failed, err %d",
                 __FUNCTION__, width, height, err);
     return NS_ERROR_FAILURE;
   }
   if (mMinBitrateEstimate != 0) {