Bug 1515471 - Persist the track fragment header box on the Moof class. r=jya
authorBryce Van Dyk <bvandyk@mozilla.com>
Thu, 03 Jan 2019 14:14:00 +0000
changeset 452583 e9b36f8f6c2231074a9de8489d0cdfecfe78d7be
parent 452582 6bcfd324b867a5861824f40cbcfe3360f4f688d1
child 452584 416d0d25d932ececd8f54036429f3fb91e4c351d
push id75498
push userbvandyk@mozilla.com
push dateFri, 04 Jan 2019 18:09:30 +0000
treeherderautoland@8bbbc4ae3211 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1515471, 1487416
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 - Persist the track fragment header box on the Moof class. r=jya Persisting this box lets us use it later while indexing into metadata. Importantly, it lets us look up the appropriate sample description entry, which lets us determine if a fragment is associated with crypto information in the init segment. Being able to do this is required for cbcs encryption. This will be done in a follow up bug: Bug 1487416 (and possibly others). Differential Revision: https://phabricator.services.mozilla.com/D15440
dom/media/mp4/MoofParser.cpp
dom/media/mp4/MoofParser.h
--- a/dom/media/mp4/MoofParser.cpp
+++ b/dom/media/mp4/MoofParser.cpp
@@ -349,17 +349,17 @@ class CtsComparator {
   }
   bool LessThan(Sample* const aA, Sample* const aB) const {
     return aA->mCompositionRange.start < aB->mCompositionRange.start;
   }
 };
 
 Moof::Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
            Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio)
-    : mRange(aBox.Range()), mMaxRoundingError(35000) {
+    : mRange(aBox.Range()), mTfhd(aTrex), mMaxRoundingError(35000) {
   nsTArray<Box> psshBoxes;
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("traf")) {
       ParseTraf(box, aTrex, aMvhd, aMdhd, aEdts, aSinf, aDecodeTime, aIsAudio);
     }
     if (box.IsType("pssh")) {
       psshBoxes.AppendElement(box);
     }
@@ -503,23 +503,22 @@ bool Moof::ProcessCenc() {
   }
   return true;
 }
 
 void Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd,
                      Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime,
                      bool aIsAudio) {
   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);
-    } else if (!aTrex.mTrackId || tfhd.mTrackId == aTrex.mTrackId) {
+      mTfhd = Tfhd(box, aTrex);
+    } else if (!aTrex.mTrackId || mTfhd.mTrackId == aTrex.mTrackId) {
       if (box.IsType("tfdt")) {
         tfdt = Tfdt(box);
       } else if (box.IsType("sgpd")) {
         Sgpd sgpd(box);
         if (sgpd.IsValid() && sgpd.mGroupingType == "seig") {
           mFragmentSampleEncryptionInfoEntries.Clear();
           if (!mFragmentSampleEncryptionInfoEntries.AppendElements(
                   sgpd.mEntries, mozilla::fallible)) {
@@ -547,26 +546,25 @@ void Moof::ParseTraf(Box& aBox, Trex& aT
         if (!mSaios.AppendElement(Saio(box, aSinf.mDefaultEncryptionType),
                                   mozilla::fallible)) {
           LOG(Moof, "OOM");
           return;
         }
       }
     }
   }
-  if (aTrex.mTrackId && tfhd.mTrackId != aTrex.mTrackId) {
+  if (aTrex.mTrackId && mTfhd.mTrackId != aTrex.mTrackId) {
     return;
   }
   // Now search for TRUN boxes.
   uint64_t decodeTime =
       tfdt.IsValid() ? tfdt.mBaseMediaDecodeTime : *aDecodeTime;
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("trun")) {
-      if (ParseTrun(box, tfhd, aMvhd, aMdhd, aEdts, &decodeTime, aIsAudio)
-              .isOk()) {
+      if (ParseTrun(box, aMvhd, aMdhd, aEdts, &decodeTime, aIsAudio).isOk()) {
         mValid = true;
       } else {
         LOG(Moof, "ParseTrun failed");
         mValid = false;
         break;
       }
     }
   }
@@ -575,23 +573,23 @@ void Moof::ParseTraf(Box& aBox, Trex& aT
 
 void Moof::FixRounding(const Moof& aMoof) {
   Microseconds gap = aMoof.mTimeRange.start - mTimeRange.end;
   if (gap > 0 && gap <= mMaxRoundingError) {
     mTimeRange.end = aMoof.mTimeRange.start;
   }
 }
 
-Result<Ok, nsresult> Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd,
-                                     Mdhd& aMdhd, Edts& aEdts,
-                                     uint64_t* aDecodeTime, bool aIsAudio) {
-  if (!aTfhd.IsValid() || !aMvhd.IsValid() || !aMdhd.IsValid() ||
+Result<Ok, nsresult> Moof::ParseTrun(Box& aBox, Mvhd& aMvhd, Mdhd& aMdhd,
+                                     Edts& aEdts, uint64_t* aDecodeTime,
+                                     bool aIsAudio) {
+  if (!mTfhd.IsValid() || !aMvhd.IsValid() || !aMdhd.IsValid() ||
       !aEdts.IsValid()) {
-    LOG(Moof, "Invalid dependencies: aTfhd(%d) aMvhd(%d) aMdhd(%d) aEdts(%d)",
-        aTfhd.IsValid(), aMvhd.IsValid(), aMdhd.IsValid(), !aEdts.IsValid());
+    LOG(Moof, "Invalid dependencies: mTfhd(%d) aMvhd(%d) aMdhd(%d) aEdts(%d)",
+        mTfhd.IsValid(), aMvhd.IsValid(), aMdhd.IsValid(), !aEdts.IsValid());
     return Err(NS_ERROR_FAILURE);
   }
 
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Moof, "Incomplete Box (missing flags)");
     return Err(NS_ERROR_FAILURE);
   }
@@ -603,44 +601,44 @@ Result<Ok, nsresult> Moof::ParseTrun(Box
     return Err(NS_ERROR_FAILURE);
   }
   uint32_t sampleCount;
   MOZ_TRY_VAR(sampleCount, reader->ReadU32());
   if (sampleCount == 0) {
     return Ok();
   }
 
-  uint64_t offset = aTfhd.mBaseDataOffset;
+  uint64_t offset = mTfhd.mBaseDataOffset;
   if (flags & 0x01) {
     uint32_t tmp;
     MOZ_TRY_VAR(tmp, reader->ReadU32());
     offset += tmp;
   }
-  uint32_t firstSampleFlags = aTfhd.mDefaultSampleFlags;
+  uint32_t firstSampleFlags = mTfhd.mDefaultSampleFlags;
   if (flags & 0x04) {
     MOZ_TRY_VAR(firstSampleFlags, reader->ReadU32());
   }
   uint64_t decodeTime = *aDecodeTime;
   nsTArray<MP4Interval<Microseconds>> timeRanges;
 
   if (!mIndex.SetCapacity(sampleCount, fallible)) {
     LOG(Moof, "Out of Memory");
     return Err(NS_ERROR_FAILURE);
   }
 
   for (size_t i = 0; i < sampleCount; i++) {
-    uint32_t sampleDuration = aTfhd.mDefaultSampleDuration;
+    uint32_t sampleDuration = mTfhd.mDefaultSampleDuration;
     if (flags & 0x100) {
       MOZ_TRY_VAR(sampleDuration, reader->ReadU32());
     }
-    uint32_t sampleSize = aTfhd.mDefaultSampleSize;
+    uint32_t sampleSize = mTfhd.mDefaultSampleSize;
     if (flags & 0x200) {
       MOZ_TRY_VAR(sampleSize, reader->ReadU32());
     }
-    uint32_t sampleFlags = i ? aTfhd.mDefaultSampleFlags : firstSampleFlags;
+    uint32_t sampleFlags = i ? mTfhd.mDefaultSampleFlags : firstSampleFlags;
     if (flags & 0x400) {
       MOZ_TRY_VAR(sampleFlags, reader->ReadU32());
     }
     int32_t ctsOffset = 0;
     if (flags & 0x800) {
       MOZ_TRY_VAR(ctsOffset, reader->Read32());
     }
 
--- a/dom/media/mp4/MoofParser.h
+++ b/dom/media/mp4/MoofParser.h
@@ -228,28 +228,29 @@ class Moof final : public Atom {
   mozilla::MediaByteRange mMdatRange;
   MP4Interval<Microseconds> mTimeRange;
   FallibleTArray<Sample> mIndex;
 
   FallibleTArray<CencSampleEncryptionInfoEntry>
       mFragmentSampleEncryptionInfoEntries;
   FallibleTArray<SampleToGroupEntry> mFragmentSampleToGroupEntries;
 
+  Tfhd mTfhd;
   FallibleTArray<Saiz> mSaizs;
   FallibleTArray<Saio> mSaios;
   nsTArray<nsTArray<uint8_t>> mPsshes;
 
  private:
   // aDecodeTime is updated to the end of the parsed TRAF on return.
   void ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
                  Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio);
   // aDecodeTime is updated to the end of the parsed TRUN on return.
-  Result<Ok, nsresult> ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd,
-                                 Mdhd& aMdhd, Edts& aEdts,
-                                 uint64_t* aDecodeTime, bool aIsAudio);
+  Result<Ok, nsresult> ParseTrun(Box& aBox, Mvhd& aMvhd, Mdhd& aMdhd,
+                                 Edts& aEdts, uint64_t* aDecodeTime,
+                                 bool aIsAudio);
   bool ProcessCenc();
   uint64_t mMaxRoundingError;
 };
 
 DDLoggedTypeDeclName(MoofParser);
 
 class MoofParser : public DecoderDoctorLifeLogger<MoofParser> {
  public: