Bug 1308481: process maxBr/TIAS setting for all codecs, not just H264 r=bwc
☠☠ backed out by 787c66dd535f ☠ ☠
authorRandell Jesup <rjesup@jesup.org>
Sun, 20 Nov 2016 03:55:41 -0500
changeset 323526 6a57b36e6c173803831562bce0ad45ec597b8f25
parent 323525 f3511bf4d1448df2252e8bdd1aa7e057f54266bd
child 323527 787c66dd535fc380ced60ce4aaf68926c5c163dc
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1308481
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1308481: process maxBr/TIAS setting for all codecs, not just H264 r=bwc
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.h
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -44,16 +44,22 @@
 
 namespace mozilla {
 
 static const char* logTag ="WebrtcVideoSessionConduit";
 
 // 32 bytes is what WebRTC CodecInst expects
 const unsigned int WebrtcVideoConduit::CODEC_PLNAME_SIZE = 32;
 
+template<typename T>
+T MinIgnoreZero(const T& a, const T& b)
+{
+  return std::min(a? a:b, b? b:a);
+}
+
 /**
  * Factory Method for VideoConduit
  */
 RefPtr<VideoSessionConduit>
 VideoSessionConduit::Create()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   CSFLogDebug(logTag,  "%s ", __FUNCTION__);
@@ -90,17 +96,18 @@ WebrtcVideoConduit::WebrtcVideoConduit()
   mReceivingHeight(0),
   mSendingFramerate(DEFAULT_VIDEO_MAX_FRAMERATE),
   mLastFramerateTenths(DEFAULT_VIDEO_MAX_FRAMERATE*10),
   mNumReceivingStreams(1),
   mVideoLatencyTestEnable(false),
   mVideoLatencyAvg(0),
   mMinBitrate(0),
   mStartBitrate(0),
-  mMaxBitrate(0),
+  mPrefMaxBitrate(0),
+  mNegotiatedMaxBitrate(0),
   mMinBitrateEstimate(0),
   mRtpStreamIdEnabled(false),
   mRtpStreamIdExtId(0),
   mCodecMode(webrtc::kRealtimeVideo)
 {}
 
 WebrtcVideoConduit::~WebrtcVideoConduit()
 {
@@ -290,27 +297,28 @@ WebrtcVideoConduit::InitMain()
       {
          if (temp >= 0) {
          mStartBitrate = temp;
          }
       }
       if (!NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp))))
       {
         if (temp >= 0) {
-          mMaxBitrate = temp;
+          mPrefMaxBitrate = temp;
+          mNegotiatedMaxBitrate = temp; // simplifies logic in SelectBitrate (don't have to do two limit tests)
         }
       }
       if (mMinBitrate != 0 && mMinBitrate < webrtc::kViEMinCodecBitrate) {
         mMinBitrate = webrtc::kViEMinCodecBitrate;
       }
       if (mStartBitrate < mMinBitrate) {
         mStartBitrate = mMinBitrate;
       }
-      if (mStartBitrate > mMaxBitrate) {
-        mStartBitrate = mMaxBitrate;
+      if (mPrefMaxBitrate && mStartBitrate > mPrefMaxBitrate) {
+        mStartBitrate = mPrefMaxBitrate;
       }
       if (!NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate_estimate", &temp))))
       {
         if (temp >= 0) {
           mMinBitrateEstimate = temp;
         }
       }
       bool use_loadmanager = false;
@@ -738,16 +746,18 @@ WebrtcVideoConduit::ConfigureSendMediaCo
     video_codec.width = mSendingWidth;
     video_codec.height = mSendingHeight;
     video_codec.maxFramerate = mSendingFramerate;
   } else {
     mSendingWidth = 0;
     mSendingHeight = 0;
     mSendingFramerate = video_codec.maxFramerate;
   }
+  // So we can comply with b=TIAS/b=AS/maxbr=X when input resolution changes
+  mNegotiatedMaxBitrate = MinIgnoreZero(mPrefMaxBitrate, video_codec.maxBitrate);
 
   video_codec.mode = mCodecMode;
 
   if(mPtrViECodec->SetSendCodec(mChannel, video_codec) == -1)
   {
     error = mPtrViEBase->LastError();
     if(error == kViECodecInvalidCodec)
     {
@@ -1089,22 +1099,16 @@ WebrtcVideoConduit::ConfigureRecvMediaCo
 
   // by now we should be successfully started the reception
   CSFLogDebug(logTag, "REMB enabled for video stream %s",
               (use_remb ? "yes" : "no"));
   mPtrRTP->SetRembStatus(mChannel, use_remb, true);
   return kMediaConduitNoError;
 }
 
-template<typename T>
-T MinIgnoreZero(const T& a, const T& b)
-{
-  return std::min(a? a:b, b? b:a);
-}
-
 struct ResolutionAndBitrateLimits {
   uint32_t resolution_in_mb;
   uint16_t min_bitrate;
   uint16_t start_bitrate;
   uint16_t max_bitrate;
 };
 
 #define MB_OF(w,h) ((unsigned int)((((w+15)>>4))*((unsigned int)((h+15)>>4))))
@@ -1173,23 +1177,25 @@ WebrtcVideoConduit::SelectBitrates(unsig
   // If we try to set a minimum bitrate that is too low, ViE will reject it.
   out_min = std::max((unsigned int) webrtc::kViEMinCodecBitrate,
                                   out_min);
   if (mStartBitrate && mStartBitrate > out_start) {
     out_start = mStartBitrate;
   }
   out_start = std::max(out_start, out_min);
 
-  // Note: mMaxBitrate is the max transport bitrate - it applies to a
-  // single codec encoding, but should also apply to the sum of all
-  // simulcast layers in this encoding!
-  // So sum(layers.maxBitrate) <= mMaxBitrate
-  if (mMaxBitrate && mMaxBitrate > out_max) {
-    out_max = mMaxBitrate;
+  // Note: mNegotiatedMaxBitrate is the max transport bitrate - it applies to
+  // a single codec encoding, but should also apply to the sum of all
+  // simulcast layers in this encoding!  So sum(layers.maxBitrate) <=
+  // mNegotiatedMaxBitrate
+  // Note that out_max already has had mPrefMaxBitrate applied to it
+  if (mNegotiatedMaxBitrate != 0 && mNegotiatedMaxBitrate > out_max) {
+    out_max = mNegotiatedMaxBitrate;
   }
+  MOZ_ASSERT(out_max <= mPrefMaxBitrate);
 }
 
 static void ConstrainPreservingAspectRatioExact(uint32_t max_fs,
                                                 unsigned short* width,
                                                 unsigned short* height)
 {
   // We could try to pick a better starting divisor, but it won't make any real
   // performance difference.
@@ -1964,34 +1970,30 @@ WebrtcVideoConduit::CodecConfigToWebRTCC
     cinst.maxFramerate = DEFAULT_VIDEO_MAX_FRAMERATE;
   }
 
   // Defaults if rates aren't forced by pref.  Typically defaults are
   // overridden on the first video frame.
   cinst.minBitrate = mMinBitrate ? mMinBitrate : 200;
   cinst.startBitrate = mStartBitrate ? mStartBitrate : 300;
   cinst.targetBitrate = cinst.startBitrate;
-  cinst.maxBitrate = mMaxBitrate ? mMaxBitrate : 2000;
+  cinst.maxBitrate = MinIgnoreZero(2000U, codecInfo->mEncodingConstraints.maxBr)/1000;
+  // not mNegotiatedMaxBitrate! cinst.maxBitrate is the max for the codec, which will be overridden
+  cinst.maxBitrate = MinIgnoreZero(cinst.maxBitrate, mPrefMaxBitrate);
 
   if (cinst.codecType == webrtc::kVideoCodecH264)
   {
 #ifdef MOZ_WEBRTC_OMX
     cinst.resolution_divisor = 16;
 #endif
     // cinst.codecSpecific.H264.profile = ?
     cinst.codecSpecific.H264.profile_byte = codecInfo->mProfile;
     cinst.codecSpecific.H264.constraints = codecInfo->mConstraints;
     cinst.codecSpecific.H264.level = codecInfo->mLevel;
     cinst.codecSpecific.H264.packetizationMode = codecInfo->mPacketizationMode;
-    if (codecInfo->mEncodingConstraints.maxBr > 0) {
-      // webrtc.org uses kbps, we use bps
-      cinst.maxBitrate =
-        MinIgnoreZero(cinst.maxBitrate,
-                      codecInfo->mEncodingConstraints.maxBr)/1000;
-    }
     if (codecInfo->mEncodingConstraints.maxMbps > 0) {
       // Not supported yet!
       CSFLogError(logTag,  "%s H.264 max_mbps not supported yet  ", __FUNCTION__);
     }
     // XXX parse the encoded SPS/PPS data
     // paranoia
     cinst.codecSpecific.H264.spsData = nullptr;
     cinst.codecSpecific.H264.spsLen = 0;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -396,17 +396,18 @@ private:
   unsigned int   mSendingFramerate;
   // scaled by *10 because Atomic<double/float> isn't supported
   mozilla::Atomic<int32_t, mozilla::Relaxed> mLastFramerateTenths;
   unsigned short mNumReceivingStreams;
   bool mVideoLatencyTestEnable;
   uint64_t mVideoLatencyAvg;
   uint32_t mMinBitrate;
   uint32_t mStartBitrate;
-  uint32_t mMaxBitrate;
+  uint32_t mPrefMaxBitrate;
+  uint32_t mNegotiatedMaxBitrate;
   uint32_t mMinBitrateEstimate;
 
   bool mRtpStreamIdEnabled;
   uint8_t mRtpStreamIdExtId;
 
   static const unsigned int sAlphaNum = 7;
   static const unsigned int sAlphaDen = 8;
   static const unsigned int sRoundingPadding = 1024;