Bug 1410565 - check mTimescale to avoid dividing by zero. r?kinetik draft
authorAlfredo.Yang <ayang@mozilla.com>
Tue, 24 Oct 2017 14:44:19 +0800
changeset 685865 7f6c22fec2eb31473518d142ad869bf2568790a0
parent 685608 a124f4901430f6db74cfc7fe3b07957a1c691b40
child 685866 df1ad0c649f821c06fde48010eea2d679c94a0ab
push id86025
push userbmo:ayang@mozilla.com
push dateWed, 25 Oct 2017 03:50:06 +0000
reviewerskinetik
bugs1410565
milestone58.0a1
Bug 1410565 - check mTimescale to avoid dividing by zero. r?kinetik MozReview-Commit-ID: 7uxgaVAbQds
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -437,19 +437,20 @@ Moof::Moof(Box& aBox, Trex& aTrex, Mvhd&
       // In MP4, the duration of a sample is defined as the delta between two decode
       // timestamps. The operation above has updated the duration of each sample
       // as a Sample's duration is mCompositionRange.end - mCompositionRange.start
       // MSE's TrackBuffersManager expects dts that increased by the sample's
       // duration, so we rewrite the dts accordingly.
       int64_t presentationDuration =
         ctsOrder.LastElement()->mCompositionRange.end
         - ctsOrder[0]->mCompositionRange.start;
-      int64_t endDecodeTime =
-        aMdhd.ToMicroseconds((int64_t)*aDecodeTime - aEdts.mMediaStart)
-        + aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
+      auto decodeOffset = aMdhd.ToMicroseconds((int64_t)*aDecodeTime - aEdts.mMediaStart);
+      auto offsetOffset = aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
+      int64_t endDecodeTime = decodeOffset.isOk() & offsetOffset.isOk() ?
+                              decodeOffset.unwrap() + offsetOffset.unwrap() : 0;
       int64_t decodeDuration = endDecodeTime - mIndex[0].mDecodeTime;
       double adjust = (double)decodeDuration / presentationDuration;
       int64_t dtsOffset = mIndex[0].mDecodeTime;
       int64_t compositionDuration = 0;
       // Adjust the dts, ensuring that the new adjusted dts will never be greater
       // than decodeTime (the next moof's decode start time).
       for (auto& sample : mIndex) {
         sample.mDecodeTime = dtsOffset + int64_t(compositionDuration * adjust);
@@ -675,34 +676,37 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
       MOZ_TRY_VAR(ctsOffset, reader->Read32());
     }
 
     if (sampleSize) {
       Sample sample;
       sample.mByteRange = MediaByteRange(offset, offset + sampleSize);
       offset += sampleSize;
 
-      sample.mDecodeTime =
-        aMdhd.ToMicroseconds((int64_t)decodeTime - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
-      sample.mCompositionRange = Interval<Microseconds>(
-        aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset),
-        aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset));
-
+      Microseconds decodeOffset, emptyOffset, startCts, endCts;
+      MOZ_TRY_VAR(decodeOffset, aMdhd.ToMicroseconds((int64_t)decodeTime - aEdts.mMediaStart));
+      MOZ_TRY_VAR(emptyOffset, aMvhd.ToMicroseconds(aEdts.mEmptyOffset));
+      sample.mDecodeTime = decodeOffset + emptyOffset;
+      MOZ_TRY_VAR(startCts, aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset - aEdts.mMediaStart));
+      MOZ_TRY_VAR(endCts, aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart));
+      sample.mCompositionRange = Interval<Microseconds>(startCts + emptyOffset, endCts + emptyOffset);
       // Sometimes audio streams don't properly mark their samples as keyframes,
       // because every audio sample is a keyframe.
       sample.mSync = !(sampleFlags & 0x1010000) || aIsAudio;
 
       // FIXME: Make this infallible after bug 968520 is done.
       MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample, fallible));
 
       mMdatRange = mMdatRange.Span(sample.mByteRange);
     }
     decodeTime += sampleDuration;
   }
-  mMaxRoundingError += aMdhd.ToMicroseconds(sampleCount);
+  Microseconds roundTime;
+  MOZ_TRY_VAR(roundTime, aMdhd.ToMicroseconds(sampleCount));
+  mMaxRoundingError += roundTime;
 
   *aDecodeTime = decodeTime;
 
   return Ok();
 }
 
 Tkhd::Tkhd(Box& aBox)
 {
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -28,18 +28,22 @@ public:
     : mCreationTime(0)
     , mModificationTime(0)
     , mTimescale(0)
     , mDuration(0)
   {
   }
   explicit Mvhd(Box& aBox);
 
-  Microseconds ToMicroseconds(int64_t aTimescaleUnits)
+  Result<Microseconds, nsresult> ToMicroseconds(int64_t aTimescaleUnits)
   {
+    if (!mTimescale) {
+      NS_WARNING("invalid mTimescale");
+      return Err(NS_ERROR_FAILURE);
+    }
     int64_t major = aTimescaleUnits / mTimescale;
     int64_t remainder = aTimescaleUnits % mTimescale;
     return major * 1000000ll + remainder * 1000000ll / mTimescale;
   }
 
   uint64_t mCreationTime;
   uint64_t mModificationTime;
   uint32_t mTimescale;