Bug 1319269 - part3 : remove MediaDataDecoder::Init(). draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 13 Mar 2017 21:27:48 +0800
changeset 497496 a34cb23dbfa5b31051f1db0c9dba9280f1f147a2
parent 497495 87e4688bfdb26568238a2f80576ede25aaa5eab3
child 548918 49a7867731ad5f35ee836b377d254df661b2d95b
push id48931
push useralwu@mozilla.com
push dateMon, 13 Mar 2017 13:28:17 +0000
bugs1319269
milestone55.0a1
Bug 1319269 - part3 : remove MediaDataDecoder::Init(). MozReview-Commit-ID: IpLNpoqxMGp
dom/media/MediaFormatReader.cpp
dom/media/ipc/PVideoDecoder.ipdl
dom/media/ipc/RemoteVideoDecoder.cpp
dom/media/ipc/RemoteVideoDecoder.h
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderChild.h
dom/media/ipc/VideoDecoderParent.cpp
dom/media/ipc/VideoDecoderParent.h
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/agnostic/OpusDecoder.cpp
dom/media/platforms/agnostic/OpusDecoder.h
dom/media/platforms/agnostic/TheoraDecoder.cpp
dom/media/platforms/agnostic/TheoraDecoder.h
dom/media/platforms/agnostic/VPXDecoder.cpp
dom/media/platforms/agnostic/VPXDecoder.h
dom/media/platforms/agnostic/VorbisDecoder.cpp
dom/media/platforms/agnostic/VorbisDecoder.h
dom/media/platforms/agnostic/WAVDecoder.cpp
dom/media/platforms/agnostic/WAVDecoder.h
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
dom/media/platforms/android/RemoteDataDecoder.cpp
dom/media/platforms/android/RemoteDataDecoder.h
dom/media/platforms/apple/AppleATDecoder.cpp
dom/media/platforms/apple/AppleATDecoder.h
dom/media/platforms/apple/AppleDecoderModule.cpp
dom/media/platforms/apple/AppleVTDecoder.cpp
dom/media/platforms/apple/AppleVTDecoder.h
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
dom/media/platforms/omx/OmxDataDecoder.cpp
dom/media/platforms/omx/OmxDataDecoder.h
dom/media/platforms/wmf/WMFDecoderModule.cpp
dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
dom/media/platforms/wmf/WMFMediaDataDecoder.h
dom/media/platforms/wrappers/H264Converter.cpp
dom/media/platforms/wrappers/H264Converter.h
dom/media/platforms/wrappers/MediaDataDecoderProxy.cpp
dom/media/platforms/wrappers/MediaDataDecoderProxy.h
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -456,17 +456,16 @@ MediaFormatReader::DecoderData::Flush()
                mOwner->NotifyError(type, aError);
              });
   }
   mFlushed = true;
 }
 
 class MediaFormatReader::DecoderFactory
 {
-  using InitPromise = MediaDataDecoder::InitPromise;
   using TokenPromise = GlobalAllocPolicy::Promise;
   using Token = GlobalAllocPolicy::Token;
 
 public:
   explicit DecoderFactory(MediaFormatReader* aOwner)
     : mAudio(aOwner->mAudio, TrackInfo::kAudioTrack, aOwner->OwnerThread())
     , mVideo(aOwner->mVideo, TrackInfo::kVideoTrack, aOwner->OwnerThread())
     , mOwner(WrapNotNull(aOwner)) { }
@@ -536,17 +535,16 @@ class MediaFormatReader::DecoderFactory:
 {
   using Token = GlobalAllocPolicy::Token;
 
 public:
   Wrapper(already_AddRefed<MediaDataDecoder> aDecoder,
           already_AddRefed<Token> aToken)
     : mDecoder(aDecoder), mToken(aToken) {}
 
-  RefPtr<InitPromise> Init() override { return mDecoder->Init(); }
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
   {
     return mDecoder->Decode(aSample);
   }
   RefPtr<DecodePromise> Drain() override { return mDecoder->Drain(); }
   RefPtr<FlushPromise> Flush() override { return mDecoder->Flush(); }
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override
   {
--- a/dom/media/ipc/PVideoDecoder.ipdl
+++ b/dom/media/ipc/PVideoDecoder.ipdl
@@ -41,31 +41,27 @@ struct MediaRawDataIPDL
 // The parent side currently is only implemented to work with
 // Window Media Foundation, but can be extended easily to support other backends.
 // The child side runs in the content process, and the parent side runs in the
 // GPU process. We run a separate IPDL thread for both sides.
 async protocol PVideoDecoder
 {
   manager PVideoDecoderManager;
 parent:
-  async Init();
-
   async Input(MediaRawDataIPDL data);
 
   async Flush();
   async Drain();
   async Shutdown();
 
   async SetSeekThreshold(int64_t time);
 
   async __delete__();
 
 child:
-  async InitComplete(bool hardware, nsCString hardwareReason, uint32_t conversion);
-  async InitFailed(nsresult reason);
   async CreateDecoderCompleted(bool hardware,
                                nsCString hardwareReason,
                                uint32_t conversion);
   async CreateDecoderFailed();
 
   async FlushComplete();
 
   // Each output includes a SurfaceDescriptorGPUVideo that represents the decoded
--- a/dom/media/ipc/RemoteVideoDecoder.cpp
+++ b/dom/media/ipc/RemoteVideoDecoder.cpp
@@ -66,24 +66,16 @@ RemoteVideoDecoder::CreateRemoteDecoder(
       },
       [self] () {
         self->mCreateDecoderPromise.Reject(false, __func__);
     });
 
   return mCreateDecoderPromise.Ensure(__func__);
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
-RemoteVideoDecoder::Init()
-{
-  RefPtr<RemoteVideoDecoder> self = this;
-  return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
-                     __func__, [self, this]() { return mActor->Init(); });
-}
-
 RefPtr<MediaDataDecoder::DecodePromise>
 RemoteVideoDecoder::Decode(MediaRawData* aSample)
 {
   RefPtr<RemoteVideoDecoder> self = this;
   RefPtr<MediaRawData> sample = aSample;
   return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
                      __func__,
                      [self, this, sample]() { return mActor->Decode(sample); });
--- a/dom/media/ipc/RemoteVideoDecoder.h
+++ b/dom/media/ipc/RemoteVideoDecoder.h
@@ -26,17 +26,16 @@ class RemoteDecoderModule;
 class RemoteVideoDecoder : public MediaDataDecoder
 {
 public:
   friend class RemoteDecoderModule;
 
   RefPtr<CreateDecoderPromise> CreateRemoteDecoder(const CreateDecoderParams& aParams);
 
   // MediaDataDecoder
-  RefPtr<InitPromise> Init() override;
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
   void SetSeekThreshold(const media::TimeUnit& aTime) override;
 
   const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -17,28 +17,26 @@ namespace dom {
 using base::Thread;
 using namespace ipc;
 using namespace layers;
 using namespace gfx;
 
 VideoDecoderChild::VideoDecoderChild()
   : mThread(VideoDecoderManagerChild::GetManagerThread())
   , mCanSend(false)
-  , mInitialized(false)
   , mHasDecoder(false)
   , mIsHardwareAccelerated(false)
   , mConversion(MediaDataDecoder::ConversionRequired::kNeedNone)
   , mNeedNewDecoder(false)
 {
 }
 
 VideoDecoderChild::~VideoDecoderChild()
 {
   AssertOnManagerThread();
-  mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mCreateDecoderPromise.RejectIfExists(false, __func__);
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvOutput(const VideoDataIPDL& aData)
 {
   AssertOnManagerThread();
   VideoInfo info(aData.display().width, aData.display().height);
@@ -85,38 +83,16 @@ VideoDecoderChild::RecvError(const nsres
   mDecodedData.Clear();
   mDecodePromise.RejectIfExists(aError, __func__);
   mDrainPromise.RejectIfExists(aError, __func__);
   mFlushPromise.RejectIfExists(aError, __func__);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-VideoDecoderChild::RecvInitComplete(const bool& aHardware,
-                                    const nsCString& aHardwareReason,
-                                    const uint32_t& aConversion)
-{
-  AssertOnManagerThread();
-  mInitPromise.ResolveIfExists(TrackInfo::kVideoTrack, __func__);
-  mInitialized = true;
-  mIsHardwareAccelerated = aHardware;
-  mHardwareAcceleratedReason = aHardwareReason;
-  mConversion = static_cast<MediaDataDecoder::ConversionRequired>(aConversion);
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-VideoDecoderChild::RecvInitFailed(const nsresult& aReason)
-{
-  AssertOnManagerThread();
-  mInitPromise.RejectIfExists(aReason, __func__);
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
 VideoDecoderChild::RecvCreateDecoderCompleted(const bool& aHardware,
                                               const nsCString& aHardwareReason,
                                               const uint32_t& aConversion)
 {
   AssertOnManagerThread();
   mCreateDecoderPromise.ResolveIfExists(nullptr, __func__);
   mHasDecoder = true;
   mIsHardwareAccelerated = aHardware;
@@ -175,16 +151,17 @@ VideoDecoderChild::InitIPDL(const VideoI
   RefPtr<VideoDecoderManagerChild> manager =
     VideoDecoderManagerChild::GetSingleton();
   // If the manager isn't available, then don't initialize mIPDLSelfRef and
   // leave us in an error state. We'll then immediately reject the promise when
   // Init() is called and the caller can try again. Hopefully by then the new
   // manager is ready, or we've notified the caller of it being no longer
   // available. If not, then the cycle repeats until we're ready.
   if (!manager || !manager->CanSend()) {
+    // TODO : promise for init manager.
     return CreateDecoderPromise::CreateAndReject(false, __func__);
   }
 
   mIPDLSelfRef = this;
   if (manager->SendPVideoDecoderConstructor(this, aVideoInfo, aIdentifier)) {
     mCanSend = true;
   }
   return mCreateDecoderPromise.Ensure(__func__);
@@ -201,33 +178,16 @@ VideoDecoderChild::DestroyIPDL()
 void
 VideoDecoderChild::IPDLActorDestroyed()
 {
   mIPDLSelfRef = nullptr;
 }
 
 // MediaDataDecoder methods
 
-RefPtr<MediaDataDecoder::InitPromise>
-VideoDecoderChild::Init()
-{
-  AssertOnManagerThread();
-
-  if (!mIPDLSelfRef) {
-    return MediaDataDecoder::InitPromise::CreateAndReject(
-      NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
-  }
-  // If we failed to send this, then we'll still resolve the Init promise
-  // as ActorDestroy handles it.
-  if (mCanSend) {
-    SendInit();
-  }
-  return mInitPromise.Ensure(__func__);
-}
-
 RefPtr<MediaDataDecoder::DecodePromise>
 VideoDecoderChild::Decode(MediaRawData* aSample)
 {
   AssertOnManagerThread();
 
   if (mNeedNewDecoder) {
     return MediaDataDecoder::DecodePromise::CreateAndReject(
       NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER, __func__);
@@ -290,22 +250,20 @@ VideoDecoderChild::Drain()
   }
   return mDrainPromise.Ensure(__func__);
 }
 
 void
 VideoDecoderChild::Shutdown()
 {
   AssertOnManagerThread();
-  mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mCreateDecoderPromise.RejectIfExists(false, __func__);
   if (mCanSend) {
     SendShutdown();
   }
-  mInitialized = false;
   mHasDecoder = false;
 }
 
 bool
 VideoDecoderChild::IsHardwareAccelerated(nsACString& aFailureReason) const
 {
   aFailureReason = mHardwareAcceleratedReason;
   return mIsHardwareAccelerated;
--- a/dom/media/ipc/VideoDecoderChild.h
+++ b/dom/media/ipc/VideoDecoderChild.h
@@ -26,29 +26,24 @@ public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoderChild)
 
   // PVideoDecoderChild
   mozilla::ipc::IPCResult RecvOutput(const VideoDataIPDL& aData) override;
   mozilla::ipc::IPCResult RecvInputExhausted() override;
   mozilla::ipc::IPCResult RecvDrainComplete() override;
   mozilla::ipc::IPCResult RecvError(const nsresult& aError) override;
-  mozilla::ipc::IPCResult RecvInitComplete(const bool& aHardware,
-                                           const nsCString& aHardwareReason,
-                                           const uint32_t& aConversion) override;
-  mozilla::ipc::IPCResult RecvInitFailed(const nsresult& aReason) override;
   mozilla::ipc::IPCResult RecvCreateDecoderCompleted(const bool& aHardware,
                                                      const nsCString& aHardwareReason,
                                                      const uint32_t& aConversion) override;
   mozilla::ipc::IPCResult RecvCreateDecoderFailed() override;
   mozilla::ipc::IPCResult RecvFlushComplete() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  RefPtr<MediaDataDecoder::InitPromise> Init();
   RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample);
   RefPtr<MediaDataDecoder::DecodePromise> Drain();
   RefPtr<MediaDataDecoder::FlushPromise> Flush();
   void Shutdown();
   bool IsHardwareAccelerated(nsACString& aFailureReason) const;
   void SetSeekThreshold(const media::TimeUnit& aTime);
   MediaDataDecoder::ConversionRequired NeedsConversion() const;
 
@@ -65,25 +60,23 @@ public:
 private:
   ~VideoDecoderChild();
 
   void AssertOnManagerThread() const;
 
   RefPtr<VideoDecoderChild> mIPDLSelfRef;
   RefPtr<nsIThread> mThread;
 
-  MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDrainPromise;
   MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushPromise;
   MozPromiseHolder<CreateDecoderPromise> mCreateDecoderPromise;
 
   nsCString mHardwareAcceleratedReason;
   bool mCanSend;
-  bool mInitialized;
   bool mHasDecoder;
   Atomic<bool> mIsHardwareAccelerated;
   Atomic<MediaDataDecoder::ConversionRequired> mConversion;
 
   // Set to true if the actor got destroyed and we haven't yet notified the
   // caller.
   bool mNeedNewDecoder;
   MediaDataDecoder::DecodedData mDecodedData;
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -111,41 +111,16 @@ VideoDecoderParent::Destroy()
 {
   MOZ_ASSERT(OnManagerThread());
   mDecodeTaskQueue->AwaitShutdownAndIdle();
   mDestroyed = true;
   mIPDLSelfRef = nullptr;
 }
 
 mozilla::ipc::IPCResult
-VideoDecoderParent::RecvInit()
-{
-  MOZ_ASSERT(OnManagerThread());
-  RefPtr<VideoDecoderParent> self = this;
-  mDecoder->Init()->Then(mManagerTaskQueue, __func__,
-    [self] (TrackInfo::TrackType aTrack) {
-      if (self->mDecoder) {
-        nsCString hardwareReason;
-        bool hardwareAccelerated =
-          self->mDecoder->IsHardwareAccelerated(hardwareReason);
-        uint32_t conversion =
-          static_cast<uint32_t>(self->mDecoder->NeedsConversion());
-        Unused << self->SendInitComplete(
-          hardwareAccelerated, hardwareReason, conversion);
-      }
-    },
-    [self] (MediaResult aReason) {
-      if (!self->mDestroyed) {
-        Unused << self->SendInitFailed(aReason);
-      }
-    });
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
 VideoDecoderParent::RecvInput(const MediaRawDataIPDL& aData)
 {
   MOZ_ASSERT(OnManagerThread());
   // XXX: This copies the data into a buffer owned by the MediaRawData. Ideally
   // we'd just take ownership of the shmem.
   RefPtr<MediaRawData> data = new MediaRawData(aData.buffer().get<uint8_t>(),
                                                aData.buffer().Size<uint8_t>());
   if (aData.buffer().Size<uint8_t>() && !data->Data()) {
--- a/dom/media/ipc/VideoDecoderParent.h
+++ b/dom/media/ipc/VideoDecoderParent.h
@@ -30,17 +30,16 @@ public:
                      const VideoInfo& aVideoInfo,
                      const layers::TextureFactoryIdentifier& aIdentifier,
                      TaskQueue* aManagerTaskQueue,
                      TaskQueue* aDecodeTaskQueue);
 
   void Destroy();
 
   // PVideoDecoderParent
-  mozilla::ipc::IPCResult RecvInit() override;
   mozilla::ipc::IPCResult RecvInput(const MediaRawDataIPDL& aData) override;
   mozilla::ipc::IPCResult RecvFlush() override;
   mozilla::ipc::IPCResult RecvDrain() override;
   mozilla::ipc::IPCResult RecvShutdown() override;
   mozilla::ipc::IPCResult RecvSetSeekThreshold(const int64_t& aTime) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -194,16 +194,18 @@ protected:
   // On Windows the task queue's threads in have MSCOM initialized with
   // COINIT_MULTITHREADED.
   // It is safe to store a reference to aConfig.
   // This is called on the decode task queue.
   virtual already_AddRefed<CreateDecoderPromise>
   CreateAudioDecoder(const CreateDecoderParams& aParams) = 0;
 };
 
+// Add comment for get after finishing init.
+
 // MediaDataDecoder is the interface exposed by decoders created by the
 // PlatformDecoderModule's Create*Decoder() functions. The type of
 // media data that the decoder accepts as valid input and produces as
 // output is determined when the MediaDataDecoder is created.
 //
 // Unless otherwise noted, all functions are only called on the decode task
 // queue.  An exception is the MediaDataDecoder in
 // MediaFormatReader::IsVideoAccelerated() for which all calls (Init(),
@@ -219,32 +221,30 @@ protected:
 class MediaDataDecoder
 {
 protected:
   virtual ~MediaDataDecoder() { }
 
 public:
   typedef TrackInfo::TrackType TrackType;
   typedef nsTArray<RefPtr<MediaData>> DecodedData;
-  typedef MozPromise<TrackType, MediaResult, /* IsExclusive = */ true>
-    InitPromise;
   typedef MozPromise<DecodedData, MediaResult, /* IsExclusive = */ true>
     DecodePromise;
   typedef MozPromise<bool, MediaResult, /* IsExclusive = */ true> FlushPromise;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder)
 
   // Initialize the decoder. The decoder should be ready to decode once
   // promise resolves. The decoder should do any initialization here, rather
   // than in its constructor or PlatformDecoderModule::Create*Decoder(),
   // so that if the MediaFormatReader needs to shutdown during initialization,
   // it can call Shutdown() to cancel this operation. Any initialization
   // that requires blocking the calling thread in this function *must*
   // be done here so that it can be canceled by calling Shutdown()!
-  virtual RefPtr<InitPromise> Init() = 0;
+  // virtual RefPtr<InitPromise> Init() = 0;
 
   // Inserts a sample into the decoder's decode pipeline. The DecodePromise will
   // be resolved with the decoded MediaData. In case the decoder needs more
   // input, the DecodePromise may be resolved with an empty array of samples to
   // indicate that Decode should be called again before a MediaData is returned.
   virtual RefPtr<DecodePromise> Decode(MediaRawData* aSample) = 0;
 
   // Causes all complete samples in the pipeline that can be decoded to be
@@ -326,11 +326,23 @@ public:
   // The demuxed data will be converted accordingly before feeding it to
   // Decode().
   virtual ConversionRequired NeedsConversion() const
   {
     return ConversionRequired::kNeedNone;
   }
 };
 
+// TODO : modify
+// Since MediaDataDecoder would only be used after finising initialization,
+// this class is used for the client who is response to create and init the
+// MediaDataDecoder, ex. DecoderModule.
+class MediaDataDecoderInitiator : public MediaDataDecoder
+{
+public:
+  typedef MozPromise<TrackInfo::TrackType, MediaResult, /* IsExclusive = */ true>
+    InitPromise;
+  virtual RefPtr<InitPromise> Init() = 0;
+};
+
 } // namespace mozilla
 
 #endif
--- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
@@ -28,17 +28,17 @@ AgnosticDecoderModule::SupportsMimeType(
   MOZ_LOG(sPDMLog, LogLevel::Debug, ("Agnostic decoder %s requested type",
         supports ? "supports" : "rejects"));
   return supports;
 }
 
 already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
 AgnosticDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
 {
-  RefPtr<MediaDataDecoder> decoder;
+  RefPtr<MediaDataDecoderInitiator> decoder;
   if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) {
     decoder = new VPXDecoder(aParams);
   } else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
     decoder = new TheoraDecoder(aParams);
   }
 
   RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
   RefPtr<AgnosticDecoderModule> self = this;
@@ -52,17 +52,17 @@ AgnosticDecoderModule::CreateVideoDecode
   });
 
   return promise.forget();
 }
 
 already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
 AgnosticDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
 {
-  RefPtr<MediaDataDecoder> decoder;
+  RefPtr<MediaDataDecoderInitiator> decoder;
   const TrackInfo& config = aParams.mConfig;
   if (VorbisDataDecoder::IsVorbis(config.mMimeType)) {
     decoder = new VorbisDataDecoder(aParams);
   } else if (OpusDataDecoder::IsOpus(config.mMimeType)) {
     decoder = new OpusDataDecoder(aParams);
   } else if (WaveDataDecoder::IsWave(config.mMimeType)) {
     decoder = new WaveDataDecoder(aParams);
   }
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -21,17 +21,17 @@
 #include "nsAutoPtr.h"
 #include "nsRect.h"
 
 namespace mozilla {
 
 // Decoder that uses a passed in object's Create function to create blank
 // MediaData objects.
 template<class BlankMediaDataCreator>
-class BlankMediaDataDecoder : public MediaDataDecoder
+class BlankMediaDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   BlankMediaDataDecoder(BlankMediaDataCreator* aCreator,
                         const CreateDecoderParams& aParams)
     : mCreator(aCreator)
     , mIsH264(MP4Decoder::IsH264(aParams.mConfig.mMimeType))
     , mMaxRefFrames(
         mIsH264
@@ -240,17 +240,17 @@ public:
 
   // Decode thread.
   already_AddRefed<CreateDecoderPromise>
   CreateVideoDecoder(const CreateDecoderParams& aParams) override
   {
     const VideoInfo& config = aParams.VideoConfig();
     BlankVideoDataCreator* creator = new BlankVideoDataCreator(
       config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
-    RefPtr<MediaDataDecoder> decoder =
+    RefPtr<MediaDataDecoderInitiator> decoder =
       new BlankMediaDataDecoder<BlankVideoDataCreator>(creator, aParams);
 
     RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
     RefPtr<BlankDecoderModule> self = this;
     decoder->Init()
       ->Then(AbstractThread::GetCurrent(), __func__,
         [self, decoder] () {
           self->mVideoPromise.Resolve(decoder, __func__);
@@ -265,17 +265,17 @@ public:
   // Decode thread.
   already_AddRefed<CreateDecoderPromise>
   CreateAudioDecoder(const CreateDecoderParams& aParams) override
   {
     const AudioInfo& config = aParams.AudioConfig();
     BlankAudioDataCreator* creator = new BlankAudioDataCreator(
       config.mChannels, config.mRate);
 
-    RefPtr<MediaDataDecoder> decoder =
+    RefPtr<MediaDataDecoderInitiator> decoder =
       new BlankMediaDataDecoder<BlankAudioDataCreator>(creator, aParams);
 
     RefPtr<CreateDecoderPromise> promise = mAudioPromise.Ensure(__func__);
     RefPtr<BlankDecoderModule> self = this;
     decoder->Init()
       ->Then(AbstractThread::GetCurrent(), __func__,
         [self, decoder] () {
           self->mAudioPromise.Resolve(decoder, __func__);
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -57,17 +57,17 @@ OpusDataDecoder::Shutdown()
 void
 OpusDataDecoder::AppendCodecDelay(MediaByteBuffer* config, uint64_t codecDelayUS)
 {
   uint8_t buffer[sizeof(uint64_t)];
   BigEndian::writeUint64(buffer, codecDelayUS);
   config->AppendElements(buffer, sizeof(uint64_t));
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 OpusDataDecoder::Init()
 {
   size_t length = mInfo.mCodecSpecificConfig->Length();
   uint8_t *p = mInfo.mCodecSpecificConfig->Elements();
   if (length < sizeof(uint64_t)) {
     OPUS_DEBUG("CodecSpecificConfig too short to read codecDelay!");
     return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
   }
--- a/dom/media/platforms/agnostic/OpusDecoder.h
+++ b/dom/media/platforms/agnostic/OpusDecoder.h
@@ -12,23 +12,26 @@
 #include "nsAutoPtr.h"
 
 struct OpusMSDecoder;
 
 namespace mozilla {
 
 class OpusParser;
 
-class OpusDataDecoder : public MediaDataDecoder
+class OpusDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   explicit OpusDataDecoder(const CreateDecoderParams& aParams);
   ~OpusDataDecoder();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override
   {
     return "opus audio decoder";
   }
--- a/dom/media/platforms/agnostic/TheoraDecoder.cpp
+++ b/dom/media/platforms/agnostic/TheoraDecoder.cpp
@@ -64,17 +64,17 @@ TheoraDecoder::Shutdown()
     if (mTheoraDecoderContext) {
       th_decode_free(mTheoraDecoderContext);
       mTheoraDecoderContext = nullptr;
     }
     return ShutdownPromise::CreateAndResolve(true, __func__);
   });
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 TheoraDecoder::Init()
 {
   th_comment_init(&mTheoraComment);
   th_info_init(&mTheoraInfo);
 
   nsTArray<unsigned char*> headers;
   nsTArray<size_t> headerLens;
   if (!XiphExtradataToHeaders(headers, headerLens,
--- a/dom/media/platforms/agnostic/TheoraDecoder.h
+++ b/dom/media/platforms/agnostic/TheoraDecoder.h
@@ -8,22 +8,25 @@
 
 #include "PlatformDecoderModule.h"
 #include "ogg/ogg.h"
 #include "theora/theoradec.h"
 #include <stdint.h>
 
 namespace mozilla {
 
-class TheoraDecoder : public MediaDataDecoder
+class TheoraDecoder : public MediaDataDecoderInitiator
 {
 public:
   explicit TheoraDecoder(const CreateDecoderParams& aParams);
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
 
   // Return true if mimetype is a Theora codec
   static bool IsTheora(const nsACString& aMimeType);
 
--- a/dom/media/platforms/agnostic/VPXDecoder.cpp
+++ b/dom/media/platforms/agnostic/VPXDecoder.cpp
@@ -88,31 +88,31 @@ VPXDecoder::Shutdown()
   RefPtr<VPXDecoder> self = this;
   return InvokeAsync(mTaskQueue, __func__, [self, this]() {
     vpx_codec_destroy(&mVPX);
     vpx_codec_destroy(&mVPXAlpha);
     return ShutdownPromise::CreateAndResolve(true, __func__);
   });
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 VPXDecoder::Init()
 {
   if (NS_FAILED(InitContext(&mVPX, mInfo, mCodec))) {
-    return VPXDecoder::InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                                    __func__);
+    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                                               __func__);
   }
   if (mInfo.HasAlpha()) {
     if (NS_FAILED(InitContext(&mVPXAlpha, mInfo, mCodec))) {
-      return VPXDecoder::InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                                      __func__);
+      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                                                 __func__);
     }
   }
-  return VPXDecoder::InitPromise::CreateAndResolve(TrackInfo::kVideoTrack,
-                                                   __func__);
+  return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack,
+                                              __func__);
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 VPXDecoder::Flush()
 {
   return InvokeAsync(mTaskQueue, __func__, []() {
     return FlushPromise::CreateAndResolve(true, __func__);
   });
--- a/dom/media/platforms/agnostic/VPXDecoder.h
+++ b/dom/media/platforms/agnostic/VPXDecoder.h
@@ -11,22 +11,25 @@
 #include <stdint.h>
 #define VPX_DONT_DEFINE_STDINT_TYPES
 #include "vpx/vp8dx.h"
 #include "vpx/vpx_codec.h"
 #include "vpx/vpx_decoder.h"
 
 namespace mozilla {
 
-class VPXDecoder : public MediaDataDecoder
+class VPXDecoder : public MediaDataDecoderInitiator
 {
 public:
   explicit VPXDecoder(const CreateDecoderParams& aParams);
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override
   {
     return "libvpx video decoder";
   }
--- a/dom/media/platforms/agnostic/VorbisDecoder.cpp
+++ b/dom/media/platforms/agnostic/VorbisDecoder.cpp
@@ -56,17 +56,17 @@ RefPtr<ShutdownPromise>
 VorbisDataDecoder::Shutdown()
 {
   RefPtr<VorbisDataDecoder> self = this;
   return InvokeAsync(mTaskQueue, __func__, [self]() {
     return ShutdownPromise::CreateAndResolve(true, __func__);
   });
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 VorbisDataDecoder::Init()
 {
   vorbis_info_init(&mVorbisInfo);
   vorbis_comment_init(&mVorbisComment);
   PodZero(&mVorbisDsp);
   PodZero(&mVorbisBlock);
 
   AutoTArray<unsigned char*,4> headers;
--- a/dom/media/platforms/agnostic/VorbisDecoder.h
+++ b/dom/media/platforms/agnostic/VorbisDecoder.h
@@ -13,23 +13,26 @@
 #ifdef MOZ_TREMOR
 #include "tremor/ivorbiscodec.h"
 #else
 #include "vorbis/codec.h"
 #endif
 
 namespace mozilla {
 
-class VorbisDataDecoder : public MediaDataDecoder
+class VorbisDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   explicit VorbisDataDecoder(const CreateDecoderParams& aParams);
   ~VorbisDataDecoder();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override
   {
     return "vorbis audio decoder";
   }
--- a/dom/media/platforms/agnostic/WAVDecoder.cpp
+++ b/dom/media/platforms/agnostic/WAVDecoder.cpp
@@ -55,17 +55,17 @@ RefPtr<ShutdownPromise>
 WaveDataDecoder::Shutdown()
 {
   RefPtr<WaveDataDecoder> self = this;
   return InvokeAsync(mTaskQueue, __func__, [self]() {
     return ShutdownPromise::CreateAndResolve(true, __func__);
   });
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 WaveDataDecoder::Init()
 {
   return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 WaveDataDecoder::Decode(MediaRawData* aSample)
 {
--- a/dom/media/platforms/agnostic/WAVDecoder.h
+++ b/dom/media/platforms/agnostic/WAVDecoder.h
@@ -7,25 +7,28 @@
 #if !defined(WaveDecoder_h_)
 #define WaveDecoder_h_
 
 #include "PlatformDecoderModule.h"
 #include "mp4_demuxer/ByteReader.h"
 
 namespace mozilla {
 
-class WaveDataDecoder : public MediaDataDecoder
+class WaveDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   explicit WaveDataDecoder(const CreateDecoderParams& aParams);
 
   // Return true if mimetype is Wave
   static bool IsWave(const nsACString& aMimeType);
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override
   {
     return "wave audio decoder";
   }
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -38,22 +38,16 @@ public:
     , mProxy(aProxy)
     , mSamplesWaitingForKey(
         new SamplesWaitingForKey(mProxy, aType, aOnWaitingForKey))
     , mThroughputLimiter(aDecodeTaskQueue)
     , mIsShutdown(false)
   {
   }
 
-  RefPtr<InitPromise> Init() override
-  {
-    MOZ_ASSERT(!mIsShutdown);
-    return mDecoder->Init();
-  }
-
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
   {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_RELEASE_ASSERT(mDecrypts.Count() == 0,
                        "Can only process one sample at a time");
     RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
 
     RefPtr<EMEDecryptor> self = this;
@@ -350,18 +344,21 @@ EMEDecoderModule::CreateVideoDecoder(con
 
   RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
   RefPtr<EMEDecoderModule> self = this;
   if (SupportsMimeType(aParams.mConfig.mMimeType, nullptr)) {
     // GMP decodes. Assume that means it can decrypt too.
     RefPtr<MediaDataDecoderProxy> wrapper =
       CreateDecoderWrapper(mProxy, aParams);
     auto params = GMPVideoDecoderParams(aParams);
-    wrapper->SetProxyTarget(new EMEVideoDecoder(mProxy, params));
-    wrapper->Init()
+
+    RefPtr<EMEVideoDecoder> decoder = new EMEVideoDecoder(mProxy, params);
+    wrapper->SetProxyTarget(decoder);
+
+    decoder->Init()
       ->Then(AbstractThread::GetCurrent()->AsTaskQueue(), __func__,
         [self, wrapper] () {
           self->mVideoPromise.Resolve(wrapper, __func__);
         },
         [self, wrapper] () {
           self->mVideoPromise.Reject(false, __func__);
       });
 
--- a/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
@@ -56,20 +56,21 @@ GMPDecoderModule::CreateVideoDecoder(con
   if (!MP4Decoder::IsH264(aParams.mConfig.mMimeType)
       && !VPXDecoder::IsVP8(aParams.mConfig.mMimeType)
       && !VPXDecoder::IsVP9(aParams.mConfig.mMimeType)) {
     return nullptr;
   }
 
   RefPtr<MediaDataDecoderProxy> wrapper = CreateDecoderWrapper();
   auto params = GMPVideoDecoderParams(aParams);
-  wrapper->SetProxyTarget(new GMPVideoDecoder(params));
+  RefPtr<MediaDataDecoderInitiator> decoder = new GMPVideoDecoder(params);
+  wrapper->SetProxyTarget(decoder);
 
   RefPtr<GMPDecoderModule> self = this;
-  wrapper->Init()
+  decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, wrapper] () {
         self->mVideoPromise.Resolve(wrapper, __func__);
       },
       [self] () {
         self->mVideoPromise.Reject(false, __func__);
     });
 
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
@@ -281,17 +281,17 @@ GMPVideoDecoder::GMPInitDone(GMPVideoDec
   // combined with kGMPVideoCodecH264) to mean "like AVCC but restricted to
   // 4-byte NAL lengths" (i.e. buffer lengths are specified in big-endian
   // and do not include the length of the buffer length field.
   mConvertNALUnitLengths = isOpenH264;
 
   mInitPromise.Resolve(TrackInfo::kVideoTrack, __func__);
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 GMPVideoDecoder::Init()
 {
   MOZ_ASSERT(IsOnGMPThread());
 
   mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   MOZ_ASSERT(mMPS);
 
   RefPtr<InitPromise> promise(mInitPromise.Ensure(__func__));
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
@@ -22,23 +22,26 @@ struct GMPVideoDecoderParams
 
   const VideoInfo& mConfig;
   TaskQueue* mTaskQueue;
   layers::ImageContainer* mImageContainer;
   layers::LayersBackend mLayersBackend;
   RefPtr<GMPCrashHelper> mCrashHelper;
 };
 
-class GMPVideoDecoder : public MediaDataDecoder,
+class GMPVideoDecoder : public MediaDataDecoderInitiator,
                         public GMPVideoDecoderCallbackProxy
 {
 public:
   explicit GMPVideoDecoder(const GMPVideoDecoderParams& aParams);
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override
   {
     return "GMP video decoder";
   }
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -222,16 +222,17 @@ public:
     : RemoteDataDecoder(MediaData::Type::VIDEO_DATA, aConfig.mMimeType,
                         aFormat, aDrmStubId, aTaskQueue)
     , mImageContainer(aImageContainer)
     , mMutex("RemoteVideoDecoder Mutex")
     , mConfig(aConfig)
   {
   }
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override
   {
     mSurfaceTexture = AndroidSurfaceTexture::Create();
     if (!mSurfaceTexture) {
       NS_WARNING("Failed to create SurfaceTexture for video decode\n");
       return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                                           __func__);
     }
@@ -315,16 +316,17 @@ public:
       jni::ByteBuffer::LocalRef buffer(env);
       buffer = jni::ByteBuffer::New(aConfig.mCodecSpecificConfig->Elements(),
                                     aConfig.mCodecSpecificConfig->Length());
       NS_ENSURE_SUCCESS_VOID(
         aFormat->SetByteBuffer(NS_LITERAL_STRING("csd-0"), buffer));
     }
   }
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override
   {
     // Register native methods.
     JavaCallbacksSupport::Init();
 
     mJavaCallbacks = CodecProxy::NativeCallbacks::New();
     JavaCallbacksSupport::AttachNative(
       mJavaCallbacks, mozilla::MakeUnique<CallbacksSupport>(this));
@@ -444,17 +446,17 @@ RemoteDataDecoder::CreateAudioDecoder(co
 {
   const AudioInfo& config = aParams.AudioConfig();
   MediaFormat::LocalRef format;
   NS_ENSURE_SUCCESS(
     MediaFormat::CreateAudioFormat(
       config.mMimeType, config.mRate, config.mChannels, &format),
     nullptr);
 
-  RefPtr<MediaDataDecoder> decoder =
+  RefPtr<MediaDataDecoderInitiator> decoder =
     new RemoteAudioDecoder(config, format, aDrmStubId, aParams.mTaskQueue);
 
   RefPtr<CreateDecoderPromise> promise = mAudioPromise.Ensure(__func__);
   RefPtr<RemoteDataDecoder> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, decoder, aProxy] () {
        if (aProxy) {
@@ -479,17 +481,17 @@ RemoteDataDecoder::CreateVideoDecoder(co
   MediaFormat::LocalRef format;
   NS_ENSURE_SUCCESS(
     MediaFormat::CreateVideoFormat(TranslateMimeType(config.mMimeType),
                                    config.mDisplay.width,
                                    config.mDisplay.height,
                                    &format),
     nullptr);
 
-  RefPtr<MediaDataDecoder> decoder = new RemoteVideoDecoder(
+  RefPtr<MediaDataDecoderInitiator> decoder = new RemoteVideoDecoder(
     config, format, aParams.mImageContainer, aDrmStubId, aParams.mTaskQueue);
 
   RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
   RefPtr<RemoteDataDecoder> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, decoder, aProxy] () {
        if (aProxy) {
--- a/dom/media/platforms/android/RemoteDataDecoder.h
+++ b/dom/media/platforms/android/RemoteDataDecoder.h
@@ -9,25 +9,25 @@
 #include "FennecJNIWrappers.h"
 #include "SurfaceTexture.h"
 #include "TimeUnits.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Monitor.h"
 
 namespace mozilla {
 
-class RemoteDataDecoder : public MediaDataDecoder
+class RemoteDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   static already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
   CreateAudioDecoder(const CreateDecoderParams& aParams,
                      const nsString& aDrmStubId,
                      CDMProxy* aProxy);
 
-  static already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
+  static already_AddRefed<PlatformDecoderModule::CreateDecoderPromiseh>
   CreateVideoDecoder(const CreateDecoderParams& aParams,
                      const nsString& aDrmStubId,
                      CDMProxy* aProxy);
 
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -47,17 +47,17 @@ AppleATDecoder::AppleATDecoder(const Aud
 }
 
 AppleATDecoder::~AppleATDecoder()
 {
   MOZ_COUNT_DTOR(AppleATDecoder);
   MOZ_ASSERT(!mConverter);
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 AppleATDecoder::Init()
 {
   if (!mFormatID) {
     NS_ERROR("Non recognised format");
     return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
   }
 
   return InitPromise::CreateAndResolve(TrackType::kAudioTrack, __func__);
--- a/dom/media/platforms/apple/AppleATDecoder.h
+++ b/dom/media/platforms/apple/AppleATDecoder.h
@@ -12,23 +12,27 @@
 #include "mozilla/Vector.h"
 #include "nsIThread.h"
 #include "AudioConverter.h"
 
 namespace mozilla {
 
 class TaskQueue;
 
-class AppleATDecoder : public MediaDataDecoder {
+class AppleATDecoder : public MediaDataDecoderInitiator
+{
 public:
   AppleATDecoder(const AudioInfo& aConfig,
                  TaskQueue* aTaskQueue);
   ~AppleATDecoder();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
 
   const char* GetDescriptionName() const override
   {
     return "apple CoreMedia decoder";
--- a/dom/media/platforms/apple/AppleDecoderModule.cpp
+++ b/dom/media/platforms/apple/AppleDecoderModule.cpp
@@ -63,17 +63,17 @@ AppleDecoderModule::Startup()
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
 AppleDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
 {
-  RefPtr<MediaDataDecoder> decoder =
+  RefPtr<MediaDataDecoderInitiator> decoder =
     new AppleVTDecoder(aParams.VideoConfig(),
                        aParams.mTaskQueue,
                        aParams.mImageContainer);
 
   RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
   RefPtr<AppleDecoderModule> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
@@ -85,17 +85,17 @@ AppleDecoderModule::CreateVideoDecoder(c
   });
 
   return promise.forget();
 }
 
 already_AddRefed<PlatformDecoderModule::CreateDecoderPromise>
 AppleDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
 {
-  RefPtr<MediaDataDecoder> decoder =
+  RefPtr<MediaDataDecoderInitiator> decoder =
     new AppleATDecoder(aParams.AudioConfig(), aParams.mTaskQueue);
 
   RefPtr<CreateDecoderPromise> promise = mAudioPromise.Ensure(__func__);
   RefPtr<AppleDecoderModule> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, decoder] () {
         self->mAudioPromise.Resolve(decoder, __func__);
--- a/dom/media/platforms/apple/AppleVTDecoder.cpp
+++ b/dom/media/platforms/apple/AppleVTDecoder.cpp
@@ -56,17 +56,17 @@ AppleVTDecoder::AppleVTDecoder(const Vid
   mPromise.SetMonitor(&mMonitor);
 }
 
 AppleVTDecoder::~AppleVTDecoder()
 {
   MOZ_COUNT_DTOR(AppleVTDecoder);
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 AppleVTDecoder::Init()
 {
   nsresult rv = InitializeSession();
 
   if (NS_SUCCEEDED(rv)) {
     return InitPromise::CreateAndResolve(TrackType::kVideoTrack, __func__);
   }
 
--- a/dom/media/platforms/apple/AppleVTDecoder.h
+++ b/dom/media/platforms/apple/AppleVTDecoder.h
@@ -12,17 +12,17 @@
 #include "nsIThread.h"
 #include "ReorderQueue.h"
 #include "TimeUnits.h"
 
 #include "VideoToolbox/VideoToolbox.h"
 
 namespace mozilla {
 
-class AppleVTDecoder : public MediaDataDecoder {
+class AppleVTDecoder : public MediaDataDecoderInitiator {
 public:
   AppleVTDecoder(const VideoInfo& aConfig,
                  TaskQueue* aTaskQueue,
                  layers::ImageContainer* aImageContainer);
 
   class AppleFrameRef {
   public:
     media::TimeUnit decode_timestamp;
@@ -36,17 +36,20 @@ public:
       , composition_timestamp(media::TimeUnit::FromMicroseconds(aSample.mTime))
       , duration(media::TimeUnit::FromMicroseconds(aSample.mDuration))
       , byte_offset(aSample.mOffset)
       , is_sync_point(aSample.mKeyframe)
     {
     }
   };
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   void SetSeekThreshold(const media::TimeUnit& aTime) override;
 
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override
   {
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -21,25 +21,25 @@ FFmpegAudioDecoder<LIBAV_VER>::FFmpegAud
   // Use a new MediaByteBuffer as the object will be modified during
   // initialization.
   if (aConfig.mCodecSpecificConfig && aConfig.mCodecSpecificConfig->Length()) {
     mExtraData = new MediaByteBuffer;
     mExtraData->AppendElements(*aConfig.mCodecSpecificConfig);
   }
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 FFmpegAudioDecoder<LIBAV_VER>::Init()
 {
   nsresult rv = InitDecoder();
 
   return rv == NS_OK
          ? InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__)
          : InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                        __func__);
+                                               __func__);
 }
 
 void
 FFmpegAudioDecoder<LIBAV_VER>::InitCodecContext()
 {
   MOZ_ASSERT(mCodecContext);
   // We do not want to set this value to 0 as FFmpeg by default will
   // use the number of cores, which with our mozlibavutil get_cpu_count
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
@@ -19,17 +19,19 @@ template <int V> class FFmpegAudioDecode
 template <>
 class FFmpegAudioDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
 {
 public:
   FFmpegAudioDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
                      const AudioInfo& aConfig);
   virtual ~FFmpegAudioDecoder();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
   void InitCodecContext() override;
   static AVCodecID GetCodecId(const nsACString& aMimeType);
   const char* GetDescriptionName() const override
   {
     return "ffmpeg audio decoder";
   }
 
 private:
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
@@ -15,26 +15,29 @@
 namespace mozilla {
 
 template <int V>
 class FFmpegDataDecoder : public MediaDataDecoder
 {
 };
 
 template <>
-class FFmpegDataDecoder<LIBAV_VER> : public MediaDataDecoder
+class FFmpegDataDecoder<LIBAV_VER> : public MediaDataDecoderInitiator
 {
 public:
   FFmpegDataDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
                     AVCodecID aCodecID);
   virtual ~FFmpegDataDecoder();
 
   static bool Link();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override = 0;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
 
   static AVCodec* FindAVCodec(FFmpegLibWrapper* aLib, AVCodecID aCodec);
 
 protected:
--- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
@@ -35,17 +35,17 @@ public:
   {
 
     if (!CanCreateVideoDecoder(aParams)) {
       RefPtr<CreateDecoderPromise> promise =
         CreateDecoderPromise::CreateAndReject(false, __func__);
       return promise.forget();
     }
 
-    RefPtr<MediaDataDecoder> decoder = new FFmpegVideoDecoder<V>(
+    RefPtr<FFmpegVideoDecoder<V>> decoder = new FFmpegVideoDecoder<V>(
       mLib,
       aParams.mTaskQueue,
       aParams.VideoConfig(),
       aParams.mImageContainer,
       aParams.mOptions.contains(CreateDecoderParams::Option::LowLatency));
 
     RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
     RefPtr<FFmpegDecoderModule> self = this;
@@ -59,17 +59,17 @@ public:
     });
 
     return promise.forget();
   }
 
   already_AddRefed<CreateDecoderPromise>
   CreateAudioDecoder(const CreateDecoderParams& aParams) override
   {
-    RefPtr<MediaDataDecoder> decoder =
+    RefPtr<FFmpegAudioDecoder<V>> decoder =
       new FFmpegAudioDecoder<V>(mLib,
                                 aParams.mTaskQueue,
                                 aParams.AudioConfig());
     RefPtr<CreateDecoderPromise> promise = mAudioPromise.Ensure(__func__);
     RefPtr<FFmpegDecoderModule> self = this;
     decoder->Init()
       ->Then(AbstractThread::GetCurrent(), __func__,
         [self, decoder] () {
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -111,17 +111,17 @@ FFmpegVideoDecoder<LIBAV_VER>::FFmpegVid
 {
   MOZ_COUNT_CTOR(FFmpegVideoDecoder);
   // Use a new MediaByteBuffer as the object will be modified during
   // initialization.
   mExtraData = new MediaByteBuffer;
   mExtraData->AppendElements(*aConfig.mExtraData);
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 FFmpegVideoDecoder<LIBAV_VER>::Init()
 {
   if (NS_FAILED(InitDecoder())) {
     return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
   }
 
   return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
 }
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -27,17 +27,19 @@ class FFmpegVideoDecoder<LIBAV_VER> : pu
 
 public:
   FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
                      const VideoInfo& aConfig,
                      ImageContainer* aImageContainer,
                      bool aLowLatency);
   virtual ~FFmpegVideoDecoder();
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
   void InitCodecContext() override;
   const char* GetDescriptionName() const override
   {
 #ifdef USING_MOZFFVPX
     return "ffvpx video decoder";
 #else
     return "ffmpeg video decoder";
 #endif
--- a/dom/media/platforms/omx/OmxDataDecoder.cpp
+++ b/dom/media/platforms/omx/OmxDataDecoder.cpp
@@ -139,17 +139,17 @@ OmxDataDecoder::EndOfStream()
             mDecodedData.Clear();
         },
         [self, this] () {
           mDrainPromise.ResolveIfExists(mDecodedData, __func__);
           mDecodedData.Clear();
         });
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 OmxDataDecoder::Init()
 {
   LOG("");
 
   RefPtr<OmxDataDecoder> self = this;
   return InvokeAsync(mOmxTaskQueue, __func__, [self, this]() {
     InitializationTask();
 
--- a/dom/media/platforms/omx/OmxDataDecoder.h
+++ b/dom/media/platforms/omx/OmxDataDecoder.h
@@ -50,25 +50,28 @@ typedef OmxPromiseLayer::BUFFERLIST BUFF
  *   OmxPromiseLayer acts as the OpenMAX IL component.
  *
  * OpenMAX IL core:
  *   "Platform-specific code that has the functionality necessary to locate and
  *   then load an OpenMAX IL component into main memory."
  *
  *   OmxPlatformLayer acts as the OpenMAX IL core.
  */
-class OmxDataDecoder : public MediaDataDecoder {
+class OmxDataDecoder : public MediaDataDecoderInitiator {
 protected:
   virtual ~OmxDataDecoder();
 
 public:
   OmxDataDecoder(const TrackInfo& aTrackInfo,
                  layers::ImageContainer* aImageContainer);
 
+  // MediaDataDecoderInitiator API
   RefPtr<InitPromise> Init() override;
+
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
 
   const char* GetDescriptionName() const override
   {
     return "omx decoder";
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -92,17 +92,17 @@ WMFDecoderModule::CreateVideoDecoder(con
                            aParams.mKnowsCompositor,
                            aParams.mImageContainer,
                            sDXVAEnabled));
 
   if (!manager->Init()) {
     return CreateDecoderPromise::CreateAndReject(false, __func__);
   }
 
-  RefPtr<MediaDataDecoder> decoder =
+  RefPtr<MediaDataDecoderInitiator> decoder =
     new WMFMediaDataDecoder(manager.forget(), aParams.mTaskQueue);
 
   RefPtr<WMFDecoderModule> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, decoder] () {
         self->mVideoPromise.Resolve(decoder, __func__);
       },
@@ -121,17 +121,17 @@ WMFDecoderModule::CreateAudioDecoder(con
     new WMFAudioMFTManager(aParams.AudioConfig()));
 
   RefPtr<CreateDecoderPromise> promise;
   if (!manager->Init()) {
     promise = CreateDecoderPromise::CreateAndReject(false, __func__);
     return promise.forget();
   }
 
-  RefPtr<MediaDataDecoder> decoder =
+  RefPtr<MediaDataDecoderInitiator> decoder =
     new WMFMediaDataDecoder(manager.forget(), aParams.mTaskQueue);
 
   RefPtr<WMFDecoderModule> self = this;
   decoder->Init()
     ->Then(AbstractThread::GetCurrent(), __func__,
       [self, decoder] () {
         self->mAudioPromise.Resolve(decoder, __func__);
       },
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -23,17 +23,17 @@ WMFMediaDataDecoder::WMFMediaDataDecoder
   , mMFTManager(aMFTManager)
 {
 }
 
 WMFMediaDataDecoder::~WMFMediaDataDecoder()
 {
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
+RefPtr<MediaDataDecoderInitiator::InitPromise>
 WMFMediaDataDecoder::Init()
 {
   MOZ_ASSERT(!mIsShutDown);
   return InitPromise::CreateAndResolve(mMFTManager->GetType(), __func__);
 }
 
 // A single telemetry sample is reported for each MediaDataDecoder object
 // that has detected error or produced output successfully.
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -79,24 +79,26 @@ protected:
   Maybe<media::TimeUnit> mSeekTargetThreshold;
 };
 
 // Decodes audio and video using Windows Media Foundation. Samples are decoded
 // using the MFTDecoder created by the MFTManager. This class implements
 // the higher-level logic that drives mapping the MFT to the async
 // MediaDataDecoder interface. The specifics of decoding the exact stream
 // type are handled by MFTManager and the MFTDecoder it creates.
-class WMFMediaDataDecoder : public MediaDataDecoder
+class WMFMediaDataDecoder : public MediaDataDecoderInitiator
 {
 public:
   WMFMediaDataDecoder(MFTManager* aOutputSource, TaskQueue* aTaskQueue);
   ~WMFMediaDataDecoder();
 
-  RefPtr<MediaDataDecoder::InitPromise> Init() override;
+  // MediaDataDecoderInitiator API
+  RefPtr<InitPromise> Init() override;
 
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
 
   RefPtr<DecodePromise> Drain() override;
 
   RefPtr<FlushPromise> Flush() override;
 
   RefPtr<ShutdownPromise> Shutdown() override;
 
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -63,28 +63,16 @@ H264Converter::CreateVideoDecoder()
     [self] () {
       self->mVideoPromise.Reject(false, __func__);
   });
 
   RefPtr<CreateDecoderPromise> promise = mVideoPromise.Ensure(__func__);
   return promise.forget();
 }
 
-RefPtr<MediaDataDecoder::InitPromise>
-H264Converter::Init()
-{
-  if (mDecoder) {
-    return mDecoder->Init();
-  }
-
-  // We haven't been able to initialize a decoder due to a missing SPS/PPS.
-  return MediaDataDecoder::InitPromise::CreateAndResolve(
-           TrackType::kVideoTrack, __func__);
-}
-
 RefPtr<MediaDataDecoder::DecodePromise>
 H264Converter::Decode(MediaRawData* aSample)
 {
   MOZ_RELEASE_ASSERT(!mDecodePromiseRequest.Exists() &&
                      !mCreateDecoderRequest.Exists(),
                      "Can't request a new decode until previous one completed");
 
   if (!mp4_demuxer::AnnexB::ConvertSampleToAVCC(aSample)) {
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -27,17 +27,17 @@ class H264Converter : public MediaDataDe
 public:
 
   H264Converter(PlatformDecoderModule* aPDM,
                 const CreateDecoderParams& aParams);
   virtual ~H264Converter();
 
   RefPtr<CreateDecoderPromise> CreateVideoDecoder();
 
-  RefPtr<InitPromise> Init() override;
+  // MediaDataDecoder API
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
   const char* GetDescriptionName() const override
   {
     if (mDecoder) {
--- a/dom/media/platforms/wrappers/MediaDataDecoderProxy.cpp
+++ b/dom/media/platforms/wrappers/MediaDataDecoderProxy.cpp
@@ -3,29 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaDataDecoderProxy.h"
 
 namespace mozilla {
 
-RefPtr<MediaDataDecoder::InitPromise>
-MediaDataDecoderProxy::Init()
-{
-  MOZ_ASSERT(!mIsShutdown);
-
-  if (!mProxyThread) {
-    return mProxyDecoder->Init();
-  }
-  RefPtr<MediaDataDecoderProxy> self = this;
-  return InvokeAsync(mProxyThread, __func__,
-                     [self, this]() { return mProxyDecoder->Init(); });
-}
-
 RefPtr<MediaDataDecoder::DecodePromise>
 MediaDataDecoderProxy::Decode(MediaRawData* aSample)
 {
   MOZ_ASSERT(!mIsShutdown);
 
   if (!mProxyThread) {
     return mProxyDecoder->Decode(aSample);
   }
--- a/dom/media/platforms/wrappers/MediaDataDecoderProxy.h
+++ b/dom/media/platforms/wrappers/MediaDataDecoderProxy.h
@@ -36,17 +36,16 @@ public:
   }
 
   void SetProxyTarget(MediaDataDecoder* aProxyDecoder)
   {
     MOZ_ASSERT(aProxyDecoder);
     mProxyDecoder = aProxyDecoder;
   }
 
-  RefPtr<InitPromise> Init() override;
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   const char* GetDescriptionName() const override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
   void SetSeekThreshold(const media::TimeUnit& aTime) override;
   bool SupportDecoderRecycling() const override;