Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: webrtc/modules/audio_coding/neteq/nack_unittest.cc

Issue 1410073006: ACM: Move NACK functionality inside NetEq (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_coding/neteq/nack.cc ('k') | webrtc/modules/audio_coding/neteq/neteq.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_coding/main/acm2/nack.h" 11 #include "webrtc/modules/audio_coding/neteq/nack.h"
12 12
13 #include <stdint.h> 13 #include <stdint.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 16
17 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/base/scoped_ptr.h" 18 #include "webrtc/base/scoped_ptr.h"
19 #include "webrtc/typedefs.h" 19 #include "webrtc/typedefs.h"
20 #include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs. h" 20 #include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs. h"
21 21
22 namespace webrtc { 22 namespace webrtc {
23
24 namespace acm2 {
25
26 namespace { 23 namespace {
27 24
28 const int kNackThreshold = 3; 25 const int kNackThreshold = 3;
29 const int kSampleRateHz = 16000; 26 const int kSampleRateHz = 16000;
30 const int kPacketSizeMs = 30; 27 const int kPacketSizeMs = 30;
31 const uint32_t kTimestampIncrement = 480; // 30 ms. 28 const uint32_t kTimestampIncrement = 480; // 30 ms.
32 const int64_t kShortRoundTripTimeMs = 1; 29 const int64_t kShortRoundTripTimeMs = 1;
33 30
34 bool IsNackListCorrect(const std::vector<uint16_t>& nack_list, 31 bool IsNackListCorrect(const std::vector<uint16_t>& nack_list,
35 const uint16_t* lost_sequence_numbers, 32 const uint16_t* lost_sequence_numbers,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 uint32_t timestamp = 0; 80 uint32_t timestamp = 0;
84 std::vector<uint16_t> nack_list; 81 std::vector<uint16_t> nack_list;
85 82
86 nack->UpdateLastReceivedPacket(seq_num, timestamp); 83 nack->UpdateLastReceivedPacket(seq_num, timestamp);
87 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 84 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
88 EXPECT_TRUE(nack_list.empty()); 85 EXPECT_TRUE(nack_list.empty());
89 int num_late_packets = kNackThreshold + 1; 86 int num_late_packets = kNackThreshold + 1;
90 87
91 // Push in reverse order 88 // Push in reverse order
92 while (num_late_packets > 0) { 89 while (num_late_packets > 0) {
93 nack->UpdateLastReceivedPacket(seq_num + num_late_packets, timestamp + 90 nack->UpdateLastReceivedPacket(
94 num_late_packets * kTimestampIncrement); 91 seq_num + num_late_packets,
92 timestamp + num_late_packets * kTimestampIncrement);
95 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 93 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
96 EXPECT_TRUE(nack_list.empty()); 94 EXPECT_TRUE(nack_list.empty());
97 num_late_packets--; 95 num_late_packets--;
98 } 96 }
99 } 97 }
100 98
101 TEST(NackTest, LatePacketsMovedToNackThenNackListDoesNotChange) { 99 TEST(NackTest, LatePacketsMovedToNackThenNackListDoesNotChange) {
102 const uint16_t kSequenceNumberLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; 100 const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
103 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) / 101 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
104 sizeof(kSequenceNumberLostPackets[0]); 102 sizeof(kSequenceNumberLostPackets[0]);
105 103
106 for (int k = 0; k < 2; k++) { // Two iteration with/without wrap around. 104 for (int k = 0; k < 2; k++) { // Two iteration with/without wrap around.
107 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); 105 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold));
108 nack->UpdateSampleRate(kSampleRateHz); 106 nack->UpdateSampleRate(kSampleRateHz);
109 107
110 uint16_t sequence_num_lost_packets[kNumAllLostPackets]; 108 uint16_t sequence_num_lost_packets[kNumAllLostPackets];
111 for (int n = 0; n < kNumAllLostPackets; n++) { 109 for (int n = 0; n < kNumAllLostPackets; n++) {
112 sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] + k * 110 sequence_num_lost_packets[n] =
113 65531; // Have wrap around in sequence numbers for |k == 1|. 111 kSequenceNumberLostPackets[n] +
112 k * 65531; // Have wrap around in sequence numbers for |k == 1|.
114 } 113 }
115 uint16_t seq_num = sequence_num_lost_packets[0] - 1; 114 uint16_t seq_num = sequence_num_lost_packets[0] - 1;
116 115
117 uint32_t timestamp = 0; 116 uint32_t timestamp = 0;
118 std::vector<uint16_t> nack_list; 117 std::vector<uint16_t> nack_list;
119 118
120 nack->UpdateLastReceivedPacket(seq_num, timestamp); 119 nack->UpdateLastReceivedPacket(seq_num, timestamp);
121 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 120 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
122 EXPECT_TRUE(nack_list.empty()); 121 EXPECT_TRUE(nack_list.empty());
123 122
(...skipping 16 matching lines...) Expand all
140 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 139 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
141 EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets, 140 EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets,
142 kNumAllLostPackets)); 141 kNumAllLostPackets));
143 seq_num++; 142 seq_num++;
144 timestamp += kTimestampIncrement; 143 timestamp += kTimestampIncrement;
145 } 144 }
146 } 145 }
147 } 146 }
148 147
149 TEST(NackTest, ArrivedPacketsAreRemovedFromNackList) { 148 TEST(NackTest, ArrivedPacketsAreRemovedFromNackList) {
150 const uint16_t kSequenceNumberLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; 149 const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
151 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) / 150 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
152 sizeof(kSequenceNumberLostPackets[0]); 151 sizeof(kSequenceNumberLostPackets[0]);
153 152
154 for (int k = 0; k < 2; ++k) { // Two iteration with/without wrap around. 153 for (int k = 0; k < 2; ++k) { // Two iteration with/without wrap around.
155 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); 154 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold));
156 nack->UpdateSampleRate(kSampleRateHz); 155 nack->UpdateSampleRate(kSampleRateHz);
157 156
158 uint16_t sequence_num_lost_packets[kNumAllLostPackets]; 157 uint16_t sequence_num_lost_packets[kNumAllLostPackets];
159 for (int n = 0; n < kNumAllLostPackets; ++n) { 158 for (int n = 0; n < kNumAllLostPackets; ++n) {
160 sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] + k * 159 sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] +
161 65531; // Wrap around for |k == 1|. 160 k * 65531; // Wrap around for |k == 1|.
162 } 161 }
163 162
164 uint16_t seq_num = sequence_num_lost_packets[0] - 1; 163 uint16_t seq_num = sequence_num_lost_packets[0] - 1;
165 uint32_t timestamp = 0; 164 uint32_t timestamp = 0;
166 165
167 nack->UpdateLastReceivedPacket(seq_num, timestamp); 166 nack->UpdateLastReceivedPacket(seq_num, timestamp);
168 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); 167 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs);
169 EXPECT_TRUE(nack_list.empty()); 168 EXPECT_TRUE(nack_list.empty());
170 169
171 size_t index_retransmitted_rtp = 0; 170 size_t index_retransmitted_rtp = 0;
(...skipping 29 matching lines...) Expand all
201 nack_list, &sequence_num_lost_packets[index_retransmitted_rtp], 200 nack_list, &sequence_num_lost_packets[index_retransmitted_rtp],
202 num_lost_packets - 1)); // One less lost packet in the list. 201 num_lost_packets - 1)); // One less lost packet in the list.
203 } 202 }
204 ASSERT_TRUE(nack_list.empty()); 203 ASSERT_TRUE(nack_list.empty());
205 } 204 }
206 } 205 }
207 206
208 // Assess if estimation of timestamps and time-to-play is correct. Introduce all 207 // Assess if estimation of timestamps and time-to-play is correct. Introduce all
209 // combinations that timestamps and sequence numbers might have wrap around. 208 // combinations that timestamps and sequence numbers might have wrap around.
210 TEST(NackTest, EstimateTimestampAndTimeToPlay) { 209 TEST(NackTest, EstimateTimestampAndTimeToPlay) {
211 const uint16_t kLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 210 const uint16_t kLostPackets[] = {2, 3, 4, 5, 6, 7, 8,
212 11, 12, 13, 14, 15 }; 211 9, 10, 11, 12, 13, 14, 15};
213 static const int kNumAllLostPackets = sizeof(kLostPackets) / 212 static const int kNumAllLostPackets =
214 sizeof(kLostPackets[0]); 213 sizeof(kLostPackets) / sizeof(kLostPackets[0]);
215
216 214
217 for (int k = 0; k < 4; ++k) { 215 for (int k = 0; k < 4; ++k) {
218 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); 216 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold));
219 nack->UpdateSampleRate(kSampleRateHz); 217 nack->UpdateSampleRate(kSampleRateHz);
220 218
221 // Sequence number wrap around if |k| is 2 or 3; 219 // Sequence number wrap around if |k| is 2 or 3;
222 int seq_num_offset = (k < 2) ? 0 : 65531; 220 int seq_num_offset = (k < 2) ? 0 : 65531;
223 221
224 // Timestamp wrap around if |k| is 1 or 3. 222 // Timestamp wrap around if |k| is 1 or 3.
225 uint32_t timestamp_offset = (k & 0x1) ? 223 uint32_t timestamp_offset =
226 static_cast<uint32_t>(0xffffffff) - 6 : 0; 224 (k & 0x1) ? static_cast<uint32_t>(0xffffffff) - 6 : 0;
227 225
228 uint32_t timestamp_lost_packets[kNumAllLostPackets]; 226 uint32_t timestamp_lost_packets[kNumAllLostPackets];
229 uint16_t seq_num_lost_packets[kNumAllLostPackets]; 227 uint16_t seq_num_lost_packets[kNumAllLostPackets];
230 for (int n = 0; n < kNumAllLostPackets; ++n) { 228 for (int n = 0; n < kNumAllLostPackets; ++n) {
231 timestamp_lost_packets[n] = timestamp_offset + kLostPackets[n] * 229 timestamp_lost_packets[n] =
232 kTimestampIncrement; 230 timestamp_offset + kLostPackets[n] * kTimestampIncrement;
233 seq_num_lost_packets[n] = seq_num_offset + kLostPackets[n]; 231 seq_num_lost_packets[n] = seq_num_offset + kLostPackets[n];
234 } 232 }
235 233
236 // We and to push two packets before lost burst starts. 234 // We and to push two packets before lost burst starts.
237 uint16_t seq_num = seq_num_lost_packets[0] - 2; 235 uint16_t seq_num = seq_num_lost_packets[0] - 2;
238 uint32_t timestamp = timestamp_lost_packets[0] - 2 * kTimestampIncrement; 236 uint32_t timestamp = timestamp_lost_packets[0] - 2 * kTimestampIncrement;
239 237
240 const uint16_t first_seq_num = seq_num; 238 const uint16_t first_seq_num = seq_num;
241 const uint32_t first_timestamp = timestamp; 239 const uint32_t first_timestamp = timestamp;
242 240
243 // Two consecutive packets to have a correct estimate of timestamp increase. 241 // Two consecutive packets to have a correct estimate of timestamp increase.
244 nack->UpdateLastReceivedPacket(seq_num, timestamp); 242 nack->UpdateLastReceivedPacket(seq_num, timestamp);
245 seq_num++; 243 seq_num++;
246 timestamp += kTimestampIncrement; 244 timestamp += kTimestampIncrement;
247 nack->UpdateLastReceivedPacket(seq_num, timestamp); 245 nack->UpdateLastReceivedPacket(seq_num, timestamp);
248 246
249 // A packet after the last one which is supposed to be lost. 247 // A packet after the last one which is supposed to be lost.
250 seq_num = seq_num_lost_packets[kNumAllLostPackets - 1] + 1; 248 seq_num = seq_num_lost_packets[kNumAllLostPackets - 1] + 1;
251 timestamp = timestamp_lost_packets[kNumAllLostPackets - 1] + 249 timestamp =
252 kTimestampIncrement; 250 timestamp_lost_packets[kNumAllLostPackets - 1] + kTimestampIncrement;
253 nack->UpdateLastReceivedPacket(seq_num, timestamp); 251 nack->UpdateLastReceivedPacket(seq_num, timestamp);
254 252
255 Nack::NackList nack_list = nack->GetNackList(); 253 Nack::NackList nack_list = nack->GetNackList();
256 EXPECT_EQ(static_cast<size_t>(kNumAllLostPackets), nack_list.size()); 254 EXPECT_EQ(static_cast<size_t>(kNumAllLostPackets), nack_list.size());
257 255
258 // Pretend the first packet is decoded. 256 // Pretend the first packet is decoded.
259 nack->UpdateLastDecodedPacket(first_seq_num, first_timestamp); 257 nack->UpdateLastDecodedPacket(first_seq_num, first_timestamp);
260 nack_list = nack->GetNackList(); 258 nack_list = nack->GetNackList();
261 259
262 Nack::NackList::iterator it = nack_list.begin(); 260 Nack::NackList::iterator it = nack_list.begin();
(...skipping 22 matching lines...) Expand all
285 283
286 TEST(NackTest, MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList) { 284 TEST(NackTest, MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList) {
287 for (int m = 0; m < 2; ++m) { 285 for (int m = 0; m < 2; ++m) {
288 uint16_t seq_num_offset = (m == 0) ? 0 : 65531; // Wrap around if |m| is 1. 286 uint16_t seq_num_offset = (m == 0) ? 0 : 65531; // Wrap around if |m| is 1.
289 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); 287 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold));
290 nack->UpdateSampleRate(kSampleRateHz); 288 nack->UpdateSampleRate(kSampleRateHz);
291 289
292 // Two consecutive packets to have a correct estimate of timestamp increase. 290 // Two consecutive packets to have a correct estimate of timestamp increase.
293 uint16_t seq_num = 0; 291 uint16_t seq_num = 0;
294 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, 292 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num,
295 seq_num * kTimestampIncrement); 293 seq_num * kTimestampIncrement);
296 seq_num++; 294 seq_num++;
297 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, 295 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num,
298 seq_num * kTimestampIncrement); 296 seq_num * kTimestampIncrement);
299 297
300 // Skip 10 packets (larger than NACK threshold). 298 // Skip 10 packets (larger than NACK threshold).
301 const int kNumLostPackets = 10; 299 const int kNumLostPackets = 10;
302 seq_num += kNumLostPackets + 1; 300 seq_num += kNumLostPackets + 1;
303 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, 301 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num,
304 seq_num * kTimestampIncrement); 302 seq_num * kTimestampIncrement);
305 303
306 const size_t kExpectedListSize = kNumLostPackets - kNackThreshold; 304 const size_t kExpectedListSize = kNumLostPackets - kNackThreshold;
307 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); 305 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs);
308 EXPECT_EQ(kExpectedListSize, nack_list.size()); 306 EXPECT_EQ(kExpectedListSize, nack_list.size());
309 307
310 for (int k = 0; k < 2; ++k) { 308 for (int k = 0; k < 2; ++k) {
311 // Decoding of the first and the second arrived packets. 309 // Decoding of the first and the second arrived packets.
312 for (int n = 0; n < kPacketSizeMs / 10; ++n) { 310 for (int n = 0; n < kPacketSizeMs / 10; ++n) {
313 nack->UpdateLastDecodedPacket(seq_num_offset + k, 311 nack->UpdateLastDecodedPacket(seq_num_offset + k,
314 k * kTimestampIncrement); 312 k * kTimestampIncrement);
315 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 313 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
316 EXPECT_EQ(kExpectedListSize, nack_list.size()); 314 EXPECT_EQ(kExpectedListSize, nack_list.size());
317 } 315 }
318 } 316 }
319 317
320 // Decoding of the last received packet. 318 // Decoding of the last received packet.
321 nack->UpdateLastDecodedPacket(seq_num + seq_num_offset, 319 nack->UpdateLastDecodedPacket(seq_num + seq_num_offset,
322 seq_num * kTimestampIncrement); 320 seq_num * kTimestampIncrement);
323 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 321 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
324 EXPECT_TRUE(nack_list.empty()); 322 EXPECT_TRUE(nack_list.empty());
325 323
326 // Make sure list of late packets is also empty. To check that, push few 324 // Make sure list of late packets is also empty. To check that, push few
327 // packets, if the late list is not empty its content will pop up in NACK 325 // packets, if the late list is not empty its content will pop up in NACK
328 // list. 326 // list.
329 for (int n = 0; n < kNackThreshold + 10; ++n) { 327 for (int n = 0; n < kNackThreshold + 10; ++n) {
330 seq_num++; 328 seq_num++;
331 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, 329 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num,
332 seq_num * kTimestampIncrement); 330 seq_num * kTimestampIncrement);
333 nack_list = nack->GetNackList(kShortRoundTripTimeMs); 331 nack_list = nack->GetNackList(kShortRoundTripTimeMs);
334 EXPECT_TRUE(nack_list.empty()); 332 EXPECT_TRUE(nack_list.empty());
335 } 333 }
336 } 334 }
337 } 335 }
338 336
339 TEST(NackTest, Reset) { 337 TEST(NackTest, Reset) {
340 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); 338 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold));
341 nack->UpdateSampleRate(kSampleRateHz); 339 nack->UpdateSampleRate(kSampleRateHz);
342 340
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 // 472 //
475 // sequence number: 1, 2, 3, 4, 5 473 // sequence number: 1, 2, 3, 4, 5
476 // time-to-play: 20, 50, 80, 110, 140 474 // time-to-play: 20, 50, 80, 110, 140
477 // 475 //
478 std::vector<uint16_t> nack_list = nack->GetNackList(100); 476 std::vector<uint16_t> nack_list = nack->GetNackList(100);
479 ASSERT_EQ(2u, nack_list.size()); 477 ASSERT_EQ(2u, nack_list.size());
480 EXPECT_EQ(4, nack_list[0]); 478 EXPECT_EQ(4, nack_list[0]);
481 EXPECT_EQ(5, nack_list[1]); 479 EXPECT_EQ(5, nack_list[1]);
482 } 480 }
483 481
484 } // namespace acm2
485
486 } // namespace webrtc 482 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/neteq/nack.cc ('k') | webrtc/modules/audio_coding/neteq/neteq.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698