tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit fa7d0e1257b3fb6b84a02978be0c25664b122766
parent 20ccceccb14fb410de75a67867434695600d314d
Author: Andreas Pehrson <apehrson@mozilla.com>
Date:   Fri,  5 Dec 2025 16:34:21 +0000

Bug 1992567 - Enforce a hard limit of 1 frame in flight in WebRTC GMP encoder. r=webrtc-reviewers,bwc

This avoids an ~unbounded memory leak when OpenH264 is not able to keep up with
encoding in real-time.

Also report frame drops from Encode() upwards.

Differential Revision: https://phabricator.services.mozilla.com/D272451

Diffstat:
Mdom/media/webrtc/libwebrtcglue/WebrtcGmpVideoCodec.cpp | 32++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/dom/media/webrtc/libwebrtcglue/WebrtcGmpVideoCodec.cpp b/dom/media/webrtc/libwebrtcglue/WebrtcGmpVideoCodec.cpp @@ -340,6 +340,14 @@ void WebrtcGmpVideoEncoder::RegetEncoderForResolutionChange(uint32_t aWidth, void WebrtcGmpVideoEncoder::Encode_g( const webrtc::VideoFrame& aInputImage, std::vector<webrtc::VideoFrameType> aFrameTypes) { + auto reportDroppedOnExit = MakeScopeExit([&] { + MutexAutoLock lock(mCallbackMutex); + if (mCallback) { + mCallback->OnDroppedFrame( + webrtc::EncodedImageCallback::DropReason::kDroppedByEncoder); + } + }); + if (!mGMP) { // destroyed via Terminate(), failed to init, or just not initted yet GMP_LOG_DEBUG("GMP Encode: not initted yet"); @@ -347,6 +355,13 @@ void WebrtcGmpVideoEncoder::Encode_g( } MOZ_ASSERT(mHost); + if (mInputImageMap.Length() >= kMaxImagesInFlight) { + GMP_LOG_WARNING( + "GMP Encode: Max number of frames already in flight. Dropping this " + "one."); + return; + } + if (static_cast<uint32_t>(aInputImage.width()) != mCodecParams.mWidth || static_cast<uint32_t>(aInputImage.height()) != mCodecParams.mHeight) { GMP_LOG_DEBUG("GMP Encode: resolution change from %ux%u to %dx%d", @@ -423,18 +438,23 @@ void WebrtcGmpVideoEncoder::Encode_g( MOZ_RELEASE_ASSERT(mInputImageMap.IsEmpty() || mInputImageMap.LastElement().ntp_timestamp_ms < aInputImage.ntp_time_ms()); - mInputImageMap.AppendElement( - InputImageData{.gmp_timestamp_us = gmpTimestamp, - .ntp_timestamp_ms = aInputImage.ntp_time_ms(), - .timestamp_us = aInputImage.timestamp_us(), - .rtp_timestamp = aInputImage.rtp_timestamp(), - .frame_config = frameConfigs[0]}); GMP_LOG_DEBUG("GMP Encode: %" PRIu64, (frame->Timestamp())); err = mGMP->Encode(std::move(frame), codecSpecificInfo, gmp_frame_types); if (err != GMPNoErr) { GMP_LOG_DEBUG("GMP Encode: failed to encode frame"); + return; } + + // Once in mInputImageMap, frame drops are reported by GMP callbacks + // (Encoded/Dropped). + reportDroppedOnExit.release(); + mInputImageMap.AppendElement( + InputImageData{.gmp_timestamp_us = gmpTimestamp, + .ntp_timestamp_ms = aInputImage.ntp_time_ms(), + .timestamp_us = aInputImage.timestamp_us(), + .rtp_timestamp = aInputImage.rtp_timestamp(), + .frame_config = frameConfigs[0]}); } int32_t WebrtcGmpVideoEncoder::RegisterEncodeCompleteCallback(