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
{}
83 void SetUp() 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_
.incoming_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_
;
149 DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest
);
152 TEST_F(FrameReceiverTest
, RejectsUnparsablePackets
) {
153 CreateFrameReceiverOfVideo();
155 SimpleEventSubscriber event_subscriber
;
156 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
158 const bool success
= receiver_
->ProcessPacket(
159 scoped_ptr
<Packet
>(new Packet(kPacketSize
, 0xff)).Pass());
160 EXPECT_FALSE(success
);
162 // Confirm no log events.
163 std::vector
<FrameEvent
> frame_events
;
164 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
165 EXPECT_TRUE(frame_events
.empty());
166 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
169 TEST_F(FrameReceiverTest
, ReceivesOneFrame
) {
170 CreateFrameReceiverOfAudio();
172 SimpleEventSubscriber event_subscriber
;
173 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
175 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
176 .WillRepeatedly(testing::Return());
178 FeedLipSyncInfoIntoReceiver();
179 task_runner_
->RunTasks();
181 // Enqueue a request for a frame.
182 receiver_
->RequestEncodedFrame(
183 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
184 base::Unretained(&frame_client_
)));
186 // The request should not be satisfied since no packets have been received.
187 task_runner_
->RunTasks();
188 EXPECT_EQ(0, frame_client_
.number_times_called());
190 // Deliver one frame to the receiver and expect to get one frame back.
191 const base::TimeDelta target_playout_delay
=
192 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
193 frame_client_
.AddExpectedResult(
194 kFirstFrameId
, testing_clock_
->NowTicks() + target_playout_delay
);
195 FeedOneFrameIntoReceiver();
196 task_runner_
->RunTasks();
197 EXPECT_EQ(1, frame_client_
.number_times_called());
199 // Was the frame logged?
200 std::vector
<FrameEvent
> frame_events
;
201 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
202 ASSERT_TRUE(!frame_events
.empty());
203 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
.begin()->type
);
204 EXPECT_EQ(AUDIO_EVENT
, frame_events
.begin()->media_type
);
205 EXPECT_EQ(rtp_header_
.frame_id
, frame_events
.begin()->frame_id
);
206 EXPECT_EQ(rtp_header_
.rtp_timestamp
, frame_events
.begin()->rtp_timestamp
);
207 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
210 TEST_F(FrameReceiverTest
, ReceivesFramesSkippingWhenAppropriate
) {
211 CreateFrameReceiverOfAudio();
213 SimpleEventSubscriber event_subscriber
;
214 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
216 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
217 .WillRepeatedly(testing::Return());
219 const uint32 rtp_advance_per_frame
=
220 config_
.rtp_timebase
/ config_
.target_frame_rate
;
221 const base::TimeDelta time_advance_per_frame
=
222 base::TimeDelta::FromSeconds(1) / config_
.target_frame_rate
;
224 // Feed and process lip sync in receiver.
225 FeedLipSyncInfoIntoReceiver();
226 task_runner_
->RunTasks();
227 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
229 // Enqueue a request for a frame.
230 const ReceiveEncodedFrameCallback frame_encoded_callback
=
231 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
232 base::Unretained(&frame_client_
));
233 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
234 task_runner_
->RunTasks();
235 EXPECT_EQ(0, frame_client_
.number_times_called());
237 // Receive one frame and expect to see the first request satisfied.
238 const base::TimeDelta target_playout_delay
=
239 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
240 frame_client_
.AddExpectedResult(
241 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
242 rtp_header_
.rtp_timestamp
= 0;
243 FeedOneFrameIntoReceiver(); // Frame 1
244 task_runner_
->RunTasks();
245 EXPECT_EQ(1, frame_client_
.number_times_called());
247 // Enqueue a second request for a frame, but it should not be fulfilled yet.
248 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
249 task_runner_
->RunTasks();
250 EXPECT_EQ(1, frame_client_
.number_times_called());
252 // Receive one frame out-of-order: Make sure that we are not continuous and
253 // that the RTP timestamp represents a time in the future.
254 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
255 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
256 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
257 frame_client_
.AddExpectedResult(
259 first_frame_capture_time
+ 2 * time_advance_per_frame
+
260 target_playout_delay
);
261 FeedOneFrameIntoReceiver(); // Frame 3
263 // Frame 2 should not come out at this point in time.
264 task_runner_
->RunTasks();
265 EXPECT_EQ(1, frame_client_
.number_times_called());
267 // Enqueue a third request for a frame.
268 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
269 task_runner_
->RunTasks();
270 EXPECT_EQ(1, frame_client_
.number_times_called());
272 // Now, advance time forward such that the receiver is convinced it should
273 // skip Frame 2. Frame 3 is emitted (to satisfy the second request) because a
274 // decision was made to skip over the no-show Frame 2.
275 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
276 task_runner_
->RunTasks();
277 EXPECT_EQ(2, frame_client_
.number_times_called());
279 // Receive Frame 4 and expect it to fulfill the third request immediately.
280 rtp_header_
.frame_id
= kFirstFrameId
+ 3; // "Frame 4"
281 rtp_header_
.reference_frame_id
= rtp_header_
.frame_id
;
282 rtp_header_
.rtp_timestamp
+= rtp_advance_per_frame
;
283 frame_client_
.AddExpectedResult(
284 kFirstFrameId
+ 3, first_frame_capture_time
+ 3 * time_advance_per_frame
+
285 target_playout_delay
);
286 FeedOneFrameIntoReceiver(); // Frame 4
287 task_runner_
->RunTasks();
288 EXPECT_EQ(3, frame_client_
.number_times_called());
290 // Move forward to the playout time of an unreceived Frame 5. Expect no
291 // additional frames were emitted.
292 testing_clock_
->Advance(3 * time_advance_per_frame
);
293 task_runner_
->RunTasks();
294 EXPECT_EQ(3, frame_client_
.number_times_called());
296 // Were only non-skipped frames logged?
297 std::vector
<FrameEvent
> frame_events
;
298 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
299 ASSERT_TRUE(!frame_events
.empty());
300 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
301 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
302 EXPECT_EQ(AUDIO_EVENT
, frame_events
[i
].media_type
);
303 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
304 EXPECT_GE(kFirstFrameId
+ 4, frame_events
[i
].frame_id
);
305 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
306 EXPECT_NE(frame_offset
, 1); // Frame 2 never received.
307 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
308 frame_events
[i
].rtp_timestamp
);
310 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
313 TEST_F(FrameReceiverTest
, ReceivesFramesRefusingToSkipAny
) {
314 CreateFrameReceiverOfVideo();
316 SimpleEventSubscriber event_subscriber
;
317 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
319 EXPECT_CALL(mock_transport_
, SendRtcpFromRtpReceiver(_
, _
, _
, _
, _
, _
, _
))
320 .WillRepeatedly(testing::Return());
322 const uint32 rtp_advance_per_frame
=
323 config_
.rtp_timebase
/ config_
.target_frame_rate
;
324 const base::TimeDelta time_advance_per_frame
=
325 base::TimeDelta::FromSeconds(1) / config_
.target_frame_rate
;
327 // Feed and process lip sync in receiver.
328 FeedLipSyncInfoIntoReceiver();
329 task_runner_
->RunTasks();
330 const base::TimeTicks first_frame_capture_time
= testing_clock_
->NowTicks();
332 // Enqueue a request for a frame.
333 const ReceiveEncodedFrameCallback frame_encoded_callback
=
334 base::Bind(&FakeFrameClient::DeliverEncodedFrame
,
335 base::Unretained(&frame_client_
));
336 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
337 task_runner_
->RunTasks();
338 EXPECT_EQ(0, frame_client_
.number_times_called());
340 // Receive one frame and expect to see the first request satisfied.
341 const base::TimeDelta target_playout_delay
=
342 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis
);
343 frame_client_
.AddExpectedResult(
344 kFirstFrameId
, first_frame_capture_time
+ target_playout_delay
);
345 rtp_header_
.rtp_timestamp
= 0;
346 FeedOneFrameIntoReceiver(); // Frame 1
347 task_runner_
->RunTasks();
348 EXPECT_EQ(1, frame_client_
.number_times_called());
350 // Enqueue a second request for a frame, but it should not be fulfilled yet.
351 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
352 task_runner_
->RunTasks();
353 EXPECT_EQ(1, frame_client_
.number_times_called());
355 // Receive one frame out-of-order: Make sure that we are not continuous and
356 // that the RTP timestamp represents a time in the future.
357 rtp_header_
.is_key_frame
= false;
358 rtp_header_
.frame_id
= kFirstFrameId
+ 2; // "Frame 3"
359 rtp_header_
.reference_frame_id
= kFirstFrameId
+ 1; // "Frame 2"
360 rtp_header_
.rtp_timestamp
+= 2 * rtp_advance_per_frame
;
361 FeedOneFrameIntoReceiver(); // Frame 3
363 // Frame 2 should not come out at this point in time.
364 task_runner_
->RunTasks();
365 EXPECT_EQ(1, frame_client_
.number_times_called());
367 // Enqueue a third request for a frame.
368 receiver_
->RequestEncodedFrame(frame_encoded_callback
);
369 task_runner_
->RunTasks();
370 EXPECT_EQ(1, frame_client_
.number_times_called());
372 // Now, advance time forward such that Frame 2 is now too late for playback.
373 // Regardless, the receiver must NOT emit Frame 3 yet because it is not
374 // allowed to skip frames when dependencies are not satisfied. In other
375 // words, Frame 3 is not decodable without Frame 2.
376 testing_clock_
->Advance(2 * time_advance_per_frame
+ target_playout_delay
);
377 task_runner_
->RunTasks();
378 EXPECT_EQ(1, frame_client_
.number_times_called());
380 // Now receive Frame 2 and expect both the second and third requests to be
381 // fulfilled immediately.
382 frame_client_
.AddExpectedResult(
383 kFirstFrameId
+ 1, // "Frame 2"
384 first_frame_capture_time
+ 1 * time_advance_per_frame
+
385 target_playout_delay
);
386 frame_client_
.AddExpectedResult(
387 kFirstFrameId
+ 2, // "Frame 3"
388 first_frame_capture_time
+ 2 * time_advance_per_frame
+
389 target_playout_delay
);
390 --rtp_header_
.frame_id
; // "Frame 2"
391 --rtp_header_
.reference_frame_id
; // "Frame 1"
392 rtp_header_
.rtp_timestamp
-= rtp_advance_per_frame
;
393 FeedOneFrameIntoReceiver(); // Frame 2
394 task_runner_
->RunTasks();
395 EXPECT_EQ(3, frame_client_
.number_times_called());
397 // Move forward to the playout time of an unreceived Frame 5. Expect no
398 // additional frames were emitted.
399 testing_clock_
->Advance(3 * time_advance_per_frame
);
400 task_runner_
->RunTasks();
401 EXPECT_EQ(3, frame_client_
.number_times_called());
403 // Sanity-check logging results.
404 std::vector
<FrameEvent
> frame_events
;
405 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
406 ASSERT_TRUE(!frame_events
.empty());
407 for (size_t i
= 0; i
< frame_events
.size(); ++i
) {
408 EXPECT_EQ(FRAME_ACK_SENT
, frame_events
[i
].type
);
409 EXPECT_EQ(VIDEO_EVENT
, frame_events
[i
].media_type
);
410 EXPECT_LE(kFirstFrameId
, frame_events
[i
].frame_id
);
411 EXPECT_GE(kFirstFrameId
+ 3, frame_events
[i
].frame_id
);
412 const int frame_offset
= frame_events
[i
].frame_id
- kFirstFrameId
;
413 EXPECT_EQ(frame_offset
* rtp_advance_per_frame
,
414 frame_events
[i
].rtp_timestamp
);
416 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);