Roll leveldb 3f7758:803d69 (v1.17 -> v1.18)
[chromium-blink-merge.git] / media / cast / receiver / frame_receiver_unittest.cc
blob24e1a0b9eebe93f13cb41d69e47a37edeea88ab5
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.
5 #include <deque>
6 #include <utility>
8 #include "base/bind.h"
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"
22 using ::testing::_;
24 namespace media {
25 namespace cast {
27 namespace {
29 const int kPacketSize = 1500;
30 const uint32 kFirstFrameId = 1234;
31 const int kPlayoutDelayMillis = 100;
33 class FakeFrameClient {
34 public:
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_);
46 ASSERT_FALSE(!frame)
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();
52 ++num_called_;
55 int number_times_called() const { return num_called_; }
57 private:
58 std::deque<std::pair<uint32, base::TimeTicks> > expected_results_;
59 int num_called_;
61 DISALLOW_COPY_AND_ASSIGN(FakeFrameClient);
63 } // namespace
65 class FrameReceiverTest : public ::testing::Test {
66 protected:
67 FrameReceiverTest() {
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_);
73 cast_environment_ =
74 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
75 task_runner_,
76 task_runner_,
77 task_runner_);
80 ~FrameReceiverTest() override {}
82 void SetUp() override {
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_[0], 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);
124 uint32 ntp_seconds;
125 uint32 ntp_fraction;
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(
257 kFirstFrameId + 2,
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);
418 } // namespace cast
419 } // namespace media