Bug 1297311: P1. Always recreate a decoder when SPS changes. r?cpearce draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 26 Sep 2016 12:28:07 +1000
changeset 417518 3e3417b8101674b816b1576774bc22cfdabf06bb
parent 417517 91d5239c1307e76fdafb39fee3fd12ee64fe4473
child 417519 40ab37aaad770cc98baedf51926ff9edb3fb686a
push id30410
push userbmo:jyavenard@mozilla.com
push dateMon, 26 Sep 2016 02:36:42 +0000
reviewerscpearce
bugs1297311
milestone52.0a1
Bug 1297311: P1. Always recreate a decoder when SPS changes. r?cpearce This allow consistency between platforms. A decoder will now always be shutdown and another one created if the video configuration changes. MozReview-Commit-ID: 1SPzhVuBrip
dom/media/ipc/RemoteVideoDecoder.h
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
dom/media/platforms/wmf/WMFMediaDataDecoder.h
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.h
dom/media/platforms/wrappers/FuzzingWrapper.cpp
dom/media/platforms/wrappers/FuzzingWrapper.h
dom/media/platforms/wrappers/H264Converter.cpp
dom/media/platforms/wrappers/H264Converter.h
--- a/dom/media/ipc/RemoteVideoDecoder.h
+++ b/dom/media/ipc/RemoteVideoDecoder.h
@@ -27,17 +27,16 @@ public:
   friend class RemoteDecoderModule;
 
   // MediaDataDecoder
   RefPtr<InitPromise> Init() override;
   void Input(MediaRawData* aSample) override;
   void Flush() override;
   void Drain() override;
   void Shutdown() override;
-  void ConfigurationChanged(const TrackInfo& aConfig) override { MOZ_ASSERT(false); }
 
   const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
 
 private:
   explicit RemoteVideoDecoder(MediaDataDecoderCallback* aCallback);
   ~RemoteVideoDecoder();
 
   RefPtr<InitPromise> InitInternal();
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -261,24 +261,16 @@ public:
   // returned.
   virtual void Shutdown() = 0;
 
   // Called from the state machine task queue or main thread.
   // Decoder needs to decide whether or not hardware accelearation is supported
   // after creating. It doesn't need to call Init() before calling this function.
   virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
 
-  // ConfigurationChanged will be called to inform the video or audio decoder
-  // that the format of the next input sample is about to change.
-  // If video decoder, aConfig will be a VideoInfo object.
-  // If audio decoder, aConfig will be a AudioInfo object.
-  // It is not safe to store a reference to this object and the decoder must
-  // make a copy.
-  virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
-
   // Return the name of the MediaDataDecoder, only used for decoding.
   // Only return a static const string, as the information may be accessed
   // in a non thread-safe fashion.
   virtual const char* GetDescriptionName() const = 0;
 
   // Set a hint of seek target time to decoder. Decoder will drop any decoded
   // data which pts is smaller than this value. This threshold needs to be clear
   // after reset decoder.
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -205,37 +205,16 @@ WMFMediaDataDecoder::Drain()
 bool
 WMFMediaDataDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const {
   MOZ_ASSERT(!mIsShutDown);
 
   return mMFTManager && mMFTManager->IsHardwareAccelerated(aFailureReason);
 }
 
 void
-WMFMediaDataDecoder::ConfigurationChanged(const TrackInfo& aConfig)
-{
-  MOZ_ASSERT(mCallback->OnReaderTaskQueue());
-
-  nsCOMPtr<nsIRunnable> runnable =
-    NewRunnableMethod<UniquePtr<TrackInfo>&&>(
-    this,
-    &WMFMediaDataDecoder::ProcessConfigurationChanged,
-    aConfig.Clone());
-  mTaskQueue->Dispatch(runnable.forget());
-}
-
-void
-WMFMediaDataDecoder::ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig)
-{
-  if (mMFTManager) {
-    mMFTManager->ConfigurationChanged(*aConfig);
-  }
-}
-
-void
 WMFMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
 
   RefPtr<WMFMediaDataDecoder> self = this;
   nsCOMPtr<nsIRunnable> runnable =
     NS_NewRunnableFunction([self, aTime]() {
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -52,18 +52,16 @@ public:
 
   // Destroys all resources.
   virtual void Shutdown() = 0;
 
   virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
 
   virtual TrackInfo::TrackType GetType() = 0;
 
-  virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
-
   virtual const char* GetDescriptionName() const = 0;
 
   virtual void SetSeekThreshold(const media::TimeUnit& aTime) {
     mSeekTargetThreshold = Some(aTime);
   }
 
 protected:
   // IMFTransform wrapper that performs the decoding.
@@ -91,18 +89,16 @@ public:
   void Flush() override;
 
   void Drain() override;
 
   void Shutdown() override;
 
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
 
-  void ConfigurationChanged(const TrackInfo& aConfig) override;
-
   const char* GetDescriptionName() const override
   {
     return mMFTManager ? mMFTManager->GetDescriptionName() : "";
   }
 
   virtual void SetSeekThreshold(const media::TimeUnit& aTime) override;
 
 private:
@@ -120,20 +116,16 @@ private:
   void ProcessFlush();
 
   // Called on the task queue. Orders the MFT to drain, and then extracts
   // all available output.
   void ProcessDrain();
 
   void ProcessShutdown();
 
-  // Called on the task queue. Tell the MFT that the next Input will have a
-  // different configuration (typically resolution change).
-  void ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig);
-
   const RefPtr<TaskQueue> mTaskQueue;
   MediaDataDecoderCallback* mCallback;
 
   nsAutoPtr<MFTManager> mMFTManager;
 
   // The last offset into the media resource that was passed into Input().
   // This is used to approximate the decoder's position in the media resource.
   int64_t mLastStreamOffset;
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -958,18 +958,9 @@ WMFVideoMFTManager::Shutdown()
 
 bool
 WMFVideoMFTManager::IsHardwareAccelerated(nsACString& aFailureReason) const
 {
   aFailureReason = mDXVAFailureReason;
   return mDecoder && mUseHwAccel;
 }
 
-void
-WMFVideoMFTManager::ConfigurationChanged(const TrackInfo& aConfig)
-{
-  MOZ_ASSERT(aConfig.GetAsVideoInfo());
-  mVideoInfo = *aConfig.GetAsVideoInfo();
-  mImageSize = mVideoInfo.mImage;
-  ValidateVideoInfo();
-}
-
 } // namespace mozilla
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -35,18 +35,16 @@ public:
   void Shutdown() override;
 
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
 
   TrackInfo::TrackType GetType() override {
     return TrackInfo::kVideoTrack;
   }
 
-  void ConfigurationChanged(const TrackInfo& aConfig) override;
-
   const char* GetDescriptionName() const override
   {
     nsCString failureReason;
     return IsHardwareAccelerated(failureReason)
       ? "wmf hardware video decoder" : "wmf software video decoder";
   }
 
   void Flush() override
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.cpp
@@ -83,25 +83,16 @@ DecoderFuzzingWrapper::Shutdown()
 bool
 DecoderFuzzingWrapper::IsHardwareAccelerated(nsACString& aFailureReason) const
 {
   DFW_LOGV("");
   MOZ_ASSERT(mDecoder);
   return mDecoder->IsHardwareAccelerated(aFailureReason);
 }
 
-void
-DecoderFuzzingWrapper::ConfigurationChanged(const TrackInfo& aConfig)
-{
-  DFW_LOGV("");
-  MOZ_ASSERT(mDecoder);
-  mDecoder->ConfigurationChanged(aConfig);
-}
-
-
 DecoderCallbackFuzzingWrapper::DecoderCallbackFuzzingWrapper(MediaDataDecoderCallback* aCallback)
   : mCallback(aCallback)
   , mDontDelayInputExhausted(false)
   , mDraining(false)
   , mTaskQueue(new TaskQueue(SharedThreadPool::Get(NS_LITERAL_CSTRING("MediaFuzzingWrapper"), 1)))
 {
   CFW_LOGV("aCallback=%p", aCallback);
 }
--- a/dom/media/platforms/wrappers/FuzzingWrapper.h
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.h
@@ -103,17 +103,16 @@ public:
 
   // MediaDataDecoder implementation.
   RefPtr<InitPromise> Init() override;
   void Input(MediaRawData* aSample) override;
   void Flush() override;
   void Drain() override;
   void Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
-  void ConfigurationChanged(const TrackInfo& aConfig) override;
   const char* GetDescriptionName() const override
   {
     return mDecoder->GetDescriptionName();
   }
 
 private:
   virtual ~DecoderFuzzingWrapper();
   RefPtr<MediaDataDecoder> mDecoder;
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -13,17 +13,16 @@
 #include "mp4_demuxer/H264.h"
 
 namespace mozilla
 {
 
 H264Converter::H264Converter(PlatformDecoderModule* aPDM,
                              const CreateDecoderParams& aParams)
   : mPDM(aPDM)
-  , mOriginalConfig(aParams.VideoConfig())
   , mCurrentConfig(aParams.VideoConfig())
   , mLayersBackend(aParams.mLayersBackend)
   , mImageContainer(aParams.mImageContainer)
   , mTaskQueue(aParams.mTaskQueue)
   , mCallback(aParams.mCallback)
   , mDecoder(nullptr)
   , mGMPCrashHelper(aParams.mCrashHelper)
   , mNeedAVCC(aPDM->DecoderNeedsConversion(aParams.mConfig)
@@ -161,47 +160,41 @@ H264Converter::SetSeekThreshold(const me
   } else {
     MediaDataDecoder::SetSeekThreshold(aTime);
   }
 }
 
 nsresult
 H264Converter::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
 {
-  if (mNeedAVCC && !mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
+  if (!mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
     // nothing found yet, will try again later
     return NS_ERROR_NOT_INITIALIZED;
   }
   UpdateConfigFromExtraData(mCurrentConfig.mExtraData);
 
   mp4_demuxer::SPSData spsdata;
   if (mp4_demuxer::H264::DecodeSPSFromExtraData(mCurrentConfig.mExtraData, spsdata)) {
     // Do some format check here.
     // WMF H.264 Video Decoder and Apple ATDecoder do not support YUV444 format.
     if (spsdata.chroma_format_idc == 3 /*YUV444*/) {
       mLastError = NS_ERROR_FAILURE;
       if (aDiagnostics) {
         aDiagnostics->SetVideoFormatNotSupport();
       }
       return NS_ERROR_FAILURE;
     }
-  } else if (mNeedAVCC) {
+  } else {
     // SPS was invalid.
     mLastError = NS_ERROR_FAILURE;
     return NS_ERROR_FAILURE;
   }
 
-  if (!mNeedAVCC) {
-    // When using a decoder handling AnnexB, we get here only once from the
-    // constructor. We do want to get the dimensions extracted from the SPS.
-    mOriginalConfig = mCurrentConfig;
-  }
-
   mDecoder = mPDM->CreateVideoDecoder({
-    mNeedAVCC ? mCurrentConfig : mOriginalConfig,
+    mCurrentConfig,
     mTaskQueue,
     mCallback,
     aDiagnostics,
     mImageContainer,
     mLayersBackend,
     mGMPCrashHelper
   });
 
@@ -276,21 +269,16 @@ H264Converter::CheckForSPSChange(MediaRa
 {
   RefPtr<MediaByteBuffer> extra_data =
     mp4_demuxer::AnnexB::ExtractExtraData(aSample);
   if (!mp4_demuxer::AnnexB::HasSPS(extra_data) ||
       mp4_demuxer::AnnexB::CompareExtraData(extra_data,
                                             mCurrentConfig.mExtraData)) {
         return NS_OK;
       }
-  if (!mNeedAVCC) {
-    UpdateConfigFromExtraData(extra_data);
-    mDecoder->ConfigurationChanged(mCurrentConfig);
-    return NS_OK;
-  }
   // The SPS has changed, signal to flush the current decoder and create a
   // new one.
   mDecoder->Flush();
   Shutdown();
   return CreateDecoderAndInit(aSample);
 }
 
 void
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -50,17 +50,16 @@ private:
   nsresult CreateDecoderAndInit(MediaRawData* aSample);
   nsresult CheckForSPSChange(MediaRawData* aSample);
   void UpdateConfigFromExtraData(MediaByteBuffer* aExtraData);
 
   void OnDecoderInitDone(const TrackType aTrackType);
   void OnDecoderInitFailed(MediaResult aError);
 
   RefPtr<PlatformDecoderModule> mPDM;
-  VideoInfo mOriginalConfig;
   VideoInfo mCurrentConfig;
   layers::LayersBackend mLayersBackend;
   RefPtr<layers::ImageContainer> mImageContainer;
   const RefPtr<TaskQueue> mTaskQueue;
   nsTArray<RefPtr<MediaRawData>> mMediaRawSamples;
   MediaDataDecoderCallback* mCallback;
   RefPtr<MediaDataDecoder> mDecoder;
   MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;