Bug 1326442: Use reconfigure whenever possible on video renegotiation r=ng
authorRandell Jesup <rjesup@jesup.org>
Fri, 30 Dec 2016 10:09:00 -0800
changeset 377559 cdc8e1a140e298a55cff0eedb053bd0155b360f7
parent 377525 e2860876fc43daab36c5dbc920dcf4d298923de2
child 377560 2b1fcb4b8c8854eea5190c22bdd31c9aca3510f1
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersng
bugs1326442
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 1326442: Use reconfigure whenever possible on video renegotiation r=ng
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
@@ -441,22 +441,22 @@ WebrtcVideoConduit::CreateRecvStream()
   if (!mRecvStream) {
     mDecoders.clear();
     return kMediaConduitUnknownError;
   }
 
   return kMediaConduitNoError;
 }
 
-static bool CompatibleH264Config(const webrtc::VideoCodecH264 &aEncoderSpecificH264,
-                                 const VideoCodecConfig* aCodecConfig)
+static bool CompatibleH264Config(const webrtc::VideoCodecH264& aEncoderSpecificH264,
+                                 const VideoCodecConfig& aCodecConfig)
 {
-  if (aEncoderSpecificH264.profile_byte != aCodecConfig->mProfile ||
-      aEncoderSpecificH264.constraints != aCodecConfig->mConstraints ||
-      aEncoderSpecificH264.packetizationMode != aCodecConfig->mPacketizationMode) {
+  if (aEncoderSpecificH264.profile_byte != aCodecConfig.mProfile ||
+      aEncoderSpecificH264.constraints != aCodecConfig.mConstraints ||
+      aEncoderSpecificH264.packetizationMode != aCodecConfig.mPacketizationMode) {
     return false;
   }
   return true;
 }
 
 /**
  * Note: Setting the send-codec on the Video Engine will restart the encoder,
  * sets up new SSRC and reset RTP_RTCP module with the new codec setting.
@@ -476,37 +476,16 @@ WebrtcVideoConduit::ConfigureSendMediaCo
 
   MediaConduitErrorCode condError = kMediaConduitNoError;
 
   // validate basic params
   if ((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError) {
     return condError;
   }
 
-  // StopTransmitting may be moot if mSendStream is null, but the code seems to
-  // allow for it.
-  // Recreating on PayloadType change may be overkill, but is safe.
-  if (!mSendStream ||
-      mSendStreamConfig.encoder_settings.payload_type != codecConfig->mType ||
-      mSendStreamConfig.encoder_settings.payload_name != codecConfig->mName ||
-      (codecConfig->mName == "H264" &&
-       !CompatibleH264Config(mEncoderSpecificH264, codecConfig))) {
-    condError = StopTransmitting();
-    if (condError != kMediaConduitNoError) {
-      return condError;
-    }
-    DeleteSendStream(); // safe if mSendStream is null
-  } // we are already using this codec - mSendStream tells us we're reconfiguring
-
-  mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
-  mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
-  mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
-  mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
-  mSendStreamConfig.overuse_callback = mLoadManager.get();
-
   size_t streamCount = std::min(codecConfig->mSimulcastEncodings.size(),
                                 (size_t)webrtc::kMaxSimulcastStreams);
   CSFLogDebug(logTag, "%s for VideoConduit:%p stream count:%d", __FUNCTION__,
               this, static_cast<int>(streamCount));
 
   mSendingFramerate = 0;
   mEncoderConfig.ClearStreams();
 
@@ -637,16 +616,45 @@ WebrtcVideoConduit::ConfigureSendMediaCo
   }
 
   mEncoderConfig.SetContentType(mCodecMode == webrtc::kRealtimeVideo ?
     webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo :
     webrtc::VideoEncoderConfig::ContentType::kScreen);
   // for the GMP H.264 encoder/decoder!!
   mEncoderConfig.SetMinTransmitBitrateBps(0);
 
+  // If only encoder stream attibutes have been changed, there is no need to stop,
+  // create a new webrtc::VideoSendStream, and restart.
+  // Recreating on PayloadType change may be overkill, but is safe.
+  if (mSendStream) {
+    if (!RequiresNewSendStream(*codecConfig)) {
+      if (!mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
+        CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
+        // Don't return here; let it try to destroy the encoder and rebuild it
+        // on StartTransmitting()
+      } else {
+        return kMediaConduitNoError;
+      }
+    }
+
+    condError = StopTransmitting();
+    if (condError != kMediaConduitNoError) {
+      return condError;
+    }
+
+    // This will cause a new encoder to be created by StartTransmitting()
+    DeleteSendStream();
+  }
+
+  mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
+  mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
+  mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
+  mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
+  mSendStreamConfig.overuse_callback = mLoadManager.get();
+
   // See Bug 1297058, enabling FEC when basic NACK is to be enabled in H.264 is problematic
   if (codecConfig->RtcpFbFECIsSet() &&
       !(codecConfig->mName == "H264" && codecConfig->RtcpFbNackIsSet(""))) {
     mSendStreamConfig.rtp.fec.ulpfec_payload_type = kUlpFecPayloadType;
     mSendStreamConfig.rtp.fec.red_payload_type = kRedPayloadType;
     mSendStreamConfig.rtp.fec.red_rtx_payload_type = kNullPayloadType;
   }
 
@@ -654,28 +662,16 @@ WebrtcVideoConduit::ConfigureSendMediaCo
     codecConfig->RtcpFbNackIsSet("") ? 1000 : 0;
 
   {
     MutexAutoLock lock(mCodecMutex);
     // Copy the applied config for future reference.
     mCurSendCodecConfig = new VideoCodecConfig(*codecConfig);
   }
 
-  // Is this a reconfigure of a running codec?
-  if (mSendStream &&
-      !mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
-    CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
-    // This will cause a new encoder to be created by StartTransmitting()
-    condError = StopTransmitting();
-    if (condError != kMediaConduitNoError) {
-      return condError;
-    }
-    DeleteSendStream();
-  }
-
   return condError;
 }
 
 bool
 WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
 {
   mRecvStreamConfig.rtp.remote_ssrc = ssrc;
   unsigned int current_ssrc;
@@ -1999,16 +1995,28 @@ WebrtcVideoConduit::CodecPluginID()
     return mSendCodecPlugin->PluginID();
   } else if (mRecvCodecPlugin) {
     return mRecvCodecPlugin->PluginID();
   }
 
   return 0;
 }
 
+bool
+WebrtcVideoConduit::RequiresNewSendStream(const VideoCodecConfig& newConfig) const
+{
+  return !mCurSendCodecConfig
+    || mCurSendCodecConfig->mName != newConfig.mName
+    || mCurSendCodecConfig->mType != newConfig.mType
+    || mCurSendCodecConfig->RtcpFbNackIsSet("") != newConfig.RtcpFbNackIsSet("")
+    || mCurSendCodecConfig->RtcpFbFECIsSet() != newConfig.RtcpFbFECIsSet()
+    || (newConfig.mName == "H264" &&
+        !CompatibleH264Config(mEncoderSpecificH264, newConfig));
+}
+
 void
 WebrtcVideoConduit::VideoEncoderConfigBuilder::SetEncoderSpecificSettings(
   void* aSettingsObj)
 {
   mConfig.encoder_specific_settings = aSettingsObj;
 };
 
 void
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -432,24 +432,26 @@ private:
   void DeleteRecvStream();
 
   webrtc::VideoDecoder* CreateDecoder(webrtc::VideoDecoder::DecoderType aType);
   webrtc::VideoEncoder* CreateEncoder(webrtc::VideoEncoder::EncoderType aType,
                                       bool enable_simulcast);
 
   MediaConduitErrorCode DeliverPacket(const void *data, int len);
 
+  bool RequiresNewSendStream(const VideoCodecConfig& newConfig) const;
+
   mozilla::ReentrantMonitor mTransportMonitor;
   RefPtr<TransportInterface> mTransmitterTransport;
   RefPtr<TransportInterface> mReceiverTransport;
   RefPtr<mozilla::VideoRenderer> mRenderer;
 
   // Engine state we are concerned with.
-  mozilla::Atomic<bool> mEngineTransmitting; //If true ==> Transmit Sub-system is up and running
-  mozilla::Atomic<bool> mEngineReceiving;    // if true ==> Receive Sus-sysmtem up and running
+  mozilla::Atomic<bool> mEngineTransmitting; // If true ==> Transmit Subsystem is up and running
+  mozilla::Atomic<bool> mEngineReceiving;    // if true ==> Receive Subsystem up and running
 
   int mCapId;   // Capturer for this conduit
   //Local database of currently applied receive codecs
   nsTArray<UniquePtr<VideoCodecConfig>> mRecvCodecList;
 
   Mutex mCodecMutex; // protects mCurrSendCodecConfig, mVideoSend/RecvStreamStats
   nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
   bool mInReconfig;