OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2013 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/main/acm2/nack.h" | |
12 | |
13 #include <stdint.h> | |
14 | |
15 #include <algorithm> | |
16 | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 #include "webrtc/base/scoped_ptr.h" | |
19 #include "webrtc/typedefs.h" | |
20 #include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.
h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 namespace acm2 { | |
25 | |
26 namespace { | |
27 | |
28 const int kNackThreshold = 3; | |
29 const int kSampleRateHz = 16000; | |
30 const int kPacketSizeMs = 30; | |
31 const uint32_t kTimestampIncrement = 480; // 30 ms. | |
32 const int64_t kShortRoundTripTimeMs = 1; | |
33 | |
34 bool IsNackListCorrect(const std::vector<uint16_t>& nack_list, | |
35 const uint16_t* lost_sequence_numbers, | |
36 size_t num_lost_packets) { | |
37 if (nack_list.size() != num_lost_packets) | |
38 return false; | |
39 | |
40 if (num_lost_packets == 0) | |
41 return true; | |
42 | |
43 for (size_t k = 0; k < nack_list.size(); ++k) { | |
44 int seq_num = nack_list[k]; | |
45 bool seq_num_matched = false; | |
46 for (size_t n = 0; n < num_lost_packets; ++n) { | |
47 if (seq_num == lost_sequence_numbers[n]) { | |
48 seq_num_matched = true; | |
49 break; | |
50 } | |
51 } | |
52 if (!seq_num_matched) | |
53 return false; | |
54 } | |
55 return true; | |
56 } | |
57 | |
58 } // namespace | |
59 | |
60 TEST(NackTest, EmptyListWhenNoPacketLoss) { | |
61 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
62 nack->UpdateSampleRate(kSampleRateHz); | |
63 | |
64 int seq_num = 1; | |
65 uint32_t timestamp = 0; | |
66 | |
67 std::vector<uint16_t> nack_list; | |
68 for (int n = 0; n < 100; n++) { | |
69 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
70 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
71 seq_num++; | |
72 timestamp += kTimestampIncrement; | |
73 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
74 EXPECT_TRUE(nack_list.empty()); | |
75 } | |
76 } | |
77 | |
78 TEST(NackTest, NoNackIfReorderWithinNackThreshold) { | |
79 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
80 nack->UpdateSampleRate(kSampleRateHz); | |
81 | |
82 int seq_num = 1; | |
83 uint32_t timestamp = 0; | |
84 std::vector<uint16_t> nack_list; | |
85 | |
86 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
87 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
88 EXPECT_TRUE(nack_list.empty()); | |
89 int num_late_packets = kNackThreshold + 1; | |
90 | |
91 // Push in reverse order | |
92 while (num_late_packets > 0) { | |
93 nack->UpdateLastReceivedPacket(seq_num + num_late_packets, timestamp + | |
94 num_late_packets * kTimestampIncrement); | |
95 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
96 EXPECT_TRUE(nack_list.empty()); | |
97 num_late_packets--; | |
98 } | |
99 } | |
100 | |
101 TEST(NackTest, LatePacketsMovedToNackThenNackListDoesNotChange) { | |
102 const uint16_t kSequenceNumberLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; | |
103 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) / | |
104 sizeof(kSequenceNumberLostPackets[0]); | |
105 | |
106 for (int k = 0; k < 2; k++) { // Two iteration with/without wrap around. | |
107 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
108 nack->UpdateSampleRate(kSampleRateHz); | |
109 | |
110 uint16_t sequence_num_lost_packets[kNumAllLostPackets]; | |
111 for (int n = 0; n < kNumAllLostPackets; n++) { | |
112 sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] + k * | |
113 65531; // Have wrap around in sequence numbers for |k == 1|. | |
114 } | |
115 uint16_t seq_num = sequence_num_lost_packets[0] - 1; | |
116 | |
117 uint32_t timestamp = 0; | |
118 std::vector<uint16_t> nack_list; | |
119 | |
120 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
121 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
122 EXPECT_TRUE(nack_list.empty()); | |
123 | |
124 seq_num = sequence_num_lost_packets[kNumAllLostPackets - 1] + 1; | |
125 timestamp += kTimestampIncrement * (kNumAllLostPackets + 1); | |
126 int num_lost_packets = std::max(0, kNumAllLostPackets - kNackThreshold); | |
127 | |
128 for (int n = 0; n < kNackThreshold + 1; ++n) { | |
129 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
130 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
131 EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets, | |
132 num_lost_packets)); | |
133 seq_num++; | |
134 timestamp += kTimestampIncrement; | |
135 num_lost_packets++; | |
136 } | |
137 | |
138 for (int n = 0; n < 100; ++n) { | |
139 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
140 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
141 EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets, | |
142 kNumAllLostPackets)); | |
143 seq_num++; | |
144 timestamp += kTimestampIncrement; | |
145 } | |
146 } | |
147 } | |
148 | |
149 TEST(NackTest, ArrivedPacketsAreRemovedFromNackList) { | |
150 const uint16_t kSequenceNumberLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; | |
151 static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) / | |
152 sizeof(kSequenceNumberLostPackets[0]); | |
153 | |
154 for (int k = 0; k < 2; ++k) { // Two iteration with/without wrap around. | |
155 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
156 nack->UpdateSampleRate(kSampleRateHz); | |
157 | |
158 uint16_t sequence_num_lost_packets[kNumAllLostPackets]; | |
159 for (int n = 0; n < kNumAllLostPackets; ++n) { | |
160 sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] + k * | |
161 65531; // Wrap around for |k == 1|. | |
162 } | |
163 | |
164 uint16_t seq_num = sequence_num_lost_packets[0] - 1; | |
165 uint32_t timestamp = 0; | |
166 | |
167 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
168 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
169 EXPECT_TRUE(nack_list.empty()); | |
170 | |
171 size_t index_retransmitted_rtp = 0; | |
172 uint32_t timestamp_retransmitted_rtp = timestamp + kTimestampIncrement; | |
173 | |
174 seq_num = sequence_num_lost_packets[kNumAllLostPackets - 1] + 1; | |
175 timestamp += kTimestampIncrement * (kNumAllLostPackets + 1); | |
176 size_t num_lost_packets = std::max(0, kNumAllLostPackets - kNackThreshold); | |
177 for (int n = 0; n < kNumAllLostPackets; ++n) { | |
178 // Number of lost packets does not change for the first | |
179 // |kNackThreshold + 1| packets, one is added to the list and one is | |
180 // removed. Thereafter, the list shrinks every iteration. | |
181 if (n >= kNackThreshold + 1) | |
182 num_lost_packets--; | |
183 | |
184 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
185 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
186 EXPECT_TRUE(IsNackListCorrect( | |
187 nack_list, &sequence_num_lost_packets[index_retransmitted_rtp], | |
188 num_lost_packets)); | |
189 seq_num++; | |
190 timestamp += kTimestampIncrement; | |
191 | |
192 // Retransmission of a lost RTP. | |
193 nack->UpdateLastReceivedPacket( | |
194 sequence_num_lost_packets[index_retransmitted_rtp], | |
195 timestamp_retransmitted_rtp); | |
196 index_retransmitted_rtp++; | |
197 timestamp_retransmitted_rtp += kTimestampIncrement; | |
198 | |
199 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
200 EXPECT_TRUE(IsNackListCorrect( | |
201 nack_list, &sequence_num_lost_packets[index_retransmitted_rtp], | |
202 num_lost_packets - 1)); // One less lost packet in the list. | |
203 } | |
204 ASSERT_TRUE(nack_list.empty()); | |
205 } | |
206 } | |
207 | |
208 // Assess if estimation of timestamps and time-to-play is correct. Introduce all | |
209 // combinations that timestamps and sequence numbers might have wrap around. | |
210 TEST(NackTest, EstimateTimestampAndTimeToPlay) { | |
211 const uint16_t kLostPackets[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, | |
212 11, 12, 13, 14, 15 }; | |
213 static const int kNumAllLostPackets = sizeof(kLostPackets) / | |
214 sizeof(kLostPackets[0]); | |
215 | |
216 | |
217 for (int k = 0; k < 4; ++k) { | |
218 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
219 nack->UpdateSampleRate(kSampleRateHz); | |
220 | |
221 // Sequence number wrap around if |k| is 2 or 3; | |
222 int seq_num_offset = (k < 2) ? 0 : 65531; | |
223 | |
224 // Timestamp wrap around if |k| is 1 or 3. | |
225 uint32_t timestamp_offset = (k & 0x1) ? | |
226 static_cast<uint32_t>(0xffffffff) - 6 : 0; | |
227 | |
228 uint32_t timestamp_lost_packets[kNumAllLostPackets]; | |
229 uint16_t seq_num_lost_packets[kNumAllLostPackets]; | |
230 for (int n = 0; n < kNumAllLostPackets; ++n) { | |
231 timestamp_lost_packets[n] = timestamp_offset + kLostPackets[n] * | |
232 kTimestampIncrement; | |
233 seq_num_lost_packets[n] = seq_num_offset + kLostPackets[n]; | |
234 } | |
235 | |
236 // We and to push two packets before lost burst starts. | |
237 uint16_t seq_num = seq_num_lost_packets[0] - 2; | |
238 uint32_t timestamp = timestamp_lost_packets[0] - 2 * kTimestampIncrement; | |
239 | |
240 const uint16_t first_seq_num = seq_num; | |
241 const uint32_t first_timestamp = timestamp; | |
242 | |
243 // Two consecutive packets to have a correct estimate of timestamp increase. | |
244 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
245 seq_num++; | |
246 timestamp += kTimestampIncrement; | |
247 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
248 | |
249 // A packet after the last one which is supposed to be lost. | |
250 seq_num = seq_num_lost_packets[kNumAllLostPackets - 1] + 1; | |
251 timestamp = timestamp_lost_packets[kNumAllLostPackets - 1] + | |
252 kTimestampIncrement; | |
253 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
254 | |
255 Nack::NackList nack_list = nack->GetNackList(); | |
256 EXPECT_EQ(static_cast<size_t>(kNumAllLostPackets), nack_list.size()); | |
257 | |
258 // Pretend the first packet is decoded. | |
259 nack->UpdateLastDecodedPacket(first_seq_num, first_timestamp); | |
260 nack_list = nack->GetNackList(); | |
261 | |
262 Nack::NackList::iterator it = nack_list.begin(); | |
263 while (it != nack_list.end()) { | |
264 seq_num = it->first - seq_num_offset; | |
265 int index = seq_num - kLostPackets[0]; | |
266 EXPECT_EQ(timestamp_lost_packets[index], it->second.estimated_timestamp); | |
267 EXPECT_EQ((index + 2) * kPacketSizeMs, it->second.time_to_play_ms); | |
268 ++it; | |
269 } | |
270 | |
271 // Pretend 10 ms is passed, and we had pulled audio from NetEq, it still | |
272 // reports the same sequence number as decoded, time-to-play should be | |
273 // updated by 10 ms. | |
274 nack->UpdateLastDecodedPacket(first_seq_num, first_timestamp); | |
275 nack_list = nack->GetNackList(); | |
276 it = nack_list.begin(); | |
277 while (it != nack_list.end()) { | |
278 seq_num = it->first - seq_num_offset; | |
279 int index = seq_num - kLostPackets[0]; | |
280 EXPECT_EQ((index + 2) * kPacketSizeMs - 10, it->second.time_to_play_ms); | |
281 ++it; | |
282 } | |
283 } | |
284 } | |
285 | |
286 TEST(NackTest, MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList) { | |
287 for (int m = 0; m < 2; ++m) { | |
288 uint16_t seq_num_offset = (m == 0) ? 0 : 65531; // Wrap around if |m| is 1. | |
289 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
290 nack->UpdateSampleRate(kSampleRateHz); | |
291 | |
292 // Two consecutive packets to have a correct estimate of timestamp increase. | |
293 uint16_t seq_num = 0; | |
294 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, | |
295 seq_num * kTimestampIncrement); | |
296 seq_num++; | |
297 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, | |
298 seq_num * kTimestampIncrement); | |
299 | |
300 // Skip 10 packets (larger than NACK threshold). | |
301 const int kNumLostPackets = 10; | |
302 seq_num += kNumLostPackets + 1; | |
303 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, | |
304 seq_num * kTimestampIncrement); | |
305 | |
306 const size_t kExpectedListSize = kNumLostPackets - kNackThreshold; | |
307 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
308 EXPECT_EQ(kExpectedListSize, nack_list.size()); | |
309 | |
310 for (int k = 0; k < 2; ++k) { | |
311 // Decoding of the first and the second arrived packets. | |
312 for (int n = 0; n < kPacketSizeMs / 10; ++n) { | |
313 nack->UpdateLastDecodedPacket(seq_num_offset + k, | |
314 k * kTimestampIncrement); | |
315 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
316 EXPECT_EQ(kExpectedListSize, nack_list.size()); | |
317 } | |
318 } | |
319 | |
320 // Decoding of the last received packet. | |
321 nack->UpdateLastDecodedPacket(seq_num + seq_num_offset, | |
322 seq_num * kTimestampIncrement); | |
323 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
324 EXPECT_TRUE(nack_list.empty()); | |
325 | |
326 // 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 | |
328 // list. | |
329 for (int n = 0; n < kNackThreshold + 10; ++n) { | |
330 seq_num++; | |
331 nack->UpdateLastReceivedPacket(seq_num_offset + seq_num, | |
332 seq_num * kTimestampIncrement); | |
333 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
334 EXPECT_TRUE(nack_list.empty()); | |
335 } | |
336 } | |
337 } | |
338 | |
339 TEST(NackTest, Reset) { | |
340 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
341 nack->UpdateSampleRate(kSampleRateHz); | |
342 | |
343 // Two consecutive packets to have a correct estimate of timestamp increase. | |
344 uint16_t seq_num = 0; | |
345 nack->UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement); | |
346 seq_num++; | |
347 nack->UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement); | |
348 | |
349 // Skip 10 packets (larger than NACK threshold). | |
350 const int kNumLostPackets = 10; | |
351 seq_num += kNumLostPackets + 1; | |
352 nack->UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement); | |
353 | |
354 const size_t kExpectedListSize = kNumLostPackets - kNackThreshold; | |
355 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
356 EXPECT_EQ(kExpectedListSize, nack_list.size()); | |
357 | |
358 nack->Reset(); | |
359 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
360 EXPECT_TRUE(nack_list.empty()); | |
361 } | |
362 | |
363 TEST(NackTest, ListSizeAppliedFromBeginning) { | |
364 const size_t kNackListSize = 10; | |
365 for (int m = 0; m < 2; ++m) { | |
366 uint16_t seq_num_offset = (m == 0) ? 0 : 65525; // Wrap around if |m| is 1. | |
367 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
368 nack->UpdateSampleRate(kSampleRateHz); | |
369 nack->SetMaxNackListSize(kNackListSize); | |
370 | |
371 uint16_t seq_num = seq_num_offset; | |
372 uint32_t timestamp = 0x12345678; | |
373 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
374 | |
375 // Packet lost more than NACK-list size limit. | |
376 uint16_t num_lost_packets = kNackThreshold + kNackListSize + 5; | |
377 | |
378 seq_num += num_lost_packets + 1; | |
379 timestamp += (num_lost_packets + 1) * kTimestampIncrement; | |
380 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
381 | |
382 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
383 EXPECT_EQ(kNackListSize - kNackThreshold, nack_list.size()); | |
384 } | |
385 } | |
386 | |
387 TEST(NackTest, ChangeOfListSizeAppliedAndOldElementsRemoved) { | |
388 const size_t kNackListSize = 10; | |
389 for (int m = 0; m < 2; ++m) { | |
390 uint16_t seq_num_offset = (m == 0) ? 0 : 65525; // Wrap around if |m| is 1. | |
391 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
392 nack->UpdateSampleRate(kSampleRateHz); | |
393 | |
394 uint16_t seq_num = seq_num_offset; | |
395 uint32_t timestamp = 0x87654321; | |
396 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
397 | |
398 // Packet lost more than NACK-list size limit. | |
399 uint16_t num_lost_packets = kNackThreshold + kNackListSize + 5; | |
400 | |
401 rtc::scoped_ptr<uint16_t[]> seq_num_lost(new uint16_t[num_lost_packets]); | |
402 for (int n = 0; n < num_lost_packets; ++n) { | |
403 seq_num_lost[n] = ++seq_num; | |
404 } | |
405 | |
406 ++seq_num; | |
407 timestamp += (num_lost_packets + 1) * kTimestampIncrement; | |
408 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
409 size_t expected_size = num_lost_packets - kNackThreshold; | |
410 | |
411 std::vector<uint16_t> nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
412 EXPECT_EQ(expected_size, nack_list.size()); | |
413 | |
414 nack->SetMaxNackListSize(kNackListSize); | |
415 expected_size = kNackListSize - kNackThreshold; | |
416 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
417 EXPECT_TRUE(IsNackListCorrect( | |
418 nack_list, &seq_num_lost[num_lost_packets - kNackListSize], | |
419 expected_size)); | |
420 | |
421 // NACK list does not change size but the content is changing. The oldest | |
422 // element is removed and one from late list is inserted. | |
423 size_t n; | |
424 for (n = 1; n <= static_cast<size_t>(kNackThreshold); ++n) { | |
425 ++seq_num; | |
426 timestamp += kTimestampIncrement; | |
427 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
428 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
429 EXPECT_TRUE(IsNackListCorrect( | |
430 nack_list, &seq_num_lost[num_lost_packets - kNackListSize + n], | |
431 expected_size)); | |
432 } | |
433 | |
434 // NACK list should shrink. | |
435 for (; n < kNackListSize; ++n) { | |
436 ++seq_num; | |
437 timestamp += kTimestampIncrement; | |
438 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
439 --expected_size; | |
440 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
441 EXPECT_TRUE(IsNackListCorrect( | |
442 nack_list, &seq_num_lost[num_lost_packets - kNackListSize + n], | |
443 expected_size)); | |
444 } | |
445 | |
446 // After this packet, NACK list should be empty. | |
447 ++seq_num; | |
448 timestamp += kTimestampIncrement; | |
449 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
450 nack_list = nack->GetNackList(kShortRoundTripTimeMs); | |
451 EXPECT_TRUE(nack_list.empty()); | |
452 } | |
453 } | |
454 | |
455 TEST(NackTest, RoudTripTimeIsApplied) { | |
456 const int kNackListSize = 200; | |
457 rtc::scoped_ptr<Nack> nack(Nack::Create(kNackThreshold)); | |
458 nack->UpdateSampleRate(kSampleRateHz); | |
459 nack->SetMaxNackListSize(kNackListSize); | |
460 | |
461 uint16_t seq_num = 0; | |
462 uint32_t timestamp = 0x87654321; | |
463 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
464 | |
465 // Packet lost more than NACK-list size limit. | |
466 uint16_t kNumLostPackets = kNackThreshold + 5; | |
467 | |
468 seq_num += (1 + kNumLostPackets); | |
469 timestamp += (1 + kNumLostPackets) * kTimestampIncrement; | |
470 nack->UpdateLastReceivedPacket(seq_num, timestamp); | |
471 | |
472 // Expected time-to-play are: | |
473 // kPacketSizeMs - 10, 2*kPacketSizeMs - 10, 3*kPacketSizeMs - 10, ... | |
474 // | |
475 // sequence number: 1, 2, 3, 4, 5 | |
476 // time-to-play: 20, 50, 80, 110, 140 | |
477 // | |
478 std::vector<uint16_t> nack_list = nack->GetNackList(100); | |
479 ASSERT_EQ(2u, nack_list.size()); | |
480 EXPECT_EQ(4, nack_list[0]); | |
481 EXPECT_EQ(5, nack_list[1]); | |
482 } | |
483 | |
484 } // namespace acm2 | |
485 | |
486 } // namespace webrtc | |
OLD | NEW |