OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/cast/video_receiver/video_receiver.h" | 5 #include "media/cast/video_receiver/video_receiver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 } // namespace | 22 } // namespace |
23 | 23 |
24 namespace media { | 24 namespace media { |
25 namespace cast { | 25 namespace cast { |
26 | 26 |
27 VideoReceiver::VideoReceiver(scoped_refptr<CastEnvironment> cast_environment, | 27 VideoReceiver::VideoReceiver(scoped_refptr<CastEnvironment> cast_environment, |
28 const VideoReceiverConfig& video_config, | 28 const VideoReceiverConfig& video_config, |
29 transport::PacedPacketSender* const packet_sender) | 29 transport::PacedPacketSender* const packet_sender) |
30 : RtpReceiver(cast_environment->Clock(), NULL, &video_config), | 30 : RtpReceiver(cast_environment->Clock(), NULL, &video_config), |
31 cast_environment_(cast_environment), | 31 cast_environment_(cast_environment), |
32 event_subscriber_(kReceiverRtcpEventHistorySize, | 32 event_subscriber_(kReceiverRtcpEventHistorySize, VIDEO_EVENT), |
33 ReceiverRtcpEventSubscriber::kVideoEventSubscriber), | |
34 codec_(video_config.codec), | 33 codec_(video_config.codec), |
35 target_delay_delta_( | 34 target_delay_delta_( |
36 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), | 35 base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)), |
37 expected_frame_duration_( | 36 expected_frame_duration_( |
38 base::TimeDelta::FromSeconds(1) / video_config.max_frame_rate), | 37 base::TimeDelta::FromSeconds(1) / video_config.max_frame_rate), |
39 framer_(cast_environment->Clock(), | 38 framer_(cast_environment->Clock(), |
40 this, | 39 this, |
41 video_config.incoming_ssrc, | 40 video_config.incoming_ssrc, |
42 video_config.decoder_faster_than_max_frame_rate, | 41 video_config.decoder_faster_than_max_frame_rate, |
43 video_config.rtp_max_delay_ms * video_config.max_frame_rate / | 42 video_config.rtp_max_delay_ms * video_config.max_frame_rate / |
44 1000), | 43 1000), |
45 rtcp_(cast_environment_, | 44 rtcp_(cast_environment_, |
46 NULL, | 45 NULL, |
47 NULL, | 46 NULL, |
48 packet_sender, | 47 packet_sender, |
49 GetStatistics(), | 48 GetStatistics(), |
50 video_config.rtcp_mode, | 49 video_config.rtcp_mode, |
51 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), | 50 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), |
52 video_config.feedback_ssrc, | 51 video_config.feedback_ssrc, |
53 video_config.incoming_ssrc, | 52 video_config.incoming_ssrc, |
54 video_config.rtcp_c_name), | 53 video_config.rtcp_c_name, |
| 54 false), |
55 time_offset_counter_(0), | 55 time_offset_counter_(0), |
56 time_incoming_packet_updated_(false), | 56 time_incoming_packet_updated_(false), |
57 incoming_rtp_timestamp_(0), | 57 incoming_rtp_timestamp_(0), |
58 is_waiting_for_consecutive_frame_(false), | 58 is_waiting_for_consecutive_frame_(false), |
59 weak_factory_(this) { | 59 weak_factory_(this) { |
60 DCHECK_GT(video_config.rtp_max_delay_ms, 0); | 60 DCHECK_GT(video_config.rtp_max_delay_ms, 0); |
61 DCHECK_GT(video_config.max_frame_rate, 0); | 61 DCHECK_GT(video_config.max_frame_rate, 0); |
62 if (!video_config.use_external_decoder) { | 62 if (!video_config.use_external_decoder) { |
63 video_decoder_.reset(new VideoDecoder(cast_environment, video_config)); | 63 video_decoder_.reset(new VideoDecoder(cast_environment, video_config)); |
64 } | 64 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 const VideoFrameDecodedCallback& callback, | 118 const VideoFrameDecodedCallback& callback, |
119 uint32 frame_id, | 119 uint32 frame_id, |
120 uint32 rtp_timestamp, | 120 uint32 rtp_timestamp, |
121 const base::TimeTicks& playout_time, | 121 const base::TimeTicks& playout_time, |
122 const scoped_refptr<VideoFrame>& video_frame, | 122 const scoped_refptr<VideoFrame>& video_frame, |
123 bool is_continuous) { | 123 bool is_continuous) { |
124 DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN)); | 124 DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN)); |
125 if (video_frame) { | 125 if (video_frame) { |
126 const base::TimeTicks now = cast_environment->Clock()->NowTicks(); | 126 const base::TimeTicks now = cast_environment->Clock()->NowTicks(); |
127 cast_environment->Logging()->InsertFrameEvent( | 127 cast_environment->Logging()->InsertFrameEvent( |
128 now, kVideoFrameDecoded, rtp_timestamp, frame_id); | 128 now, FRAME_DECODED, VIDEO_EVENT, rtp_timestamp, frame_id); |
129 cast_environment->Logging()->InsertFrameEventWithDelay( | 129 cast_environment->Logging()->InsertFrameEventWithDelay( |
130 now, kVideoRenderDelay, rtp_timestamp, frame_id, | 130 now, FRAME_PLAYOUT, VIDEO_EVENT, rtp_timestamp, frame_id, |
131 playout_time - now); | 131 playout_time - now); |
132 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 132 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
133 TRACE_EVENT_INSTANT1( | 133 TRACE_EVENT_INSTANT1( |
134 "cast_perf_test", "FrameDecoded", | 134 "cast_perf_test", "FrameDecoded", |
135 TRACE_EVENT_SCOPE_THREAD, | 135 TRACE_EVENT_SCOPE_THREAD, |
136 "rtp_timestamp", rtp_timestamp); | 136 "rtp_timestamp", rtp_timestamp); |
137 } | 137 } |
138 callback.Run(video_frame, playout_time, is_continuous); | 138 callback.Run(video_frame, playout_time, is_continuous); |
139 } | 139 } |
140 | 140 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 if (rtp_header.packet_id == 0) { | 322 if (rtp_header.packet_id == 0) { |
323 time_incoming_packet_ = now; | 323 time_incoming_packet_ = now; |
324 time_incoming_packet_updated_ = true; | 324 time_incoming_packet_updated_ = true; |
325 } | 325 } |
326 } | 326 } |
327 | 327 |
328 frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] = | 328 frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] = |
329 rtp_header.rtp_timestamp; | 329 rtp_header.rtp_timestamp; |
330 cast_environment_->Logging()->InsertPacketEvent( | 330 cast_environment_->Logging()->InsertPacketEvent( |
331 now, | 331 now, |
332 kVideoPacketReceived, | 332 PACKET_RECEIVED, |
| 333 VIDEO_EVENT, |
333 rtp_header.rtp_timestamp, | 334 rtp_header.rtp_timestamp, |
334 rtp_header.frame_id, | 335 rtp_header.frame_id, |
335 rtp_header.packet_id, | 336 rtp_header.packet_id, |
336 rtp_header.max_packet_id, | 337 rtp_header.max_packet_id, |
337 payload_size); | 338 payload_size); |
338 | 339 |
339 bool duplicate = false; | 340 bool duplicate = false; |
340 const bool complete = | 341 const bool complete = |
341 framer_.InsertPacket(payload_data, payload_size, rtp_header, &duplicate); | 342 framer_.InsertPacket(payload_data, payload_size, rtp_header, &duplicate); |
342 if (duplicate) { | 343 |
343 cast_environment_->Logging()->InsertPacketEvent( | 344 // Duplicate packets are ignored. |
344 now, | 345 if (duplicate) |
345 kDuplicateVideoPacketReceived, | |
346 rtp_header.rtp_timestamp, | |
347 rtp_header.frame_id, | |
348 rtp_header.packet_id, | |
349 rtp_header.max_packet_id, | |
350 payload_size); | |
351 // Duplicate packets are ignored. | |
352 return; | 346 return; |
353 } | 347 |
| 348 // Video frame not complete; wait for more packets. |
354 if (!complete) | 349 if (!complete) |
355 return; // Video frame not complete; wait for more packets. | 350 return; |
356 | 351 |
357 EmitAvailableEncodedFrames(); | 352 EmitAvailableEncodedFrames(); |
358 } | 353 } |
359 | 354 |
360 // Send a cast feedback message. Actual message created in the framer (cast | 355 // Send a cast feedback message. Actual message created in the framer (cast |
361 // message builder). | 356 // message builder). |
362 void VideoReceiver::CastFeedback(const RtcpCastMessage& cast_message) { | 357 void VideoReceiver::CastFeedback(const RtcpCastMessage& cast_message) { |
363 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 358 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
364 | 359 |
365 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 360 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
366 RtpTimestamp rtp_timestamp = | 361 RtpTimestamp rtp_timestamp = |
367 frame_id_to_rtp_timestamp_[cast_message.ack_frame_id_ & 0xff]; | 362 frame_id_to_rtp_timestamp_[cast_message.ack_frame_id_ & 0xff]; |
368 cast_environment_->Logging()->InsertFrameEvent( | 363 cast_environment_->Logging()->InsertFrameEvent( |
369 now, kVideoAckSent, rtp_timestamp, cast_message.ack_frame_id_); | 364 now, FRAME_ACK_SENT, VIDEO_EVENT, |
| 365 rtp_timestamp, cast_message.ack_frame_id_); |
370 | 366 |
371 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | 367 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; |
372 event_subscriber_.GetRtcpEventsAndReset(&rtcp_events); | 368 event_subscriber_.GetRtcpEventsAndReset(&rtcp_events); |
373 rtcp_.SendRtcpFromRtpReceiver(&cast_message, &rtcp_events); | 369 rtcp_.SendRtcpFromRtpReceiver(&cast_message, &rtcp_events); |
374 } | 370 } |
375 | 371 |
376 // Cast messages should be sent within a maximum interval. Schedule a call | 372 // Cast messages should be sent within a maximum interval. Schedule a call |
377 // if not triggered elsewhere, e.g. by the cast message_builder. | 373 // if not triggered elsewhere, e.g. by the cast message_builder. |
378 void VideoReceiver::ScheduleNextCastMessage() { | 374 void VideoReceiver::ScheduleNextCastMessage() { |
379 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 375 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 } | 410 } |
415 | 411 |
416 void VideoReceiver::SendNextRtcpReport() { | 412 void VideoReceiver::SendNextRtcpReport() { |
417 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 413 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
418 rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); | 414 rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); |
419 ScheduleNextRtcpReport(); | 415 ScheduleNextRtcpReport(); |
420 } | 416 } |
421 | 417 |
422 } // namespace cast | 418 } // namespace cast |
423 } // namespace media | 419 } // namespace media |
OLD | NEW |