Bug 1053674 - Remove subclass of StateMachine and use our own task queue. r=cpearce
☠☠ backed out by 9bde32496fa3 ☠ ☠
authorMatthew Gregan <kinetik@flim.org>
Thu, 14 Aug 2014 01:14:00 +1200
changeset 200042 0f59a9eb1658c10da2e01354c9cd0bdf48e0e8c8
parent 200041 e6fff68b6af8e4207c2e4f5ab1b357733284adc9
child 200043 19f58dab5e16e07ea6e7820fed50f425c46d074e
push id27330
push useremorley@mozilla.com
push dateMon, 18 Aug 2014 13:22:34 +0000
treeherdermozilla-central@6b75f748388a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1053674
milestone34.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 1053674 - Remove subclass of StateMachine and use our own task queue. r=cpearce
content/media/mediasource/MediaSourceDecoder.cpp
content/media/mediasource/MediaSourceDecoder.h
content/media/mediasource/MediaSourceReader.cpp
content/media/mediasource/MediaSourceReader.h
--- a/content/media/mediasource/MediaSourceDecoder.cpp
+++ b/content/media/mediasource/MediaSourceDecoder.cpp
@@ -24,72 +24,34 @@ extern PRLogModuleInfo* GetMediaSourceAP
 #define MSE_DEBUGV(...)
 #define MSE_API(...)
 #endif
 
 namespace mozilla {
 
 class SubBufferDecoder;
 
-class MediaSourceStateMachine : public MediaDecoderStateMachine
-{
-public:
-  MediaSourceStateMachine(MediaDecoder* aDecoder,
-                          MediaDecoderReader* aReader,
-                          bool aRealTime = false)
-    : MediaDecoderStateMachine(aDecoder, aReader, aRealTime)
-  {
-  }
-
-  already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType,
-                                                      MediaSourceDecoder* aParentDecoder) {
-    if (!mReader) {
-      return nullptr;
-    }
-    MediaSourceReader* reader = static_cast<MediaSourceReader*>(mReader.get());
-    return reader->CreateSubDecoder(aType, aParentDecoder, mDecodeTaskQueue);
-  }
-
-  nsresult EnqueueDecoderInitialization() {
-    AssertCurrentThreadInMonitor();
-    if (!mReader) {
-      return NS_ERROR_FAILURE;
-    }
-    RefPtr<nsIRunnable> task =
-      NS_NewRunnableMethod(this, &MediaSourceStateMachine::InitializePendingDecoders);
-    return mDecodeTaskQueue->Dispatch(task);
-  }
-
-private:
-  void InitializePendingDecoders() {
-    if (!mReader) {
-      return;
-    }
-    MediaSourceReader* reader = static_cast<MediaSourceReader*>(mReader.get());
-    reader->InitializePendingDecoders();
-  }
-};
-
 MediaSourceDecoder::MediaSourceDecoder(dom::HTMLMediaElement* aElement)
   : mMediaSource(nullptr)
 {
   Init(aElement);
 }
 
 MediaDecoder*
 MediaSourceDecoder::Clone()
 {
   // TODO: Sort out cloning.
   return nullptr;
 }
 
 MediaDecoderStateMachine*
 MediaSourceDecoder::CreateStateMachine()
 {
-  return new MediaSourceStateMachine(this, new MediaSourceReader(this, mMediaSource));
+  mReader = new MediaSourceReader(this, mMediaSource);
+  return new MediaDecoderStateMachine(this, mReader);
 }
 
 nsresult
 MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
 {
   MOZ_ASSERT(!mDecoderStateMachine);
   mDecoderStateMachine = CreateStateMachine();
   if (!mDecoderStateMachine) {
@@ -143,26 +105,12 @@ void
 MediaSourceDecoder::DetachMediaSource()
 {
   mMediaSource = nullptr;
 }
 
 already_AddRefed<SubBufferDecoder>
 MediaSourceDecoder::CreateSubDecoder(const nsACString& aType)
 {
-  if (!mDecoderStateMachine) {
-    return nullptr;
-  }
-  MediaSourceStateMachine* sm = static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get());
-  return sm->CreateSubDecoder(aType, this);
-}
-
-nsresult
-MediaSourceDecoder::EnqueueDecoderInitialization()
-{
-  if (!mDecoderStateMachine) {
-    return NS_ERROR_FAILURE;
-  }
-  MediaSourceStateMachine* sm = static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get());
-  return sm->EnqueueDecoderInitialization();
+  return mReader->CreateSubDecoder(aType, this);
 }
 
 } // namespace mozilla
--- a/content/media/mediasource/MediaSourceDecoder.h
+++ b/content/media/mediasource/MediaSourceDecoder.h
@@ -13,16 +13,17 @@
 #include "MediaDecoder.h"
 
 class nsIStreamListener;
 
 namespace mozilla {
 
 class MediaResource;
 class MediaDecoderStateMachine;
+class MediaSourceReader;
 class SubBufferDecoder;
 
 namespace dom {
 
 class HTMLMediaElement;
 class MediaSource;
 
 } // namespace dom
@@ -39,20 +40,19 @@ public:
 
   static already_AddRefed<MediaResource> CreateResource();
 
   void AttachMediaSource(dom::MediaSource* aMediaSource);
   void DetachMediaSource();
 
   already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType);
 
-  nsresult EnqueueDecoderInitialization();
-
 private:
   // The owning MediaSource holds a strong reference to this decoder, and
   // calls Attach/DetachMediaSource on this decoder to set and clear
   // mMediaSource.
   dom::MediaSource* mMediaSource;
+  nsRefPtr<MediaSourceReader> mReader;
 };
 
 } // namespace mozilla
 
 #endif /* MOZILLA_MEDIASOURCEDECODER_H_ */
--- a/content/media/mediasource/MediaSourceReader.cpp
+++ b/content/media/mediasource/MediaSourceReader.cpp
@@ -6,16 +6,17 @@
 #include "MediaSourceReader.h"
 
 #include "mozilla/dom/TimeRanges.h"
 #include "DecoderTraits.h"
 #include "MediaDataDecodedListener.h"
 #include "MediaDecoderOwner.h"
 #include "MediaSource.h"
 #include "MediaSourceDecoder.h"
+#include "SharedThreadPool.h"
 #include "SubBufferDecoder.h"
 
 #ifdef MOZ_FMP4
 #include "MP4Decoder.h"
 #include "MP4Reader.h"
 #endif
 
 #ifdef PR_LOGGING
@@ -36,16 +37,17 @@ namespace mozilla {
 MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder, dom::MediaSource* aSource)
   : MediaDecoderReader(aDecoder)
   , mTimeThreshold(-1)
   , mDropVideoBeforeThreshold(false)
   , mActiveVideoDecoder(-1)
   , mActiveAudioDecoder(-1)
   , mMediaSource(aSource)
 {
+  mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool());
 }
 
 bool
 MediaSourceReader::IsWaitingMediaResources()
 {
   return mDecoders.IsEmpty() && mPendingDecoders.IsEmpty();
 }
 
@@ -130,16 +132,17 @@ MediaSourceReader::OnDecodeError()
 
 void
 MediaSourceReader::Shutdown()
 {
   MediaDecoderReader::Shutdown();
   for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
     mDecoders[i]->GetReader()->Shutdown();
   }
+  mTaskQueue->Shutdown();
 }
 
 void
 MediaSourceReader::BreakCycles()
 {
   MediaDecoderReader::BreakCycles();
   for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
     mDecoders[i]->GetReader()->BreakCycles();
@@ -294,40 +297,41 @@ CreateReaderForType(const nsACString& aT
     return new MP4Reader(aDecoder);
   }
 #endif
   return DecoderTraits::CreateReader(aType, aDecoder);
 }
 
 already_AddRefed<SubBufferDecoder>
 MediaSourceReader::CreateSubDecoder(const nsACString& aType,
-                                    MediaSourceDecoder* aParentDecoder,
-                                    MediaTaskQueue* aTaskQueue)
+                                    MediaSourceDecoder* aParentDecoder)
 {
   // XXX: Why/when is mDecoder null here, since it should be equal to aParentDecoder?!
   nsRefPtr<SubBufferDecoder> decoder =
     new SubBufferDecoder(new SourceBufferResource(nullptr, aType), aParentDecoder);
   nsRefPtr<MediaDecoderReader> reader(CreateReaderForType(aType, decoder));
   if (!reader) {
     return nullptr;
   }
   // Set a callback on the subreader that forwards calls to this reader.
   // This reader will then forward them onto the state machine via this
   // reader's callback.
   RefPtr<MediaDataDecodedListener<MediaSourceReader>> callback =
-    new MediaDataDecodedListener<MediaSourceReader>(this, aTaskQueue);
+    new MediaDataDecodedListener<MediaSourceReader>(this, mTaskQueue);
   reader->SetCallback(callback);
-  reader->SetTaskQueue(aTaskQueue);
+  reader->SetTaskQueue(mTaskQueue);
   reader->Init(nullptr);
   ReentrantMonitorAutoEnter mon(aParentDecoder->GetReentrantMonitor());
   MSE_DEBUG("MediaSourceReader(%p)::CreateSubDecoder subdecoder %p subreader %p",
             this, decoder.get(), reader.get());
   decoder->SetReader(reader);
   mPendingDecoders.AppendElement(decoder);
-  if (NS_FAILED(static_cast<MediaSourceDecoder*>(mDecoder)->EnqueueDecoderInitialization())) {
+  RefPtr<nsIRunnable> task =
+    NS_NewRunnableMethod(this, &MediaSourceReader::InitializePendingDecoders);
+  if (NS_FAILED(mTaskQueue->Dispatch(task))) {
     MSE_DEBUG("MediaSourceReader(%p): Failed to enqueue decoder initialization task", this);
     return nullptr;
   }
   mDecoder->NotifyWaitingForResourcesStatusChanged();
   return decoder.forget();
 }
 
 namespace {
--- a/content/media/mediasource/MediaSourceReader.h
+++ b/content/media/mediasource/MediaSourceReader.h
@@ -66,18 +66,17 @@ public:
   }
 
   bool IsMediaSeekable() { return true; }
 
   nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;
   nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
                 int64_t aCurrentTime) MOZ_OVERRIDE;
   already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType,
-                                                      MediaSourceDecoder* aParentDecoder,
-                                                      MediaTaskQueue* aTaskQueue);
+                                                      MediaSourceDecoder* aParentDecoder);
 
   void Shutdown();
 
   virtual void BreakCycles();
 
   void InitializePendingDecoders();
 
   bool IsShutdown()
@@ -104,16 +103,18 @@ private:
 
   // These are read and written on the decode task queue threads.
   int64_t mTimeThreshold;
   bool mDropVideoBeforeThreshold;
 
   nsTArray<nsRefPtr<SubBufferDecoder>> mPendingDecoders;
   nsTArray<nsRefPtr<SubBufferDecoder>> mDecoders;
 
+  nsRefPtr<MediaTaskQueue> mTaskQueue;
+
   int32_t mActiveVideoDecoder;
   int32_t mActiveAudioDecoder;
   dom::MediaSource* mMediaSource;
 };
 
 } // namespace mozilla
 
 #endif /* MOZILLA_MEDIASOURCEREADER_H_ */