Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/gtest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  TestTimeUnit.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "gtest/gtest.h"
#include <algorithm>
#include <vector>

#include "TimeUnits.h"

using namespace mozilla;
using namespace mozilla::media;
using TimeUnit = mozilla::media::TimeUnit;

TEST(TimeUnit, BasicArithmetic)
{
  const TimeUnit a(1000, 44100);
  {
    TimeUnit b = a * 10;
    EXPECT_EQ(b.mBase, 44100);
    EXPECT_EQ(b.mTicks.value(), a.mTicks.value() * 10);
    EXPECT_EQ(a * 10, b);
  }
  {
    TimeUnit b = a / 10;
    EXPECT_EQ(b.mBase, 44100);
    EXPECT_EQ(b.mTicks.value(), a.mTicks.value() / 10);
    EXPECT_EQ(a / 10, b);
  }
  {
    TimeUnit b = TimeUnit(10, 44100);
    b += a;
    EXPECT_EQ(b.mBase, 44100);
    EXPECT_EQ(b.mTicks.value(), a.mTicks.value() + 10);
    EXPECT_EQ(b - a, TimeUnit(10, 44100));
  }
  {
    TimeUnit b = TimeUnit(1010, 44100);
    b -= a;  // now 10
    EXPECT_EQ(b.mBase, 44100);
    EXPECT_EQ(b.mTicks.value(), 10);
    EXPECT_EQ(a + b, TimeUnit(1010, 44100));
  }
  {
    TimeUnit b = TimeUnit(4010, 44100);
    TimeUnit c = b % a;  // now 10
    EXPECT_EQ(c.mBase, 44100);
    EXPECT_EQ(c.mTicks.value(), 10);
  }
  {
    // Adding 6s in nanoseconds (e.g. coming from script) to a typical number
    // from an mp4, 9001 in base 90000
    TimeUnit b = TimeUnit(6000000000, 1000000000);
    TimeUnit c = TimeUnit(9001, 90000);
    TimeUnit d = c + b;
    EXPECT_EQ(d.mBase, 90000);
    EXPECT_EQ(d.mTicks.value(), 549001);
  }
  {
    // Subtracting 9001 in base 9000 from 6s in nanoseconds (e.g. coming from
    // script), converting to back to base 9000.
    TimeUnit b = TimeUnit(6000000000, 1000000000);
    TimeUnit c = TimeUnit(9001, 90000);
    TimeUnit d = (b - c).ToBase(90000);
    EXPECT_EQ(d.mBase, 90000);
    EXPECT_EQ(d.mTicks.value(), 530999);
  }
}

TEST(TimeUnit, Base)
{
  {
    TimeUnit a = TimeUnit::FromSeconds(1);
    EXPECT_EQ(a.mTicks.value(), 1000000);
    EXPECT_EQ(a.mBase, 1000000);
  }
  {
    TimeUnit a = TimeUnit::FromMicroseconds(44100000000);
    EXPECT_EQ(a.mTicks.value(), 44100000000);
    EXPECT_EQ(a.mBase, 1000000);
  }
  {
    TimeUnit a = TimeUnit::FromSeconds(6.0);
    EXPECT_EQ(a.mTicks.value(), 6000000);
    EXPECT_EQ(a.mBase, 1000000);
    double error;
    TimeUnit b = a.ToBase(90000, error);
    EXPECT_EQ(error, 0);
    EXPECT_EQ(b.mTicks.value(), 540000);
    EXPECT_EQ(b.mBase, 90000);
  }
}

TEST(TimeUnit, Rounding)
{
  int64_t usecs = 662617;
  double seconds = TimeUnit::FromMicroseconds(usecs).ToSeconds();
  TimeUnit fromSeconds = TimeUnit::FromSeconds(seconds);
  EXPECT_EQ(fromSeconds.mTicks.value(), usecs);
  // TimeUnit base is microseconds if not explicitly passed.
  EXPECT_EQ(fromSeconds.mBase, 1000000);
  EXPECT_EQ(fromSeconds.ToMicroseconds(), usecs);

  seconds = 4.169470123;
  int64_t nsecs = 4169470123;
  EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToNanoseconds(), nsecs);
  EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToMicroseconds(), nsecs / 1000);

  seconds = 2312312.16947012;
  nsecs = 2312312169470120;
  EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToNanoseconds(), nsecs);
  EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToMicroseconds(), nsecs / 1000);

  seconds = 2312312.169470123;
  nsecs = 2312312169470123;
  // A double doesn't have enough precision to roundtrip this time value
  // correctly in this base, but the number of microseconds is still correct.
  // This value is about 142.5 days however.
  // This particular calculation results in exactly 1ns of difference after
  // roundtrip. Enable this after remoing the MOZ_CRASH in TimeUnit::FromSeconds
  // EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToNanoseconds() - nsecs, 1);
  EXPECT_EQ(TimeUnit::FromSeconds(seconds, 1e9).ToMicroseconds(), nsecs / 1000);
}

TEST(TimeUnit, Comparisons)
{
  TimeUnit a(0, 1e9);
  TimeUnit b(1, 1e9);
  TimeUnit c(1, 1e6);

  EXPECT_GE(b, a);
  EXPECT_GE(c, a);
  EXPECT_GE(c, b);

  EXPECT_GT(b, a);
  EXPECT_GT(c, a);
  EXPECT_GT(c, b);

  EXPECT_LE(a, b);
  EXPECT_LE(a, c);
  EXPECT_LE(b, c);

  EXPECT_LT(a, b);
  EXPECT_LT(a, c);
  EXPECT_LT(b, c);

  // Equivalence of zero regardless of the base
  TimeUnit d(0, 1);
  TimeUnit e(0, 1000);
  EXPECT_EQ(a, d);
  EXPECT_EQ(a, e);

  // Equivalence of time accross bases
  TimeUnit f(1000, 1e9);
  TimeUnit g(1, 1e6);
  EXPECT_EQ(f, g);

  // Comparisons with infinity, same base
  TimeUnit h = TimeUnit::FromInfinity();
  TimeUnit i = TimeUnit::Zero();
  EXPECT_LE(i, h);
  EXPECT_LT(i, h);
  EXPECT_GE(h, i);
  EXPECT_GT(h, i);

  // Comparisons with infinity, different base
  TimeUnit j = TimeUnit::FromInfinity();
  TimeUnit k = TimeUnit::Zero(1000000);
  EXPECT_LE(k, j);
  EXPECT_LT(k, j);
  EXPECT_GE(j, k);
  EXPECT_GT(j, k);

  // Comparison of very big numbers, different base that have a gcd that makes
  // it easy to reduce, to test the fraction reduction code
  TimeUnit l = TimeUnit(123123120000000, 1000000000);
  TimeUnit m = TimeUnit(123123120000000, 1000);
  EXPECT_LE(l, m);
  EXPECT_LT(l, m);
  EXPECT_GE(m, l);
  EXPECT_GT(m, l);

  // Comparison of very big numbers, different base that are co-prime: worst
  // cast scenario.
  TimeUnit n = TimeUnit(123123123123123, 1000000000);
  TimeUnit o = TimeUnit(123123123123123, 1000000001);
  EXPECT_LE(o, n);
  EXPECT_LT(o, n);
  EXPECT_GE(n, o);
  EXPECT_GT(n, o);
  // Comparison of very big numbers with different bases
  TimeUnit p(12312312312312312, 100000000);
  TimeUnit q(123123123123123119, 1000000000);
  TimeUnit r(123123123123123120, 1000000000);
  TimeUnit s(123123123123123121, 1000000000);
  EXPECT_LE(q, p);
  EXPECT_LT(q, p);
  EXPECT_NE(q, p);
  EXPECT_EQ(p, r);
  EXPECT_GE(s, p);
  EXPECT_GT(s, p);
  EXPECT_NE(s, p);
  // Comparison of different very big numbers.  There is intentionally only
  // one factor of 3 in numerator or denominator to reproduce bug 1909614.
  TimeUnit t = TimeUnit(123123123123124, 100000000 * 3);
  TimeUnit u = TimeUnit(123123123123124 * 3, 100000000);
  EXPECT_NE(t, u);

  // Values taken from a real website (this is about 53 years, Date.now() in
  // 2023).
  TimeUnit leftBound(74332508253360, 44100);
  TimeUnit rightBound(74332508297392, 44100);
  TimeUnit fuzz(250000, 1000000);
  TimeUnit time(1685544404790205, 1000000);

  EXPECT_LT(leftBound - fuzz, time);
  EXPECT_GT(time, leftBound - fuzz);
  EXPECT_GE(rightBound + fuzz, time);
  EXPECT_LT(time, rightBound + fuzz);

  TimeUnit zero = TimeUnit::Zero();  // default base 1e6
  TimeUnit datenow(
      151737439364679,
      90000);  // Also from `Date.now()` in a common base for an mp4
  EXPECT_NE(zero, datenow);
}

TEST(TimeUnit, InfinityMath)
{
  // Operator plus/minus uses floating point behaviour for positive and
  // negative infinity values, i.e.:
  //  posInf + posInf = inf
  //  posInf + negInf = -nan
  //  posInf + finite = inf
  //  posInf - posInf = -nan
  //  posInf - negInf = inf
  //  posInf - finite = inf
  //  negInf + negInf = -inf
  //  negInf + posInf = -nan
  //  negInf + finite = -inf
  //  negInf - negInf = -nan
  //  negInf - posInf = -inf
  //  negInf - finite = -inf
  //  finite + posInf = inf
  //  finite - posInf = -inf
  //  finite + negInf = -inf
  //  finite - negInf = inf

  const TimeUnit posInf = TimeUnit::FromInfinity();
  EXPECT_EQ(TimeUnit::FromSeconds(mozilla::PositiveInfinity<double>()), posInf);

  const TimeUnit negInf = TimeUnit::FromNegativeInfinity();
  EXPECT_EQ(TimeUnit::FromSeconds(mozilla::NegativeInfinity<double>()), negInf);

  EXPECT_EQ(posInf + posInf, posInf);
  EXPECT_FALSE((posInf + negInf).IsValid());
  EXPECT_FALSE((posInf - posInf).IsValid());
  EXPECT_EQ(posInf - negInf, posInf);
  EXPECT_EQ(negInf + negInf, negInf);
  EXPECT_FALSE((negInf + posInf).IsValid());
  EXPECT_FALSE((negInf - negInf).IsValid());
  EXPECT_EQ(negInf - posInf, negInf);

  const TimeUnit finite = TimeUnit::FromSeconds(42.0);
  EXPECT_EQ(posInf - finite, posInf);
  EXPECT_EQ(posInf + finite, posInf);
  EXPECT_EQ(negInf - finite, negInf);
  EXPECT_EQ(negInf + finite, negInf);

  EXPECT_EQ(finite + posInf, posInf);
  EXPECT_EQ(finite - posInf, negInf);
  EXPECT_EQ(finite + negInf, negInf);
  EXPECT_EQ(finite - negInf, posInf);
}

TEST(TimeUnit, BaseConversion)
{
  const int64_t packetSize = 1024;  // typical for AAC
  int64_t sampleRates[] = {16000, 44100, 48000, 88200, 96000};
  const double hnsPerSeconds = 10000000.;
  for (auto sampleRate : sampleRates) {
    int64_t frameCount = 0;
    TimeUnit pts;
    do {
      // Compute a time in hundreds of nanoseconds based of frame count, typical
      // on Windows platform, checking that it round trips properly.
      int64_t hns = AssertedCast<int64_t>(
          std::round(hnsPerSeconds * static_cast<double>(frameCount) /
                     static_cast<double>(sampleRate)));
      pts = TimeUnit::FromHns(hns, sampleRate);
      EXPECT_EQ(
          AssertedCast<int64_t>(std::round(pts.ToSeconds() * hnsPerSeconds)),
          hns);
      frameCount += packetSize;
    } while (pts.ToSeconds() < 36000);
  }
}

TEST(TimeUnit, MinimumRoundingError)
{
  TimeUnit a(448, 48000);  // ≈9333 us
  TimeUnit b(1, 1000000);  // 1 us
  TimeUnit rv = a - b;     // should close to 9332 us as much as possible
  EXPECT_EQ(rv.mTicks.value(), 448);  // ≈9333 us is closer to 9332 us
  EXPECT_EQ(rv.mBase, 48000);

  TimeUnit c(11, 1000000);  // 11 us
  rv = a - c;               // should close to 9322 as much as possible
  EXPECT_EQ(rv.mTicks.value(), 447);  // ≈9312 us is closer to 9322 us
  EXPECT_EQ(rv.mBase, 48000);
}

Messung V0.5
C=91 H=91 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.