| 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 |