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