Bug 1313398: P4. Check that the out of band extradata hasn't changed. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 31 May 2017 22:03:55 +0200
changeset 361783 66daa8f31b5499c158bce7955224153a2035e8dd
parent 361782 fb7c6768faf53c6000f5021e3686590bec0eab41
child 361784 d0fea6559ec29e78eeb2d353975720d18a592b25
push id31942
push userryanvm@gmail.com
push dateThu, 01 Jun 2017 15:54:15 +0000
treeherdermozilla-central@cac2fd43de81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1313398
milestone55.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 1313398: P4. Check that the out of band extradata hasn't changed. r=gerald On android, where decoders can sometimes be recycled, the h264converter can be fed over its lifetime MediaRawData with different mExtraData. So we need to ensure that not only, the inband ones don't change, but that the out of band one hasn't changed either. This is a condition we could totally ignore on desktop, as when the resolution change the H264Converter is destroyed. MozReview-Commit-ID: 7w6ku6by1Qi
dom/media/platforms/wrappers/H264Converter.cpp
dom/media/platforms/wrappers/H264Converter.h
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -29,16 +29,21 @@ H264Converter::H264Converter(PlatformDec
   , mDecoder(nullptr)
   , mGMPCrashHelper(aParams.mCrashHelper)
   , mLastError(NS_OK)
   , mType(aParams.mType)
   , mOnWaitingForKeyEvent(aParams.mOnWaitingForKeyEvent)
   , mDecoderOptions(aParams.mOptions)
 {
   CreateDecoder(mOriginalConfig, aParams.mDiagnostics);
+  if (mDecoder) {
+    MOZ_ASSERT(mp4_demuxer::AnnexB::HasSPS(mOriginalConfig.mExtraData));
+    // The video metadata contains out of band SPS/PPS (AVC1) store it.
+    mOriginalExtraData = mOriginalConfig.mExtraData;
+  }
 }
 
 H264Converter::~H264Converter()
 {
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 H264Converter::Init()
@@ -323,19 +328,34 @@ H264Converter::DecodeFirstSample(MediaRa
     ->Track(mDecodePromiseRequest);
 }
 
 nsresult
 H264Converter::CheckForSPSChange(MediaRawData* aSample)
 {
   RefPtr<MediaByteBuffer> extra_data =
     mp4_demuxer::AnnexB::ExtractExtraData(aSample);
-  if (!mp4_demuxer::AnnexB::HasSPS(extra_data)
-      || mp4_demuxer::AnnexB::CompareExtraData(extra_data,
-                                               mCurrentConfig.mExtraData)) {
+  if (!mp4_demuxer::AnnexB::HasSPS(extra_data)) {
+    MOZ_ASSERT(mCanRecycleDecoder.isSome());
+    if (!*mCanRecycleDecoder) {
+      // If the decoder can't be recycled, the out of band extradata will never
+      // change as the H264Converter will be recreated by the MediaFormatReader
+      // instead. So there's no point in testing for changes.
+      return NS_OK;
+    }
+    // This sample doesn't contain inband SPS/PPS
+    // We now check if the out of band one has changed.
+    if (mp4_demuxer::AnnexB::HasSPS(aSample->mExtraData) &&
+        !mp4_demuxer::AnnexB::CompareExtraData(aSample->mExtraData,
+                                               mOriginalExtraData)) {
+      extra_data = mOriginalExtraData = aSample->mExtraData;
+    }
+  }
+  if (mp4_demuxer::AnnexB::CompareExtraData(extra_data,
+                                            mCurrentConfig.mExtraData)) {
     return NS_OK;
   }
 
   RefPtr<MediaRawData> sample = aSample;
   MOZ_ASSERT(mCanRecycleDecoder.isSome());
   if (*mCanRecycleDecoder) {
     // Do not recreate the decoder, reuse it.
     UpdateConfigFromExtraData(extra_data);
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -76,16 +76,18 @@ private:
 
   bool CanRecycleDecoder() const;
 
   void DecodeFirstSample(MediaRawData* aSample);
 
   RefPtr<PlatformDecoderModule> mPDM;
   const VideoInfo mOriginalConfig;
   VideoInfo mCurrentConfig;
+  // Current out of band extra data (as found in metadata's VideoInfo).
+  RefPtr<MediaByteBuffer> mOriginalExtraData;
   RefPtr<layers::KnowsCompositor> mKnowsCompositor;
   RefPtr<layers::ImageContainer> mImageContainer;
   const RefPtr<TaskQueue> mTaskQueue;
   RefPtr<MediaRawData> mPendingSample;
   RefPtr<MediaDataDecoder> mDecoder;
   MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
   MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest;
   MozPromiseHolder<DecodePromise> mDecodePromise;