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