1 // Copyright 2014 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.
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "media/cast/cast_defines.h"
13 #include "media/cast/cast_environment.h"
14 #include "media/cast/logging/simple_event_subscriber.h"
15 #include "media/cast/net/pacing/mock_paced_packet_sender.h"
16 #include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
17 #include "media/cast/receiver/frame_receiver.h"
18 #include "media/cast/test/fake_single_thread_task_runner.h"
19 #include "media/cast/test/utility/default_config.h"
20 #include "testing/gmock/include/gmock/gmock.h"
29 const int kPacketSize
= 1500;
30 const uint32 kFirstFrameId
= 1234;
31 const int kPlayoutDelayMillis
= 100;
33 class FakeFrameClient
{
35 FakeFrameClient() : num_called_(0) {}
36 virtual ~FakeFrameClient() {}
38 void AddExpectedResult(uint32 expected_frame_id
,
39 const base::TimeTicks
& expected_playout_time
) {
40 expected_results_
.push_back(
41 std::make_pair(expected_frame_id
, expected_playout_time
));
44 void DeliverEncodedFrame(scoped_ptr
<EncodedFrame
> frame
) {
45 SCOPED_TRACE(::testing::Message() << "num_called_ is " << num_called_
);
47 << "If at shutdown: There were unsatisfied requests enqueued.";
48 ASSERT_FALSE(expected_results_
.empty());
49 EXPECT_EQ(expected_results_
.front().first
, frame
->frame_id
);
50 EXPECT_EQ(expected_results_
.front().second
, frame
->reference_time
);
51 expected_results_
.pop_front();
55 int number_times_called() const { return num_called_
; }
58 std::deque
<std::pair
<uint32
, base::TimeTicks
> > expected_results_
;
61 DISALLOW_COPY_AND_ASSIGN(FakeFrameClient
);
65 class FrameReceiverTest
: public ::testing::Test
{
68 testing_clock_
= new base::SimpleTestTickClock();
69 testing_clock_
->Advance(base::TimeTicks::Now() - base::TimeTicks());
70 start_time_
= testing_clock_
->NowTicks();
71 task_runner_
= new test::FakeSingleThreadTaskRunner(testing_clock_
);
74 new CastEnvironment(scoped_ptr
<base::TickClock
>(testing_clock_
).Pass(),
80 virtual ~FrameReceiverTest() {}
82 virtual void SetUp() {
83 payload_
.assign(kPacketSize
, 0);
85 // Always start with a key frame.
86 rtp_header_
.is_key_frame
= true;
87 rtp_header_
.frame_id
= kFirstFrameId
;
88 rtp_header_
.packet_id
= 0;
89 rtp_header_
.max_packet_id
= 0;
90 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
91 rtp_header_
.rtp_timestamp
= 0;
94 void CreateFrameReceiverOfAudio() {
95 config_
= GetDefaultAudioReceiverConfig();
96 config_
.rtp_max_delay_ms
= kPlayoutDelayMillis
;
98 receiver_
.reset(new FrameReceiver(
99 cast_environment_
, config_
, AUDIO_EVENT
, &mock_transport_
));
102 void CreateFrameReceiverOfVideo() {
103 config_
= GetDefaultVideoReceiverConfig();
104 config_
.rtp_max_delay_ms
= kPlayoutDelayMillis
;
105 // Note: Frame rate must divide 1000 without remainder so the test code
106 // doesn't have to account for rounding errors.
107 config_
.max_frame_rate
= 25;
109 receiver_
.reset(new FrameReceiver(
110 cast_environment_
, config_
, VIDEO_EVENT
, &mock_transport_
));
113 void FeedOneFrameIntoReceiver() {
114 // Note: For testing purposes, a frame consists of only a single packet.
115 receiver_
->ProcessParsedPacket(
116 rtp_header_
, payload_
.data(), payload_
.size());
119 void FeedLipSyncInfoIntoReceiver() {
120 const base::TimeTicks now
= testing_clock_
->NowTicks();
121 const int64 rtp_timestamp
= (now
- start_time_
) *
122 config_
.frequency
/ base::TimeDelta::FromSeconds(1);
123 CHECK_LE(0, rtp_timestamp
);
126 ConvertTimeTicksToNtp(now
, &ntp_seconds
, &ntp_fraction
);
127 TestRtcpPacketBuilder rtcp_packet
;
128 rtcp_packet
.AddSrWithNtp(config_
.incoming_ssrc
,
129 ntp_seconds
, ntp_fraction
,
130 static_cast<uint32
>(rtp_timestamp
));
131 ASSERT_TRUE(receiver_
->ProcessPacket(rtcp_packet
.GetPacket().Pass()));
134 FrameReceiverConfig config_
;
135 std::vector
<uint8
> payload_
;
136 RtpCastHeader rtp_header_
;
137 base::SimpleTestTickClock
* testing_clock_
; // Owned by CastEnvironment.
138 base::TimeTicks start_time_
;
139 MockPacedPacketSender mock_transport_
;
140 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
141 scoped_refptr
<CastEnvironment
> cast_environment_
;
142 FakeFrameClient frame_client_
;
144 // Important for the FrameReceiver to be declared last, since its dependencies
145 // must remain alive until after its destruction.
146 scoped_ptr
<FrameReceiver
> receiver_
;
148 DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest
);
151 TEST_F(FrameReceiverTest
, RejectsUnparsablePackets
) {
152 CreateFrameReceiverOfVideo();
154 SimpleEventSubscriber event_subscriber
;
155 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
157 const bool success
= receiver_
->ProcessPacket(
158 scoped_ptr
<Packet
>(new Packet(kPacketSize
, 0xff)).Pass());
159 EXPECT_FALSE(success
);
161 // Confirm no log events.
162 std::vector
<FrameEvent
> frame_events
;
163 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
164 EXPECT_TRUE(frame_events
.empty());
165 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
168 TEST_F(FrameReceiverTest
, ReceivesOneFrame
) {
169 CreateFrameReceiverOfAudio();
171 SimpleEventSubscriber event_subscriber
;
172 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
174 EXPECT_CALL(mock_transport_
, SendRtcpPacket(_
, _
))
175 .WillRepeatedly(testing::Return(true));
177 FeedLipSyncInfoIntoReceiver();
178 task_runner_
->RunTasks();
180 // Enqueue a request for a frame.
181 receiver_
->RequestEncodedFrame(
182 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
183 base::Unretained(&frame_client_
)));
185 // The request should not be satisfied since no packets have been received.
186 task_runner_
->RunTasks();
187 EXPECT_EQ(0, frame_client_
.number_times_called());
189 // Deliver one frame to the receiver and expect to get one frame back.
190 const base::TimeDelta target_playout_delay
=
191 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
192 frame_client_
.AddExpectedResult(
193 kFirstFrameId
, testing_clock_
->NowTicks() + target_playout_delay
);
194 FeedOneFrameIntoReceiver();
195 task_runner_
->RunTasks();
196 EXPECT_EQ(1, frame_client_
.number_times_called());
198 // Was the frame logged?
199 std::vector
<FrameEvent
> frame_events
;
200 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
201 ASSERT_TRUE(!frame_events
.empty());
202 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
.begin()->type
);
203 EXPECT_EQ(AUDIO_EVENT
, frame_events
.begin()->media_type
);
204 EXPECT_EQ(rtp_header_
.frame_id
, frame_events
.begin()->frame_id
);
205 EXPECT_EQ(rtp_header_
.rtp_timestamp
, frame_events
.begin()->rtp_timestamp
);
206 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
209 TEST_F(FrameReceiverTest
, ReceivesFramesSkippingWhenAppropriate
) {
210 CreateFrameReceiverOfAudio();
212 SimpleEventSubscriber event_subscriber
;
213 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
215 EXPECT_CALL(mock_transport_
, SendRtcpPacket(_
, _
))
216 .WillRepeatedly(testing::Return(true));
218 const uint32 rtp_advance_per_frame
=
219 config_
.frequency
/ config_
.max_frame_rate
;
220 const base::TimeDelta time_advance_per_frame
=
221 base::TimeDelta::FromSeconds(1) / config_
.max_frame_rate
;
223 // Feed and process lip sync in receiver.
224 FeedLipSyncInfoIntoReceiver();
225 task_runner_
->RunTasks();
226 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
228 // Enqueue a request for a frame.
229 const ReceiveEncodedFrameCallback frame_encoded_callback
=
230 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
231 base::Unretained(&frame_client_
));
232 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
233 task_runner_
->RunTasks();
234 EXPECT_EQ(0, frame_client_
.number_times_called());
236 // Receive one frame and expect to see the first request satisfied.
237 const base::TimeDelta target_playout_delay
=
238 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
239 frame_client_
.AddExpectedResult(
240 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
241 rtp_header_
.rtp_timestamp
= 0;
242 FeedOneFrameIntoReceiver(); // Frame 1
243 task_runner_
->RunTasks();
244 EXPECT_EQ(1, frame_client_
.number_times_called());
246 // Enqueue a second request for a frame, but it should not be fulfilled yet.
247 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
248 task_runner_
->RunTasks();
249 EXPECT_EQ(1, frame_client_
.number_times_called());
251 // Receive one frame out-of-order: Make sure that we are not continuous and
252 // that the RTP timestamp represents a time in the future.
253 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
254 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
255 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
256 frame_client_
.AddExpectedResult(
258 first_frame_capture_time
+ 2 * time_advance_per_frame
+
259 target_playout_delay
);
260 FeedOneFrameIntoReceiver(); // Frame 3
262 // Frame 2 should not come out at this point in time.
263 task_runner_
->RunTasks();
264 EXPECT_EQ(1, frame_client_
.number_times_called());
266 // Enqueue a third request for a frame.
267 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
268 task_runner_
->RunTasks();
269 EXPECT_EQ(1, frame_client_
.number_times_called());
271 // Now, advance time forward such that the receiver is convinced it should
272 // skip Frame 2. Frame 3 is emitted (to satisfy the second request) because a
273 // decision was made to skip over the no-show Frame 2.
274 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
275 task_runner_
->RunTasks();
276 EXPECT_EQ(2, frame_client_
.number_times_called());
278 // Receive Frame 4 and expect it to fulfill the third request immediately.
279 rtp_header_
.frame_id
= kFirstFrameId
+ 3; // "Frame 4"
280 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
281 rtp_header_
.rtp_timestamp
+= rtp_advance_per_frame
;
282 frame_client_
.AddExpectedResult(
283 kFirstFrameId
+ 3, first_frame_capture_time
+ 3 * time_advance_per_frame
+
284 target_playout_delay
);
285 FeedOneFrameIntoReceiver(); // Frame 4
286 task_runner_
->RunTasks();
287 EXPECT_EQ(3, frame_client_
.number_times_called());
289 // Move forward to the playout time of an unreceived Frame 5. Expect no
290 // additional frames were emitted.
291 testing_clock_
->Advance(3 * time_advance_per_frame
);
292 task_runner_
->RunTasks();
293 EXPECT_EQ(3, frame_client_
.number_times_called());
295 // Were only non-skipped frames logged?
296 std::vector
<FrameEvent
> frame_events
;
297 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
298 ASSERT_TRUE(!frame_events
.empty());
299 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
300 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
301 EXPECT_EQ(AUDIO_EVENT
, frame_events
[i
].media_type
);
302 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
303 EXPECT_GE(kFirstFrameId
+ 4, frame_events
[i
].frame_id
);
304 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
305 EXPECT_NE(frame_offset
, 1); // Frame 2 never received.
306 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
307 frame_events
[i
].rtp_timestamp
);
309 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
312 TEST_F(FrameReceiverTest
, ReceivesFramesRefusingToSkipAny
) {
313 CreateFrameReceiverOfVideo();
315 SimpleEventSubscriber event_subscriber
;
316 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
318 EXPECT_CALL(mock_transport_
, SendRtcpPacket(_
, _
))
319 .WillRepeatedly(testing::Return(true));
321 const uint32 rtp_advance_per_frame
=
322 config_
.frequency
/ config_
.max_frame_rate
;
323 const base::TimeDelta time_advance_per_frame
=
324 base::TimeDelta::FromSeconds(1) / config_
.max_frame_rate
;
326 // Feed and process lip sync in receiver.
327 FeedLipSyncInfoIntoReceiver();
328 task_runner_
->RunTasks();
329 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
331 // Enqueue a request for a frame.
332 const ReceiveEncodedFrameCallback frame_encoded_callback
=
333 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
334 base::Unretained(&frame_client_
));
335 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
336 task_runner_
->RunTasks();
337 EXPECT_EQ(0, frame_client_
.number_times_called());
339 // Receive one frame and expect to see the first request satisfied.
340 const base::TimeDelta target_playout_delay
=
341 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
342 frame_client_
.AddExpectedResult(
343 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
344 rtp_header_
.rtp_timestamp
= 0;
345 FeedOneFrameIntoReceiver(); // Frame 1
346 task_runner_
->RunTasks();
347 EXPECT_EQ(1, frame_client_
.number_times_called());
349 // Enqueue a second request for a frame, but it should not be fulfilled yet.
350 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
351 task_runner_
->RunTasks();
352 EXPECT_EQ(1, frame_client_
.number_times_called());
354 // Receive one frame out-of-order: Make sure that we are not continuous and
355 // that the RTP timestamp represents a time in the future.
356 rtp_header_
.is_key_frame
= false;
357 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
358 rtp_header_
.reference_frame_id
= kFirstFrameId
+ 1; // "Frame 2"
359 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
360 FeedOneFrameIntoReceiver(); // Frame 3
362 // Frame 2 should not come out at this point in time.
363 task_runner_
->RunTasks();
364 EXPECT_EQ(1, frame_client_
.number_times_called());
366 // Enqueue a third request for a frame.
367 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
368 task_runner_
->RunTasks();
369 EXPECT_EQ(1, frame_client_
.number_times_called());
371 // Now, advance time forward such that Frame 2 is now too late for playback.
372 // Regardless, the receiver must NOT emit Frame 3 yet because it is not
373 // allowed to skip frames when dependencies are not satisfied. In other
374 // words, Frame 3 is not decodable without Frame 2.
375 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
376 task_runner_
->RunTasks();
377 EXPECT_EQ(1, frame_client_
.number_times_called());
379 // Now receive Frame 2 and expect both the second and third requests to be
380 // fulfilled immediately.
381 frame_client_
.AddExpectedResult(
382 kFirstFrameId
+ 1, // "Frame 2"
383 first_frame_capture_time
+ 1 * time_advance_per_frame
+
384 target_playout_delay
);
385 frame_client_
.AddExpectedResult(
386 kFirstFrameId
+ 2, // "Frame 3"
387 first_frame_capture_time
+ 2 * time_advance_per_frame
+
388 target_playout_delay
);
389 --rtp_header_
.frame_id
; // "Frame 2"
390 --rtp_header_
.reference_frame_id
; // "Frame 1"
391 rtp_header_
.rtp_timestamp
-= rtp_advance_per_frame
;
392 FeedOneFrameIntoReceiver(); // Frame 2
393 task_runner_
->RunTasks();
394 EXPECT_EQ(3, frame_client_
.number_times_called());
396 // Move forward to the playout time of an unreceived Frame 5. Expect no
397 // additional frames were emitted.
398 testing_clock_
->Advance(3 * time_advance_per_frame
);
399 task_runner_
->RunTasks();
400 EXPECT_EQ(3, frame_client_
.number_times_called());
402 // Sanity-check logging results.
403 std::vector
<FrameEvent
> frame_events
;
404 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
405 ASSERT_TRUE(!frame_events
.empty());
406 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
407 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
408 EXPECT_EQ(VIDEO_EVENT
, frame_events
[i
].media_type
);
409 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
410 EXPECT_GE(kFirstFrameId
+ 3, frame_events
[i
].frame_id
);
411 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
412 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
413 frame_events
[i
].rtp_timestamp
);
415 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);