зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 0d953ca28add (bug 1374774) for bustage at media/libstagefright/binding/H264.cpp(205). 'ptr' not declared. r=backout on a CLOSED TREE
This commit is contained in:
Родитель
f5e3176d23
Коммит
261b25bf86
|
@ -520,9 +520,9 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
}
|
||||
for (const auto& sample : samples->mSamples) {
|
||||
// Collect telemetry from h264 Annex B SPS.
|
||||
if (mNeedSPSForTelemetry && mp4_demuxer::H264::HasSPS(sample)) {
|
||||
if (mNeedSPSForTelemetry && mp4_demuxer::AnnexB::HasSPS(sample)) {
|
||||
RefPtr<MediaByteBuffer> extradata =
|
||||
mp4_demuxer::H264::ExtractExtraData(sample);
|
||||
mp4_demuxer::AnnexB::ExtractExtraData(sample);
|
||||
mNeedSPSForTelemetry = AccumulateSPSTelemetry(extradata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -939,7 +939,7 @@ ChromiumCDMParent::InitializeVideoDecoder(
|
|||
|
||||
mMaxRefFrames =
|
||||
(aConfig.mCodec() == cdm::VideoDecoderConfig::kCodecH264)
|
||||
? mp4_demuxer::H264::HasSPS(aInfo.mExtraData)
|
||||
? mp4_demuxer::AnnexB::HasSPS(aInfo.mExtraData)
|
||||
? mp4_demuxer::H264::ComputeMaxRefFrames(aInfo.mExtraData)
|
||||
: 16
|
||||
: 0;
|
||||
|
|
|
@ -19,7 +19,7 @@ DummyMediaDataDecoder::DummyMediaDataDecoder(UniquePtr<DummyDataCreator>&& aCrea
|
|||
, mIsH264(MP4Decoder::IsH264(aParams.mConfig.mMimeType))
|
||||
, mMaxRefFrames(
|
||||
mIsH264
|
||||
? mp4_demuxer::H264::HasSPS(aParams.VideoConfig().mExtraData)
|
||||
? mp4_demuxer::AnnexB::HasSPS(aParams.VideoConfig().mExtraData)
|
||||
? mp4_demuxer::H264::ComputeMaxRefFrames(aParams.VideoConfig().mExtraData)
|
||||
: 16
|
||||
: 0)
|
||||
|
|
|
@ -35,7 +35,7 @@ H264Converter::H264Converter(PlatformDecoderModule* aPDM,
|
|||
{
|
||||
CreateDecoder(mOriginalConfig, aParams.mDiagnostics);
|
||||
if (mDecoder) {
|
||||
MOZ_ASSERT(mp4_demuxer::H264::HasSPS(mOriginalConfig.mExtraData));
|
||||
MOZ_ASSERT(mp4_demuxer::AnnexB::HasSPS(mOriginalConfig.mExtraData));
|
||||
// The video metadata contains out of band SPS/PPS (AVC1) store it.
|
||||
mOriginalExtraData = mOriginalConfig.mExtraData;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ nsresult
|
|||
H264Converter::CreateDecoder(const VideoInfo& aConfig,
|
||||
DecoderDoctorDiagnostics* aDiagnostics)
|
||||
{
|
||||
if (!mp4_demuxer::H264::HasSPS(aConfig.mExtraData)) {
|
||||
if (!mp4_demuxer::AnnexB::HasSPS(aConfig.mExtraData)) {
|
||||
// nothing found yet, will try again later
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
@ -290,10 +290,10 @@ nsresult
|
|||
H264Converter::CreateDecoderAndInit(MediaRawData* aSample)
|
||||
{
|
||||
RefPtr<MediaByteBuffer> extra_data =
|
||||
mp4_demuxer::H264::ExtractExtraData(aSample);
|
||||
bool inbandExtradata = mp4_demuxer::H264::HasSPS(extra_data);
|
||||
mp4_demuxer::AnnexB::ExtractExtraData(aSample);
|
||||
bool inbandExtradata = mp4_demuxer::AnnexB::HasSPS(extra_data);
|
||||
if (!inbandExtradata &&
|
||||
!mp4_demuxer::H264::HasSPS(mCurrentConfig.mExtraData)) {
|
||||
!mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -393,8 +393,8 @@ nsresult
|
|||
H264Converter::CheckForSPSChange(MediaRawData* aSample)
|
||||
{
|
||||
RefPtr<MediaByteBuffer> extra_data =
|
||||
mp4_demuxer::H264::ExtractExtraData(aSample);
|
||||
if (!mp4_demuxer::H264::HasSPS(extra_data)) {
|
||||
mp4_demuxer::AnnexB::ExtractExtraData(aSample);
|
||||
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
|
||||
|
@ -406,15 +406,15 @@ H264Converter::CheckForSPSChange(MediaRawData* aSample)
|
|||
// We now check if the out of band one has changed.
|
||||
// This scenario can only occur on Android with devices that can recycle a
|
||||
// decoder.
|
||||
if (!mp4_demuxer::H264::HasSPS(aSample->mExtraData) ||
|
||||
mp4_demuxer::H264::CompareExtraData(aSample->mExtraData,
|
||||
mOriginalExtraData)) {
|
||||
if (!mp4_demuxer::AnnexB::HasSPS(aSample->mExtraData) ||
|
||||
mp4_demuxer::AnnexB::CompareExtraData(aSample->mExtraData,
|
||||
mOriginalExtraData)) {
|
||||
return NS_OK;
|
||||
}
|
||||
extra_data = mOriginalExtraData = aSample->mExtraData;
|
||||
}
|
||||
if (mp4_demuxer::H264::CompareExtraData(extra_data,
|
||||
mCurrentConfig.mExtraData)) {
|
||||
if (mp4_demuxer::AnnexB::CompareExtraData(extra_data,
|
||||
mCurrentConfig.mExtraData)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -271,6 +271,108 @@ AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample)
|
|||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::MediaByteBuffer>
|
||||
AnnexB::ExtractExtraData(const mozilla::MediaRawData* aSample)
|
||||
{
|
||||
MOZ_ASSERT(IsAVCC(aSample));
|
||||
|
||||
RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
|
||||
|
||||
// SPS content
|
||||
nsTArray<uint8_t> sps;
|
||||
ByteWriter spsw(sps);
|
||||
int numSps = 0;
|
||||
// PPS content
|
||||
nsTArray<uint8_t> pps;
|
||||
ByteWriter ppsw(pps);
|
||||
int numPps = 0;
|
||||
|
||||
int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
|
||||
|
||||
size_t sampleSize = aSample->Size();
|
||||
if (aSample->mCrypto.mValid) {
|
||||
// The content is encrypted, we can only parse the non-encrypted data.
|
||||
MOZ_ASSERT(aSample->mCrypto.mPlainSizes.Length() > 0);
|
||||
if (aSample->mCrypto.mPlainSizes.Length() == 0 ||
|
||||
aSample->mCrypto.mPlainSizes[0] > sampleSize) {
|
||||
// This is invalid content.
|
||||
return nullptr;
|
||||
}
|
||||
sampleSize = aSample->mCrypto.mPlainSizes[0];
|
||||
}
|
||||
|
||||
ByteReader reader(aSample->Data(), sampleSize);
|
||||
|
||||
// Find SPS and PPS NALUs in AVCC data
|
||||
while (reader.Remaining() > nalLenSize) {
|
||||
uint32_t nalLen;
|
||||
switch (nalLenSize) {
|
||||
case 1: nalLen = reader.ReadU8(); break;
|
||||
case 2: nalLen = reader.ReadU16(); break;
|
||||
case 3: nalLen = reader.ReadU24(); break;
|
||||
case 4: nalLen = reader.ReadU32(); break;
|
||||
}
|
||||
uint8_t nalType = reader.PeekU8() & 0x1f;
|
||||
const uint8_t* p = reader.Read(nalLen);
|
||||
if (!p) {
|
||||
return extradata.forget();
|
||||
}
|
||||
|
||||
if (nalType == 0x7) { /* SPS */
|
||||
numSps++;
|
||||
if (!spsw.WriteU16(nalLen)
|
||||
|| !spsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
} else if (nalType == 0x8) { /* PPS */
|
||||
numPps++;
|
||||
if (!ppsw.WriteU16(nalLen)
|
||||
|| !ppsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numSps && sps.Length() > 5) {
|
||||
extradata->AppendElement(1); // version
|
||||
extradata->AppendElement(sps[3]); // profile
|
||||
extradata->AppendElement(sps[4]); // profile compat
|
||||
extradata->AppendElement(sps[5]); // level
|
||||
extradata->AppendElement(0xfc | 3); // nal size - 1
|
||||
extradata->AppendElement(0xe0 | numSps);
|
||||
extradata->AppendElements(sps.Elements(), sps.Length());
|
||||
extradata->AppendElement(numPps);
|
||||
if (numPps) {
|
||||
extradata->AppendElements(pps.Elements(), pps.Length());
|
||||
}
|
||||
}
|
||||
|
||||
return extradata.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
AnnexB::HasSPS(const mozilla::MediaRawData* aSample)
|
||||
{
|
||||
return HasSPS(aSample->mExtraData);
|
||||
}
|
||||
|
||||
bool
|
||||
AnnexB::HasSPS(const mozilla::MediaByteBuffer* aExtraData)
|
||||
{
|
||||
if (!aExtraData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ByteReader reader(aExtraData);
|
||||
const uint8_t* ptr = reader.Read(5);
|
||||
if (!ptr || !reader.CanRead8()) {
|
||||
return false;
|
||||
}
|
||||
uint8_t numSps = reader.ReadU8() & 0x1f;
|
||||
|
||||
return numSps > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
AnnexB::ConvertSampleTo4BytesAVCC(mozilla::MediaRawData* aSample)
|
||||
{
|
||||
|
@ -322,4 +424,12 @@ AnnexB::IsAnnexB(const mozilla::MediaRawData* aSample)
|
|||
return header == 0x00000001 || (header >> 8) == 0x000001;
|
||||
}
|
||||
|
||||
bool
|
||||
AnnexB::CompareExtraData(const mozilla::MediaByteBuffer* aExtraData1,
|
||||
const mozilla::MediaByteBuffer* aExtraData2)
|
||||
{
|
||||
// Very crude comparison.
|
||||
return aExtraData1 == aExtraData2 || *aExtraData1 == *aExtraData2;
|
||||
}
|
||||
|
||||
} // namespace mp4_demuxer
|
||||
|
|
|
@ -586,7 +586,7 @@ H264::vui_parameters(BitReader& aBr, SPSData& aDest)
|
|||
H264::DecodeSPSFromExtraData(const mozilla::MediaByteBuffer* aExtraData,
|
||||
SPSData& aDest)
|
||||
{
|
||||
if (!HasSPS(aExtraData)) {
|
||||
if (!AnnexB::HasSPS(aExtraData)) {
|
||||
return false;
|
||||
}
|
||||
ByteReader reader(aExtraData);
|
||||
|
@ -704,117 +704,6 @@ H264::GetFrameType(const mozilla::MediaRawData* aSample)
|
|||
return FrameType::OTHER;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<mozilla::MediaByteBuffer>
|
||||
H264::ExtractExtraData(const mozilla::MediaRawData* aSample)
|
||||
{
|
||||
MOZ_ASSERT(AnnexB::IsAVCC(aSample));
|
||||
|
||||
RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
|
||||
|
||||
// SPS content
|
||||
nsTArray<uint8_t> sps;
|
||||
ByteWriter spsw(sps);
|
||||
int numSps = 0;
|
||||
// PPS content
|
||||
nsTArray<uint8_t> pps;
|
||||
ByteWriter ppsw(pps);
|
||||
int numPps = 0;
|
||||
|
||||
int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
|
||||
|
||||
size_t sampleSize = aSample->Size();
|
||||
if (aSample->mCrypto.mValid) {
|
||||
// The content is encrypted, we can only parse the non-encrypted data.
|
||||
MOZ_ASSERT(aSample->mCrypto.mPlainSizes.Length() > 0);
|
||||
if (aSample->mCrypto.mPlainSizes.Length() == 0 ||
|
||||
aSample->mCrypto.mPlainSizes[0] > sampleSize) {
|
||||
// This is invalid content.
|
||||
return nullptr;
|
||||
}
|
||||
sampleSize = aSample->mCrypto.mPlainSizes[0];
|
||||
}
|
||||
|
||||
ByteReader reader(aSample->Data(), sampleSize);
|
||||
|
||||
// Find SPS and PPS NALUs in AVCC data
|
||||
while (reader.Remaining() > nalLenSize) {
|
||||
uint32_t nalLen;
|
||||
switch (nalLenSize) {
|
||||
case 1: nalLen = reader.ReadU8(); break;
|
||||
case 2: nalLen = reader.ReadU16(); break;
|
||||
case 3: nalLen = reader.ReadU24(); break;
|
||||
case 4: nalLen = reader.ReadU32(); break;
|
||||
}
|
||||
uint8_t nalType = reader.PeekU8() & 0x1f;
|
||||
const uint8_t* p = reader.Read(nalLen);
|
||||
if (!p) {
|
||||
return extradata.forget();
|
||||
}
|
||||
|
||||
if (nalType == 0x7) { /* SPS */
|
||||
numSps++;
|
||||
if (!spsw.WriteU16(nalLen)
|
||||
|| !spsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
} else if (nalType == 0x8) { /* PPS */
|
||||
numPps++;
|
||||
if (!ppsw.WriteU16(nalLen)
|
||||
|| !ppsw.Write(p, nalLen)) {
|
||||
return extradata.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numSps && sps.Length() > 5) {
|
||||
extradata->AppendElement(1); // version
|
||||
extradata->AppendElement(sps[3]); // profile
|
||||
extradata->AppendElement(sps[4]); // profile compat
|
||||
extradata->AppendElement(sps[5]); // level
|
||||
extradata->AppendElement(0xfc | 3); // nal size - 1
|
||||
extradata->AppendElement(0xe0 | numSps);
|
||||
extradata->AppendElements(sps.Elements(), sps.Length());
|
||||
extradata->AppendElement(numPps);
|
||||
if (numPps) {
|
||||
extradata->AppendElements(pps.Elements(), pps.Length());
|
||||
}
|
||||
}
|
||||
|
||||
return extradata.forget();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
H264::HasSPS(const mozilla::MediaRawData* aSample)
|
||||
{
|
||||
return HasSPS(aSample->mExtraData);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
H264::HasSPS(const mozilla::MediaByteBuffer* aExtraData)
|
||||
{
|
||||
if (!aExtraData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ByteReader reader(aExtraData);
|
||||
const uint8_t* ptr = reader.Read(5);
|
||||
if (!ptr || !reader.CanRead8()) {
|
||||
return false;
|
||||
}
|
||||
uint8_t numSps = reader.ReadU8() & 0x1f;
|
||||
|
||||
return numSps > 0;
|
||||
}
|
||||
|
||||
|
||||
/* static */ bool
|
||||
H264::CompareExtraData(const mozilla::MediaByteBuffer* aExtraData1,
|
||||
const mozilla::MediaByteBuffer* aExtraData2)
|
||||
{
|
||||
// Very crude comparison.
|
||||
return aExtraData1 == aExtraData2 || *aExtraData1 == *aExtraData2;
|
||||
}
|
||||
|
||||
#undef READUE
|
||||
#undef READSE
|
||||
|
||||
|
|
|
@ -29,10 +29,19 @@ public:
|
|||
// Parse an AVCC extradata and construct the Annex B sample header.
|
||||
static already_AddRefed<mozilla::MediaByteBuffer> ConvertExtraDataToAnnexB(
|
||||
const mozilla::MediaByteBuffer* aExtraData);
|
||||
// Extract SPS and PPS NALs from aSample by looking into each NALs.
|
||||
// aSample must be in AVCC format.
|
||||
static already_AddRefed<mozilla::MediaByteBuffer> ExtractExtraData(
|
||||
const mozilla::MediaRawData* aSample);
|
||||
static bool HasSPS(const mozilla::MediaRawData* aSample);
|
||||
static bool HasSPS(const mozilla::MediaByteBuffer* aExtraData);
|
||||
// Returns true if format is AVCC and sample has valid extradata.
|
||||
static bool IsAVCC(const mozilla::MediaRawData* aSample);
|
||||
// Returns true if format is AnnexB.
|
||||
static bool IsAnnexB(const mozilla::MediaRawData* aSample);
|
||||
// Return true if both extradata are equal.
|
||||
static bool CompareExtraData(const mozilla::MediaByteBuffer* aExtraData1,
|
||||
const mozilla::MediaByteBuffer* aExtraData2);
|
||||
|
||||
private:
|
||||
// AVCC box parser helper.
|
||||
|
|
|
@ -413,16 +413,6 @@ public:
|
|||
static already_AddRefed<mozilla::MediaByteBuffer> DecodeNALUnit(
|
||||
const mozilla::MediaByteBuffer* aNAL);
|
||||
|
||||
static bool HasSPS(const mozilla::MediaRawData* aSample);
|
||||
static bool HasSPS(const mozilla::MediaByteBuffer* aExtraData);
|
||||
// Extract SPS and PPS NALs from aSample by looking into each NALs.
|
||||
// aSample must be in AVCC format.
|
||||
static already_AddRefed<mozilla::MediaByteBuffer> ExtractExtraData(
|
||||
const mozilla::MediaRawData* aSample);
|
||||
// Return true if both extradata are equal.
|
||||
static bool CompareExtraData(const mozilla::MediaByteBuffer* aExtraData1,
|
||||
const mozilla::MediaByteBuffer* aExtraData2);
|
||||
|
||||
// Ensure that SPS data makes sense, Return true if SPS data was, and false
|
||||
// otherwise. If false, then content will be adjusted accordingly.
|
||||
static bool EnsureSPSIsSane(SPSData& aSPS);
|
||||
|
|
Загрузка…
Ссылка в новой задаче