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 "gmock/gmock.h"
     14 #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 TEST(TimestampScaler, TestOpusLargeStep) {
    256   MockDecoderDatabase db;
    257   DecoderDatabase::DecoderInfo info;
    258   info.codec_type = kDecoderOpus;  // Uses a factor 2/3 scaling.
    259   static const uint8_t kRtpPayloadType = 17;
    260   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    261       .WillRepeatedly(Return(&info));
    262 
    263   TimestampScaler scaler(db);
    264   // Test both sides of the timestamp wrap-around.
    265   static const uint32_t kStep = 960;
    266   uint32_t external_timestamp = 0;
    267   // |external_timestamp| will be a large positive value.
    268   external_timestamp = external_timestamp - 5 * kStep;
    269   uint32_t internal_timestamp = external_timestamp;
    270   for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
    271     // Scale to internal timestamp.
    272     EXPECT_EQ(internal_timestamp,
    273               scaler.ToInternal(external_timestamp, kRtpPayloadType));
    274     // Scale back.
    275     EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    276     // Internal timestamp should be incremented with twice the step.
    277     internal_timestamp += 2 * kStep / 3;
    278   }
    279 
    280   EXPECT_CALL(db, Die());  // Called when database object is deleted.
    281 }
    282 
    283 TEST(TimestampScaler, TestIsacFbLargeStep) {
    284   MockDecoderDatabase db;
    285   DecoderDatabase::DecoderInfo info;
    286   info.codec_type = kDecoderISACfb;  // Uses a factor 2/3 scaling.
    287   static const uint8_t kRtpPayloadType = 17;
    288   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    289       .WillRepeatedly(Return(&info));
    290 
    291   TimestampScaler scaler(db);
    292   // Test both sides of the timestamp wrap-around.
    293   static const uint32_t kStep = 960;
    294   uint32_t external_timestamp = 0;
    295   // |external_timestamp| will be a large positive value.
    296   external_timestamp = external_timestamp - 5 * kStep;
    297   uint32_t internal_timestamp = external_timestamp;
    298   for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
    299     // Scale to internal timestamp.
    300     EXPECT_EQ(internal_timestamp,
    301               scaler.ToInternal(external_timestamp, kRtpPayloadType));
    302     // Scale back.
    303     EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
    304     // Internal timestamp should be incremented with twice the step.
    305     internal_timestamp += 2 * kStep / 3;
    306   }
    307 
    308   EXPECT_CALL(db, Die());  // Called when database object is deleted.
    309 }
    310 
    311 TEST(TimestampScaler, Failures) {
    312   static const uint8_t kRtpPayloadType = 17;
    313   MockDecoderDatabase db;
    314   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
    315       .WillOnce(ReturnNull());  // Return NULL to indicate unknown payload type.
    316 
    317   TimestampScaler scaler(db);
    318   uint32_t timestamp = 4711;  // Some number.
    319   EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
    320 
    321   Packet* packet = NULL;
    322   scaler.ToInternal(packet);  // Should not crash. That's all we can test.
    323 
    324   EXPECT_CALL(db, Die());  // Called when database object is deleted.
    325 }
    326 
    327 }  // namespace webrtc
    328