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/cast_transport_sender_impl.h"
16 #include "media/cast/net/mock_cast_transport_sender.h"
17 #include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
18 #include "media/cast/receiver/frame_receiver.h"
19 #include "media/cast/test/fake_single_thread_task_runner.h"
20 #include "media/cast/test/utility/default_config.h"
21 #include "testing/gmock/include/gmock/gmock.h"
30 const int kPacketSize
= 1500;
31 const uint32 kFirstFrameId
= 1234;
32 const int kPlayoutDelayMillis
= 100;
34 class FakeFrameClient
{
36 FakeFrameClient() : num_called_(0) {}
37 virtual ~FakeFrameClient() {}
39 void AddExpectedResult(uint32 expected_frame_id
,
40 const base::TimeTicks
& expected_playout_time
) {
41 expected_results_
.push_back(
42 std::make_pair(expected_frame_id
, expected_playout_time
));
45 void DeliverEncodedFrame(scoped_ptr
<EncodedFrame
> frame
) {
46 SCOPED_TRACE(::testing::Message() << "num_called_ is " << num_called_
);
48 << "If at shutdown: There were unsatisfied requests enqueued.";
49 ASSERT_FALSE(expected_results_
.empty());
50 EXPECT_EQ(expected_results_
.front().first
, frame
->frame_id
);
51 EXPECT_EQ(expected_results_
.front().second
, frame
->reference_time
);
52 expected_results_
.pop_front();
56 int number_times_called() const { return num_called_
; }
59 std::deque
<std::pair
<uint32
, base::TimeTicks
> > expected_results_
;
62 DISALLOW_COPY_AND_ASSIGN(FakeFrameClient
);
66 class FrameReceiverTest
: public ::testing::Test
{
69 testing_clock_
= new base::SimpleTestTickClock();
70 testing_clock_
->Advance(base::TimeTicks::Now() - base::TimeTicks());
71 start_time_
= testing_clock_
->NowTicks();
72 task_runner_
= new test::FakeSingleThreadTaskRunner(testing_clock_
);
75 new CastEnvironment(scoped_ptr
<base::TickClock
>(testing_clock_
).Pass(),
81 ~FrameReceiverTest() override
{}
84 payload_
.assign(kPacketSize
, 0);
86 // Always start with a key frame.
87 rtp_header_
.is_key_frame
= true;
88 rtp_header_
.frame_id
= kFirstFrameId
;
89 rtp_header_
.packet_id
= 0;
90 rtp_header_
.max_packet_id
= 0;
91 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
92 rtp_header_
.rtp_timestamp
= 0;
95 void CreateFrameReceiverOfAudio() {
96 config_
= GetDefaultAudioReceiverConfig();
97 config_
.rtp_max_delay_ms
= kPlayoutDelayMillis
;
99 receiver_
.reset(new FrameReceiver(
100 cast_environment_
, config_
, AUDIO_EVENT
, &mock_transport_
));
103 void CreateFrameReceiverOfVideo() {
104 config_
= GetDefaultVideoReceiverConfig();
105 config_
.rtp_max_delay_ms
= kPlayoutDelayMillis
;
106 // Note: Frame rate must divide 1000 without remainder so the test code
107 // doesn't have to account for rounding errors.
108 config_
.target_frame_rate
= 25;
110 receiver_
.reset(new FrameReceiver(
111 cast_environment_
, config_
, VIDEO_EVENT
, &mock_transport_
));
114 void FeedOneFrameIntoReceiver() {
115 // Note: For testing purposes, a frame consists of only a single packet.
116 receiver_
->ProcessParsedPacket(
117 rtp_header_
, &payload_
[0], payload_
.size());
120 void FeedLipSyncInfoIntoReceiver() {
121 const base::TimeTicks now
= testing_clock_
->NowTicks();
122 const int64 rtp_timestamp
= (now
- start_time_
) *
123 config_
.rtp_timebase
/ base::TimeDelta::FromSeconds(1);
124 CHECK_LE(0, rtp_timestamp
);
127 ConvertTimeTicksToNtp(now
, &ntp_seconds
, &ntp_fraction
);
128 TestRtcpPacketBuilder rtcp_packet
;
129 rtcp_packet
.AddSrWithNtp(config_
.sender_ssrc
,
130 ntp_seconds
, ntp_fraction
,
131 static_cast<uint32
>(rtp_timestamp
));
132 ASSERT_TRUE(receiver_
->ProcessPacket(rtcp_packet
.GetPacket().Pass()));
135 FrameReceiverConfig config_
;
136 std::vector
<uint8
> payload_
;
137 RtpCastHeader rtp_header_
;
138 base::SimpleTestTickClock
* testing_clock_
; // Owned by CastEnvironment.
139 base::TimeTicks start_time_
;
140 MockCastTransportSender mock_transport_
;
141 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
142 scoped_refptr
<CastEnvironment
> cast_environment_
;
143 FakeFrameClient frame_client_
;
145 // Important for the FrameReceiver to be declared last, since its dependencies
146 // must remain alive until after its destruction.
147 scoped_ptr
<FrameReceiver
> receiver_
;
150 DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest
);
153 TEST_F(FrameReceiverTest
, RejectsUnparsablePackets
) {
154 CreateFrameReceiverOfVideo();
156 SimpleEventSubscriber event_subscriber
;
157 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
159 const bool success
= receiver_
->ProcessPacket(
160 scoped_ptr
<Packet
>(new Packet(kPacketSize
, 0xff)).Pass());
161 EXPECT_FALSE(success
);
163 // Confirm no log events.
164 std::vector
<FrameEvent
> frame_events
;
165 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
166 EXPECT_TRUE(frame_events
.empty());
167 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
170 TEST_F(FrameReceiverTest
, ReceivesOneFrame
) {
171 CreateFrameReceiverOfAudio();
173 SimpleEventSubscriber event_subscriber
;
174 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
176 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
177 .WillRepeatedly(testing::Return());
179 FeedLipSyncInfoIntoReceiver();
180 task_runner_
->RunTasks();
182 // Enqueue a request for a frame.
183 receiver_
->RequestEncodedFrame(
184 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
185 base::Unretained(&frame_client_
)));
187 // The request should not be satisfied since no packets have been received.
188 task_runner_
->RunTasks();
189 EXPECT_EQ(0, frame_client_
.number_times_called());
191 // Deliver one frame to the receiver and expect to get one frame back.
192 const base::TimeDelta target_playout_delay
=
193 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
194 frame_client_
.AddExpectedResult(
195 kFirstFrameId
, testing_clock_
->NowTicks() + target_playout_delay
);
196 FeedOneFrameIntoReceiver();
197 task_runner_
->RunTasks();
198 EXPECT_EQ(1, frame_client_
.number_times_called());
200 // Was the frame logged?
201 std::vector
<FrameEvent
> frame_events
;
202 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
203 ASSERT_TRUE(!frame_events
.empty());
204 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
.begin()->type
);
205 EXPECT_EQ(AUDIO_EVENT
, frame_events
.begin()->media_type
);
206 EXPECT_EQ(rtp_header_
.frame_id
, frame_events
.begin()->frame_id
);
207 EXPECT_EQ(rtp_header_
.rtp_timestamp
, frame_events
.begin()->rtp_timestamp
);
208 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
211 TEST_F(FrameReceiverTest
, ReceivesFramesSkippingWhenAppropriate
) {
212 CreateFrameReceiverOfAudio();
214 SimpleEventSubscriber event_subscriber
;
215 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
217 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
218 .WillRepeatedly(testing::Return());
220 const uint32 rtp_advance_per_frame
=
221 config_
.rtp_timebase
/ config_
.target_frame_rate
;
222 const base::TimeDelta time_advance_per_frame
=
223 base::TimeDelta::FromSeconds(1) / config_
.target_frame_rate
;
225 // Feed and process lip sync in receiver.
226 FeedLipSyncInfoIntoReceiver();
227 task_runner_
->RunTasks();
228 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
230 // Enqueue a request for a frame.
231 const ReceiveEncodedFrameCallback frame_encoded_callback
=
232 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
233 base::Unretained(&frame_client_
));
234 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
235 task_runner_
->RunTasks();
236 EXPECT_EQ(0, frame_client_
.number_times_called());
238 // Receive one frame and expect to see the first request satisfied.
239 const base::TimeDelta target_playout_delay
=
240 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
241 frame_client_
.AddExpectedResult(
242 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
243 rtp_header_
.rtp_timestamp
= 0;
244 FeedOneFrameIntoReceiver(); // Frame 1
245 task_runner_
->RunTasks();
246 EXPECT_EQ(1, frame_client_
.number_times_called());
248 // Enqueue a second request for a frame, but it should not be fulfilled yet.
249 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
250 task_runner_
->RunTasks();
251 EXPECT_EQ(1, frame_client_
.number_times_called());
253 // Receive one frame out-of-order: Make sure that we are not continuous and
254 // that the RTP timestamp represents a time in the future.
255 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
256 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
257 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
258 frame_client_
.AddExpectedResult(
260 first_frame_capture_time
+ 2 * time_advance_per_frame
+
261 target_playout_delay
);
262 FeedOneFrameIntoReceiver(); // Frame 3
264 // Frame 2 should not come out at this point in time.
265 task_runner_
->RunTasks();
266 EXPECT_EQ(1, frame_client_
.number_times_called());
268 // Enqueue a third request for a frame.
269 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
270 task_runner_
->RunTasks();
271 EXPECT_EQ(1, frame_client_
.number_times_called());
273 // Now, advance time forward such that the receiver is convinced it should
274 // skip Frame 2. Frame 3 is emitted (to satisfy the second request) because a
275 // decision was made to skip over the no-show Frame 2.
276 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
277 task_runner_
->RunTasks();
278 EXPECT_EQ(2, frame_client_
.number_times_called());
280 // Receive Frame 4 and expect it to fulfill the third request immediately.
281 rtp_header_
.frame_id
= kFirstFrameId
+ 3; // "Frame 4"
282 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
283 rtp_header_
.rtp_timestamp
+= rtp_advance_per_frame
;
284 frame_client_
.AddExpectedResult(
285 kFirstFrameId
+ 3, first_frame_capture_time
+ 3 * time_advance_per_frame
+
286 target_playout_delay
);
287 FeedOneFrameIntoReceiver(); // Frame 4
288 task_runner_
->RunTasks();
289 EXPECT_EQ(3, frame_client_
.number_times_called());
291 // Move forward to the playout time of an unreceived Frame 5. Expect no
292 // additional frames were emitted.
293 testing_clock_
->Advance(3 * time_advance_per_frame
);
294 task_runner_
->RunTasks();
295 EXPECT_EQ(3, frame_client_
.number_times_called());
297 // Were only non-skipped frames logged?
298 std::vector
<FrameEvent
> frame_events
;
299 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
300 ASSERT_TRUE(!frame_events
.empty());
301 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
302 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
303 EXPECT_EQ(AUDIO_EVENT
, frame_events
[i
].media_type
);
304 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
305 EXPECT_GE(kFirstFrameId
+ 4, frame_events
[i
].frame_id
);
306 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
307 EXPECT_NE(frame_offset
, 1); // Frame 2 never received.
308 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
309 frame_events
[i
].rtp_timestamp
);
311 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
314 TEST_F(FrameReceiverTest
, ReceivesFramesRefusingToSkipAny
) {
315 CreateFrameReceiverOfVideo();
317 SimpleEventSubscriber event_subscriber
;
318 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
320 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
321 .WillRepeatedly(testing::Return());
323 const uint32 rtp_advance_per_frame
=
324 config_
.rtp_timebase
/ config_
.target_frame_rate
;
325 const base::TimeDelta time_advance_per_frame
=
326 base::TimeDelta::FromSeconds(1) / config_
.target_frame_rate
;
328 // Feed and process lip sync in receiver.
329 FeedLipSyncInfoIntoReceiver();
330 task_runner_
->RunTasks();
331 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
333 // Enqueue a request for a frame.
334 const ReceiveEncodedFrameCallback frame_encoded_callback
=
335 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
336 base::Unretained(&frame_client_
));
337 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
338 task_runner_
->RunTasks();
339 EXPECT_EQ(0, frame_client_
.number_times_called());
341 // Receive one frame and expect to see the first request satisfied.
342 const base::TimeDelta target_playout_delay
=
343 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
344 frame_client_
.AddExpectedResult(
345 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
346 rtp_header_
.rtp_timestamp
= 0;
347 FeedOneFrameIntoReceiver(); // Frame 1
348 task_runner_
->RunTasks();
349 EXPECT_EQ(1, frame_client_
.number_times_called());
351 // Enqueue a second request for a frame, but it should not be fulfilled yet.
352 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
353 task_runner_
->RunTasks();
354 EXPECT_EQ(1, frame_client_
.number_times_called());
356 // Receive one frame out-of-order: Make sure that we are not continuous and
357 // that the RTP timestamp represents a time in the future.
358 rtp_header_
.is_key_frame
= false;
359 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
360 rtp_header_
.reference_frame_id
= kFirstFrameId
+ 1; // "Frame 2"
361 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
362 FeedOneFrameIntoReceiver(); // Frame 3
364 // Frame 2 should not come out at this point in time.
365 task_runner_
->RunTasks();
366 EXPECT_EQ(1, frame_client_
.number_times_called());
368 // Enqueue a third request for a frame.
369 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
370 task_runner_
->RunTasks();
371 EXPECT_EQ(1, frame_client_
.number_times_called());
373 // Now, advance time forward such that Frame 2 is now too late for playback.
374 // Regardless, the receiver must NOT emit Frame 3 yet because it is not
375 // allowed to skip frames when dependencies are not satisfied. In other
376 // words, Frame 3 is not decodable without Frame 2.
377 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
378 task_runner_
->RunTasks();
379 EXPECT_EQ(1, frame_client_
.number_times_called());
381 // Now receive Frame 2 and expect both the second and third requests to be
382 // fulfilled immediately.
383 frame_client_
.AddExpectedResult(
384 kFirstFrameId
+ 1, // "Frame 2"
385 first_frame_capture_time
+ 1 * time_advance_per_frame
+
386 target_playout_delay
);
387 frame_client_
.AddExpectedResult(
388 kFirstFrameId
+ 2, // "Frame 3"
389 first_frame_capture_time
+ 2 * time_advance_per_frame
+
390 target_playout_delay
);
391 --rtp_header_
.frame_id
; // "Frame 2"
392 --rtp_header_
.reference_frame_id
; // "Frame 1"
393 rtp_header_
.rtp_timestamp
-= rtp_advance_per_frame
;
394 FeedOneFrameIntoReceiver(); // Frame 2
395 task_runner_
->RunTasks();
396 EXPECT_EQ(3, frame_client_
.number_times_called());
398 // Move forward to the playout time of an unreceived Frame 5. Expect no
399 // additional frames were emitted.
400 testing_clock_
->Advance(3 * time_advance_per_frame
);
401 task_runner_
->RunTasks();
402 EXPECT_EQ(3, frame_client_
.number_times_called());
404 // Sanity-check logging results.
405 std::vector
<FrameEvent
> frame_events
;
406 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
407 ASSERT_TRUE(!frame_events
.empty());
408 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
409 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
410 EXPECT_EQ(VIDEO_EVENT
, frame_events
[i
].media_type
);
411 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
412 EXPECT_GE(kFirstFrameId
+ 3, frame_events
[i
].frame_id
);
413 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
414 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
415 frame_events
[i
].rtp_timestamp
);
417 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);