Bug 1069730 - Grab decoder monitor when clearing mEssentialTrackBuffers. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Fri, 19 Sep 2014 15:55:58 +1200
changeset 206131 cafcd5e8dc591a55a29018c671cfeb73aede31e8
parent 206130 1674d241ce3d325eaf631fe44440d2da5886b125
child 206132 4660a2d871f1ae617484fdfa6b3aabf209a759f3
push id27513
push usercbook@mozilla.com
push dateFri, 19 Sep 2014 12:15:35 +0000
treeherdermozilla-central@dadafedc0760 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscajbir
bugs1069730
milestone35.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 1069730 - Grab decoder monitor when clearing mEssentialTrackBuffers. r=cajbir Also ensure MediaSource::InitializationEvent is only queued once.
content/media/mediasource/MediaSource.cpp
content/media/mediasource/MediaSource.h
content/media/mediasource/MediaSourceReader.cpp
--- a/content/media/mediasource/MediaSource.cpp
+++ b/content/media/mediasource/MediaSource.cpp
@@ -333,17 +333,17 @@ MediaSource::Detach()
             this, mDecoder.get(), mDecoder ? mDecoder->GetOwner() : nullptr);
   if (!mDecoder) {
     MOZ_ASSERT(mReadyState == MediaSourceReadyState::Closed);
     MOZ_ASSERT(mActiveSourceBuffers->IsEmpty() && mSourceBuffers->IsEmpty());
     return;
   }
   mDecoder->DetachMediaSource();
   mDecoder = nullptr;
-  mFirstSourceBufferInitialization = false;
+  mFirstSourceBufferInitialized = false;
   SetReadyState(MediaSourceReadyState::Closed);
   mDuration = UnspecifiedNaN<double>();
   if (mActiveSourceBuffers) {
     mActiveSourceBuffers->Clear();
   }
   if (mSourceBuffers) {
     mSourceBuffers->Clear();
   }
@@ -390,17 +390,17 @@ MediaSource::GetBuffered(TimeRanges* aBu
   MSE_DEBUG("MediaSource(%p)::GetBuffered ranges=%s", this, DumpTimeRanges(intersectionRanges).get());
 }
 
 MediaSource::MediaSource(nsPIDOMWindow* aWindow)
   : DOMEventTargetHelper(aWindow)
   , mDuration(UnspecifiedNaN<double>())
   , mDecoder(nullptr)
   , mReadyState(MediaSourceReadyState::Closed)
-  , mFirstSourceBufferInitialization(false)
+  , mFirstSourceBufferInitialized(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mSourceBuffers = new SourceBufferList(this);
   mActiveSourceBuffers = new SourceBufferList(this);
   MSE_API("MediaSource(%p)::MediaSource(aWindow=%p) mSourceBuffers=%p mActiveSourceBuffers=%p",
           this, aWindow, mSourceBuffers.get(), mActiveSourceBuffers.get());
 }
 
@@ -482,19 +482,20 @@ MediaSource::NotifyEvicted(double aStart
   // the given range.
   mSourceBuffers->Evict(aStart, aEnd);
 }
 
 void
 MediaSource::QueueInitializationEvent()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (!mFirstSourceBufferInitialization) {
-    mFirstSourceBufferInitialization = true;
+  if (mFirstSourceBufferInitialized) {
+    return;
   }
+  mFirstSourceBufferInitialized = true;
   MSE_DEBUG("MediaSource(%p)::QueueInitializationEvent()", this);
   nsRefPtr<nsIRunnable> task =
     NS_NewRunnableMethod(this, &MediaSource::InitializationEvent);
   NS_DispatchToMainThread(task);
 }
 
 void
 MediaSource::InitializationEvent()
--- a/content/media/mediasource/MediaSource.h
+++ b/content/media/mediasource/MediaSource.h
@@ -87,17 +87,17 @@ public:
 
   // Called by SourceBuffers to notify this MediaSource that data has
   // been evicted from the buffered data. The start and end times
   // that were evicted are provided.
   void NotifyEvicted(double aStart, double aEnd);
 
   // Queue InitializationEvent to run on the main thread.  Called when a
   // SourceBuffer has an initialization segment appended, but only
-  // dispatched the first time (using mFirstSourceBufferInitialization).
+  // dispatched the first time (using mFirstSourceBufferInitialized).
   // Demarcates the point in time at which only currently registered
   // TrackBuffers are treated as essential by the MediaSourceReader for
   // initialization.
   void QueueInitializationEvent();
 
 #if defined(DEBUG)
   // Dump the contents of each SourceBuffer to a series of files under aPath.
   // aPath must exist.  Debug only, invoke from your favourite debugger.
@@ -125,17 +125,17 @@ private:
 
   nsRefPtr<SourceBufferList> mSourceBuffers;
   nsRefPtr<SourceBufferList> mActiveSourceBuffers;
 
   nsRefPtr<MediaSourceDecoder> mDecoder;
 
   MediaSourceReadyState mReadyState;
 
-  bool mFirstSourceBufferInitialization;
+  bool mFirstSourceBufferInitialized;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)
 
 } // namespace dom
 
 } // namespace mozilla
 #endif /* mozilla_dom_MediaSource_h_ */
--- a/content/media/mediasource/MediaSourceReader.cpp
+++ b/content/media/mediasource/MediaSourceReader.cpp
@@ -468,17 +468,20 @@ MediaSourceReader::Seek(int64_t aTime, i
 
 nsresult
 MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
 {
   MSE_DEBUG("MediaSourceReader(%p)::ReadMetadata tracks=%u/%u audio=%p video=%p",
             this, mEssentialTrackBuffers.Length(), mTrackBuffers.Length(),
             mAudioTrack.get(), mVideoTrack.get());
 
-  mEssentialTrackBuffers.Clear();
+  {
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+    mEssentialTrackBuffers.Clear();
+  }
   if (!mAudioTrack && !mVideoTrack) {
     MSE_DEBUG("MediaSourceReader(%p)::ReadMetadata missing track: mAudioTrack=%p mVideoTrack=%p",
               this, mAudioTrack.get(), mVideoTrack.get());
     return NS_ERROR_FAILURE;
   }
 
   int64_t maxDuration = -1;