зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1128381: Part3. Handle on the fly video format change. r=cpearce
Add monitoring of the current SPS NAL and destroy/recreate H264 decoder as required. --HG-- extra : rebase_source : fbab04b0ae3b4be42eea34a1c6f1b19bf39ad2f0
This commit is contained in:
Родитель
06ae6e08e7
Коммит
adf3e336a3
|
@ -44,6 +44,7 @@ private:
|
|||
// will set mError accordingly.
|
||||
nsresult CreateDecoder();
|
||||
nsresult CreateDecoderAndInit(mp4_demuxer::MP4Sample* aSample);
|
||||
nsresult CheckForSPSChange(mp4_demuxer::MP4Sample* aSample);
|
||||
|
||||
nsRefPtr<PlatformDecoderModule> mPDM;
|
||||
mp4_demuxer::VideoDecoderConfig mCurrentConfig;
|
||||
|
@ -92,18 +93,21 @@ AVCCMediaDataDecoder::Input(mp4_demuxer::MP4Sample* aSample)
|
|||
if (!mp4_demuxer::AnnexB::ConvertSampleToAVCC(aSample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv;
|
||||
if (!mDecoder) {
|
||||
// It is not possible to create an AVCC H264 decoder without SPS.
|
||||
// As such, creation will fail if the extra_data just extracted doesn't
|
||||
// contain a SPS.
|
||||
nsresult rv = CreateDecoderAndInit(aSample);
|
||||
rv = CreateDecoderAndInit(aSample);
|
||||
if (rv == NS_ERROR_NOT_INITIALIZED) {
|
||||
// We are missing the required SPS to create the decoder.
|
||||
// Ignore for the time being, the MP4Sample will be dropped.
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
rv = CheckForSPSChange(aSample);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aSample->extra_data = mCurrentConfig.extra_data;
|
||||
|
||||
|
@ -230,6 +234,23 @@ AVCCMediaDataDecoder::IsHardwareAccelerated() const
|
|||
return MediaDataDecoder::IsHardwareAccelerated();
|
||||
}
|
||||
|
||||
nsresult
|
||||
AVCCMediaDataDecoder::CheckForSPSChange(mp4_demuxer::MP4Sample* aSample)
|
||||
{
|
||||
nsRefPtr<mp4_demuxer::ByteBuffer> extra_data =
|
||||
mp4_demuxer::AnnexB::ExtractExtraData(aSample);
|
||||
if (!mp4_demuxer::AnnexB::HasSPS(extra_data) ||
|
||||
mp4_demuxer::AnnexB::CompareExtraData(extra_data,
|
||||
mCurrentConfig.extra_data)) {
|
||||
return NS_OK;
|
||||
}
|
||||
// The SPS has changed, signal to flush the current decoder and create a
|
||||
// new one.
|
||||
mDecoder->Flush();
|
||||
mDecoder->Shutdown();
|
||||
return CreateDecoderAndInit(aSample);
|
||||
}
|
||||
|
||||
// AVCCDecoderModule
|
||||
|
||||
AVCCDecoderModule::AVCCDecoderModule(PlatformDecoderModule* aPDM)
|
||||
|
|
|
@ -378,4 +378,12 @@ AnnexB::IsAnnexB(const MP4Sample* aSample)
|
|||
return header == 0x00000001 || (header >> 8) == 0x000001;
|
||||
}
|
||||
|
||||
bool
|
||||
AnnexB::CompareExtraData(const ByteBuffer* aExtraData1,
|
||||
const ByteBuffer* aExtraData2)
|
||||
{
|
||||
// Very crude comparison.
|
||||
return aExtraData1 == aExtraData2 || *aExtraData1 == *aExtraData2;
|
||||
}
|
||||
|
||||
} // namespace mp4_demuxer
|
||||
|
|
|
@ -39,6 +39,9 @@ public:
|
|||
static bool IsAVCC(const MP4Sample* aSample);
|
||||
// Returns true if format is AnnexB.
|
||||
static bool IsAnnexB(const MP4Sample* aSample);
|
||||
// Return true if both extradata are equal.
|
||||
static bool CompareExtraData(const ByteBuffer* aExtraData1,
|
||||
const ByteBuffer* aExtraData2);
|
||||
|
||||
private:
|
||||
// AVCC box parser helper.
|
||||
|
|
Загрузка…
Ссылка в новой задаче