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