Bug 1344772 - set a dirty flag so we can process the notification later. r?jya draft
authorJW Wang <jwwang@mozilla.com>
Wed, 15 Mar 2017 15:20:45 +0800
changeset 498740 0a4eb41e65b51ddb5436c3006ac42fc3d04f6b3d
parent 498704 8f504239db0719485314dc307beabebfb7702195
child 549236 87d313a78c99384867950964ac10c13ea745ea18
push id49290
push userjwwang@mozilla.com
push dateWed, 15 Mar 2017 07:35:23 +0000
reviewersjya
bugs1344772
milestone55.0a1
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
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
--- 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);
   }