MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs, bool fuzzy) const { if ((isPositiveInfinite() && rhs.isPositiveInfinite()) || (isNegativeInfinite() && rhs.isNegativeInfinite()) || (isInvalid() && rhs.isInvalid()) || (isIndefinite() && rhs.isIndefinite())) return EqualTo; if (isInvalid()) return GreaterThan; if (rhs.isInvalid()) return LessThan; if (rhs.isNegativeInfinite() || isPositiveInfinite()) return GreaterThan; if (rhs.isPositiveInfinite() || isNegativeInfinite()) return LessThan; if (isIndefinite()) return GreaterThan; if (rhs.isIndefinite()) return LessThan; if (hasDoubleValue() && rhs.hasDoubleValue()) { if (m_timeValueAsDouble == rhs.m_timeValueAsDouble) return EqualTo; if (fuzzy && fabs(m_timeValueAsDouble - rhs.m_timeValueAsDouble) <= fuzzinessThreshold().toDouble()) return EqualTo; return m_timeValueAsDouble < rhs.m_timeValueAsDouble ? LessThan : GreaterThan; } MediaTime a = *this; MediaTime b = rhs; if (a.hasDoubleValue()) a.setTimeScale(DefaultTimeScale); if (b.hasDoubleValue()) b.setTimeScale(DefaultTimeScale); int64_t rhsWhole = b.m_timeValue / b.m_timeScale; int64_t lhsWhole = a.m_timeValue / a.m_timeScale; if (lhsWhole > rhsWhole) return GreaterThan; if (lhsWhole < rhsWhole) return LessThan; int64_t rhsRemain = b.m_timeValue % b.m_timeScale; int64_t lhsRemain = a.m_timeValue % a.m_timeScale; int64_t lhsFactor = lhsRemain * b.m_timeScale; int64_t rhsFactor = rhsRemain * a.m_timeScale; if (lhsFactor == rhsFactor) return EqualTo; return lhsFactor > rhsFactor ? GreaterThan : LessThan; }
MediaTime MediaTime::operator-(const MediaTime& rhs) const { if (rhs.isInvalid() || isInvalid()) return invalidTime(); if (rhs.isIndefinite() || isIndefinite()) return indefiniteTime(); if (isPositiveInfinite() && rhs.isPositiveInfinite()) return invalidTime(); if (isNegativeInfinite() && rhs.isNegativeInfinite()) return invalidTime(); if (isPositiveInfinite() || rhs.isNegativeInfinite()) return positiveInfiniteTime(); if (isNegativeInfinite() || rhs.isPositiveInfinite()) return negativeInfiniteTime(); if (hasDoubleValue() && rhs.hasDoubleValue()) return MediaTime::createWithDouble(m_timeValueAsDouble - rhs.m_timeValueAsDouble); MediaTime a = *this; MediaTime b = rhs; if (a.hasDoubleValue()) a.setTimeScale(DefaultTimeScale); else if (b.hasDoubleValue()) b.setTimeScale(DefaultTimeScale); int32_t commonTimeScale; if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale) commonTimeScale = MaximumTimeScale; a.setTimeScale(commonTimeScale); b.setTimeScale(commonTimeScale); while (!safeSub(a.m_timeValue, b.m_timeValue, a.m_timeValue)) { if (commonTimeScale == 1) return a.m_timeValue > 0 ? positiveInfiniteTime() : negativeInfiniteTime(); commonTimeScale /= 2; a.setTimeScale(commonTimeScale); b.setTimeScale(commonTimeScale); } return a; }
double MediaTime::toDouble() const { if (isInvalid() || isIndefinite()) return std::numeric_limits<double>::quiet_NaN(); if (isPositiveInfinite()) return std::numeric_limits<double>::infinity(); if (isNegativeInfinite()) return -std::numeric_limits<double>::infinity(); return static_cast<double>(m_timeValue) / m_timeScale; }
MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const { if ((isPositiveInfinite() && rhs.isPositiveInfinite()) || (isNegativeInfinite() && rhs.isNegativeInfinite()) || (isInvalid() && rhs.isInvalid()) || (isIndefinite() && rhs.isIndefinite())) return EqualTo; if (isInvalid()) return GreaterThan; if (rhs.isInvalid()) return LessThan; if (rhs.isNegativeInfinite() || isPositiveInfinite()) return GreaterThan; if (rhs.isPositiveInfinite() || isNegativeInfinite()) return LessThan; if (isIndefinite()) return GreaterThan; if (rhs.isIndefinite()) return LessThan; int64_t rhsWhole = rhs.m_timeValue / rhs.m_timeScale; int64_t lhsWhole = m_timeValue / m_timeScale; if (lhsWhole > rhsWhole) return GreaterThan; if (lhsWhole < rhsWhole) return LessThan; int64_t rhsRemain = rhs.m_timeValue % rhs.m_timeScale; int64_t lhsRemain = m_timeValue % m_timeScale; int64_t lhsFactor = lhsRemain * rhs.m_timeScale; int64_t rhsFactor = rhsRemain * m_timeScale; if (lhsFactor == rhsFactor) return EqualTo; return lhsFactor > rhsFactor ? GreaterThan : LessThan; }
float MediaTime::toFloat() const { if (isInvalid() || isIndefinite()) return std::numeric_limits<float>::quiet_NaN(); if (isPositiveInfinite()) return std::numeric_limits<float>::infinity(); if (isNegativeInfinite()) return -std::numeric_limits<float>::infinity(); if (hasDoubleValue()) return m_timeValueAsDouble; return static_cast<float>(m_timeValue) / m_timeScale; }
MediaTime MediaTime::operator-() const { if (isInvalid()) return invalidTime(); if (isIndefinite()) return indefiniteTime(); if (isPositiveInfinite()) return negativeInfiniteTime(); if (isNegativeInfinite()) return positiveInfiniteTime(); MediaTime negativeTime = *this; if (negativeTime.hasDoubleValue()) negativeTime.m_timeValueAsDouble = -negativeTime.m_timeValueAsDouble; else negativeTime.m_timeValue = -negativeTime.m_timeValue; return negativeTime; }
MediaTime MediaTime::operator*(int32_t rhs) const { if (isInvalid()) return invalidTime(); if (isIndefinite()) return indefiniteTime(); if (!rhs) return zeroTime(); if (isPositiveInfinite()) { if (rhs > 0) return positiveInfiniteTime(); return negativeInfiniteTime(); } if (isNegativeInfinite()) { if (rhs > 0) return negativeInfiniteTime(); return positiveInfiniteTime(); } MediaTime a = *this; if (a.hasDoubleValue()) { a.m_timeValueAsDouble *= rhs; return a; } while (!safeMultiply(a.m_timeValue, rhs, a.m_timeValue)) { if (a.m_timeScale == 1) return signum(a.m_timeValue) == signum(rhs) ? positiveInfiniteTime() : negativeInfiniteTime(); a.setTimeScale(a.m_timeScale / 2); } return a; }
MediaTime MediaTime::operator-(const MediaTime& rhs) const { if (rhs.isInvalid() || isInvalid()) return invalidTime(); if (rhs.isIndefinite() || isIndefinite()) return indefiniteTime(); if (isPositiveInfinite()) { if (rhs.isPositiveInfinite()) return invalidTime(); return positiveInfiniteTime(); } if (isNegativeInfinite()) { if (rhs.isNegativeInfinite()) return invalidTime(); return negativeInfiniteTime(); } int32_t commonTimeScale; if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale) commonTimeScale = MaximumTimeScale; MediaTime a = *this; MediaTime b = rhs; a.setTimeScale(commonTimeScale); b.setTimeScale(commonTimeScale); while (!safeSub(a.m_timeValue, b.m_timeValue, a.m_timeValue)) { if (commonTimeScale == 1) return a.m_timeValue > 0 ? positiveInfiniteTime() : negativeInfiniteTime(); commonTimeScale /= 2; a.setTimeScale(commonTimeScale); b.setTimeScale(commonTimeScale); } return a; }