Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}