Index: media/formats/mp4/track_run_iterator.cc |
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc |
index e2a145e0d9dded316adf25563599ecf3bfb6ad16..bc38352bf8ee1a7063bf5f29cae44d501c34bc8b 100644 |
--- a/media/formats/mp4/track_run_iterator.cc |
+++ b/media/formats/mp4/track_run_iterator.cc |
@@ -57,10 +57,22 @@ TrackRunInfo::TrackRunInfo() |
TrackRunInfo::~TrackRunInfo() {} |
TimeDelta TimeDeltaFromRational(int64 numer, int64 denom) { |
- DCHECK_LT((numer > 0 ? numer : -numer), |
- kint64max / base::Time::kMicrosecondsPerSecond); |
- return TimeDelta::FromMicroseconds( |
- base::Time::kMicrosecondsPerSecond * numer / denom); |
+ // To avoid overflow, split the following calculation: |
DaleCurtis
2014/02/22 01:41:20
Why not TimeDelta::FromMicroseconds((static_cast<d
damienv1
2014/02/22 01:53:01
I was wondering if in some cases you can loose som
acolwell GONE FROM CHROMIUM
2014/02/22 02:00:35
The conversion to double can lose precision if |nu
|
+ // (numer * base::Time::kMicrosecondsPerSecond) / denom |
+ // into: |
+ // (numer / denom) * base::Time::kMicrosecondsPerSecond + |
+ // ((numer % denom) * base::Time::kMicrosecondsPerSecond) / denom |
+ int64 a = numer / denom; |
+ DCHECK_LE((a > 0 ? a : -a), kint64max / base::Time::kMicrosecondsPerSecond); |
+ int64 timea_in_us = a * base::Time::kMicrosecondsPerSecond; |
+ |
+ int64 b = numer % denom; |
+ DCHECK_LE((b > 0 ? b : -b), kint64max / base::Time::kMicrosecondsPerSecond); |
+ int64 timeb_in_us = (b * base::Time::kMicrosecondsPerSecond) / denom; |
+ |
+ DCHECK((timeb_in_us < 0) || (timea_in_us <= kint64max - timeb_in_us)); |
+ DCHECK((timeb_in_us > 0) || (timea_in_us >= kint64min - timeb_in_us)); |
+ return TimeDelta::FromMicroseconds(timea_in_us + timeb_in_us); |
} |
TrackRunIterator::TrackRunIterator(const Movie* moov, |