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