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 509668 6bcfd324b867a5861824f40cbcfe3360f4f688d1
parent 509667 9386061fb62afedfafa3b51ea7ec0b05e8d9f210
child 509669 e9b36f8f6c2231074a9de8489d0cdfecfe78d7be
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1515471
milestone66.0a1
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
dom/media/mp4/MoofParser.cpp
dom/media/mp4/MoofParser.h
--- a/dom/media/mp4/MoofParser.cpp
+++ b/dom/media/mp4/MoofParser.cpp
@@ -294,21 +294,42 @@ void MoofParser::ParseStbl(Box& aBox) {
           return;
         }
       }
     }
   }
 }
 
 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;
+  }
+  MOZ_ASSERT(
+      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")) {
       ParseEncrypted(box);
+      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;
 
  protected:
   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 {
  public:
   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<CencSampleEncryptionInfoEntry>
       mTrackSampleEncryptionInfoEntries;
   FallibleTArray<SampleToGroupEntry> mTrackSampleToGroupEntries;
+  FallibleTArray<SampleDescriptionEntry> mSampleDescriptions;
 
   nsTArray<Moof>& Moofs() { return mMoofs; }
 
  private:
   void ScanForMetadata(mozilla::MediaByteRange& aMoov);
   nsTArray<Moof> mMoofs;
   nsTArray<MediaByteRange> mMediaRanges;
   bool mIsAudio;