Bug 1297311: P1. Always recreate a decoder when SPS changes. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 26 Sep 2016 12:28:07 +1000
changeset 315113 19e90148741868f6ee0b864696f16147fa121240
parent 315112 1dd2d2b5c5c86ff3a034cdfbd4fbc64d6050b946
child 315114 74cc37d7da2c4f830787a2eb8af5a7543131237f
push id32560
push userjyavenard@mozilla.com
push dateMon, 26 Sep 2016 06:01:59 +0000
treeherderautoland@74cc37d7da2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1297311
milestone52.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 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;