Bug 1289438: [ogg] P4. Use SaferMultDiv where appropriate. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 27 Jul 2016 17:17:21 +1000
changeset 347449 9852c16d65e4b9ee4027745babac8ff15be79d6c
parent 347448 0f13ecf177c65ee9438b3c32d3a064cde5b29f1e
child 347450 9fac9a76954f66b448ee8787b90ec1370ffe4cd3
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1289438
milestone50.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 1289438: [ogg] P4. Use SaferMultDiv where appropriate. r=gerald MozReview-Commit-ID: 3AWTGciNj4D
dom/media/ogg/OggCodecState.cpp
--- a/dom/media/ogg/OggCodecState.cpp
+++ b/dom/media/ogg/OggCodecState.cpp
@@ -452,21 +452,19 @@ int64_t TheoraState::StartTime(int64_t g
 }
 
 int64_t
 TheoraState::PacketDuration(ogg_packet* aPacket)
 {
   if (!mActive || mInfo.fps_numerator == 0) {
     return -1;
   }
-  CheckedInt64 t = CheckedInt64(mInfo.fps_denominator) * USECS_PER_S;
-  if (!t.isValid()) {
-    return -1;
-  }
-  return t.value() / mInfo.fps_numerator;
+  CheckedInt64 t =
+    SaferMultDiv(mInfo.fps_denominator, USECS_PER_S, mInfo.fps_numerator);
+  return t.isValid() ? t.value() : -1;
 }
 
 int64_t
 TheoraState::MaxKeyframeOffset()
 {
   // Determine the maximum time in microseconds by which a key frame could
   // offset for the theora bitstream. Theora granulepos encode time as:
   // ((key_frame_number << granule_shift) + frame_offset).
@@ -729,21 +727,18 @@ VorbisState::Time(int64_t granulepos)
 }
 
 int64_t
 VorbisState::Time(vorbis_info* aInfo, int64_t aGranulepos)
 {
   if (aGranulepos == -1 || aInfo->rate == 0) {
     return -1;
   }
-  CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
-  if (!t.isValid()) {
-    t = 0;
-  }
-  return t.value() / aInfo->rate;
+  CheckedInt64 t = SaferMultDiv(aGranulepos, USECS_PER_S, aInfo->rate);
+  return t.isValid() ? t.value() : 0;
 }
 
 int64_t
 VorbisState::PacketDuration(ogg_packet* aPacket)
 {
   if (!mActive) {
     return -1;
   }
@@ -1074,18 +1069,18 @@ OpusState::Time(int64_t aGranulepos)
 int64_t
 OpusState::Time(int aPreSkip, int64_t aGranulepos)
 {
   if (aGranulepos < 0) {
     return -1;
   }
 
   // Ogg Opus always runs at a granule rate of 48 kHz.
-  CheckedInt64 t = (CheckedInt64(aGranulepos) - aPreSkip) * USECS_PER_S;
-  return t.isValid() ? t.value() / 48000 : -1;
+  CheckedInt64 t = SaferMultDiv(aGranulepos - aPreSkip, USECS_PER_S, 48000);
+  return t.isValid() ? t.value() : -1;
 }
 
 bool
 OpusState::IsHeader(ogg_packet* aPacket)
 {
   return aPacket->bytes >= 16 &&
          (!memcmp(aPacket->packet, "OpusHead", 8) ||
           !memcmp(aPacket->packet, "OpusTags", 8));
@@ -1135,18 +1130,18 @@ GetOpusDeltaGP(ogg_packet* packet)
   }
   NS_WARNING("Invalid Opus packet.");
   return nframes;
 }
 
 int64_t
 OpusState::PacketDuration(ogg_packet* aPacket)
 {
-  CheckedInt64 t = CheckedInt64(GetOpusDeltaGP(aPacket)) * USECS_PER_S;
-  return t.isValid() ? t.value() / 48000 : -1;
+  CheckedInt64 t = SaferMultDiv(GetOpusDeltaGP(aPacket), USECS_PER_S, 48000);
+  return t.isValid() ? t.value() : -1;
 }
 
 bool
 OpusState::ReconstructOpusGranulepos(void)
 {
   NS_ASSERTION(mUnstamped.Length() > 0, "Must have unstamped packets");
   ogg_packet* last = mUnstamped[mUnstamped.Length()-1];
   NS_ASSERTION(last->e_o_s || last->granulepos > 0,
@@ -1356,30 +1351,30 @@ SkeletonState::DecodeIndex(ogg_packet* a
   if (timeDenom == 0) {
     LOG(LogLevel::Debug, ("Ogg Skeleton Index packet for stream %u has 0 "
                        "timestamp denominator.", serialno));
     return (mActive = false);
   }
 
   // Extract the start time.
   int64_t timeRawInt = LittleEndian::readInt64(p + INDEX_FIRST_NUMER_OFFSET);
-  CheckedInt64 t = CheckedInt64(timeRawInt) * USECS_PER_S;
+  CheckedInt64 t = SaferMultDiv(timeRawInt, USECS_PER_S, timeDenom);
   if (!t.isValid()) {
     return (mActive = false);
   } else {
-    startTime = t.value() / timeDenom;
+    startTime = t.value();
   }
 
   // Extract the end time.
   timeRawInt = LittleEndian::readInt64(p + INDEX_LAST_NUMER_OFFSET);
-  t = CheckedInt64(timeRawInt) * USECS_PER_S;
+  t = SaferMultDiv(timeRawInt, USECS_PER_S, timeDenom);
   if (!t.isValid()) {
     return (mActive = false);
   } else {
-    endTime = t.value() / timeDenom;
+    endTime = t.value();
   }
 
   // Check the numKeyPoints value read, ensure we're not going to run out of
   // memory while trying to decode the index packet.
   CheckedInt64 minPacketSize =
     (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
   if (!minPacketSize.isValid())
   {
@@ -1423,21 +1418,20 @@ SkeletonState::DecodeIndex(ogg_packet* a
     }
     p = ReadVariableLengthInt(p, limit, delta);
     time += delta;
     if (!time.isValid() ||
         time.value() > endTime ||
         time.value() < startTime) {
       return (mActive = false);
     }
-    CheckedInt64 timeUsecs = time * USECS_PER_S;
+    CheckedInt64 timeUsecs = SaferMultDiv(time.value(), USECS_PER_S, timeDenom);
     if (!timeUsecs.isValid()) {
-      return mActive = false;
+      return (mActive = false);
     }
-    timeUsecs /= timeDenom;
     keyPoints->Add(offset.value(), timeUsecs.value());
     numKeyPointsRead++;
   }
 
   int32_t keyPointsRead = keyPoints->Length();
   if (keyPointsRead > 0) {
     mIndex.Put(serialno, keyPoints.forget());
   }