Bug 1091008 - Factor out IsDataCachedToEndOfResource() into a higher-level question and answer it sensibly for MSE. r=cpearce
☠☠ backed out by 43a51201545a ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Wed, 05 Nov 2014 10:08:57 +0100
changeset 214037 8aaa10a8d95656121d06939273d8de0d485a19d9
parent 214036 541dc2f509e2454ee5d3f9cdd05476d3832bb959
child 214038 856016c0118ab665cf79f947e2ee03e207b1fa38
push id51401
push userbobbyholley@gmail.com
push dateWed, 05 Nov 2014 09:09:19 +0000
treeherdermozilla-inbound@21ddb8a58fea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1091008
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1091008 - Factor out IsDataCachedToEndOfResource() into a higher-level question and answer it sensibly for MSE. r=cpearce
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/mediasource/MediaSourceDecoder.cpp
dom/media/mediasource/MediaSourceDecoder.h
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -674,21 +674,32 @@ void MediaDecoder::QueueMetadata(int64_t
                                  MetadataTags* aTags)
 {
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
   GetReentrantMonitor().AssertCurrentThreadIn();
   mDecoderStateMachine->QueueMetadata(aPublishTime, aInfo, aTags);
 }
 
 bool
-MediaDecoder::IsDataCachedToEndOfResource()
+MediaDecoder::IsExpectingMoreData()
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  return (mResource &&
-          mResource->IsDataCachedToEndOfResource(mDecoderPosition));
+
+  // If there's no resource, we're probably just getting set up.
+  if (!mResource) {
+    return true;
+  }
+
+  // If we've downloaded anything, we're not waiting for anything.
+  if (mResource->IsDataCachedToEndOfResource(mDecoderPosition)) {
+    return false;
+  }
+
+  // Otherwise, we should be getting data unless the stream is suspended.
+  return !mResource->IsSuspended();
 }
 
 void MediaDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mShuttingDown) {
     return;
   }
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -793,19 +793,22 @@ public:
   // Removes all audio tracks and video tracks that are previously added into
   // the track list. Call on the main thread only.
   virtual void RemoveMediaTracks() MOZ_OVERRIDE;
 
   // Called when the first frame has been loaded.
   // Call on the main thread only.
   void FirstFrameLoaded();
 
-  // Returns true if the resource has been loaded. Acquires the monitor.
-  // Call from any thread.
-  virtual bool IsDataCachedToEndOfResource();
+  // Returns true if the this decoder is expecting any more data to arrive
+  // sometime in the not-too-distant future, either from the network or from
+  // an appendBuffer call on a MediaSource element.
+  //
+  // Acquires the monitor. Call from any thread.
+  virtual bool IsExpectingMoreData();
 
   // Called when the video has completed playing.
   // Call on the main thread only.
   void PlaybackEnded();
 
   // Seeking has stopped. Inform the element on the main
   // thread.
   void SeekingStopped();
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2416,19 +2416,18 @@ nsresult MediaDecoderStateMachine::RunSt
       // We will remain in the buffering state if we've not decoded enough
       // data to begin playback, or if we've not downloaded a reasonable
       // amount of data inside our buffering time.
       TimeDuration elapsed = now - mBufferingStart;
       bool isLiveStream = resource->GetLength() == -1;
       if ((isLiveStream || !mDecoder->CanPlayThrough()) &&
             elapsed < TimeDuration::FromSeconds(mBufferingWait * mPlaybackRate) &&
             (mQuickBuffering ? HasLowDecodedData(QUICK_BUFFERING_LOW_DATA_USECS)
-                            : HasLowUndecodedData(mBufferingWait * USECS_PER_S)) &&
-            !mDecoder->IsDataCachedToEndOfResource() &&
-            !resource->IsSuspended())
+                             : HasLowUndecodedData(mBufferingWait * USECS_PER_S)) &&
+            mDecoder->IsExpectingMoreData())
       {
         DECODER_LOG("Buffering: wait %ds, timeout in %.3lfs %s",
                     mBufferingWait, mBufferingWait - elapsed.ToSeconds(),
                     (mQuickBuffering ? "(quick exit)" : ""));
         ScheduleStateMachine(USECS_PER_S);
         return NS_OK;
       } else {
         DECODER_LOG("Changed state from BUFFERING to DECODING");
@@ -2677,22 +2676,20 @@ void MediaDecoderStateMachine::AdvanceFr
       int64_t now = IsPlaying() ? clock_time : mStartTime + mPlayDuration;
 
       remainingTime = frame->mTime - now;
     }
   }
 
   // Check to see if we don't have enough data to play up to the next frame.
   // If we don't, switch to buffering mode.
-  MediaResource* resource = mDecoder->GetResource();
   if (mState == DECODER_STATE_DECODING &&
       mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING &&
       HasLowDecodedData(remainingTime + EXHAUSTED_DATA_MARGIN_USECS) &&
-      !mDecoder->IsDataCachedToEndOfResource() &&
-      !resource->IsSuspended()) {
+      mDecoder->IsExpectingMoreData()) {
     if (JustExitedQuickBuffering() || HasLowUndecodedData()) {
       if (currentFrame) {
         VideoQueue().PushFront(currentFrame.forget());
       }
       StartBuffering();
       // Don't go straight back to the state machine loop since that might
       // cause us to start decoding again and we could flip-flop between
       // decoding and quick-buffering.
--- a/dom/media/mediasource/MediaSourceDecoder.cpp
+++ b/dom/media/mediasource/MediaSourceDecoder.cpp
@@ -159,16 +159,23 @@ MediaSourceDecoder::OnTrackBufferConfigu
 void
 MediaSourceDecoder::Ended()
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mReader->Ended();
   mon.NotifyAll();
 }
 
+bool
+MediaSourceDecoder::IsExpectingMoreData()
+{
+  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
+  return !mReader->IsEnded();
+}
+
 void
 MediaSourceDecoder::SetMediaSourceDuration(double aDuration)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mMediaSource) {
     return;
   }
   ErrorResult dummy;
--- a/dom/media/mediasource/MediaSourceDecoder.h
+++ b/dom/media/mediasource/MediaSourceDecoder.h
@@ -47,16 +47,17 @@ public:
   void DetachMediaSource();
 
   already_AddRefed<SourceBufferDecoder> CreateSubDecoder(const nsACString& aType);
   void AddTrackBuffer(TrackBuffer* aTrackBuffer);
   void RemoveTrackBuffer(TrackBuffer* aTrackBuffer);
   void OnTrackBufferConfigured(TrackBuffer* aTrackBuffer, const MediaInfo& aInfo);
 
   void Ended();
+  bool IsExpectingMoreData() MOZ_OVERRIDE;
 
   void SetMediaSourceDuration(double aDuration);
 
   // Called whenever a TrackBuffer has new data appended or a new decoder
   // initializes.  Safe to call from any thread.
   void NotifyTimeRangesChanged();
 
   // Indicates the point in time at which the reader should consider