Bug 1163227: Part6. Always notify MediaSourceReader of new data on its own task queue. r=mattwoodrow
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 25 May 2015 15:09:16 +1000
changeset 245452 d5c950a3f7311557e6b1cf09a33adfac1ebbd234
parent 245451 81f13a822200f3e573bea0993ef1247405372d48
child 245453 48053f713a9d1c11fe77e7e2781958cc0450acb9
push id28806
push userphilringnalda@gmail.com
push dateTue, 26 May 2015 02:10:16 +0000
treeherdermozilla-central@4362d9251296 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1163227
milestone41.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 1163227: Part6. Always notify MediaSourceReader of new data on its own task queue. r=mattwoodrow
dom/media/mediasource/TrackBuffer.cpp
dom/media/mediasource/TrackBuffer.h
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -236,17 +236,17 @@ TrackBuffer::AppendData(MediaLargeByteBu
   if (decoders.Length()) {
     // We're going to have to wait for the decoder to initialize, the promise
     // will be resolved once initialization completes.
     return p;
   }
 
   // Tell our reader that we have more data to ensure that playback starts if
   // required when data is appended.
-  mParentDecoder->GetReader()->MaybeNotifyHaveData();
+  NotifyTimeRangesChanged();
 
   mInitializationPromise.Resolve(gotMedia, __func__);
   return p;
 }
 
 bool
 TrackBuffer::AppendDataToCurrentResource(MediaLargeByteBuffer* aData, uint32_t aDuration)
 {
@@ -258,21 +258,30 @@ TrackBuffer::AppendDataToCurrentResource
   SourceBufferResource* resource = mCurrentDecoder->GetResource();
   int64_t appendOffset = resource->GetLength();
   resource->AppendData(aData);
   mCurrentDecoder->SetRealMediaDuration(mCurrentDecoder->GetRealMediaDuration() + aDuration);
   // XXX: For future reference: NDA call must run on the main thread.
   mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData->Elements()),
                                      aData->Length(), appendOffset);
   mParentDecoder->NotifyBytesDownloaded();
-  mParentDecoder->NotifyTimeRangesChanged();
+  NotifyTimeRangesChanged();
 
   return true;
 }
 
+void
+TrackBuffer::NotifyTimeRangesChanged()
+{
+  RefPtr<nsIRunnable> task =
+    NS_NewRunnableMethod(mParentDecoder->GetReader(),
+                         &MediaSourceReader::NotifyTimeRangesChanged);
+  mParentDecoder->GetReader()->GetTaskQueue()->Dispatch(task.forget());
+}
+
 class DecoderSorter
 {
 public:
   bool LessThan(SourceBufferDecoder* aFirst, SourceBufferDecoder* aSecond) const
   {
     media::TimeIntervals first = aFirst->GetBuffered();
     media::TimeIntervals second = aSecond->GetBuffered();
 
@@ -428,17 +437,17 @@ TrackBuffer::EvictData(double aPlaybackT
     } else {
       // We do not currently have data to play yet.
       // Avoid evicting anymore data to minimize rebuffering time.
       *aBufferStartTime = 0.0;
     }
   }
 
   if (evicted) {
-    mParentDecoder->NotifyTimeRangesChanged();
+    NotifyTimeRangesChanged();
   }
 
   return evicted;
 }
 
 void
 TrackBuffer::RemoveEmptyDecoders(nsTArray<mozilla::SourceBufferDecoder*>& aDecoders)
 {
@@ -496,17 +505,17 @@ TrackBuffer::EvictBefore(double aTime)
     int64_t endOffset = mInitializedDecoders[i]->ConvertToByteOffset(aTime);
     if (endOffset > 0) {
       MSE_DEBUG("decoder=%u offset=%lld",
                 i, endOffset);
       mInitializedDecoders[i]->GetResource()->EvictBefore(endOffset);
       mInitializedDecoders[i]->GetReader()->NotifyDataRemoved();
     }
   }
-  mParentDecoder->NotifyTimeRangesChanged();
+  NotifyTimeRangesChanged();
 }
 
 media::TimeIntervals
 TrackBuffer::Buffered()
 {
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
 
   media::TimeIntervals buffered;
@@ -792,17 +801,17 @@ TrackBuffer::CompleteInitializeDecoder(S
   if (!duration) {
     // Treat a duration of 0 as infinity
     duration = -1;
   }
   mParentDecoder->SetInitialDuration(duration);
 
   // Tell our reader that we have more data to ensure that playback starts if
   // required when data is appended.
-  mParentDecoder->GetReader()->MaybeNotifyHaveData();
+  NotifyTimeRangesChanged();
 
   MSE_DEBUG("Reader %p activated",
             aDecoder->GetReader());
   mInitializationPromise.ResolveIfExists(aDecoder->GetRealMediaDuration() > 0, __func__);
 }
 
 bool
 TrackBuffer::ValidateTrackFormats(const MediaInfo& aInfo)
@@ -834,17 +843,17 @@ TrackBuffer::RegisterDecoder(SourceBuffe
     mInfo = info;
     mParentDecoder->OnTrackBufferConfigured(this, mInfo);
   }
   if (!ValidateTrackFormats(info)) {
     MSE_DEBUG("mismatched audio/video tracks");
     return false;
   }
   mInitializedDecoders.AppendElement(aDecoder);
-  mParentDecoder->NotifyTimeRangesChanged();
+  NotifyTimeRangesChanged();
   return true;
 }
 
 void
 TrackBuffer::DiscardCurrentDecoder()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
@@ -1110,17 +1119,17 @@ TrackBuffer::RangeRemoval(media::TimeUni
         decoders[i]->Trim(aStart.ToMicroseconds());
       }
       decoders[i]->GetReader()->NotifyDataRemoved();
     }
   }
 
   RemoveEmptyDecoders(decoders);
 
-  mParentDecoder->NotifyTimeRangesChanged();
+  NotifyTimeRangesChanged();
   return true;
 }
 
 void
 TrackBuffer::AdjustDecodersTimestampOffset(int32_t aOffset)
 {
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
   for (uint32_t i = 0; i < mDecoders.Length(); i++) {
--- a/dom/media/mediasource/TrackBuffer.h
+++ b/dom/media/mediasource/TrackBuffer.h
@@ -124,16 +124,18 @@ private:
   // The decoder is not considered initialized until it is added to
   // mInitializedDecoders.
   already_AddRefed<SourceBufferDecoder> NewDecoder(int64_t aTimestampOffset /* microseconds */);
 
   // Helper for AppendData, ensures NotifyDataArrived is called whenever
   // data is appended to the current decoder's SourceBufferResource.
   bool AppendDataToCurrentResource(MediaLargeByteBuffer* aData,
                                    uint32_t aDuration /* microseconds */);
+  // Queue on the parent's decoder task queue a call to NotifyTimeRangesChanged.
+  void NotifyTimeRangesChanged();
 
   // Queue execution of InitializeDecoder on mTaskQueue.
   bool QueueInitializeDecoder(SourceBufferDecoder* aDecoder);
 
   // Runs decoder initialization including calling ReadMetadata.  Runs as an
   // event on the decode thread pool.
   void InitializeDecoder(SourceBufferDecoder* aDecoder);
   // Once decoder has been initialized, set mediasource duration if required