diff options
-rw-r--r-- | dom/media/fmp4/MP4Demuxer.cpp | 6 | ||||
-rw-r--r-- | media/libstagefright/binding/Index.cpp | 32 | ||||
-rw-r--r-- | media/libstagefright/binding/MoofParser.cpp | 21 | ||||
-rw-r--r-- | media/libstagefright/binding/include/mp4_demuxer/MoofParser.h | 8 |
4 files changed, 51 insertions, 16 deletions
diff --git a/dom/media/fmp4/MP4Demuxer.cpp b/dom/media/fmp4/MP4Demuxer.cpp index a871d73b9..646897468 100644 --- a/dom/media/fmp4/MP4Demuxer.cpp +++ b/dom/media/fmp4/MP4Demuxer.cpp @@ -349,11 +349,11 @@ MP4TrackDemuxer::GetNextSample() if (sample->mCrypto.mValid) { nsAutoPtr<MediaRawDataWriter> writer(sample->CreateWriter()); writer->mCrypto.mMode = mInfo->mCrypto.mMode; - writer->mCrypto.mIVSize = mInfo->mCrypto.mIVSize; - // The length of the key will be zero if no key was specified in the sample - // information, meaning we should fall back to the default key. + // Only use the default key parsed from the moov if we haven't already got + // one from the sample group description. if (writer->mCrypto.mKeyId.Length() == 0) { + writer->mCrypto.mIVSize = mInfo->mCrypto.mIVSize; writer->mCrypto.mKeyId.AppendElements(mInfo->mCrypto.mKeyId); } } diff --git a/media/libstagefright/binding/Index.cpp b/media/libstagefright/binding/Index.cpp index a3a3f9847..eb039b5d6 100644 --- a/media/libstagefright/binding/Index.cpp +++ b/media/libstagefright/binding/Index.cpp @@ -181,9 +181,16 @@ CencSampleEncryptionInfoEntry* SampleIterator::GetSampleEncryptionEntry() Moof* currentMoof = &moofs[mCurrentMoof]; SampleToGroupEntry* sampleToGroupEntry = nullptr; + // Default to using the sample to group entries for the fragment, otherwise + // fall back to the sample to group entries for the track. + nsTArray<SampleToGroupEntry>* sampleToGroupEntries = + currentMoof->mFragmentSampleToGroupEntries.Length() != 0 + ? ¤tMoof->mFragmentSampleToGroupEntries + : &mIndex->mMoofParser->mTrackSampleToGroupEntries; + uint32_t seen = 0; - for (SampleToGroupEntry& entry : currentMoof->mSampleToGroupEntries) { + for (SampleToGroupEntry& entry : *sampleToGroupEntries) { if (seen + entry.mSampleCount > mCurrentSample) { sampleToGroupEntry = &entry; break; @@ -200,20 +207,31 @@ CencSampleEncryptionInfoEntry* SampleIterator::GetSampleEncryptionEntry() // 1, with the value 1 in the top 16 bits, to reference fragment-local // SampleGroupDescription Box. + // According to the spec, ISO-14496-12, the sum of the sample counts in this + // box should be equal to the total number of samples, and, if less, the + // reader should behave as if an extra SampleToGroupEntry existed, with + // groupDescriptionIndex 0. + if (!sampleToGroupEntry || sampleToGroupEntry->mGroupDescriptionIndex == 0) { return nullptr; } - uint32_t group_index = sampleToGroupEntry->mGroupDescriptionIndex; + nsTArray<CencSampleEncryptionInfoEntry>* entries = + &mIndex->mMoofParser->mTrackSampleEncryptionInfoEntries; + + uint32_t groupIndex = sampleToGroupEntry->mGroupDescriptionIndex; - if (group_index > SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) { - group_index -= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase; + // If the first bit is set to a one, then we should use the sample group + // descriptions from the fragment. + if (groupIndex > SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) { + groupIndex -= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase; + entries = ¤tMoof->mFragmentSampleEncryptionInfoEntries; } - // The group_index is one indexed - return group_index > currentMoof->mSampleEncryptionInfoEntries.Length() + // The group_index is one based. + return groupIndex > entries->Length() ? nullptr - : ¤tMoof->mSampleEncryptionInfoEntries.ElementAt(group_index - 1); + : &entries->ElementAt(groupIndex - 1); } Sample* SampleIterator::Get() diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index 970bc2325..4abad747b 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -332,6 +332,18 @@ MoofParser::ParseStbl(Box& aBox) for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("stsd")) { ParseStsd(box); + } else if (box.IsType("sgpd")) { + Sgpd sgpd(box); + if (sgpd.IsValid() && sgpd.mGroupingType == "seig") { + mTrackSampleEncryptionInfoEntries.Clear(); + mTrackSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries); + } + } else if (box.IsType("sbgp")) { + Sbgp sbgp(box); + if (sbgp.IsValid() && sbgp.mGroupingType == "seig") { + mTrackSampleToGroupEntries.Clear(); + mTrackSampleToGroupEntries.AppendElements(sbgp.mEntries); + } } } } @@ -497,6 +509,7 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, S MOZ_ASSERT(aDecodeTime); Tfhd tfhd(aTrex); Tfdt tfdt; + for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("tfhd")) { tfhd = Tfhd(box, aTrex); @@ -506,14 +519,14 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, S } else if (box.IsType("sgpd")) { Sgpd sgpd(box); if (sgpd.IsValid() && sgpd.mGroupingType == "seig") { - mSampleEncryptionInfoEntries.Clear(); - mSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries); + mFragmentSampleEncryptionInfoEntries.Clear(); + mFragmentSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries); } } else if (box.IsType("sbgp")) { Sbgp sbgp(box); if (sbgp.IsValid() && sbgp.mGroupingType == "seig") { - mSampleToGroupEntries.Clear(); - mSampleToGroupEntries.AppendElements(sbgp.mEntries); + mFragmentSampleToGroupEntries.Clear(); + mFragmentSampleToGroupEntries.AppendElements(sbgp.mEntries); } } else if (box.IsType("saiz")) { mSaizs.AppendElement(Saiz(box, aSinf.mDefaultEncryptionType)); diff --git a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h index 47bd27287..bb895555c 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h +++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h @@ -230,8 +230,8 @@ public: Interval<Microseconds> mTimeRange; FallibleTArray<Sample> mIndex; - nsTArray<CencSampleEncryptionInfoEntry> mSampleEncryptionInfoEntries; - nsTArray<SampleToGroupEntry> mSampleToGroupEntries; + nsTArray<CencSampleEncryptionInfoEntry> mFragmentSampleEncryptionInfoEntries; + nsTArray<SampleToGroupEntry> mFragmentSampleToGroupEntries; nsTArray<Saiz> mSaizs; nsTArray<Saio> mSaios; @@ -297,6 +297,10 @@ public: Tfdt mTfdt; Edts mEdts; Sinf mSinf; + + nsTArray<CencSampleEncryptionInfoEntry> mTrackSampleEncryptionInfoEntries; + nsTArray<SampleToGroupEntry> mTrackSampleToGroupEntries; + nsTArray<Moof>& Moofs() { return mMoofs; } private: void ScanForMetadata(mozilla::MediaByteRange& aFtyp, |