Bug 1344772 - set a dirty flag so we can process the notification later. r?jya
https://hg.mozilla.org/mozilla-central/file/34c6c2f302e7b48e3ad2cec575cbd34d423a9d32/dom/media/MediaFormatReader.cpp#l2835
NotifyDataArrived() is dispatched again if |mNotifyDataArrivedPromise.Exists()| which will then be dispatched again
recursively until mNotifyDataArrivedPromise is completed. This is a waste of CPU cycles.
We can use a dirty flag to note we should update buffer ranges again when the current update is done.
MozReview-Commit-ID: 6hInhGKnXJE
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1077,16 +1077,17 @@ MediaFormatReader::MediaFormatReader(Abs
VideoFrameContainer* aVideoFrameContainer)
: MediaDecoderReader(aDecoder)
, mAudio(this, MediaData::AUDIO_DATA,
Preferences::GetUint("media.audio-max-decode-error", 3))
, mVideo(this, MediaData::VIDEO_DATA,
Preferences::GetUint("media.video-max-decode-error", 2))
, mDemuxer(new DemuxerProxy(aDemuxer))
, mDemuxerInitDone(false)
+ , mPendingNotifyDataArrived(false)
, mLastReportedNumDecodedFrames(0)
, mPreviousDecodedKeyframeTime_us(sNoPreviousDecodedKeyframe)
, mInitDone(false)
, mTrackDemuxersMayBlock(false)
, mSeekScheduled(false)
, mVideoFrameContainer(aVideoFrameContainer)
, mDecoderFactory(new DecoderFactory(this))
, mShutdownPromisePool(new ShutdownPromisePool())
@@ -2879,30 +2880,32 @@ MediaFormatReader::NotifyDataArrived()
if (mShutdown
|| !mDemuxer
|| (!mDemuxerInitDone && !mDemuxerInitRequest.Exists())) {
return;
}
if (mNotifyDataArrivedPromise.Exists()) {
- // Already one in progress. Reschedule for later.
- RefPtr<nsIRunnable> task(
- NewRunnableMethod(this, &MediaFormatReader::NotifyDataArrived));
- OwnerThread()->Dispatch(task.forget());
+ // Already one in progress. Set the dirty flag so we can process it later.
+ mPendingNotifyDataArrived = true;
return;
}
RefPtr<MediaFormatReader> self = this;
mDemuxer->NotifyDataArrived()
->Then(OwnerThread(), __func__,
[self]() {
self->mNotifyDataArrivedPromise.Complete();
self->UpdateBuffered();
self->NotifyTrackDemuxers();
+ if (self->mPendingNotifyDataArrived) {
+ self->mPendingNotifyDataArrived = false;
+ self->NotifyDataArrived();
+ }
},
[self]() { self->mNotifyDataArrivedPromise.Complete(); })
->Track(mNotifyDataArrivedPromise);
}
void
MediaFormatReader::UpdateBuffered()
{
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -445,16 +445,17 @@ private:
// Demuxer objects.
class DemuxerProxy;
UniquePtr<DemuxerProxy> mDemuxer;
bool mDemuxerInitDone;
void OnDemuxerInitDone(nsresult);
void OnDemuxerInitFailed(const MediaResult& aError);
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
MozPromiseRequestHolder<NotifyDataArrivedPromise> mNotifyDataArrivedPromise;
+ bool mPendingNotifyDataArrived;
void OnDemuxFailed(TrackType aTrack, const MediaResult &aError);
void DoDemuxVideo();
void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
void OnVideoDemuxFailed(const MediaResult& aError)
{
OnDemuxFailed(TrackType::kVideoTrack, aError);
}