Bug 1141914: Always use video dimensions using extradata's SPS. r=cpearce a=lsblakk
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 12 Mar 2015 11:07:20 +1100
changeset 248174 4acd7286be9e3a4b207629722127875828da836f
parent 248173 d1e899435508368c98080813bd31c7ca817ae630
child 248175 bde39a58935d277f7e0abaecf86969b0a879e89c
push id7776
push usercpearce@mozilla.com
push dateWed, 18 Mar 2015 03:12:44 +0000
treeherdermozilla-aurora@4acd7286be9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lsblakk
bugs1141914
milestone38.0a2
Bug 1141914: Always use video dimensions using extradata's SPS. r=cpearce a=lsblakk
dom/media/fmp4/AVCCDecoderModule.cpp
--- a/dom/media/fmp4/AVCCDecoderModule.cpp
+++ b/dom/media/fmp4/AVCCDecoderModule.cpp
@@ -38,16 +38,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;
@@ -171,16 +172,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;
@@ -191,25 +194,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();
 }
 
 nsresult
 AVCCMediaDataDecoder::CheckForSPSChange(mp4_demuxer::MP4Sample* aSample)
@@ -223,16 +218,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);
 }