Bug 1254187 - fix maxBitrate to respect simulcast. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Fri, 11 Mar 2016 14:18:26 -0500
changeset 340724 b59023ac345564efb47ae073840e5990dd68c1e5
parent 340723 b3612eb14d1f18b347916fb71013b8e5b0e5e4d5
child 516258 1256171ec239a285495eaead58548e4c7745bdfe
push id13044
push userjbruaroey@mozilla.com
push dateTue, 15 Mar 2016 22:14:02 +0000
bugs1254187
milestone48.0a1
Bug 1254187 - fix maxBitrate to respect simulcast. MozReview-Commit-ID: 51dz5y0q6qQ
dom/media/tests/mochitest/test_peerConnection_simulcastOffer.html
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
--- a/dom/media/tests/mochitest/test_peerConnection_simulcastOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_simulcastOffer.html
@@ -76,18 +76,18 @@
       test.chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
         function PC_LOCAL_SET_RIDS(test) {
           var senders = test.pcLocal._pc.getSenders();
           is(senders.length, 1, "We have exactly one RTP sender");
           var sender = senders[0];
           ok(sender.track, "Sender has a track");
 
           return sender.setParameters({
-            encodings: [{ rid: "foo", maxBitrate: 40000 },
-                        { rid: "bar", maxBitrate: 40000, scaleResolutionDownBy: 2 }]
+            encodings: [{ rid: "foo", maxBitrate: 200000 },
+                        { rid: "bar", maxBitrate: 200000, scaleResolutionDownBy: 2 }]
           });
         }
       ]);
 
       test.chain.insertAfter('PC_LOCAL_GET_ANSWER', [
         function PC_LOCAL_ADD_RIDS_TO_ANSWER(test) {
           test._remote_answer.sdp = sdputils.transferSimulcastProperties(
             test.originalOffer.sdp, test._remote_answer.sdp);
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -1282,16 +1282,21 @@ 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);
 
+  // Find the highest fidelity stream settings.
+  uint32_t hifiMinBitrate = 0;
+  uint32_t hifiStartBitrate = 0;
+  uint32_t hifiMaxBitrate = 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)
@@ -1304,35 +1309,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,
+                   std::min(stream.jsMaxBitrate, vie_codec.maxBitrate),
                    mLastFramerateTenths,
                    stream.minBitrate,
                    stream.targetBitrate,
                    stream.maxBitrate);
 
-    vie_codec.minBitrate = std::max(stream.minBitrate, vie_codec.minBitrate);
-    vie_codec.startBitrate += stream.targetBitrate;
-    vie_codec.maxBitrate = std::min(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;
     }
+    hifiMinBitrate = std::max(stream.minBitrate, hifiMinBitrate);
+    hifiStartBitrate = std::max(stream.targetBitrate, hifiStartBitrate);
+    hifiMaxBitrate = std::max(stream.maxBitrate, hifiMaxBitrate);
   }
   if (vie_codec.numberOfSimulcastStreams != 0) {
-    vie_codec.startBitrate /= vie_codec.numberOfSimulcastStreams;
+    vie_codec.minBitrate = std::max(hifiMinBitrate, vie_codec.minBitrate);
+    vie_codec.maxBitrate = std::min(hifiMaxBitrate, vie_codec.maxBitrate);
+    vie_codec.startBitrate = std::max(vie_codec.minBitrate,
+                                      std::min(hifiStartBitrate,
+                                               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) {