OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/test/simple_test_tick_clock.h" | |
6 #include "media/cast/framer/cast_message_builder.h" | |
7 #include "media/cast/rtcp/rtcp.h" | |
8 #include "media/cast/rtp_common/rtp_defines.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 | |
11 namespace media { | |
12 namespace cast { | |
13 | |
14 static const uint32 kSsrc = 0x1234; | |
15 static const uint32 kShortTimeIncrementMs = 10; | |
16 static const uint32 kLongTimeIncrementMs = 40; | |
17 static const int64 kStartMillisecond = 123456789; | |
18 | |
19 | |
20 class NackFeedbackVerification : public RtpPayloadFeedback { | |
21 public: | |
22 NackFeedbackVerification() | |
23 : triggered_(false), | |
24 missing_packets_(), | |
25 last_frame_acked_(0) {} | |
26 | |
27 | |
28 virtual void RequestKeyFrame() OVERRIDE { | |
29 request_key_frame_ = true; | |
30 } | |
31 | |
32 virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE { | |
33 EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_); | |
34 | |
35 last_frame_acked_ = cast_feedback.ack_frame_id_; | |
36 | |
37 std::map<uint8, std::set<uint16> >::const_iterator frame_it = | |
Alpha Left Google
2013/08/28 00:27:31
This looks bulky is there a typedef you can use?
pwestin
2013/08/28 16:40:44
Done.
| |
38 cast_feedback.missing_frames_and_packets_.begin(); | |
39 // Keep track of the number of missing packets per frame. | |
40 missing_packets_.clear(); | |
41 while (frame_it != cast_feedback.missing_frames_and_packets_.end()) { | |
42 missing_packets_.insert(std::pair<uint8, int> | |
Alpha Left Google
2013/08/28 00:27:31
you can just std::make_pair() which does the same
pwestin
2013/08/28 16:40:44
Done.
| |
43 (frame_it->first, frame_it->second.size())); | |
44 ++frame_it; | |
45 } | |
46 triggered_ = true; | |
47 } | |
48 | |
49 int num_missing_packets(uint8 frame_id) { | |
50 std::map<uint8, int>::iterator it; | |
51 it = missing_packets_.find(frame_id); | |
52 if (it == missing_packets_.end()) return 0; | |
53 return it->second; | |
54 } | |
55 | |
56 // Holds value for one call. | |
57 bool triggered() { | |
58 bool ret_val = triggered_; | |
59 triggered_ = false; | |
60 return ret_val; | |
61 } | |
62 | |
63 bool request_key_frame() { | |
64 bool ret_val = request_key_frame_; | |
65 request_key_frame_ = false; | |
66 return ret_val; | |
67 } | |
68 uint8 last_frame_acked() { return last_frame_acked_; } | |
Alpha Left Google
2013/08/28 00:27:31
nit: one space after ().
pwestin
2013/08/28 16:40:44
Done.
| |
69 | |
70 private: | |
71 bool triggered_; | |
72 // Number of missing packets per frame. | |
73 std::map<uint8, int> missing_packets_; | |
Alpha Left Google
2013/08/28 00:27:31
Use a typedef here.
pwestin
2013/08/28 16:40:44
Done.
| |
74 uint8 last_frame_acked_; | |
75 bool request_key_frame_; | |
76 }; | |
77 | |
78 class CastMessageBuilderTest : public ::testing::Test { | |
79 protected: | |
80 CastMessageBuilderTest() | |
81 : feedback_(new NackFeedbackVerification()) { | |
82 cast_msg_builder_ = new CastMessageBuilder(feedback_, | |
83 &frame_id_map_, | |
84 kSsrc, | |
85 true, | |
86 0); | |
87 rtp_header_.webrtc.header.ssrc = kSsrc; | |
88 rtp_header_.is_key_frame = false; | |
89 testing_clock_.Advance( | |
90 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | |
91 cast_msg_builder_->set_clock(&testing_clock_); | |
92 } | |
93 | |
94 ~CastMessageBuilderTest() { } | |
95 | |
96 void SetFrameId(uint8 frame_id) { | |
97 rtp_header_.frame_id = frame_id; | |
98 } | |
99 | |
100 void SetPacketId(uint16 packet_id) { | |
101 rtp_header_.packet_id = packet_id; | |
102 } | |
103 | |
104 void SetMaxPacketId(uint16 max_packet_id) { | |
105 rtp_header_.max_packet_id = max_packet_id; | |
106 } | |
107 | |
108 void SetKeyFrame(bool is_key) { | |
109 rtp_header_.is_key_frame = is_key; | |
110 } | |
111 | |
112 void SetReferenceFrameId(uint8 reference_frame_id) { | |
113 rtp_header_.is_reference = true; | |
114 rtp_header_.reference_frame_id = reference_frame_id; | |
115 } | |
116 | |
117 void InsertPacket() { | |
118 bool complete = false; | |
119 frame_id_map_.InsertPacket(rtp_header_, &complete); | |
120 if (complete) { | |
121 cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id, | |
122 rtp_header_.is_key_frame); | |
123 } | |
124 cast_msg_builder_->UpdateCastMessage(); | |
125 } | |
126 | |
127 void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) { | |
128 delete cast_msg_builder_; | |
129 cast_msg_builder_ = new CastMessageBuilder(feedback_, | |
130 &frame_id_map_, | |
131 kSsrc, | |
132 false, | |
133 max_unacked_frames); | |
134 } | |
135 | |
136 CastMessageBuilder* cast_msg_builder_; | |
Alpha Left Google
2013/08/28 00:27:31
Use scoped_ptr<>.
pwestin
2013/08/28 16:40:44
Done.
| |
137 NackFeedbackVerification* feedback_; | |
138 RtpCastHeader rtp_header_; | |
139 FrameIdMap frame_id_map_; | |
140 base::SimpleTestTickClock testing_clock_; | |
141 }; | |
142 | |
143 TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) { | |
144 SetFrameId(3); | |
145 SetPacketId(0); | |
146 SetMaxPacketId(0); | |
147 InsertPacket(); | |
148 // Should not trigger ack. | |
149 EXPECT_FALSE(feedback_->triggered()); | |
150 SetFrameId(5); | |
151 SetPacketId(0); | |
152 SetMaxPacketId(0); | |
153 SetKeyFrame(true); | |
154 InsertPacket(); | |
155 frame_id_map_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering. | |
156 testing_clock_.Advance( | |
157 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
158 cast_msg_builder_->UpdateCastMessage(); | |
159 EXPECT_TRUE(feedback_->triggered()); | |
160 EXPECT_EQ(5, feedback_->last_frame_acked()); | |
161 } | |
162 | |
163 TEST_F(CastMessageBuilderTest, OneFrameNackList) { | |
164 SetFrameId(0); | |
165 SetPacketId(4); | |
166 SetMaxPacketId(10); | |
167 InsertPacket(); | |
168 testing_clock_.Advance( | |
169 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
170 EXPECT_FALSE(feedback_->triggered()); | |
171 testing_clock_.Advance( | |
172 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
173 SetPacketId(5); | |
174 InsertPacket(); | |
175 EXPECT_TRUE(feedback_->triggered()); | |
176 EXPECT_EQ(4, feedback_->num_missing_packets(0)); | |
177 } | |
178 | |
179 TEST_F(CastMessageBuilderTest, CompleteFrameMissing) { | |
180 // TODO(mikhal): Add indication. | |
181 SetFrameId(0); | |
182 SetPacketId(2); | |
183 SetMaxPacketId(5); | |
184 InsertPacket(); | |
185 testing_clock_.Advance( | |
186 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
187 SetFrameId(2); | |
188 SetPacketId(2); | |
189 SetMaxPacketId(5); | |
190 InsertPacket(); | |
191 } | |
192 | |
193 TEST_F(CastMessageBuilderTest, FastForwardAck) { | |
194 SetFrameId(1); | |
195 SetPacketId(0); | |
196 SetMaxPacketId(0); | |
197 InsertPacket(); | |
198 EXPECT_FALSE(feedback_->triggered()); | |
199 testing_clock_.Advance( | |
200 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
201 SetFrameId(2); | |
202 SetPacketId(0); | |
203 SetMaxPacketId(0); | |
204 InsertPacket(); | |
205 EXPECT_TRUE(feedback_->triggered()); | |
206 EXPECT_EQ(255, feedback_->last_frame_acked()); | |
207 testing_clock_.Advance( | |
208 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
209 SetFrameId(0); | |
210 SetPacketId(0); | |
211 SetMaxPacketId(0); | |
212 SetKeyFrame(true); | |
213 InsertPacket(); | |
214 EXPECT_TRUE(feedback_->triggered()); | |
215 EXPECT_EQ(2, feedback_->last_frame_acked()); | |
216 } | |
217 | |
218 TEST_F(CastMessageBuilderTest, RemoveOldFrames) { | |
219 SetFrameId(1); | |
220 SetPacketId(0); | |
221 SetMaxPacketId(1); | |
222 InsertPacket(); | |
223 EXPECT_FALSE(feedback_->triggered()); | |
224 testing_clock_.Advance( | |
225 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
226 SetFrameId(2); | |
227 SetPacketId(0); | |
228 SetMaxPacketId(0); | |
229 InsertPacket(); | |
230 EXPECT_TRUE(feedback_->triggered()); | |
231 testing_clock_.Advance( | |
232 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
233 SetFrameId(3); | |
234 SetPacketId(0); | |
235 SetMaxPacketId(5); | |
236 InsertPacket(); | |
237 EXPECT_TRUE(feedback_->triggered()); | |
238 EXPECT_EQ(255, feedback_->last_frame_acked()); | |
239 testing_clock_.Advance( | |
240 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
241 SetFrameId(5); | |
242 SetPacketId(0); | |
243 SetMaxPacketId(0); | |
244 SetKeyFrame(true); | |
245 InsertPacket(); | |
246 testing_clock_.Advance( | |
247 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
248 frame_id_map_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering. | |
249 cast_msg_builder_->UpdateCastMessage(); | |
250 EXPECT_TRUE(feedback_->triggered()); | |
251 EXPECT_EQ(5, feedback_->last_frame_acked()); | |
252 testing_clock_.Advance( | |
253 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
254 SetFrameId(1); | |
255 SetPacketId(1); | |
256 SetMaxPacketId(1); | |
257 InsertPacket(); | |
258 EXPECT_FALSE(feedback_->triggered()); | |
259 testing_clock_.Advance( | |
260 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
261 InsertPacket(); | |
262 EXPECT_TRUE(feedback_->triggered()); | |
263 EXPECT_EQ(5, feedback_->last_frame_acked()); | |
264 } | |
265 | |
266 TEST_F(CastMessageBuilderTest, WrapFastForward) { | |
267 SetFrameId(254); | |
268 SetPacketId(0); | |
269 SetMaxPacketId(1); | |
270 SetKeyFrame(true); | |
271 InsertPacket(); | |
272 EXPECT_FALSE(feedback_->triggered()); | |
273 testing_clock_.Advance( | |
274 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
275 SetFrameId(255); | |
276 SetPacketId(0); | |
277 SetMaxPacketId(0); | |
278 SetKeyFrame(false); | |
279 InsertPacket(); | |
280 EXPECT_TRUE(feedback_->triggered()); | |
281 EXPECT_EQ(253, feedback_->last_frame_acked()); | |
282 testing_clock_.Advance( | |
283 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
284 SetFrameId(0); | |
285 SetPacketId(0); | |
286 SetMaxPacketId(0); | |
287 SetKeyFrame(false); | |
288 InsertPacket(); | |
289 EXPECT_TRUE(feedback_->triggered()); | |
290 EXPECT_EQ(253, feedback_->last_frame_acked()); | |
291 testing_clock_.Advance( | |
292 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
293 SetFrameId(254); | |
294 SetPacketId(1); | |
295 SetMaxPacketId(1); | |
296 SetKeyFrame(true); | |
297 InsertPacket(); | |
298 EXPECT_TRUE(feedback_->triggered()); | |
299 EXPECT_EQ(0, feedback_->last_frame_acked()); | |
300 } | |
301 | |
302 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) { | |
303 SetFrameId(0); | |
304 SetPacketId(0); | |
305 SetMaxPacketId(20); | |
306 SetKeyFrame(true); | |
307 InsertPacket(); | |
308 testing_clock_.Advance( | |
309 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
310 SetPacketId(5); | |
311 InsertPacket(); | |
312 EXPECT_TRUE(feedback_->triggered()); | |
313 EXPECT_EQ(4, feedback_->num_missing_packets(0)); | |
314 } | |
315 | |
316 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) { | |
317 SetFrameId(0); | |
318 SetPacketId(0); | |
319 SetMaxPacketId(20); | |
320 SetKeyFrame(true); | |
321 InsertPacket(); | |
322 testing_clock_.Advance( | |
323 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
324 SetPacketId(5); | |
325 InsertPacket(); | |
326 testing_clock_.Advance( | |
327 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
328 EXPECT_TRUE(feedback_->triggered()); | |
329 EXPECT_EQ(4, feedback_->num_missing_packets(0)); | |
330 SetFrameId(1); | |
331 SetMaxPacketId(2); | |
332 SetPacketId(0); | |
333 SetKeyFrame(false); | |
334 InsertPacket(); | |
335 testing_clock_.Advance( | |
336 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
337 EXPECT_TRUE(feedback_->triggered()); | |
338 EXPECT_EQ(21 - 2, feedback_->num_missing_packets(0)); | |
339 } | |
340 | |
341 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) { | |
342 SetFrameId(0); | |
343 SetPacketId(0); | |
344 SetMaxPacketId(20); | |
345 SetKeyFrame(true); | |
346 InsertPacket(); | |
347 testing_clock_.Advance( | |
348 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
349 SetPacketId(5); | |
350 InsertPacket(); | |
351 testing_clock_.Advance( | |
352 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
353 EXPECT_TRUE(feedback_->triggered()); | |
354 EXPECT_EQ(4, feedback_->num_missing_packets(0)); | |
355 SetFrameId(1); | |
356 SetMaxPacketId(0); | |
357 SetPacketId(0); | |
358 SetKeyFrame(true); | |
359 InsertPacket(); | |
360 testing_clock_.Advance( | |
361 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
362 EXPECT_TRUE(feedback_->triggered()); | |
363 EXPECT_EQ(0, feedback_->num_missing_packets(0)); | |
364 } | |
365 | |
366 TEST_F(CastMessageBuilderTest, Reset) { | |
367 InsertPacket(); | |
368 testing_clock_.Advance( | |
369 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
370 cast_msg_builder_->Reset(); | |
371 frame_id_map_.Clear(); | |
372 // Should reset nack list state and request a key frame. | |
373 cast_msg_builder_->UpdateCastMessage(); | |
374 EXPECT_TRUE(feedback_->triggered()); | |
375 EXPECT_EQ(0, feedback_->num_missing_packets(0)); | |
376 } | |
377 | |
378 TEST_F(CastMessageBuilderTest, DeltaAfterReset) { | |
379 SetFrameId(0); | |
380 SetPacketId(0); | |
381 SetMaxPacketId(0); | |
382 SetKeyFrame(true); | |
383 InsertPacket(); | |
384 EXPECT_TRUE(feedback_->triggered()); | |
385 EXPECT_EQ(0, feedback_->num_missing_packets(0)); | |
386 testing_clock_.Advance( | |
387 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
388 cast_msg_builder_->Reset(); | |
389 SetFrameId(1); | |
390 SetPacketId(0); | |
391 SetMaxPacketId(0); | |
392 SetKeyFrame(true); | |
393 EXPECT_FALSE(feedback_->triggered()); | |
394 } | |
395 | |
396 TEST_F(CastMessageBuilderTest, BasicRps) { | |
397 SetFrameId(0); | |
398 SetPacketId(0); | |
399 SetMaxPacketId(0); | |
400 SetKeyFrame(true); | |
401 InsertPacket(); | |
402 testing_clock_.Advance( | |
403 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
404 EXPECT_TRUE(feedback_->triggered()); | |
405 EXPECT_EQ(0, feedback_->last_frame_acked()); | |
406 SetFrameId(3); | |
407 SetKeyFrame(false); | |
408 SetReferenceFrameId(0); | |
409 InsertPacket(); | |
410 EXPECT_TRUE(feedback_->triggered()); | |
411 EXPECT_EQ(0, feedback_->last_frame_acked()); | |
412 testing_clock_.Advance( | |
413 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); | |
414 frame_id_map_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering. | |
415 cast_msg_builder_->UpdateCastMessage(); | |
416 EXPECT_TRUE(feedback_->triggered()); | |
417 EXPECT_EQ(3, feedback_->last_frame_acked()); | |
418 } | |
419 | |
420 TEST_F(CastMessageBuilderTest, InOrderRps) { | |
421 // Create a pattern - skip to rps, and don't look back. | |
422 SetFrameId(0); | |
423 SetPacketId(0); | |
424 SetMaxPacketId(0); | |
425 SetKeyFrame(true); | |
426 InsertPacket(); | |
427 testing_clock_.Advance( | |
428 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
429 EXPECT_TRUE(feedback_->triggered()); | |
430 EXPECT_EQ(0, feedback_->last_frame_acked()); | |
431 SetFrameId(1); | |
432 SetPacketId(0); | |
433 SetMaxPacketId(1); | |
434 SetKeyFrame(false); | |
435 InsertPacket(); | |
436 testing_clock_.Advance( | |
437 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
438 EXPECT_FALSE(feedback_->triggered()); | |
439 SetFrameId(3); | |
440 SetPacketId(0); | |
441 SetMaxPacketId(0); | |
442 SetKeyFrame(false); | |
443 SetReferenceFrameId(0); | |
444 InsertPacket(); | |
445 testing_clock_.Advance( | |
446 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
447 frame_id_map_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering. | |
448 testing_clock_.Advance( | |
449 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
450 cast_msg_builder_->UpdateCastMessage(); | |
451 EXPECT_TRUE(feedback_->triggered()); | |
452 EXPECT_EQ(3, feedback_->last_frame_acked()); | |
453 // Make an old frame complete - should not trigger an ack. | |
454 SetFrameId(1); | |
455 SetPacketId(1); | |
456 SetMaxPacketId(1); | |
457 SetKeyFrame(false); | |
458 InsertPacket(); | |
459 testing_clock_.Advance( | |
460 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
461 EXPECT_FALSE(feedback_->triggered()); | |
462 EXPECT_EQ(3, feedback_->last_frame_acked()); | |
463 } | |
464 | |
465 TEST_F(CastMessageBuilderTest, SlowDownAck) { | |
466 SetDecoderSlowerThanMaxFrameRate(3); | |
467 SetFrameId(0); | |
468 SetPacketId(0); | |
469 SetMaxPacketId(0); | |
470 SetKeyFrame(true); | |
471 InsertPacket(); | |
472 | |
473 int frame_id; | |
474 testing_clock_.Advance( | |
475 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
476 SetKeyFrame(false); | |
477 for (frame_id = 1; frame_id < 3; ++frame_id) { | |
478 EXPECT_TRUE(feedback_->triggered()); | |
479 EXPECT_EQ(frame_id - 1, feedback_->last_frame_acked()); | |
480 SetFrameId(frame_id); | |
481 InsertPacket(); | |
482 testing_clock_.Advance( | |
483 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
484 } | |
485 // We should now have entered the slowdown ACK state. | |
486 uint8_t expected_frame_id = 1; | |
487 for (; frame_id < 10; ++frame_id) { | |
488 if (frame_id % 2) ++expected_frame_id; | |
489 EXPECT_TRUE(feedback_->triggered()); | |
490 EXPECT_EQ(expected_frame_id, feedback_->last_frame_acked()); | |
491 SetFrameId(frame_id); | |
492 InsertPacket(); | |
493 testing_clock_.Advance( | |
494 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
495 } | |
496 EXPECT_TRUE(feedback_->triggered()); | |
497 EXPECT_EQ(expected_frame_id, feedback_->last_frame_acked()); | |
498 | |
499 // Simulate frame_id being pulled for rendering. | |
500 frame_id_map_.RemoveOldFrames(frame_id); | |
501 // We should now leave the slowdown ACK state. | |
502 ++frame_id; | |
503 SetFrameId(frame_id); | |
504 InsertPacket(); | |
505 testing_clock_.Advance( | |
506 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | |
507 EXPECT_TRUE(feedback_->triggered()); | |
508 EXPECT_EQ(frame_id, feedback_->last_frame_acked()); | |
509 } | |
510 | |
511 } // namespace cast | |
512 } // namespace media | |
OLD | NEW |