Bug 1141914: Always use video dimensions using extradata's SPS. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 12 Mar 2015 11:07:20 +1100
changeset 233193 54f1419ebdfac583fd96d5b2904ef765d1965ac3
parent 233192 bf7e77671f8fe478069376b98704e9f5da21f90f
child 233194 f9807e654ae7882fcfa2bbcb057302c4659bc61d
push id56774
push userjyavenard@mozilla.com
push dateThu, 12 Mar 2015 03:06:34 +0000
treeherdermozilla-inbound@f9807e654ae7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1141914
milestone39.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 1141914: Always use video dimensions using extradata's SPS. r=cpearce
dom/media/fmp4/AVCCDecoderModule.cpp
--- a/dom/media/fmp4/AVCCDecoderModule.cpp
+++ b/dom/media/fmp4/AVCCDecoderModule.cpp
@@ -39,16 +39,17 @@ public:
 
 private:
   // Will create the required MediaDataDecoder if we have a AVC SPS.
   // Returns NS_ERROR_FAILURE if error is permanent and can't be recovered and
   // will set mError accordingly.
   nsresult CreateDecoder();
   nsresult CreateDecoderAndInit(mp4_demuxer::MP4Sample* aSample);
   nsresult CheckForSPSChange(mp4_demuxer::MP4Sample* aSample);
+  void UpdateConfigFromExtraData(mp4_demuxer::ByteBuffer* aExtraData);
 
   nsRefPtr<PlatformDecoderModule> mPDM;
   mp4_demuxer::VideoDecoderConfig mCurrentConfig;
   layers::LayersBackend mLayersBackend;
   nsRefPtr<layers::ImageContainer> mImageContainer;
   nsRefPtr<FlushableMediaTaskQueue> mVideoTaskQueue;
   MediaDataDecoderCallback* mCallback;
   nsRefPtr<MediaDataDecoder> mDecoder;
@@ -172,16 +173,18 @@ AVCCMediaDataDecoder::ReleaseMediaResour
 
 nsresult
 AVCCMediaDataDecoder::CreateDecoder()
 {
   if (!mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.extra_data)) {
     // nothing found yet, will try again later
     return NS_ERROR_NOT_INITIALIZED;
   }
+  UpdateConfigFromExtraData(mCurrentConfig.extra_data);
+
   mDecoder = mPDM->CreateVideoDecoder(mCurrentConfig,
                                       mLayersBackend,
                                       mImageContainer,
                                       mVideoTaskQueue,
                                       mCallback);
   if (!mDecoder) {
     mLastError = NS_ERROR_FAILURE;
     return NS_ERROR_FAILURE;
@@ -192,25 +195,17 @@ AVCCMediaDataDecoder::CreateDecoder()
 nsresult
 AVCCMediaDataDecoder::CreateDecoderAndInit(mp4_demuxer::MP4Sample* aSample)
 {
   nsRefPtr<mp4_demuxer::ByteBuffer> extra_data =
     mp4_demuxer::AnnexB::ExtractExtraData(aSample);
   if (!mp4_demuxer::AnnexB::HasSPS(extra_data)) {
     return NS_ERROR_NOT_INITIALIZED;
   }
-  mp4_demuxer::SPSData spsdata;
-  if (mp4_demuxer::H264::DecodeSPSFromExtraData(extra_data, spsdata) &&
-      spsdata.pic_width > 0 && spsdata.pic_height > 0) {
-    mCurrentConfig.image_width = spsdata.pic_width;
-    mCurrentConfig.image_height = spsdata.pic_height;
-    mCurrentConfig.display_width = spsdata.display_width;
-    mCurrentConfig.display_height = spsdata.display_height;
-  }
-  mCurrentConfig.extra_data = extra_data;
+  UpdateConfigFromExtraData(extra_data);
 
   nsresult rv = CreateDecoder();
   NS_ENSURE_SUCCESS(rv, rv);
   return Init();
 }
 
 bool
 AVCCMediaDataDecoder::IsHardwareAccelerated() const
@@ -233,16 +228,30 @@ AVCCMediaDataDecoder::CheckForSPSChange(
   }
   // The SPS has changed, signal to flush the current decoder and create a
   // new one.
   mDecoder->Flush();
   ReleaseMediaResources();
   return CreateDecoderAndInit(aSample);
 }
 
+void
+AVCCMediaDataDecoder::UpdateConfigFromExtraData(mp4_demuxer::ByteBuffer* aExtraData)
+{
+  mp4_demuxer::SPSData spsdata;
+  if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtraData, spsdata) &&
+      spsdata.pic_width > 0 && spsdata.pic_height > 0) {
+    mCurrentConfig.image_width = spsdata.pic_width;
+    mCurrentConfig.image_height = spsdata.pic_height;
+    mCurrentConfig.display_width = spsdata.display_width;
+    mCurrentConfig.display_height = spsdata.display_height;
+  }
+  mCurrentConfig.extra_data = aExtraData;
+}
+
 // AVCCDecoderModule
 
 AVCCDecoderModule::AVCCDecoderModule(PlatformDecoderModule* aPDM)
 : mPDM(aPDM)
 {
   MOZ_ASSERT(aPDM);
 }