Bug 1497951 - P2. Always ensure the provided VideoConfig exactly match the content. r=bryce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 07 Nov 2018 13:48:51 +0000
changeset 444860 06c764a40a025b194be7a70bd220697062e54c46
parent 444859 aecd59f2fb3021d2dfda728f3fb291481cf1345c
child 444861 e8e4842ca7bf4fcb7d2796fed6a72ff1caa8c0a5
push id35005
push useraiakab@mozilla.com
push dateWed, 07 Nov 2018 21:49:53 +0000
treeherdermozilla-central@12afa29e9c8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce
bugs1497951, 1498788
milestone65.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 1497951 - P2. Always ensure the provided VideoConfig exactly match the content. r=bryce For AVC1 content (where the SPS/PPS is provided out of band), we would use VideoInfo has found in the container's metadata which may not always be correct. Likely the reason on why we had bug 1498788 (decoded sample size didn't match the video config's dimensions) We also always set the MediaRawData::mTrackInfo member for all samples, not just the first one as it's the right thing to do. Depends on D10907 Differential Revision: https://phabricator.services.mozilla.com/D10908
dom/media/platforms/wrappers/MediaChangeMonitor.cpp
dom/media/platforms/wrappers/MediaChangeMonitor.h
--- a/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
+++ b/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
@@ -104,16 +104,17 @@ public:
                            RESULT_DETAIL("ConvertSampleToAnnexB"));
       }
     }
     if (aSample->mKeyframe && mNeedKeyframe) {
       mNeedKeyframe = false;
     }
 
     aSample->mExtraData = mCurrentConfig.mExtraData;
+    aSample->mTrackInfo = mTrackInfo;
 
     return NS_OK;
   }
 
   private:
     void UpdateConfigFromExtraData(MediaByteBuffer* aExtraData)
     {
       SPSData spsdata;
@@ -121,42 +122,44 @@ public:
           spsdata.pic_width > 0 && spsdata.pic_height > 0) {
         H264::EnsureSPSIsSane(spsdata);
         mCurrentConfig.mImage.width = spsdata.pic_width;
         mCurrentConfig.mImage.height = spsdata.pic_height;
         mCurrentConfig.mDisplay.width = spsdata.display_width;
         mCurrentConfig.mDisplay.height = spsdata.display_height;
       }
       mCurrentConfig.mExtraData = aExtraData;
+      mTrackInfo = new TrackInfoSharedPtr(mCurrentConfig, mStreamID++);
     }
 
     VideoInfo mCurrentConfig;
     bool mNeedKeyframe = true;
+    uint32_t mStreamID = 0;
+    RefPtr<TrackInfoSharedPtr> mTrackInfo;
 };
 
 MediaChangeMonitor::MediaChangeMonitor(PlatformDecoderModule* aPDM,
                                        const CreateDecoderParams& aParams)
   : mPDM(aPDM)
-  , mOriginalConfig(aParams.VideoConfig())
   , mCurrentConfig(aParams.VideoConfig())
   , mKnowsCompositor(aParams.mKnowsCompositor)
   , mImageContainer(aParams.mImageContainer)
   , mTaskQueue(aParams.mTaskQueue)
   , mDecoder(nullptr)
   , mGMPCrashHelper(aParams.mCrashHelper)
   , mLastError(NS_OK)
   , mType(aParams.mType)
   , mOnWaitingForKeyEvent(aParams.mOnWaitingForKeyEvent)
   , mDecoderOptions(aParams.mOptions)
   , mRate(aParams.mRate)
 {
   mInConstructor = true;
-  MOZ_ASSERT(MP4Decoder::IsH264(mOriginalConfig.mMimeType));
-  mChangeMonitor = MakeUnique<H264ChangeMonitor>(mOriginalConfig);
-  mLastError = CreateDecoder(mOriginalConfig, aParams.mDiagnostics);
+  MOZ_ASSERT(MP4Decoder::IsH264(mCurrentConfig.mMimeType));
+  mChangeMonitor = MakeUnique<H264ChangeMonitor>(mCurrentConfig);
+  mLastError = CreateDecoder(aParams.mDiagnostics);
   mInConstructor = false;
 }
 
 MediaChangeMonitor::~MediaChangeMonitor()
 {
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
@@ -358,32 +361,31 @@ MediaChangeMonitor::SetSeekThreshold(con
   if (mDecoder) {
     mDecoder->SetSeekThreshold(aTime);
   } else {
     MediaDataDecoder::SetSeekThreshold(aTime);
   }
 }
 
 MediaResult
-MediaChangeMonitor::CreateDecoder(const VideoInfo& aConfig,
-                                  DecoderDoctorDiagnostics* aDiagnostics)
+MediaChangeMonitor::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
 {
   // This is the only one of two methods to run outside the TaskQueue when
   // called from the constructor.
   MOZ_ASSERT(mInConstructor || mTaskQueue->IsCurrentThreadIn());
 
   if (!mChangeMonitor->CanBeInstantiated()) {
     // nothing found yet, will try again later
     return NS_ERROR_NOT_INITIALIZED;
   }
   mCurrentConfig = *mChangeMonitor->Config().GetAsVideoInfo();
 
   MediaResult error = NS_OK;
   mDecoder = mPDM->CreateVideoDecoder({
-    aConfig,
+    mCurrentConfig,
     mTaskQueue,
     aDiagnostics,
     mImageContainer,
     mKnowsCompositor,
     mGMPCrashHelper,
     mType,
     mOnWaitingForKeyEvent,
     mDecoderOptions,
@@ -413,17 +415,17 @@ MediaChangeMonitor::CreateDecoderAndInit
 {
   AssertOnTaskQueue();
 
   MediaResult rv = mChangeMonitor->CheckForChange(aSample);
   if (!NS_SUCCEEDED(rv) && rv != NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) {
     return rv;
   }
 
-  rv = CreateDecoder(mCurrentConfig, /* DecoderDoctorDiagnostics* */ nullptr);
+  rv = CreateDecoder(/* DecoderDoctorDiagnostics* */ nullptr);
 
   if (NS_SUCCEEDED(rv)) {
     RefPtr<MediaChangeMonitor> self = this;
     RefPtr<MediaRawData> sample = aSample;
     mDecoder->Init()
       ->Then(
         mTaskQueue,
         __func__,
@@ -510,26 +512,18 @@ MediaChangeMonitor::CheckForChange(Media
   AssertOnTaskQueue();
 
   MediaResult rv = mChangeMonitor->CheckForChange(aSample);
 
   if (NS_SUCCEEDED(rv) || rv != NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) {
     return rv;
   }
 
-  // Content has changed, retrieve the new TrackInfo.
-  mCurrentConfig = *mChangeMonitor->Config().GetAsVideoInfo();
-
-  MOZ_ASSERT(mCanRecycleDecoder.isSome());
-
   if (*mCanRecycleDecoder) {
     // Do not recreate the decoder, reuse it.
-    if (!aSample->mTrackInfo) {
-      aSample->mTrackInfo = new TrackInfoSharedPtr(mCurrentConfig, 0);
-    }
     mNeedKeyframe = true;
     return NS_OK;
   }
 
   // The content has changed, signal to drain the current decoder and once done
   // create a new one.
   DrainThenFlushDecoder(aSample);
   return NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER;
--- a/dom/media/platforms/wrappers/MediaChangeMonitor.h
+++ b/dom/media/platforms/wrappers/MediaChangeMonitor.h
@@ -87,28 +87,26 @@ private:
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
   }
 
   bool CanRecycleDecoder() const;
 
   // Will create the required MediaDataDecoder if need AVCC and we have a SPS NAL.
   // Returns NS_ERROR_FAILURE if error is permanent and can't be recovered and
   // will set mError accordingly.
-  MediaResult CreateDecoder(const VideoInfo& aConfig,
-                         DecoderDoctorDiagnostics* aDiagnostics);
+  MediaResult CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics);
   MediaResult CreateDecoderAndInit(MediaRawData* aSample);
   MediaResult CheckForChange(MediaRawData* aSample);
 
   void DecodeFirstSample(MediaRawData* aSample);
   void DrainThenFlushDecoder(MediaRawData* aPendingSample);
   void FlushThenShutdownDecoder(MediaRawData* aPendingSample);
   RefPtr<ShutdownPromise> ShutdownDecoder();
 
   RefPtr<PlatformDecoderModule> mPDM;
-  const VideoInfo mOriginalConfig;
   VideoInfo mCurrentConfig;
   RefPtr<layers::KnowsCompositor> mKnowsCompositor;
   RefPtr<layers::ImageContainer> mImageContainer;
   const RefPtr<TaskQueue> mTaskQueue;
   RefPtr<MediaDataDecoder> mDecoder;
   MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
   MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest;
   MozPromiseHolder<DecodePromise> mDecodePromise;