Bug 881512 - Use MediaTaskQueue to run MSE tasks rather than a per-MSE thread. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Fri, 25 Apr 2014 22:42:00 +1200
changeset 198908 30b52597454bb20a22967ad448141caaeccb3038
parent 198907 ce0bd55265b30145842dbbd98b33b1d95d9e7405
child 198909 67a0d038388900081883835ef03dd86215cc3438
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscajbir
bugs881512
milestone31.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 881512 - Use MediaTaskQueue to run MSE tasks rather than a per-MSE thread. r=cajbir
content/media/mediasource/MediaSourceDecoder.cpp
content/media/mediasource/MediaSourceDecoder.h
--- a/content/media/mediasource/MediaSourceDecoder.cpp
+++ b/content/media/mediasource/MediaSourceDecoder.cpp
@@ -171,28 +171,24 @@ private:
 
   MediaDecoderReader* GetVideoReader() {
     if (mActiveVideoDecoder == -1) {
       return nullptr;
     }
     return mDecoders[mActiveVideoDecoder]->GetReader();
   }
 
-  bool EnsureWorkQueueInitialized();
-  nsresult EnqueueDecoderInitialization();
   void WaitForPendingDecoders();
 
   nsTArray<nsRefPtr<SubBufferDecoder>> mPendingDecoders;
   nsTArray<nsRefPtr<SubBufferDecoder>> mDecoders;
 
   int32_t mActiveVideoDecoder;
   int32_t mActiveAudioDecoder;
   dom::MediaSource* mMediaSource;
-
-  nsCOMPtr<nsIThread> mWorkQueue;
 };
 
 class MediaSourceStateMachine : public MediaDecoderStateMachine
 {
 public:
   MediaSourceStateMachine(MediaDecoder* aDecoder,
                           MediaDecoderReader* aReader,
                           bool aRealTime = false)
@@ -203,21 +199,31 @@ public:
   already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType,
                                                       MediaSourceDecoder* aParentDecoder) {
     if (!mReader) {
       return nullptr;
     }
     return static_cast<MediaSourceReader*>(mReader.get())->CreateSubDecoder(aType, aParentDecoder);
   }
 
+  nsresult EnqueueDecoderInitialization() {
+    AssertCurrentThreadInMonitor();
+    if (!mReader) {
+      return NS_ERROR_FAILURE;
+    }
+    return mDecodeTaskQueue->Dispatch(NS_NewRunnableMethod(this,
+                                                           &MediaSourceStateMachine::CallDecoderInitialization));
+  }
+
+private:
   void CallDecoderInitialization() {
     if (!mReader) {
       return;
     }
-    return static_cast<MediaSourceReader*>(mReader.get())->CallDecoderInitialization();
+    static_cast<MediaSourceReader*>(mReader.get())->CallDecoderInitialization();
   }
 };
 
 MediaSourceDecoder::MediaSourceDecoder(dom::HTMLMediaElement* aElement)
   : mMediaSource(nullptr)
 {
   Init(aElement);
 }
@@ -288,49 +294,23 @@ already_AddRefed<SubBufferDecoder>
 MediaSourceDecoder::CreateSubDecoder(const nsACString& aType)
 {
   if (!mDecoderStateMachine) {
     return nullptr;
   }
   return static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get())->CreateSubDecoder(aType, this);
 }
 
-void
-MediaSourceDecoder::CallDecoderInitialization()
+nsresult
+MediaSourceDecoder::EnqueueDecoderInitialization()
 {
   if (!mDecoderStateMachine) {
-    return;
-  }
-  return static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get())->CallDecoderInitialization();
-}
-
-bool
-MediaSourceReader::EnsureWorkQueueInitialized()
-{
-  // TODO: Use a global threadpool rather than a thread per MediaSource.
-  MOZ_ASSERT(NS_IsMainThread());
-  if (!mWorkQueue &&
-      NS_FAILED(NS_NewNamedThread("MediaSource",
-                                  getter_AddRefs(mWorkQueue),
-                                  nullptr,
-                                  MEDIA_THREAD_STACK_SIZE))) {
-    return false;
-  }
-  return true;
-}
-
-nsresult
-MediaSourceReader::EnqueueDecoderInitialization()
-{
-  if (!EnsureWorkQueueInitialized()) {
     return NS_ERROR_FAILURE;
   }
-  return mWorkQueue->Dispatch(NS_NewRunnableMethod(static_cast<MediaSourceDecoder*>(mDecoder),
-                                                   &MediaSourceDecoder::CallDecoderInitialization),
-                              NS_DISPATCH_NORMAL);
+  return static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get())->EnqueueDecoderInitialization();
 }
 
 class ReleaseDecodersTask : public nsRunnable {
 public:
   ReleaseDecodersTask(nsTArray<nsRefPtr<SubBufferDecoder>>& aDecoders)
   {
     mDecoders.SwapElements(aDecoders);
   }
@@ -405,17 +385,20 @@ MediaSourceReader::CreateSubDecoder(cons
   if (!reader) {
     return nullptr;
   }
   reader->Init(nullptr);
   ReentrantMonitorAutoEnter mon(aParentDecoder->GetReentrantMonitor());
   MSE_DEBUG("Registered subdecoder %p subreader %p", decoder.get(), reader.get());
   decoder->SetReader(reader.forget());
   mPendingDecoders.AppendElement(decoder);
-  EnqueueDecoderInitialization();
+  if (NS_FAILED(static_cast<MediaSourceDecoder*>(mDecoder)->EnqueueDecoderInitialization())) {
+    MSE_DEBUG("%p: Failed to enqueue decoder initialization task", this);
+    return nullptr;
+  }
   mDecoder->NotifyWaitingForResourcesStatusChanged();
   return decoder.forget();
 }
 
 nsresult
 MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
                         int64_t aCurrentTime)
 {
--- a/content/media/mediasource/MediaSourceDecoder.h
+++ b/content/media/mediasource/MediaSourceDecoder.h
@@ -45,17 +45,17 @@ public:
 
   static already_AddRefed<MediaResource> CreateResource();
 
   void AttachMediaSource(dom::MediaSource* aMediaSource);
   void DetachMediaSource();
 
   already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType);
 
-  void CallDecoderInitialization();
+  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;
 };