tor-browser

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

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

Bug 1999970 - Handle dropped-frame callbacks in the GMP PEM. r=media-playback-reviewers,padenot

The OpenH264 encoder may silently drop a frame due to rate control.
If not handled in the GMP PEM, it may risk stalling waiting for an encoded frame
that never arrives.

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

Diffstat:
Mdom/media/platforms/agnostic/gmp/GMPVideoEncoder.cpp | 41++++++++++++++++++++++++++++++-----------
Mxpcom/base/ErrorList.py | 1+
2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/dom/media/platforms/agnostic/gmp/GMPVideoEncoder.cpp b/dom/media/platforms/agnostic/gmp/GMPVideoEncoder.cpp @@ -448,7 +448,16 @@ void GMPVideoEncoder::Encoded(GMPVideoEncodedFrame* aEncodedFrame, void GMPVideoEncoder::Dropped(uint64_t aTimestamp) { MOZ_ASSERT(IsOnGMPThread()); - // TODO: implement + + RefPtr<EncodePromise::Private> promise; + if (!mPendingEncodes.Remove(aTimestamp, getter_AddRefs(promise))) { + GMP_LOG_WARNING( + "[%p] GMPVideoEncoder::Dropped -- no frame matching timestamp %" PRIu64, + this, aTimestamp); + return; + } + + promise->Reject(NS_ERROR_DOM_MEDIA_DROPPED_BY_ENCODER_ERR, __func__); } void GMPVideoEncoder::Teardown(const MediaResult& aResult, @@ -515,19 +524,29 @@ void GMPVideoEncoder::EncodeNextSample( GetCurrentSerialEventTarget(), __func__, [self = RefPtr{this}, inputs = std::move(aInputs), outputs = std::move(aOutputs)]( - MediaDataEncoder::EncodedData&& aData) mutable { + EncodePromise::ResolveOrRejectValue&& aValue) mutable { self->mEncodeBatchRequest.Complete(); + if (aValue.IsReject() && + aValue.RejectValue().Code() != + NS_ERROR_DOM_MEDIA_DROPPED_BY_ENCODER_ERR) { + auto& error = aValue.RejectValue(); + GMP_LOG_ERROR( + "[%p] GMPVideoEncoder::EncodeNextSample -- failed to encode: " + "%s", + self.get(), error.Description().get()); + self->mEncodeBatchPromise.Reject(error, __func__); + return; + } inputs.RemoveElementAt(0); - outputs.AppendElements(aData); + if (aValue.IsResolve()) { + outputs.AppendElements(aValue.ResolveValue()); + } else { + GMP_LOG_WARNING( + "[%p] GMPVideoEncoder::EncodeNextSample -- dropped by " + "encoder: %s. Continuing.", + self.get(), aValue.RejectValue().Description().get()); + } self->EncodeNextSample(std::move(inputs), std::move(outputs)); - }, - [self = RefPtr{this}](const MediaResult& aError) { - self->mEncodeBatchRequest.Complete(); - GMP_LOG_ERROR( - "[%p] GMPVideoEncoder::EncodeNextSample -- failed to encode: " - "%s", - self.get(), aError.Description().get()); - self->mEncodeBatchPromise.Reject(aError, __func__); }) ->Track(mEncodeBatchRequest); } diff --git a/xpcom/base/ErrorList.py b/xpcom/base/ErrorList.py @@ -1191,6 +1191,7 @@ with modules["DOM_MEDIA"]: errors["NS_ERROR_DOM_MEDIA_RANGE_ERR"] = FAILURE(105) errors["NS_ERROR_DOM_MEDIA_TYPE_ERR"] = FAILURE(106) errors["NS_ERROR_DOM_MEDIA_MEDIA_ENGINE_INITIALIZATION_ERR"] = FAILURE(107) + errors["NS_ERROR_DOM_MEDIA_DROPPED_BY_ENCODER_ERR"] = FAILURE(108) # ======================================================================= # 42: NS_ERROR_MODULE_URL_CLASSIFIER