blob: eeaf772b4e53933ae67090890acf66a2b83aeb87 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "api/audio_codecs/builtin_audio_decoder_factory.h"
12#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
13#include "modules/audio_coding/neteq/packet.h"
14#include "modules/audio_coding/neteq/timestamp_scaler.h"
15#include "test/gmock.h"
16#include "test/gtest.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000017
18using ::testing::Return;
19using ::testing::ReturnNull;
20using ::testing::_;
21
22namespace webrtc {
23
24TEST(TimestampScaler, TestNoScaling) {
25 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070026 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070027 // Use PCMu, because it doesn't use scaled timestamps.
Karl Wiberg08126342018-03-20 19:18:55 +010028 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +020029 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000030 static const uint8_t kRtpPayloadType = 0;
31 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
32 .WillRepeatedly(Return(&info));
33
34 TimestampScaler scaler(db);
35 // Test both sides of the timestamp wrap-around.
36 for (uint32_t timestamp = 0xFFFFFFFF - 5; timestamp != 5; ++timestamp) {
37 // Scale to internal timestamp.
38 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
39 // Scale back.
40 EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
41 }
42
43 EXPECT_CALL(db, Die()); // Called when database object is deleted.
44}
45
46TEST(TimestampScaler, TestNoScalingLargeStep) {
47 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070048 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070049 // Use PCMu, because it doesn't use scaled timestamps.
Karl Wiberg08126342018-03-20 19:18:55 +010050 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +020051 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000052 static const uint8_t kRtpPayloadType = 0;
53 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
54 .WillRepeatedly(Return(&info));
55
56 TimestampScaler scaler(db);
57 // Test both sides of the timestamp wrap-around.
58 static const uint32_t kStep = 160;
59 uint32_t start_timestamp = 0;
60 // |external_timestamp| will be a large positive value.
61 start_timestamp = start_timestamp - 5 * kStep;
62 for (uint32_t timestamp = start_timestamp; timestamp != 5 * kStep;
63 timestamp += kStep) {
64 // Scale to internal timestamp.
65 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
66 // Scale back.
67 EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
68 }
69
70 EXPECT_CALL(db, Die()); // Called when database object is deleted.
71}
72
73TEST(TimestampScaler, TestG722) {
74 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070075 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070076 // Use G722, which has a factor 2 scaling.
Karl Wiberg08126342018-03-20 19:18:55 +010077 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +020078 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000079 static const uint8_t kRtpPayloadType = 17;
80 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
81 .WillRepeatedly(Return(&info));
82
83 TimestampScaler scaler(db);
84 // Test both sides of the timestamp wrap-around.
85 uint32_t external_timestamp = 0xFFFFFFFF - 5;
86 uint32_t internal_timestamp = external_timestamp;
87 for (; external_timestamp != 5; ++external_timestamp) {
88 // Scale to internal timestamp.
89 EXPECT_EQ(internal_timestamp,
90 scaler.ToInternal(external_timestamp, kRtpPayloadType));
91 // Scale back.
92 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
93 internal_timestamp += 2;
94 }
95
96 EXPECT_CALL(db, Die()); // Called when database object is deleted.
97}
98
99TEST(TimestampScaler, TestG722LargeStep) {
100 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700101 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700102 // Use G722, which has a factor 2 scaling.
Karl Wiberg08126342018-03-20 19:18:55 +0100103 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200104 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000105 static const uint8_t kRtpPayloadType = 17;
106 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
107 .WillRepeatedly(Return(&info));
108
109 TimestampScaler scaler(db);
110 // Test both sides of the timestamp wrap-around.
111 static const uint32_t kStep = 320;
112 uint32_t external_timestamp = 0;
113 // |external_timestamp| will be a large positive value.
114 external_timestamp = external_timestamp - 5 * kStep;
115 uint32_t internal_timestamp = external_timestamp;
116 for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
117 // Scale to internal timestamp.
118 EXPECT_EQ(internal_timestamp,
119 scaler.ToInternal(external_timestamp, kRtpPayloadType));
120 // Scale back.
121 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
122 // Internal timestamp should be incremented with twice the step.
123 internal_timestamp += 2 * kStep;
124 }
125
126 EXPECT_CALL(db, Die()); // Called when database object is deleted.
127}
128
129TEST(TimestampScaler, TestG722WithCng) {
130 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700131 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700132 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700133 const DecoderDatabase::DecoderInfo info_g722(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200134 absl::nullopt, factory);
ossuf1b08da2016-09-23 02:19:43 -0700135 const DecoderDatabase::DecoderInfo info_cng(NetEqDecoder::kDecoderCNGwb,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200136 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000137 static const uint8_t kRtpPayloadTypeG722 = 17;
138 static const uint8_t kRtpPayloadTypeCng = 13;
139 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeG722))
140 .WillRepeatedly(Return(&info_g722));
141 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeCng))
142 .WillRepeatedly(Return(&info_cng));
143
144 TimestampScaler scaler(db);
145 // Test both sides of the timestamp wrap-around.
146 uint32_t external_timestamp = 0xFFFFFFFF - 5;
147 uint32_t internal_timestamp = external_timestamp;
148 bool next_is_cng = false;
149 for (; external_timestamp != 5; ++external_timestamp) {
150 // Alternate between G.722 and CNG every other packet.
151 if (next_is_cng) {
152 // Scale to internal timestamp.
153 EXPECT_EQ(internal_timestamp,
154 scaler.ToInternal(external_timestamp, kRtpPayloadTypeCng));
155 next_is_cng = false;
156 } else {
157 // Scale to internal timestamp.
158 EXPECT_EQ(internal_timestamp,
159 scaler.ToInternal(external_timestamp, kRtpPayloadTypeG722));
160 next_is_cng = true;
161 }
162 // Scale back.
163 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
164 internal_timestamp += 2;
165 }
166
167 EXPECT_CALL(db, Die()); // Called when database object is deleted.
168}
169
170// Make sure that the method ToInternal(Packet* packet) is wired up correctly.
171// Since it is simply calling the other ToInternal method, we are not doing
172// as many tests here.
173TEST(TimestampScaler, TestG722Packet) {
174 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700175 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700176 // Use G722, which has a factor 2 scaling.
Karl Wiberg08126342018-03-20 19:18:55 +0100177 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200178 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000179 static const uint8_t kRtpPayloadType = 17;
180 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
181 .WillRepeatedly(Return(&info));
182
183 TimestampScaler scaler(db);
184 // Test both sides of the timestamp wrap-around.
185 uint32_t external_timestamp = 0xFFFFFFFF - 5;
186 uint32_t internal_timestamp = external_timestamp;
187 Packet packet;
ossu7a377612016-10-18 04:06:13 -0700188 packet.payload_type = kRtpPayloadType;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000189 for (; external_timestamp != 5; ++external_timestamp) {
ossu7a377612016-10-18 04:06:13 -0700190 packet.timestamp = external_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000191 // Scale to internal timestamp.
192 scaler.ToInternal(&packet);
ossu7a377612016-10-18 04:06:13 -0700193 EXPECT_EQ(internal_timestamp, packet.timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000194 internal_timestamp += 2;
195 }
196
197 EXPECT_CALL(db, Die()); // Called when database object is deleted.
198}
199
200// Make sure that the method ToInternal(PacketList* packet_list) is wired up
201// correctly. Since it is simply calling the ToInternal(Packet* packet) method,
202// we are not doing as many tests here.
203TEST(TimestampScaler, TestG722PacketList) {
204 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700205 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700206 // Use G722, which has a factor 2 scaling.
Karl Wiberg08126342018-03-20 19:18:55 +0100207 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200208 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000209 static const uint8_t kRtpPayloadType = 17;
210 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
211 .WillRepeatedly(Return(&info));
212
213 TimestampScaler scaler(db);
214 // Test both sides of the timestamp wrap-around.
215 uint32_t external_timestamp = 0xFFFFFFFF - 5;
216 uint32_t internal_timestamp = external_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000217 PacketList packet_list;
ossua73f6c92016-10-24 08:25:28 -0700218 {
219 Packet packet1;
220 packet1.payload_type = kRtpPayloadType;
221 packet1.timestamp = external_timestamp;
222 Packet packet2;
223 packet2.payload_type = kRtpPayloadType;
224 packet2.timestamp = external_timestamp + 10;
225 packet_list.push_back(std::move(packet1));
226 packet_list.push_back(std::move(packet2));
227 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000228
229 scaler.ToInternal(&packet_list);
ossua73f6c92016-10-24 08:25:28 -0700230 EXPECT_EQ(internal_timestamp, packet_list.front().timestamp);
231 packet_list.pop_front();
232 EXPECT_EQ(internal_timestamp + 20, packet_list.front().timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000233
234 EXPECT_CALL(db, Die()); // Called when database object is deleted.
235}
236
237TEST(TimestampScaler, TestG722Reset) {
238 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700239 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700240 // Use G722, which has a factor 2 scaling.
Karl Wiberg08126342018-03-20 19:18:55 +0100241 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200242 absl::nullopt, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000243 static const uint8_t kRtpPayloadType = 17;
244 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
245 .WillRepeatedly(Return(&info));
246
247 TimestampScaler scaler(db);
248 // Test both sides of the timestamp wrap-around.
249 uint32_t external_timestamp = 0xFFFFFFFF - 5;
250 uint32_t internal_timestamp = external_timestamp;
251 for (; external_timestamp != 5; ++external_timestamp) {
252 // Scale to internal timestamp.
253 EXPECT_EQ(internal_timestamp,
254 scaler.ToInternal(external_timestamp, kRtpPayloadType));
255 // Scale back.
256 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
257 internal_timestamp += 2;
258 }
259 // Reset the scaler. After this, we expect the internal and external to start
260 // over at the same value again.
261 scaler.Reset();
262 internal_timestamp = external_timestamp;
263 for (; external_timestamp != 15; ++external_timestamp) {
264 // Scale to internal timestamp.
265 EXPECT_EQ(internal_timestamp,
266 scaler.ToInternal(external_timestamp, kRtpPayloadType));
267 // Scale back.
268 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
269 internal_timestamp += 2;
270 }
271
272 EXPECT_CALL(db, Die()); // Called when database object is deleted.
273}
274
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000275// TODO(minyue): This test becomes trivial since Opus does not need a timestamp
276// scaler. Therefore, this test may be removed in future. There is no harm to
277// keep it, since it can be taken as a test case for the situation of a trivial
278// timestamp scaler.
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000279TEST(TimestampScaler, TestOpusLargeStep) {
280 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700281 auto factory = CreateBuiltinAudioDecoderFactory();
Karl Wiberg08126342018-03-20 19:18:55 +0100282 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderOpus,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200283 absl::nullopt, factory);
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000284 static const uint8_t kRtpPayloadType = 17;
285 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
286 .WillRepeatedly(Return(&info));
287
288 TimestampScaler scaler(db);
289 // Test both sides of the timestamp wrap-around.
290 static const uint32_t kStep = 960;
291 uint32_t external_timestamp = 0;
292 // |external_timestamp| will be a large positive value.
293 external_timestamp = external_timestamp - 5 * kStep;
294 uint32_t internal_timestamp = external_timestamp;
295 for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
296 // Scale to internal timestamp.
297 EXPECT_EQ(internal_timestamp,
298 scaler.ToInternal(external_timestamp, kRtpPayloadType));
299 // Scale back.
300 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000301 internal_timestamp += kStep;
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000302 }
303
304 EXPECT_CALL(db, Die()); // Called when database object is deleted.
305}
306
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000307TEST(TimestampScaler, Failures) {
308 static const uint8_t kRtpPayloadType = 17;
309 MockDecoderDatabase db;
310 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
311 .WillOnce(ReturnNull()); // Return NULL to indicate unknown payload type.
312
313 TimestampScaler scaler(db);
314 uint32_t timestamp = 4711; // Some number.
315 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
316
317 Packet* packet = NULL;
318 scaler.ToInternal(packet); // Should not crash. That's all we can test.
319
320 EXPECT_CALL(db, Die()); // Called when database object is deleted.
321}
322
323} // namespace webrtc