blob: b3c1bb0ee0069d62508bc35b74f17bf48e495566 [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.
ossuf1b08da2016-09-23 02:19:43 -070028 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000029 static const uint8_t kRtpPayloadType = 0;
30 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
31 .WillRepeatedly(Return(&info));
32
33 TimestampScaler scaler(db);
34 // Test both sides of the timestamp wrap-around.
35 for (uint32_t timestamp = 0xFFFFFFFF - 5; timestamp != 5; ++timestamp) {
36 // Scale to internal timestamp.
37 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
38 // Scale back.
39 EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
40 }
41
42 EXPECT_CALL(db, Die()); // Called when database object is deleted.
43}
44
45TEST(TimestampScaler, TestNoScalingLargeStep) {
46 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070047 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070048 // Use PCMu, because it doesn't use scaled timestamps.
ossuf1b08da2016-09-23 02:19:43 -070049 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000050 static const uint8_t kRtpPayloadType = 0;
51 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
52 .WillRepeatedly(Return(&info));
53
54 TimestampScaler scaler(db);
55 // Test both sides of the timestamp wrap-around.
56 static const uint32_t kStep = 160;
57 uint32_t start_timestamp = 0;
58 // |external_timestamp| will be a large positive value.
59 start_timestamp = start_timestamp - 5 * kStep;
60 for (uint32_t timestamp = start_timestamp; timestamp != 5 * kStep;
61 timestamp += kStep) {
62 // Scale to internal timestamp.
63 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
64 // Scale back.
65 EXPECT_EQ(timestamp, scaler.ToExternal(timestamp));
66 }
67
68 EXPECT_CALL(db, Die()); // Called when database object is deleted.
69}
70
71TEST(TimestampScaler, TestG722) {
72 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070073 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070074 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -070075 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000076 static const uint8_t kRtpPayloadType = 17;
77 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
78 .WillRepeatedly(Return(&info));
79
80 TimestampScaler scaler(db);
81 // Test both sides of the timestamp wrap-around.
82 uint32_t external_timestamp = 0xFFFFFFFF - 5;
83 uint32_t internal_timestamp = external_timestamp;
84 for (; external_timestamp != 5; ++external_timestamp) {
85 // Scale to internal timestamp.
86 EXPECT_EQ(internal_timestamp,
87 scaler.ToInternal(external_timestamp, kRtpPayloadType));
88 // Scale back.
89 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
90 internal_timestamp += 2;
91 }
92
93 EXPECT_CALL(db, Die()); // Called when database object is deleted.
94}
95
96TEST(TimestampScaler, TestG722LargeStep) {
97 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -070098 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -070099 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700100 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000101 static const uint8_t kRtpPayloadType = 17;
102 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
103 .WillRepeatedly(Return(&info));
104
105 TimestampScaler scaler(db);
106 // Test both sides of the timestamp wrap-around.
107 static const uint32_t kStep = 320;
108 uint32_t external_timestamp = 0;
109 // |external_timestamp| will be a large positive value.
110 external_timestamp = external_timestamp - 5 * kStep;
111 uint32_t internal_timestamp = external_timestamp;
112 for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
113 // Scale to internal timestamp.
114 EXPECT_EQ(internal_timestamp,
115 scaler.ToInternal(external_timestamp, kRtpPayloadType));
116 // Scale back.
117 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
118 // Internal timestamp should be incremented with twice the step.
119 internal_timestamp += 2 * kStep;
120 }
121
122 EXPECT_CALL(db, Die()); // Called when database object is deleted.
123}
124
125TEST(TimestampScaler, TestG722WithCng) {
126 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700127 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700128 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700129 const DecoderDatabase::DecoderInfo info_g722(NetEqDecoder::kDecoderG722,
ossu09f15602016-08-29 03:59:05 -0700130 factory);
ossuf1b08da2016-09-23 02:19:43 -0700131 const DecoderDatabase::DecoderInfo info_cng(NetEqDecoder::kDecoderCNGwb,
ossu09f15602016-08-29 03:59:05 -0700132 factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000133 static const uint8_t kRtpPayloadTypeG722 = 17;
134 static const uint8_t kRtpPayloadTypeCng = 13;
135 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeG722))
136 .WillRepeatedly(Return(&info_g722));
137 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeCng))
138 .WillRepeatedly(Return(&info_cng));
139
140 TimestampScaler scaler(db);
141 // Test both sides of the timestamp wrap-around.
142 uint32_t external_timestamp = 0xFFFFFFFF - 5;
143 uint32_t internal_timestamp = external_timestamp;
144 bool next_is_cng = false;
145 for (; external_timestamp != 5; ++external_timestamp) {
146 // Alternate between G.722 and CNG every other packet.
147 if (next_is_cng) {
148 // Scale to internal timestamp.
149 EXPECT_EQ(internal_timestamp,
150 scaler.ToInternal(external_timestamp, kRtpPayloadTypeCng));
151 next_is_cng = false;
152 } else {
153 // Scale to internal timestamp.
154 EXPECT_EQ(internal_timestamp,
155 scaler.ToInternal(external_timestamp, kRtpPayloadTypeG722));
156 next_is_cng = true;
157 }
158 // Scale back.
159 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
160 internal_timestamp += 2;
161 }
162
163 EXPECT_CALL(db, Die()); // Called when database object is deleted.
164}
165
166// Make sure that the method ToInternal(Packet* packet) is wired up correctly.
167// Since it is simply calling the other ToInternal method, we are not doing
168// as many tests here.
169TEST(TimestampScaler, TestG722Packet) {
170 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700171 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700172 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700173 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000174 static const uint8_t kRtpPayloadType = 17;
175 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
176 .WillRepeatedly(Return(&info));
177
178 TimestampScaler scaler(db);
179 // Test both sides of the timestamp wrap-around.
180 uint32_t external_timestamp = 0xFFFFFFFF - 5;
181 uint32_t internal_timestamp = external_timestamp;
182 Packet packet;
ossu7a377612016-10-18 04:06:13 -0700183 packet.payload_type = kRtpPayloadType;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000184 for (; external_timestamp != 5; ++external_timestamp) {
ossu7a377612016-10-18 04:06:13 -0700185 packet.timestamp = external_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000186 // Scale to internal timestamp.
187 scaler.ToInternal(&packet);
ossu7a377612016-10-18 04:06:13 -0700188 EXPECT_EQ(internal_timestamp, packet.timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000189 internal_timestamp += 2;
190 }
191
192 EXPECT_CALL(db, Die()); // Called when database object is deleted.
193}
194
195// Make sure that the method ToInternal(PacketList* packet_list) is wired up
196// correctly. Since it is simply calling the ToInternal(Packet* packet) method,
197// we are not doing as many tests here.
198TEST(TimestampScaler, TestG722PacketList) {
199 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700200 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700201 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700202 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000203 static const uint8_t kRtpPayloadType = 17;
204 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
205 .WillRepeatedly(Return(&info));
206
207 TimestampScaler scaler(db);
208 // Test both sides of the timestamp wrap-around.
209 uint32_t external_timestamp = 0xFFFFFFFF - 5;
210 uint32_t internal_timestamp = external_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000211 PacketList packet_list;
ossua73f6c92016-10-24 08:25:28 -0700212 {
213 Packet packet1;
214 packet1.payload_type = kRtpPayloadType;
215 packet1.timestamp = external_timestamp;
216 Packet packet2;
217 packet2.payload_type = kRtpPayloadType;
218 packet2.timestamp = external_timestamp + 10;
219 packet_list.push_back(std::move(packet1));
220 packet_list.push_back(std::move(packet2));
221 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000222
223 scaler.ToInternal(&packet_list);
ossua73f6c92016-10-24 08:25:28 -0700224 EXPECT_EQ(internal_timestamp, packet_list.front().timestamp);
225 packet_list.pop_front();
226 EXPECT_EQ(internal_timestamp + 20, packet_list.front().timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000227
228 EXPECT_CALL(db, Die()); // Called when database object is deleted.
229}
230
231TEST(TimestampScaler, TestG722Reset) {
232 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700233 auto factory = CreateBuiltinAudioDecoderFactory();
kwiberg0fa0a972016-04-19 05:03:45 -0700234 // Use G722, which has a factor 2 scaling.
ossuf1b08da2016-09-23 02:19:43 -0700235 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000236 static const uint8_t kRtpPayloadType = 17;
237 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
238 .WillRepeatedly(Return(&info));
239
240 TimestampScaler scaler(db);
241 // Test both sides of the timestamp wrap-around.
242 uint32_t external_timestamp = 0xFFFFFFFF - 5;
243 uint32_t internal_timestamp = external_timestamp;
244 for (; external_timestamp != 5; ++external_timestamp) {
245 // Scale to internal timestamp.
246 EXPECT_EQ(internal_timestamp,
247 scaler.ToInternal(external_timestamp, kRtpPayloadType));
248 // Scale back.
249 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
250 internal_timestamp += 2;
251 }
252 // Reset the scaler. After this, we expect the internal and external to start
253 // over at the same value again.
254 scaler.Reset();
255 internal_timestamp = external_timestamp;
256 for (; external_timestamp != 15; ++external_timestamp) {
257 // Scale to internal timestamp.
258 EXPECT_EQ(internal_timestamp,
259 scaler.ToInternal(external_timestamp, kRtpPayloadType));
260 // Scale back.
261 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
262 internal_timestamp += 2;
263 }
264
265 EXPECT_CALL(db, Die()); // Called when database object is deleted.
266}
267
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000268// TODO(minyue): This test becomes trivial since Opus does not need a timestamp
269// scaler. Therefore, this test may be removed in future. There is no harm to
270// keep it, since it can be taken as a test case for the situation of a trivial
271// timestamp scaler.
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000272TEST(TimestampScaler, TestOpusLargeStep) {
273 MockDecoderDatabase db;
ossu09f15602016-08-29 03:59:05 -0700274 auto factory = CreateBuiltinAudioDecoderFactory();
ossuf1b08da2016-09-23 02:19:43 -0700275 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderOpus, factory);
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000276 static const uint8_t kRtpPayloadType = 17;
277 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
278 .WillRepeatedly(Return(&info));
279
280 TimestampScaler scaler(db);
281 // Test both sides of the timestamp wrap-around.
282 static const uint32_t kStep = 960;
283 uint32_t external_timestamp = 0;
284 // |external_timestamp| will be a large positive value.
285 external_timestamp = external_timestamp - 5 * kStep;
286 uint32_t internal_timestamp = external_timestamp;
287 for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
288 // Scale to internal timestamp.
289 EXPECT_EQ(internal_timestamp,
290 scaler.ToInternal(external_timestamp, kRtpPayloadType));
291 // Scale back.
292 EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
minyue@webrtc.orgf563e852014-07-18 21:11:27 +0000293 internal_timestamp += kStep;
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000294 }
295
296 EXPECT_CALL(db, Die()); // Called when database object is deleted.
297}
298
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000299TEST(TimestampScaler, Failures) {
300 static const uint8_t kRtpPayloadType = 17;
301 MockDecoderDatabase db;
302 EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
303 .WillOnce(ReturnNull()); // Return NULL to indicate unknown payload type.
304
305 TimestampScaler scaler(db);
306 uint32_t timestamp = 4711; // Some number.
307 EXPECT_EQ(timestamp, scaler.ToInternal(timestamp, kRtpPayloadType));
308
309 Packet* packet = NULL;
310 scaler.ToInternal(packet); // Should not crash. That's all we can test.
311
312 EXPECT_CALL(db, Die()); // Called when database object is deleted.
313}
314
315} // namespace webrtc