Bug 1208371 - Never send more than one disabled frame in a row to the WebRTC encoder. r?jesup
MozReview-Commit-ID: 1F7zjGz32ad
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -691,16 +691,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
{
}
@@ -770,16 +773,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
};
@@ -1255,36 +1261,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();