From 512dcfac01d5395855cf2aff96ecd62ededb05aa Mon Sep 17 00:00:00 2001 From: trav90 Date: Wed, 25 Jul 2018 22:37:39 -0500 Subject: [EME] Add support for sbgp and sgpd boxes in the traf box --- media/libstagefright/binding/MoofParser.cpp | 152 ++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) (limited to 'media/libstagefright/binding/MoofParser.cpp') diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index 491967a12..970bc2325 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -27,6 +27,8 @@ namespace mp4_demuxer using namespace stagefright; using namespace mozilla; +const uint32_t kKeyIdSize = 16; + bool MoofParser::RebuildFragmentedIndex(const MediaByteRangeSet& aByteRanges) { @@ -501,6 +503,18 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, S } else if (!aTrex.mTrackId || tfhd.mTrackId == aTrex.mTrackId) { if (box.IsType("tfdt")) { tfdt = Tfdt(box); + } else if (box.IsType("sgpd")) { + Sgpd sgpd(box); + if (sgpd.IsValid() && sgpd.mGroupingType == "seig") { + mSampleEncryptionInfoEntries.Clear(); + mSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries); + } + } else if (box.IsType("sbgp")) { + Sbgp sbgp(box); + if (sbgp.IsValid() && sbgp.mGroupingType == "seig") { + mSampleToGroupEntries.Clear(); + mSampleToGroupEntries.AppendElements(sbgp.mEntries); + } } else if (box.IsType("saiz")) { mSaizs.AppendElement(Saiz(box, aSinf.mDefaultEncryptionType)); } else if (box.IsType("saio")) { @@ -1050,5 +1064,143 @@ Saio::Saio(Box& aBox, AtomType aDefaultType) mValid = true; } +Sbgp::Sbgp(Box& aBox) +{ + BoxReader reader(aBox); + + if (!reader->CanReadType()) { + LOG(Sbgp, "Incomplete Box (missing flags)"); + return; + } + + uint32_t flags = reader->ReadU32(); + const uint8_t version = flags >> 24; + flags = flags & 0xffffff; + + // Make sure we have enough bytes to read as far as the count. + uint32_t need = (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2; + if (reader->Remaining() < need) { + LOG(Sbgp, "Incomplete Box (have:%lld, need:%lld)", + (uint64_t)reader->Remaining(), (uint64_t)need); + return; + } + + mGroupingType = reader->ReadU32(); + + if (version == 1) { + mGroupingTypeParam = reader->Read32(); + } + + uint32_t count = reader->ReadU32(); + + // Make sure we can read all the entries. + need = sizeof(uint32_t) * 2 * count; + if (reader->Remaining() < need) { + LOG(Sbgp, "Incomplete Box (have:%lld, need:%lld). Failed to read entries", + (uint64_t)reader->Remaining(), (uint64_t)need); + return; + } + + for (uint32_t i = 0; i < count; i++) { + uint32_t sampleCount = reader->ReadU32(); + uint32_t groupDescriptionIndex = reader->ReadU32(); + + SampleToGroupEntry entry(sampleCount, groupDescriptionIndex); + mEntries.AppendElement(entry); + } + + mValid = true; +} + +Sgpd::Sgpd(Box& aBox) +{ + BoxReader reader(aBox); + + if (!reader->CanReadType()) { + LOG(Sgpd, "Incomplete Box (missing flags)"); + return; + } + + uint32_t flags = reader->ReadU32(); + const uint8_t version = flags >> 24; + flags = flags & 0xffffff; + + uint32_t need = ((flags & 1) ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2; + if (reader->Remaining() < need) { + LOG(Sgpd, "Incomplete Box (have:%lld need:%lld)", + (uint64_t)reader->Remaining(), (uint64_t)need); + return; + } + + mGroupingType = reader->ReadU32(); + + const uint32_t entrySize = sizeof(uint32_t) + kKeyIdSize; + uint32_t defaultLength = 0; + + if (version == 1) { + defaultLength = reader->ReadU32(); + if (defaultLength < entrySize && defaultLength != 0) { + return; + } + } + + uint32_t count = reader->ReadU32(); + + // Make sure we have sufficient remaining bytes to read the entries. + need = + count * (sizeof(uint32_t) * (version == 1 && defaultLength == 0 ? 2 : 1) + + kKeyIdSize * sizeof(uint8_t)); + if (reader->Remaining() < need) { + LOG(Sgpd, "Incomplete Box (have:%lld need:%lld). Failed to read entries", + (uint64_t)reader->Remaining(), (uint64_t)need); + return; + } + for (uint32_t i = 0; i < count; ++i) { + if (version == 1 && defaultLength == 0) { + uint32_t descriptionLength = reader->ReadU32(); + if (descriptionLength < entrySize) { + return; + } + } + + CencSampleEncryptionInfoEntry entry; + bool valid = entry.Init(reader); + if (!valid) { + return; + } + mEntries.AppendElement(entry); + } + + mValid = true; +} + +bool CencSampleEncryptionInfoEntry::Init(BoxReader& aReader) +{ + // Skip a reserved byte. + aReader->ReadU8(); + + uint8_t possiblePatternInfo = aReader->ReadU8(); + uint8_t flag = aReader->ReadU8(); + + mIVSize = aReader->ReadU8(); + + // Read the key id. + for (uint32_t i = 0; i < kKeyIdSize; ++i) { + mKeyId.AppendElement(aReader->ReadU8()); + } + + mIsEncrypted = flag != 0; + + if (mIsEncrypted) { + if (mIVSize != 8 && mIVSize != 16) { + return false; + } + } else if (mIVSize != 0) { + return false; + } + + return true; +} + #undef LOG } -- cgit v1.2.3