tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

timestamp_scaler_unittest.cc (13471B)


      1 /*
      2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/audio_coding/neteq/timestamp_scaler.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <optional>
     16 #include <utility>
     17 
     18 #include "api/audio_codecs/audio_format.h"
     19 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
     20 #include "api/environment/environment.h"
     21 #include "api/environment/environment_factory.h"
     22 #include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
     23 #include "modules/audio_coding/neteq/packet.h"
     24 #include "test/gmock.h"
     25 #include "test/gtest.h"
     26 
     27 using ::testing::_;
     28 using ::testing::Return;
     29 using ::testing::ReturnNull;
     30 
     31 namespace webrtc {
     32 
     33 TEST(TimestampScaler, TestNoScaling) {
     34  const Environment env = CreateEnvironment();
     35  MockDecoderDatabase db;
     36  auto factory = CreateBuiltinAudioDecoderFactory();
     37  // Use PCMu, because it doesn't use scaled timestamps.
     38  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
     39                                          std::nullopt, factory.get());
     40  static const uint8_t kRtpPayloadType = 0;
     41  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
     42      .WillRepeatedly(Return(&info));
     43 
     44  TimestampScaler scaler(db);
     45  // Test both sides of the timestamp wrap-around.
     46  for (uint32_t timestamp = 0xFFFFFFFF - 5; timestamp != 5; ++timestamp) {
     47    // Scale to internal timestamp.
     48    EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
     49    // Scale back.
     50    EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
     51  }
     52 
     53  EXPECT_CALL(db, Die());  // Called when database object is deleted.
     54 }
     55 
     56 TEST(TimestampScaler, TestNoScalingLargeStep) {
     57  const Environment env = CreateEnvironment();
     58  MockDecoderDatabase db;
     59  auto factory = CreateBuiltinAudioDecoderFactory();
     60  // Use PCMu, because it doesn't use scaled timestamps.
     61  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
     62                                          std::nullopt, factory.get());
     63  static const uint8_t kRtpPayloadType = 0;
     64  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
     65      .WillRepeatedly(Return(&info));
     66 
     67  TimestampScaler scaler(db);
     68  // Test both sides of the timestamp wrap-around.
     69  static const uint32_t kStep = 160;
     70  uint32_t start_timestamp = 0;
     71  // `external_timestamp` will be a large positive value.
     72  start_timestamp = start_timestamp - 5 * kStep;
     73  for (uint32_t timestamp = start_timestamp; timestamp != 5 * kStep;
     74       timestamp += kStep) {
     75    // Scale to internal timestamp.
     76    EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
     77    // Scale back.
     78    EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
     79  }
     80 
     81  EXPECT_CALL(db, Die());  // Called when database object is deleted.
     82 }
     83 
     84 TEST(TimestampScaler, TestG722) {
     85  const Environment env = CreateEnvironment();
     86  MockDecoderDatabase db;
     87  auto factory = CreateBuiltinAudioDecoderFactory();
     88  // Use G722, which has a factor 2 scaling.
     89  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
     90                                          std::nullopt, factory.get());
     91  static const uint8_t kRtpPayloadType = 17;
     92  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
     93      .WillRepeatedly(Return(&info));
     94 
     95  TimestampScaler scaler(db);
     96  // Test both sides of the timestamp wrap-around.
     97  uint32_t external_timestamp = 0xFFFFFFFF - 5;
     98  uint32_t internal_timestamp = external_timestamp;
     99  for (; external_timestamp != 5; ++external_timestamp) {
    100    // Scale to internal timestamp.
    101    EXPECT_EQ(internal_timestamp,
    102              scaler.ToInternal(external_timestamp, kRtpPayloadType));
    103    // Scale back.
    104    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    105    internal_timestamp += 2;
    106  }
    107 
    108  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    109 }
    110 
    111 TEST(TimestampScaler, TestG722LargeStep) {
    112  const Environment env = CreateEnvironment();
    113  MockDecoderDatabase db;
    114  auto factory = CreateBuiltinAudioDecoderFactory();
    115  // Use G722, which has a factor 2 scaling.
    116  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
    117                                          std::nullopt, factory.get());
    118  static const uint8_t kRtpPayloadType = 17;
    119  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    120      .WillRepeatedly(Return(&info));
    121 
    122  TimestampScaler scaler(db);
    123  // Test both sides of the timestamp wrap-around.
    124  static const uint32_t kStep = 320;
    125  uint32_t external_timestamp = 0;
    126  // `external_timestamp` will be a large positive value.
    127  external_timestamp = external_timestamp - 5 * kStep;
    128  uint32_t internal_timestamp = external_timestamp;
    129  for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
    130    // Scale to internal timestamp.
    131    EXPECT_EQ(internal_timestamp,
    132              scaler.ToInternal(external_timestamp, kRtpPayloadType));
    133    // Scale back.
    134    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    135    // Internal timestamp should be incremented with twice the step.
    136    internal_timestamp += 2 * kStep;
    137  }
    138 
    139  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    140 }
    141 
    142 TEST(TimestampScaler, TestG722WithCng) {
    143  const Environment env = CreateEnvironment();
    144  MockDecoderDatabase db;
    145  auto factory = CreateBuiltinAudioDecoderFactory();
    146  // Use G722, which has a factor 2 scaling.
    147  const DecoderDatabase::DecoderInfo info_g722(
    148      env, SdpAudioFormat("g722", 8000, 1), std::nullopt, factory.get());
    149  const DecoderDatabase::DecoderInfo info_cng(
    150      env, SdpAudioFormat("cn", 16000, 1), std::nullopt, factory.get());
    151  static const uint8_t kRtpPayloadTypeG722 = 17;
    152  static const uint8_t kRtpPayloadTypeCng = 13;
    153  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeG722))
    154      .WillRepeatedly(Return(&info_g722));
    155  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeCng))
    156      .WillRepeatedly(Return(&info_cng));
    157 
    158  TimestampScaler scaler(db);
    159  // Test both sides of the timestamp wrap-around.
    160  uint32_t external_timestamp = 0xFFFFFFFF - 5;
    161  uint32_t internal_timestamp = external_timestamp;
    162  bool next_is_cng = false;
    163  for (; external_timestamp != 5; ++external_timestamp) {
    164    // Alternate between G.722 and CNG every other packet.
    165    if (next_is_cng) {
    166      // Scale to internal timestamp.
    167      EXPECT_EQ(internal_timestamp,
    168                scaler.ToInternal(external_timestamp, kRtpPayloadTypeCng));
    169      next_is_cng = false;
    170    } else {
    171      // Scale to internal timestamp.
    172      EXPECT_EQ(internal_timestamp,
    173                scaler.ToInternal(external_timestamp, kRtpPayloadTypeG722));
    174      next_is_cng = true;
    175    }
    176    // Scale back.
    177    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    178    internal_timestamp += 2;
    179  }
    180 
    181  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    182 }
    183 
    184 // Make sure that the method ToInternal(Packet* packet) is wired up correctly.
    185 // Since it is simply calling the other ToInternal method, we are not doing
    186 // as many tests here.
    187 TEST(TimestampScaler, TestG722Packet) {
    188  const Environment env = CreateEnvironment();
    189  MockDecoderDatabase db;
    190  auto factory = CreateBuiltinAudioDecoderFactory();
    191  // Use G722, which has a factor 2 scaling.
    192  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
    193                                          std::nullopt, factory.get());
    194  static const uint8_t kRtpPayloadType = 17;
    195  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    196      .WillRepeatedly(Return(&info));
    197 
    198  TimestampScaler scaler(db);
    199  // Test both sides of the timestamp wrap-around.
    200  uint32_t external_timestamp = 0xFFFFFFFF - 5;
    201  uint32_t internal_timestamp = external_timestamp;
    202  Packet packet;
    203  packet.payload_type = kRtpPayloadType;
    204  for (; external_timestamp != 5; ++external_timestamp) {
    205    packet.timestamp = external_timestamp;
    206    // Scale to internal timestamp.
    207    scaler.ToInternal(&packet);
    208    EXPECT_EQ(internal_timestamp, packet.timestamp);
    209    internal_timestamp += 2;
    210  }
    211 
    212  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    213 }
    214 
    215 // Make sure that the method ToInternal(PacketList* packet_list) is wired up
    216 // correctly. Since it is simply calling the ToInternal(Packet* packet) method,
    217 // we are not doing as many tests here.
    218 TEST(TimestampScaler, TestG722PacketList) {
    219  const Environment env = CreateEnvironment();
    220  MockDecoderDatabase db;
    221  auto factory = CreateBuiltinAudioDecoderFactory();
    222  // Use G722, which has a factor 2 scaling.
    223  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
    224                                          std::nullopt, factory.get());
    225  static const uint8_t kRtpPayloadType = 17;
    226  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    227      .WillRepeatedly(Return(&info));
    228 
    229  TimestampScaler scaler(db);
    230  // Test both sides of the timestamp wrap-around.
    231  uint32_t external_timestamp = 0xFFFFFFFF - 5;
    232  uint32_t internal_timestamp = external_timestamp;
    233  PacketList packet_list;
    234  {
    235    Packet packet1;
    236    packet1.payload_type = kRtpPayloadType;
    237    packet1.timestamp = external_timestamp;
    238    Packet packet2;
    239    packet2.payload_type = kRtpPayloadType;
    240    packet2.timestamp = external_timestamp + 10;
    241    packet_list.push_back(std::move(packet1));
    242    packet_list.push_back(std::move(packet2));
    243  }
    244 
    245  scaler.ToInternal(&packet_list);
    246  EXPECT_EQ(internal_timestamp, packet_list.front().timestamp);
    247  packet_list.pop_front();
    248  EXPECT_EQ(internal_timestamp + 20, packet_list.front().timestamp);
    249 
    250  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    251 }
    252 
    253 TEST(TimestampScaler, TestG722Reset) {
    254  const Environment env = CreateEnvironment();
    255  MockDecoderDatabase db;
    256  auto factory = CreateBuiltinAudioDecoderFactory();
    257  // Use G722, which has a factor 2 scaling.
    258  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
    259                                          std::nullopt, factory.get());
    260  static const uint8_t kRtpPayloadType = 17;
    261  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    262      .WillRepeatedly(Return(&info));
    263 
    264  TimestampScaler scaler(db);
    265  // Test both sides of the timestamp wrap-around.
    266  uint32_t external_timestamp = 0xFFFFFFFF - 5;
    267  uint32_t internal_timestamp = external_timestamp;
    268  for (; external_timestamp != 5; ++external_timestamp) {
    269    // Scale to internal timestamp.
    270    EXPECT_EQ(internal_timestamp,
    271              scaler.ToInternal(external_timestamp, kRtpPayloadType));
    272    // Scale back.
    273    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    274    internal_timestamp += 2;
    275  }
    276  // Reset the scaler. After this, we expect the internal and external to start
    277  // over at the same value again.
    278  scaler.Reset();
    279  internal_timestamp = external_timestamp;
    280  for (; external_timestamp != 15; ++external_timestamp) {
    281    // Scale to internal timestamp.
    282    EXPECT_EQ(internal_timestamp,
    283              scaler.ToInternal(external_timestamp, kRtpPayloadType));
    284    // Scale back.
    285    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    286    internal_timestamp += 2;
    287  }
    288 
    289  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    290 }
    291 
    292 // TODO(minyue): This test becomes trivial since Opus does not need a timestamp
    293 // scaler. Therefore, this test may be removed in future. There is no harm to
    294 // keep it, since it can be taken as a test case for the situation of a trivial
    295 // timestamp scaler.
    296 TEST(TimestampScaler, TestOpusLargeStep) {
    297  const Environment env = CreateEnvironment();
    298  MockDecoderDatabase db;
    299  auto factory = CreateBuiltinAudioDecoderFactory();
    300  const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("opus", 48000, 2),
    301                                          std::nullopt, factory.get());
    302  static const uint8_t kRtpPayloadType = 17;
    303  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    304      .WillRepeatedly(Return(&info));
    305 
    306  TimestampScaler scaler(db);
    307  // Test both sides of the timestamp wrap-around.
    308  static const uint32_t kStep = 960;
    309  uint32_t external_timestamp = 0;
    310  // `external_timestamp` will be a large positive value.
    311  external_timestamp = external_timestamp - 5 * kStep;
    312  uint32_t internal_timestamp = external_timestamp;
    313  for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
    314    // Scale to internal timestamp.
    315    EXPECT_EQ(internal_timestamp,
    316              scaler.ToInternal(external_timestamp, kRtpPayloadType));
    317    // Scale back.
    318    EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    319    internal_timestamp += kStep;
    320  }
    321 
    322  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    323 }
    324 
    325 TEST(TimestampScaler, Failures) {
    326  static const uint8_t kRtpPayloadType = 17;
    327  MockDecoderDatabase db;
    328  EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    329      .WillOnce(ReturnNull());  // Return NULL to indicate unknown payload type.
    330 
    331  TimestampScaler scaler(db);
    332  uint32_t timestamp = 4711;  // Some number.
    333  EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
    334 
    335  Packet* packet = nullptr;
    336  scaler.ToInternal(packet);  // Should not crash. That's all we can test.
    337 
    338  EXPECT_CALL(db, Die());  // Called when database object is deleted.
    339 }
    340 
    341 }  // namespace webrtc