Bug 1515471 - Have the moof parser store if sample description entries contain crypto info. r=jya
authorBryce Van Dyk <bvandyk@mozilla.com>
Fri, 04 Jan 2019 17:57:04 +0000
changeset 452565 6bcfd324b867a5861824f40cbcfe3360f4f688d1
parent 452564 9386061fb62afedfafa3b51ea7ec0b05e8d9f210
child 452566 e9b36f8f6c2231074a9de8489d0cdfecfe78d7be
push id35315
push usershindli@mozilla.com
push dateSat, 05 Jan 2019 03:59:26 +0000
treeherdermozilla-central@6dd228164d42 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515471 - Have the moof parser store if sample description entries contain crypto info. r=jya This is required to disambiguate if samples should be considered encrypted or not when parsing certain cbcs encrypted files. Unlike with cenc encryption, cbcs encrypted media may have fragments that lack characteristics from which we can infer encryption. Because of this we need to store and trust this information from the sample description box. Differential Revision: https://phabricator.services.mozilla.com/D15439
--- a/dom/media/mp4/MoofParser.cpp
+++ b/dom/media/mp4/MoofParser.cpp
@@ -294,21 +294,42 @@ void MoofParser::ParseStbl(Box& aBox) {
 void MoofParser::ParseStsd(Box& aBox) {
+  if (mTrex.mTrackId == 0) {
+    // If mTrex.mTrackId is 0, then the parser is being used to read multiple
+    // tracks metadata, and it is not a sane operation to try and map multiple
+    // sample description boxes, from different tracks, onto the parser, which
+    // is modeled around storing metadata for a single track.
+    return;
+  }
+      mSampleDescriptions.IsEmpty(),
+      "Shouldn't have any sample descriptions when starting to parse stsd");
+  uint32_t numberEncryptedEntries = 0;
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
+    SampleDescriptionEntry sampleDescriptionEntry{false};
     if (box.IsType("encv") || box.IsType("enca")) {
+      sampleDescriptionEntry.mIsEncryptedEntry = true;
+      numberEncryptedEntries++;
+    }
+    if (!mSampleDescriptions.AppendElement(sampleDescriptionEntry,
+                                           mozilla::fallible)) {
+      LOG(Moof, "OOM");
+      return;
+  MOZ_ASSERT(numberEncryptedEntries <= 1,
+             "We don't expect or handle mulitple encrypted entries per track");
 void MoofParser::ParseEncrypted(Box& aBox) {
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     // Some MP4 files have been found to have multiple sinf boxes in the same
     // enc* box. This does not match spec anyway, so just choose the first
     // one that parses properly.
     if (box.IsType("sinf")) {
--- a/dom/media/mp4/MoofParser.h
+++ b/dom/media/mp4/MoofParser.h
@@ -203,16 +203,25 @@ class Sgpd final : public Atom  // Sampl
   AtomType mGroupingType;
   FallibleTArray<CencSampleEncryptionInfoEntry> mEntries;
   Result<Ok, nsresult> Parse(Box& aBox);
+// Audio/video entries from the sample description box (stsd). We only need to
+// store if these are encrypted, so do not need a specialized class for
+// different audio and video data. Currently most of the parsing of these
+// entries is by the mp4parse-rust, but moof pasrser needs to know which of
+// these are encrypted when parsing the track fragment header (tfhd).
+struct SampleDescriptionEntry {
+  bool mIsEncryptedEntry = false;
 class Moof final : public Atom {
   Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
        Sinf& aSinf, uint64_t* aDecoderTime, bool aIsAudio);
   bool GetAuxInfo(AtomType aType, FallibleTArray<MediaByteRange>* aByteRanges);
   void FixRounding(const Moof& aMoof);
   mozilla::MediaByteRange mRange;
@@ -288,16 +297,17 @@ class MoofParser : public DecoderDoctorL
   Trex mTrex;
   Tfdt mTfdt;
   Edts mEdts;
   Sinf mSinf;
   FallibleTArray<SampleToGroupEntry> mTrackSampleToGroupEntries;
+  FallibleTArray<SampleDescriptionEntry> mSampleDescriptions;
   nsTArray<Moof>& Moofs() { return mMoofs; }
   void ScanForMetadata(mozilla::MediaByteRange& aMoov);
   nsTArray<Moof> mMoofs;
   nsTArray<MediaByteRange> mMediaRanges;
   bool mIsAudio;