diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/MediaTime.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/MediaTime.cpp')
-rw-r--r-- | Source/WTF/wtf/MediaTime.cpp | 243 |
1 files changed, 187 insertions, 56 deletions
diff --git a/Source/WTF/wtf/MediaTime.cpp b/Source/WTF/wtf/MediaTime.cpp index f856714d0..9f53402c1 100644 --- a/Source/WTF/wtf/MediaTime.cpp +++ b/Source/WTF/wtf/MediaTime.cpp @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,15 +30,17 @@ #include "MediaTime.h" #include <algorithm> +#include <cstdlib> #include <wtf/CheckedArithmetic.h> #include <wtf/MathExtras.h> +#include <wtf/PrintStream.h> namespace WTF { -static int32_t greatestCommonDivisor(int32_t a, int32_t b) +static uint32_t greatestCommonDivisor(uint32_t a, uint32_t b) { // Euclid's Algorithm - int32_t temp = 0; + uint32_t temp = 0; while (b) { temp = b; b = a % b; @@ -47,17 +49,17 @@ static int32_t greatestCommonDivisor(int32_t a, int32_t b) return a; } -static int32_t leastCommonMultiple(int32_t a, int32_t b, int32_t &result) +static uint32_t leastCommonMultiple(uint32_t a, uint32_t b, uint32_t &result) { return safeMultiply(a, b / greatestCommonDivisor(a, b), result); } -static int32_t signum(int64_t val) +static int64_t signum(int64_t val) { return (0 < val) - (val < 0); } -const int32_t MediaTime::MaximumTimeScale = 0x7fffffffL; +const uint32_t MediaTime::MaximumTimeScale = 0x7fffffffL; MediaTime::MediaTime() : m_timeValue(0) @@ -66,7 +68,7 @@ MediaTime::MediaTime() { } -MediaTime::MediaTime(int64_t value, int32_t scale, uint32_t flags) +MediaTime::MediaTime(int64_t value, uint32_t scale, uint8_t flags) : m_timeValue(value) , m_timeScale(scale) , m_timeFlags(flags) @@ -82,7 +84,23 @@ MediaTime::MediaTime(const MediaTime& rhs) *this = rhs; } -MediaTime MediaTime::createWithFloat(float floatTime, int32_t timeScale) +MediaTime MediaTime::createWithFloat(float floatTime) +{ + if (floatTime != floatTime) + return invalidTime(); + if (std::isinf(floatTime)) + return std::signbit(floatTime) ? negativeInfiniteTime() : positiveInfiniteTime(); + if (floatTime > std::numeric_limits<int64_t>::max()) + return positiveInfiniteTime(); + if (floatTime < std::numeric_limits<int64_t>::min()) + return negativeInfiniteTime(); + + MediaTime value(0, DefaultTimeScale, Valid | DoubleValue); + value.m_timeValueAsDouble = floatTime; + return value; +} + +MediaTime MediaTime::createWithFloat(float floatTime, uint32_t timeScale) { if (floatTime != floatTime) return invalidTime(); @@ -98,7 +116,23 @@ MediaTime MediaTime::createWithFloat(float floatTime, int32_t timeScale) return MediaTime(static_cast<int64_t>(floatTime * timeScale), timeScale, Valid); } -MediaTime MediaTime::createWithDouble(double doubleTime, int32_t timeScale) +MediaTime MediaTime::createWithDouble(double doubleTime) +{ + if (doubleTime != doubleTime) + return invalidTime(); + if (std::isinf(doubleTime)) + return std::signbit(doubleTime) ? negativeInfiniteTime() : positiveInfiniteTime(); + if (doubleTime > std::numeric_limits<int64_t>::max()) + return positiveInfiniteTime(); + if (doubleTime < std::numeric_limits<int64_t>::min()) + return negativeInfiniteTime(); + + MediaTime value(0, DefaultTimeScale, Valid | DoubleValue); + value.m_timeValueAsDouble = doubleTime; + return value; +} + +MediaTime MediaTime::createWithDouble(double doubleTime, uint32_t timeScale) { if (doubleTime != doubleTime) return invalidTime(); @@ -111,7 +145,7 @@ MediaTime MediaTime::createWithDouble(double doubleTime, int32_t timeScale) while (doubleTime * timeScale > std::numeric_limits<int64_t>::max()) timeScale /= 2; - return MediaTime(static_cast<int64_t>(doubleTime * timeScale), timeScale, Valid); + return MediaTime(static_cast<int64_t>(std::round(doubleTime * timeScale)), timeScale, Valid); } float MediaTime::toFloat() const @@ -122,6 +156,8 @@ float MediaTime::toFloat() const 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; } @@ -133,6 +169,8 @@ double MediaTime::toDouble() const return std::numeric_limits<double>::infinity(); if (isNegativeInfinite()) return -std::numeric_limits<double>::infinity(); + if (hasDoubleValue()) + return m_timeValueAsDouble; return static_cast<double>(m_timeValue) / m_timeScale; } @@ -164,11 +202,20 @@ MediaTime MediaTime::operator+(const MediaTime& rhs) const if (isNegativeInfinite() || rhs.isNegativeInfinite()) return negativeInfiniteTime(); - int32_t commonTimeScale; - if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale) - commonTimeScale = MaximumTimeScale; + 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); + + uint32_t commonTimeScale; + if (!leastCommonMultiple(a.m_timeScale, b.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale) + commonTimeScale = MaximumTimeScale; a.setTimeScale(commonTimeScale); b.setTimeScale(commonTimeScale); while (!safeAdd(a.m_timeValue, b.m_timeValue, a.m_timeValue)) { @@ -201,11 +248,20 @@ MediaTime MediaTime::operator-(const MediaTime& rhs) const if (isNegativeInfinite() || rhs.isPositiveInfinite()) return negativeInfiniteTime(); - int32_t commonTimeScale; - if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale) - commonTimeScale = MaximumTimeScale; + 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); + + uint32_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)) { @@ -218,6 +274,28 @@ MediaTime MediaTime::operator-(const MediaTime& rhs) const return a; } +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()) @@ -243,6 +321,11 @@ MediaTime MediaTime::operator*(int32_t rhs) const 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(); @@ -252,61 +335,86 @@ MediaTime MediaTime::operator*(int32_t rhs) const return a; } -bool MediaTime::operator<(const MediaTime& rhs) const +bool MediaTime::operator!() const { - return compare(rhs) == LessThan; + return (m_timeFlags == Valid && !m_timeValue) + || (m_timeFlags == (Valid | DoubleValue) && !m_timeValueAsDouble); } -bool MediaTime::operator>(const MediaTime& rhs) const +MediaTime::operator bool() const { - return compare(rhs) == GreaterThan; + return !(m_timeFlags == Valid && !m_timeValue) + && !(m_timeFlags == (Valid | DoubleValue) && !m_timeValueAsDouble); } -bool MediaTime::operator!=(const MediaTime& rhs) const +MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const { - return compare(rhs) != EqualTo; -} + auto andFlags = m_timeFlags & rhs.m_timeFlags; + if (andFlags & (PositiveInfinite | NegativeInfinite | Indefinite)) + return EqualTo; -bool MediaTime::operator==(const MediaTime& rhs) const -{ - return compare(rhs) == EqualTo; -} + auto orFlags = m_timeFlags | rhs.m_timeFlags; + if (!(orFlags & Valid)) + return EqualTo; -bool MediaTime::operator>=(const MediaTime& rhs) const -{ - return compare(rhs) >= EqualTo; -} + if (!(andFlags & Valid)) + return isInvalid() ? GreaterThan : LessThan; -bool MediaTime::operator<=(const MediaTime& rhs) const -{ - return compare(rhs) <= EqualTo; -} + if (orFlags & NegativeInfinite) + return isNegativeInfinite() ? LessThan : GreaterThan; -MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const -{ - if ((isPositiveInfinite() && rhs.isPositiveInfinite()) - || (isNegativeInfinite() && rhs.isNegativeInfinite()) - || (isInvalid() && rhs.isInvalid()) - || (isIndefinite() && rhs.isIndefinite())) + if (orFlags & PositiveInfinite) + return isPositiveInfinite() ? GreaterThan : LessThan; + + if (orFlags & Indefinite) + return isIndefinite() ? GreaterThan : LessThan; + + if (andFlags & DoubleValue) { + if (m_timeValueAsDouble == rhs.m_timeValueAsDouble) + return EqualTo; + + return m_timeValueAsDouble < rhs.m_timeValueAsDouble ? LessThan : GreaterThan; + } + + if (orFlags & DoubleValue) { + double a = toDouble(); + double b = rhs.toDouble(); + if (a > b) + return GreaterThan; + if (a < b) + return LessThan; return EqualTo; + } - if (isInvalid()) - return GreaterThan; + if ((m_timeValue < 0) != (rhs.m_timeValue < 0)) + return m_timeValue < 0 ? LessThan : GreaterThan; - if (rhs.isInvalid()) - return LessThan; + if (!m_timeValue && !rhs.m_timeValue) + return EqualTo; - if (rhs.isNegativeInfinite() || isPositiveInfinite()) - return GreaterThan; + if (m_timeScale == rhs.m_timeScale) { + if (m_timeValue == rhs.m_timeValue) + return EqualTo; + return m_timeValue < rhs.m_timeValue ? LessThan : GreaterThan; + } - if (rhs.isPositiveInfinite() || isNegativeInfinite()) + if (m_timeValue == rhs.m_timeValue) + return m_timeScale < rhs.m_timeScale ? GreaterThan : LessThan; + + if (m_timeValue < rhs.m_timeValue && m_timeScale > rhs.m_timeScale) return LessThan; - if (isIndefinite()) + if (m_timeValue > rhs.m_timeValue && m_timeScale < rhs.m_timeScale) return GreaterThan; - if (rhs.isIndefinite()) - return LessThan; + int64_t lhsFactor; + int64_t rhsFactor; + if (safeMultiply(m_timeValue, static_cast<int64_t>(rhs.m_timeScale), lhsFactor) + && safeMultiply(rhs.m_timeValue, static_cast<int64_t>(m_timeScale), rhsFactor)) { + if (lhsFactor == rhsFactor) + return EqualTo; + return lhsFactor < rhsFactor ? LessThan : GreaterThan; + } int64_t rhsWhole = rhs.m_timeValue / rhs.m_timeScale; int64_t lhsWhole = m_timeValue / m_timeScale; @@ -317,14 +425,21 @@ MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const 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; + lhsFactor = lhsRemain * rhs.m_timeScale; + rhsFactor = rhsRemain * m_timeScale; if (lhsFactor == rhsFactor) return EqualTo; return lhsFactor > rhsFactor ? GreaterThan : LessThan; } +bool MediaTime::isBetween(const MediaTime& a, const MediaTime& b) const +{ + if (a > b) + return *this > b && *this < a; + return *this > a && *this < b; +} + const MediaTime& MediaTime::zeroTime() { static const MediaTime* time = new MediaTime(0, 1, Valid); @@ -355,8 +470,13 @@ const MediaTime& MediaTime::indefiniteTime() return *time; } -void MediaTime::setTimeScale(int32_t timeScale) +void MediaTime::setTimeScale(uint32_t timeScale) { + if (hasDoubleValue()) { + *this = MediaTime::createWithDouble(m_timeValueAsDouble, timeScale); + return; + } + if (timeScale == m_timeScale) return; timeScale = std::min(MaximumTimeScale, timeScale); @@ -366,7 +486,7 @@ void MediaTime::setTimeScale(int32_t timeScale) // timescale by two until the number will fit, and round the // result. int64_t newWholePart; - while (!safeMultiply(wholePart, timeScale, newWholePart)) + while (!safeMultiply(wholePart, static_cast<int64_t>(timeScale), newWholePart)) timeScale /= 2; int64_t remainder = m_timeValue % m_timeScale; @@ -374,14 +494,25 @@ void MediaTime::setTimeScale(int32_t timeScale) m_timeScale = timeScale; } +void MediaTime::dump(PrintStream& out) const +{ + out.print("{"); + if (!hasDoubleValue()) + out.print(m_timeValue, "/", m_timeScale, " = "); + out.print(toDouble(), "}"); +} + MediaTime abs(const MediaTime& rhs) { if (rhs.isInvalid()) return MediaTime::invalidTime(); if (rhs.isNegativeInfinite() || rhs.isPositiveInfinite()) return MediaTime::positiveInfiniteTime(); + if (rhs.hasDoubleValue()) + return MediaTime::createWithDouble(fabs(rhs.m_timeValueAsDouble)); + MediaTime val = rhs; - val.m_timeValue *= signum(rhs.m_timeScale) * signum(rhs.m_timeValue); + val.m_timeValue = std::abs(rhs.m_timeValue); return val; } |