Bug 1141914: Always use video dimensions using extradata's SPS. r=cpearce a=lsblakk
--- 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);
}