| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 void SetUp() final { | 84 void SetUp() final { |
| 85 payload_.assign(kPacketSize, 0); | 85 payload_.assign(kPacketSize, 0); |
| 86 | 86 |
| 87 // Always start with a key frame. | 87 // Always start with a key frame. |
| 88 rtp_header_.is_key_frame = true; | 88 rtp_header_.is_key_frame = true; |
| 89 rtp_header_.frame_id = kFirstFrameId; | 89 rtp_header_.frame_id = kFirstFrameId; |
| 90 rtp_header_.packet_id = 0; | 90 rtp_header_.packet_id = 0; |
| 91 rtp_header_.max_packet_id = 0; | 91 rtp_header_.max_packet_id = 0; |
| 92 rtp_header_.reference_frame_id = rtp_header_.frame_id; | 92 rtp_header_.reference_frame_id = rtp_header_.frame_id; |
| 93 rtp_header_.rtp_timestamp = 0; | 93 rtp_header_.rtp_timestamp = RtpTimeTicks(); |
| 94 } | 94 } |
| 95 | 95 |
| 96 void CreateFrameReceiverOfAudio() { | 96 void CreateFrameReceiverOfAudio() { |
| 97 config_ = GetDefaultAudioReceiverConfig(); | 97 config_ = GetDefaultAudioReceiverConfig(); |
| 98 config_.rtp_max_delay_ms = kPlayoutDelayMillis; | 98 config_.rtp_max_delay_ms = kPlayoutDelayMillis; |
| 99 | 99 |
| 100 receiver_.reset(new FrameReceiver( | 100 receiver_.reset(new FrameReceiver( |
| 101 cast_environment_, config_, AUDIO_EVENT, &mock_transport_)); | 101 cast_environment_, config_, AUDIO_EVENT, &mock_transport_)); |
| 102 } | 102 } |
| 103 | 103 |
| 104 void CreateFrameReceiverOfVideo() { | 104 void CreateFrameReceiverOfVideo() { |
| 105 config_ = GetDefaultVideoReceiverConfig(); | 105 config_ = GetDefaultVideoReceiverConfig(); |
| 106 config_.rtp_max_delay_ms = kPlayoutDelayMillis; | 106 config_.rtp_max_delay_ms = kPlayoutDelayMillis; |
| 107 // Note: Frame rate must divide 1000 without remainder so the test code | 107 // Note: Frame rate must divide 1000 without remainder so the test code |
| 108 // doesn't have to account for rounding errors. | 108 // doesn't have to account for rounding errors. |
| 109 config_.target_frame_rate = 25; | 109 config_.target_frame_rate = 25; |
| 110 | 110 |
| 111 receiver_.reset(new FrameReceiver( | 111 receiver_.reset(new FrameReceiver( |
| 112 cast_environment_, config_, VIDEO_EVENT, &mock_transport_)); | 112 cast_environment_, config_, VIDEO_EVENT, &mock_transport_)); |
| 113 } | 113 } |
| 114 | 114 |
| 115 void FeedOneFrameIntoReceiver() { | 115 void FeedOneFrameIntoReceiver() { |
| 116 // Note: For testing purposes, a frame consists of only a single packet. | 116 // Note: For testing purposes, a frame consists of only a single packet. |
| 117 receiver_->ProcessParsedPacket( | 117 receiver_->ProcessParsedPacket( |
| 118 rtp_header_, &payload_[0], payload_.size()); | 118 rtp_header_, &payload_[0], payload_.size()); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void FeedLipSyncInfoIntoReceiver() { | 121 void FeedLipSyncInfoIntoReceiver() { |
| 122 const base::TimeTicks now = testing_clock_->NowTicks(); | 122 const base::TimeTicks now = testing_clock_->NowTicks(); |
| 123 const int64_t rtp_timestamp = (now - start_time_) * config_.rtp_timebase / | 123 const RtpTimeTicks rtp_timestamp = |
| 124 base::TimeDelta::FromSeconds(1); | 124 RtpTimeTicks::FromTimeDelta(now - start_time_, config_.rtp_timebase); |
| 125 CHECK_LE(0, rtp_timestamp); | 125 CHECK_LE(RtpTimeTicks(), rtp_timestamp); |
| 126 uint32_t ntp_seconds; | 126 uint32_t ntp_seconds; |
| 127 uint32_t ntp_fraction; | 127 uint32_t ntp_fraction; |
| 128 ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); | 128 ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); |
| 129 TestRtcpPacketBuilder rtcp_packet; | 129 TestRtcpPacketBuilder rtcp_packet; |
| 130 rtcp_packet.AddSrWithNtp(config_.sender_ssrc, ntp_seconds, ntp_fraction, | 130 rtcp_packet.AddSrWithNtp(config_.sender_ssrc, ntp_seconds, ntp_fraction, |
| 131 static_cast<uint32_t>(rtp_timestamp)); | 131 rtp_timestamp.lower_32_bits()); |
| 132 ASSERT_TRUE(receiver_->ProcessPacket(rtcp_packet.GetPacket())); | 132 ASSERT_TRUE(receiver_->ProcessPacket(rtcp_packet.GetPacket().Pass())); |
| 133 } | 133 } |
| 134 | 134 |
| 135 FrameReceiverConfig config_; | 135 FrameReceiverConfig config_; |
| 136 std::vector<uint8_t> payload_; | 136 std::vector<uint8_t> payload_; |
| 137 RtpCastHeader rtp_header_; | 137 RtpCastHeader rtp_header_; |
| 138 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. | 138 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. |
| 139 base::TimeTicks start_time_; | 139 base::TimeTicks start_time_; |
| 140 MockCastTransportSender mock_transport_; | 140 MockCastTransportSender mock_transport_; |
| 141 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 141 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
| 142 scoped_refptr<CastEnvironment> cast_environment_; | 142 scoped_refptr<CastEnvironment> cast_environment_; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 | 210 |
| 211 TEST_F(FrameReceiverTest, ReceivesFramesSkippingWhenAppropriate) { | 211 TEST_F(FrameReceiverTest, ReceivesFramesSkippingWhenAppropriate) { |
| 212 CreateFrameReceiverOfAudio(); | 212 CreateFrameReceiverOfAudio(); |
| 213 | 213 |
| 214 SimpleEventSubscriber event_subscriber; | 214 SimpleEventSubscriber event_subscriber; |
| 215 cast_environment_->logger()->Subscribe(&event_subscriber); | 215 cast_environment_->logger()->Subscribe(&event_subscriber); |
| 216 | 216 |
| 217 EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver(_, _, _, _, _, _, _)) | 217 EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver(_, _, _, _, _, _, _)) |
| 218 .WillRepeatedly(testing::Return()); | 218 .WillRepeatedly(testing::Return()); |
| 219 | 219 |
| 220 const uint32_t rtp_advance_per_frame = | |
| 221 config_.rtp_timebase / config_.target_frame_rate; | |
| 222 const base::TimeDelta time_advance_per_frame = | 220 const base::TimeDelta time_advance_per_frame = |
| 223 base::TimeDelta::FromSeconds(1) / config_.target_frame_rate; | 221 base::TimeDelta::FromSeconds(1) / config_.target_frame_rate; |
| 222 const RtpTimeDelta rtp_advance_per_frame = |
| 223 RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase); |
| 224 | 224 |
| 225 // Feed and process lip sync in receiver. | 225 // Feed and process lip sync in receiver. |
| 226 FeedLipSyncInfoIntoReceiver(); | 226 FeedLipSyncInfoIntoReceiver(); |
| 227 task_runner_->RunTasks(); | 227 task_runner_->RunTasks(); |
| 228 const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks(); | 228 const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks(); |
| 229 | 229 |
| 230 // Enqueue a request for a frame. | 230 // Enqueue a request for a frame. |
| 231 const ReceiveEncodedFrameCallback frame_encoded_callback = | 231 const ReceiveEncodedFrameCallback frame_encoded_callback = |
| 232 base::Bind(&FakeFrameClient::DeliverEncodedFrame, | 232 base::Bind(&FakeFrameClient::DeliverEncodedFrame, |
| 233 base::Unretained(&frame_client_)); | 233 base::Unretained(&frame_client_)); |
| 234 receiver_->RequestEncodedFrame(frame_encoded_callback); | 234 receiver_->RequestEncodedFrame(frame_encoded_callback); |
| 235 task_runner_->RunTasks(); | 235 task_runner_->RunTasks(); |
| 236 EXPECT_EQ(0, frame_client_.number_times_called()); | 236 EXPECT_EQ(0, frame_client_.number_times_called()); |
| 237 | 237 |
| 238 // Receive one frame and expect to see the first request satisfied. | 238 // Receive one frame and expect to see the first request satisfied. |
| 239 const base::TimeDelta target_playout_delay = | 239 const base::TimeDelta target_playout_delay = |
| 240 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis); | 240 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis); |
| 241 frame_client_.AddExpectedResult( | 241 frame_client_.AddExpectedResult( |
| 242 kFirstFrameId, first_frame_capture_time + target_playout_delay); | 242 kFirstFrameId, first_frame_capture_time + target_playout_delay); |
| 243 rtp_header_.rtp_timestamp = 0; | 243 rtp_header_.rtp_timestamp = RtpTimeTicks(); |
| 244 FeedOneFrameIntoReceiver(); // Frame 1 | 244 FeedOneFrameIntoReceiver(); // Frame 1 |
| 245 task_runner_->RunTasks(); | 245 task_runner_->RunTasks(); |
| 246 EXPECT_EQ(1, frame_client_.number_times_called()); | 246 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 247 | 247 |
| 248 // Enqueue a second request for a frame, but it should not be fulfilled yet. | 248 // Enqueue a second request for a frame, but it should not be fulfilled yet. |
| 249 receiver_->RequestEncodedFrame(frame_encoded_callback); | 249 receiver_->RequestEncodedFrame(frame_encoded_callback); |
| 250 task_runner_->RunTasks(); | 250 task_runner_->RunTasks(); |
| 251 EXPECT_EQ(1, frame_client_.number_times_called()); | 251 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 252 | 252 |
| 253 // Receive one frame out-of-order: Make sure that we are not continuous and | 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. | 254 // that the RTP timestamp represents a time in the future. |
| 255 rtp_header_.frame_id = kFirstFrameId + 2; // "Frame 3" | 255 rtp_header_.frame_id = kFirstFrameId + 2; // "Frame 3" |
| 256 rtp_header_.reference_frame_id = rtp_header_.frame_id; | 256 rtp_header_.reference_frame_id = rtp_header_.frame_id; |
| 257 rtp_header_.rtp_timestamp += 2 * rtp_advance_per_frame; | 257 rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2; |
| 258 frame_client_.AddExpectedResult( | 258 frame_client_.AddExpectedResult( |
| 259 kFirstFrameId + 2, | 259 kFirstFrameId + 2, |
| 260 first_frame_capture_time + 2 * time_advance_per_frame + | 260 first_frame_capture_time + 2 * time_advance_per_frame + |
| 261 target_playout_delay); | 261 target_playout_delay); |
| 262 FeedOneFrameIntoReceiver(); // Frame 3 | 262 FeedOneFrameIntoReceiver(); // Frame 3 |
| 263 | 263 |
| 264 // Frame 2 should not come out at this point in time. | 264 // Frame 2 should not come out at this point in time. |
| 265 task_runner_->RunTasks(); | 265 task_runner_->RunTasks(); |
| 266 EXPECT_EQ(1, frame_client_.number_times_called()); | 266 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 267 | 267 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 298 std::vector<FrameEvent> frame_events; | 298 std::vector<FrameEvent> frame_events; |
| 299 event_subscriber.GetFrameEventsAndReset(&frame_events); | 299 event_subscriber.GetFrameEventsAndReset(&frame_events); |
| 300 ASSERT_TRUE(!frame_events.empty()); | 300 ASSERT_TRUE(!frame_events.empty()); |
| 301 for (size_t i = 0; i < frame_events.size(); ++i) { | 301 for (size_t i = 0; i < frame_events.size(); ++i) { |
| 302 EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type); | 302 EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type); |
| 303 EXPECT_EQ(AUDIO_EVENT, frame_events[i].media_type); | 303 EXPECT_EQ(AUDIO_EVENT, frame_events[i].media_type); |
| 304 EXPECT_LE(kFirstFrameId, frame_events[i].frame_id); | 304 EXPECT_LE(kFirstFrameId, frame_events[i].frame_id); |
| 305 EXPECT_GE(kFirstFrameId + 4, 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; | 306 const int frame_offset = frame_events[i].frame_id - kFirstFrameId; |
| 307 EXPECT_NE(frame_offset, 1); // Frame 2 never received. | 307 EXPECT_NE(frame_offset, 1); // Frame 2 never received. |
| 308 EXPECT_EQ(frame_offset * rtp_advance_per_frame, | 308 EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset), |
| 309 frame_events[i].rtp_timestamp); | 309 frame_events[i].rtp_timestamp); |
| 310 } | 310 } |
| 311 cast_environment_->logger()->Unsubscribe(&event_subscriber); | 311 cast_environment_->logger()->Unsubscribe(&event_subscriber); |
| 312 } | 312 } |
| 313 | 313 |
| 314 TEST_F(FrameReceiverTest, ReceivesFramesRefusingToSkipAny) { | 314 TEST_F(FrameReceiverTest, ReceivesFramesRefusingToSkipAny) { |
| 315 CreateFrameReceiverOfVideo(); | 315 CreateFrameReceiverOfVideo(); |
| 316 | 316 |
| 317 SimpleEventSubscriber event_subscriber; | 317 SimpleEventSubscriber event_subscriber; |
| 318 cast_environment_->logger()->Subscribe(&event_subscriber); | 318 cast_environment_->logger()->Subscribe(&event_subscriber); |
| 319 | 319 |
| 320 EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver(_, _, _, _, _, _, _)) | 320 EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver(_, _, _, _, _, _, _)) |
| 321 .WillRepeatedly(testing::Return()); | 321 .WillRepeatedly(testing::Return()); |
| 322 | 322 |
| 323 const uint32_t rtp_advance_per_frame = | |
| 324 config_.rtp_timebase / config_.target_frame_rate; | |
| 325 const base::TimeDelta time_advance_per_frame = | 323 const base::TimeDelta time_advance_per_frame = |
| 326 base::TimeDelta::FromSeconds(1) / config_.target_frame_rate; | 324 base::TimeDelta::FromSeconds(1) / config_.target_frame_rate; |
| 325 const RtpTimeDelta rtp_advance_per_frame = |
| 326 RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase); |
| 327 | 327 |
| 328 // Feed and process lip sync in receiver. | 328 // Feed and process lip sync in receiver. |
| 329 FeedLipSyncInfoIntoReceiver(); | 329 FeedLipSyncInfoIntoReceiver(); |
| 330 task_runner_->RunTasks(); | 330 task_runner_->RunTasks(); |
| 331 const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks(); | 331 const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks(); |
| 332 | 332 |
| 333 // Enqueue a request for a frame. | 333 // Enqueue a request for a frame. |
| 334 const ReceiveEncodedFrameCallback frame_encoded_callback = | 334 const ReceiveEncodedFrameCallback frame_encoded_callback = |
| 335 base::Bind(&FakeFrameClient::DeliverEncodedFrame, | 335 base::Bind(&FakeFrameClient::DeliverEncodedFrame, |
| 336 base::Unretained(&frame_client_)); | 336 base::Unretained(&frame_client_)); |
| 337 receiver_->RequestEncodedFrame(frame_encoded_callback); | 337 receiver_->RequestEncodedFrame(frame_encoded_callback); |
| 338 task_runner_->RunTasks(); | 338 task_runner_->RunTasks(); |
| 339 EXPECT_EQ(0, frame_client_.number_times_called()); | 339 EXPECT_EQ(0, frame_client_.number_times_called()); |
| 340 | 340 |
| 341 // Receive one frame and expect to see the first request satisfied. | 341 // Receive one frame and expect to see the first request satisfied. |
| 342 const base::TimeDelta target_playout_delay = | 342 const base::TimeDelta target_playout_delay = |
| 343 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis); | 343 base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis); |
| 344 frame_client_.AddExpectedResult( | 344 frame_client_.AddExpectedResult( |
| 345 kFirstFrameId, first_frame_capture_time + target_playout_delay); | 345 kFirstFrameId, first_frame_capture_time + target_playout_delay); |
| 346 rtp_header_.rtp_timestamp = 0; | 346 rtp_header_.rtp_timestamp = RtpTimeTicks(); |
| 347 FeedOneFrameIntoReceiver(); // Frame 1 | 347 FeedOneFrameIntoReceiver(); // Frame 1 |
| 348 task_runner_->RunTasks(); | 348 task_runner_->RunTasks(); |
| 349 EXPECT_EQ(1, frame_client_.number_times_called()); | 349 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 350 | 350 |
| 351 // Enqueue a second request for a frame, but it should not be fulfilled yet. | 351 // Enqueue a second request for a frame, but it should not be fulfilled yet. |
| 352 receiver_->RequestEncodedFrame(frame_encoded_callback); | 352 receiver_->RequestEncodedFrame(frame_encoded_callback); |
| 353 task_runner_->RunTasks(); | 353 task_runner_->RunTasks(); |
| 354 EXPECT_EQ(1, frame_client_.number_times_called()); | 354 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 355 | 355 |
| 356 // Receive one frame out-of-order: Make sure that we are not continuous and | 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. | 357 // that the RTP timestamp represents a time in the future. |
| 358 rtp_header_.is_key_frame = false; | 358 rtp_header_.is_key_frame = false; |
| 359 rtp_header_.frame_id = kFirstFrameId + 2; // "Frame 3" | 359 rtp_header_.frame_id = kFirstFrameId + 2; // "Frame 3" |
| 360 rtp_header_.reference_frame_id = kFirstFrameId + 1; // "Frame 2" | 360 rtp_header_.reference_frame_id = kFirstFrameId + 1; // "Frame 2" |
| 361 rtp_header_.rtp_timestamp += 2 * rtp_advance_per_frame; | 361 rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2; |
| 362 FeedOneFrameIntoReceiver(); // Frame 3 | 362 FeedOneFrameIntoReceiver(); // Frame 3 |
| 363 | 363 |
| 364 // Frame 2 should not come out at this point in time. | 364 // Frame 2 should not come out at this point in time. |
| 365 task_runner_->RunTasks(); | 365 task_runner_->RunTasks(); |
| 366 EXPECT_EQ(1, frame_client_.number_times_called()); | 366 EXPECT_EQ(1, frame_client_.number_times_called()); |
| 367 | 367 |
| 368 // Enqueue a third request for a frame. | 368 // Enqueue a third request for a frame. |
| 369 receiver_->RequestEncodedFrame(frame_encoded_callback); | 369 receiver_->RequestEncodedFrame(frame_encoded_callback); |
| 370 task_runner_->RunTasks(); | 370 task_runner_->RunTasks(); |
| 371 EXPECT_EQ(1, frame_client_.number_times_called()); | 371 EXPECT_EQ(1, frame_client_.number_times_called()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // Sanity-check logging results. | 404 // Sanity-check logging results. |
| 405 std::vector<FrameEvent> frame_events; | 405 std::vector<FrameEvent> frame_events; |
| 406 event_subscriber.GetFrameEventsAndReset(&frame_events); | 406 event_subscriber.GetFrameEventsAndReset(&frame_events); |
| 407 ASSERT_TRUE(!frame_events.empty()); | 407 ASSERT_TRUE(!frame_events.empty()); |
| 408 for (size_t i = 0; i < frame_events.size(); ++i) { | 408 for (size_t i = 0; i < frame_events.size(); ++i) { |
| 409 EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type); | 409 EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type); |
| 410 EXPECT_EQ(VIDEO_EVENT, frame_events[i].media_type); | 410 EXPECT_EQ(VIDEO_EVENT, frame_events[i].media_type); |
| 411 EXPECT_LE(kFirstFrameId, frame_events[i].frame_id); | 411 EXPECT_LE(kFirstFrameId, frame_events[i].frame_id); |
| 412 EXPECT_GE(kFirstFrameId + 3, 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; | 413 const int frame_offset = frame_events[i].frame_id - kFirstFrameId; |
| 414 EXPECT_EQ(frame_offset * rtp_advance_per_frame, | 414 EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset), |
| 415 frame_events[i].rtp_timestamp); | 415 frame_events[i].rtp_timestamp); |
| 416 } | 416 } |
| 417 cast_environment_->logger()->Unsubscribe(&event_subscriber); | 417 cast_environment_->logger()->Unsubscribe(&event_subscriber); |
| 418 } | 418 } |
| 419 | 419 |
| 420 } // namespace cast | 420 } // namespace cast |
| 421 } // namespace media | 421 } // namespace media |
| OLD | NEW |