Bug 1208371 - Never send more than one disabled frame in a row to the WebRTC encoder. r=jesup
authorAndreas Pehrson <pehrsons@gmail.com>
Thu, 10 Mar 2016 14:35:50 +0100
changeset 292158 469e29166c55
parent 292157 a2cdbd2df8b6
child 292159 64929919a925
push id30152
push userkwierso@gmail.com
push date2016-04-07 20:42 +0000
treeherdermozilla-central@06678484909c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1208371
milestone48.0a1
Bug 1208371 - Never send more than one disabled frame in a row to the WebRTC encoder. r=jesup

MozReview-Commit-ID: 1F7zjGz32ad
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -689,16 +689,19 @@ friend class MediaPipelineTransmit;
 public:
   explicit PipelineListener(const RefPtr<MediaSessionConduit>& conduit)
     : conduit_(conduit),
       track_id_(TRACK_INVALID),
       mMutex("MediaPipelineTransmit::PipelineListener"),
       track_id_external_(TRACK_INVALID),
       active_(false),
       enabled_(false),
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+      disabled_frame_sent_(false),
+#endif
       direct_connect_(false),
       packetizer_(nullptr)
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
     , last_img_(-1)
 #endif // MOZILLA_EXTERNAL_LINKAGE
   {
   }
 
@@ -765,16 +768,19 @@ private:
 
   // active is true if there is a transport to send on
   mozilla::Atomic<bool> active_;
   // enabled is true if the media access control permits sending
   // actual content; when false you get black/silence
   mozilla::Atomic<bool> enabled_;
 
   // Written and read on the MediaStreamGraph thread
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+  bool disabled_frame_sent_;
+#endif
   bool direct_connect_;
 
   nsAutoPtr<AudioPacketizer<int16_t, int16_t>> packetizer_;
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   int32_t last_img_; // serial number of last Image
 #endif // MOZILLA_EXTERNAL_LINKAGE
 };
 
@@ -1250,36 +1256,47 @@ void MediaPipelineTransmit::PipelineList
 
   // We now need to send the video frame to the other side
   if (!img) {
     // segment.AppendFrame() allows null images, which show up here as null
     return;
   }
 
   if (!enabled_ || chunk.mFrame.GetForceBlack()) {
+    if (disabled_frame_sent_) {
+      // After disabling we just pass one black frame to the encoder.
+      // Allocating and setting it to black takes time so in some conditions
+      // that might affect MSG performance.
+      return;
+    }
+
     IntSize size = img->GetSize();
     uint32_t yPlaneLen = YSIZE(size.width, size.height);
     uint32_t cbcrPlaneLen = 2 * CRSIZE(size.width, size.height);
     uint32_t length = yPlaneLen + cbcrPlaneLen;
 
     // Send a black image.
     auto pixelData = MakeUniqueFallible<uint8_t[]>(length);
     if (pixelData) {
       // YCrCb black = 0x10 0x80 0x80
       memset(pixelData.get(), 0x10, yPlaneLen);
       // Fill Cb/Cr planes
       memset(pixelData.get() + yPlaneLen, 0x80, cbcrPlaneLen);
 
       MOZ_MTLOG(ML_DEBUG, "Sending a black video frame");
       conduit->SendVideoFrame(pixelData.get(), length, size.width, size.height,
                               mozilla::kVideoI420, 0);
+
+      disabled_frame_sent_ = true;
     }
     return;
   }
 
+  disabled_frame_sent_ = false;
+
   // We get passed duplicate frames every ~10ms even if there's no frame change!
   int32_t serial = img->GetSerial();
   if (serial == last_img_) {
     return;
   }
   last_img_ = serial;
 
   ImageFormat format = img->GetFormat();