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