1cbbf7f346e5077f9827cc67b6767e6b27787ffd
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / timestamp_scaler_unittest.cc
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 // 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