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 180760 30b52597454bb20a22967ad448141caaeccb3038
parent 180759 ce0bd55265b30145842dbbd98b33b1d95d9e7405
child 180761 67a0d038388900081883835ef03dd86215cc3438
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerscajbir
bugs881512
milestone31.0a1
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;
 };