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.
4
5#include <deque>
6#include <utility>
7
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/receiver/frame_receiver.h"
16#include "media/cast/rtcp/test_rtcp_packet_builder.h"
17#include "media/cast/test/fake_single_thread_task_runner.h"
18#include "media/cast/test/utility/default_config.h"
19#include "media/cast/transport/pacing/mock_paced_packet_sender.h"
20#include "testing/gmock/include/gmock/gmock.h"
21
22using ::testing::_;
23
24namespace media {
25namespace cast {
26
27namespace {
28
29const int kPacketSize = 1500;
30const uint32 kFirstFrameId = 1234;
31const int kPlayoutDelayMillis = 100;
32
33class FakeFrameClient {
34 public:
35  FakeFrameClient() : num_called_(0) {}
36  virtual ~FakeFrameClient() {}
37
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));
42  }
43
44  void DeliverEncodedFrame(scoped_ptr<transport::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_;
53  }
54
55  int number_times_called() const { return num_called_; }
56
57 private:
58  std::deque<std::pair<uint32, base::TimeTicks> > expected_results_;
59  int num_called_;
60
61  DISALLOW_COPY_AND_ASSIGN(FakeFrameClient);
62};
63}  // namespace
64
65class 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_);
72
73    cast_environment_ =
74        new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
75                            task_runner_,
76                            task_runner_,
77                            task_runner_);
78  }
79
80  virtual ~FrameReceiverTest() {}
81
82  virtual void SetUp() {
83    payload_.assign(kPacketSize, 0);
84
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;
92  }
93
94  void CreateFrameReceiverOfAudio() {
95    config_ = GetDefaultAudioReceiverConfig();
96    config_.rtp_max_delay_ms = kPlayoutDelayMillis;
97
98    receiver_.reset(new FrameReceiver(
99        cast_environment_, config_, AUDIO_EVENT, &mock_transport_));
100  }
101
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;
108
109    receiver_.reset(new FrameReceiver(
110        cast_environment_, config_, VIDEO_EVENT, &mock_transport_));
111  }
112
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());
117  }
118
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()));
132  }
133
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  transport::MockPacedPacketSender mock_transport_;
140  scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
141  scoped_refptr<CastEnvironment> cast_environment_;
142  FakeFrameClient frame_client_;
143
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_;
147
148  DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest);
149};
150
151TEST_F(FrameReceiverTest, RejectsUnparsablePackets) {
152  CreateFrameReceiverOfVideo();
153
154  SimpleEventSubscriber event_subscriber;
155  cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
156
157  const bool success = receiver_->ProcessPacket(
158      scoped_ptr<Packet>(new Packet(kPacketSize, 0xff)).Pass());
159  EXPECT_FALSE(success);
160
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);
166}
167
168TEST_F(FrameReceiverTest, ReceivesOneFrame) {
169  CreateFrameReceiverOfAudio();
170
171  SimpleEventSubscriber event_subscriber;
172  cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
173
174  EXPECT_CALL(mock_transport_, SendRtcpPacket(_, _))
175      .WillRepeatedly(testing::Return(true));
176
177  FeedLipSyncInfoIntoReceiver();
178  task_runner_->RunTasks();
179
180  // Enqueue a request for a frame.
181  receiver_->RequestEncodedFrame(
182      base::Bind(&FakeFrameClient::DeliverEncodedFrame,
183                 base::Unretained(&frame_client_)));
184
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());
188
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());
197
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);
207}
208
209TEST_F(FrameReceiverTest, ReceivesFramesSkippingWhenAppropriate) {
210  CreateFrameReceiverOfAudio();
211
212  SimpleEventSubscriber event_subscriber;
213  cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
214
215  EXPECT_CALL(mock_transport_, SendRtcpPacket(_, _))
216      .WillRepeatedly(testing::Return(true));
217
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;
222
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();
227
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());
235
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());
245
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());
250
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
261
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());
265
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());
270
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());
277
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());
288
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());
294
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);
308  }
309  cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
310}
311
312TEST_F(FrameReceiverTest, ReceivesFramesRefusingToSkipAny) {
313  CreateFrameReceiverOfVideo();
314
315  SimpleEventSubscriber event_subscriber;
316  cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
317
318  EXPECT_CALL(mock_transport_, SendRtcpPacket(_, _))
319      .WillRepeatedly(testing::Return(true));
320
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;
325
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();
330
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());
338
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());
348
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());
353
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
361
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());
365
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());
370
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());
378
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());
395
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());
401
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);
414  }
415  cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
416}
417
418}  // namespace cast
419}  // namespace media
420