| 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 "media/cast/sender/video_sender.h" | 5 #include "media/cast/sender/video_sender.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "media/cast/cast_defines.h" | 14 #include "media/cast/cast_defines.h" |
| 15 #include "media/cast/net/cast_transport_config.h" | 15 #include "media/cast/net/cast_transport_config.h" |
| 16 #include "media/cast/sender/external_video_encoder.h" | 16 #include "media/cast/sender/external_video_encoder.h" |
| 17 #include "media/cast/sender/video_encoder_impl.h" | 17 #include "media/cast/sender/video_encoder_impl.h" |
| 18 | 18 |
| 19 namespace media { | 19 namespace media { |
| 20 namespace cast { | 20 namespace cast { |
| 21 | 21 |
| 22 namespace { |
| 23 |
| 22 const int kNumAggressiveReportsSentAtStart = 100; | 24 const int kNumAggressiveReportsSentAtStart = 100; |
| 23 | 25 |
| 24 namespace { | |
| 25 | |
| 26 // Returns a fixed bitrate value when external video encoder is used. | 26 // Returns a fixed bitrate value when external video encoder is used. |
| 27 // Some hardware encoder shows bad behavior if we set the bitrate too | 27 // Some hardware encoder shows bad behavior if we set the bitrate too |
| 28 // frequently, e.g. quality drop, not abiding by target bitrate, etc. | 28 // frequently, e.g. quality drop, not abiding by target bitrate, etc. |
| 29 // See details: crbug.com/392086. | 29 // See details: crbug.com/392086. |
| 30 size_t GetFixedBitrate(const VideoSenderConfig& video_config) { | 30 size_t GetFixedBitrate(const VideoSenderConfig& video_config) { |
| 31 if (!video_config.use_external_encoder) | 31 if (!video_config.use_external_encoder) |
| 32 return 0; | 32 return 0; |
| 33 return (video_config.min_bitrate + video_config.max_bitrate) / 2; | 33 return (video_config.min_bitrate + video_config.max_bitrate) / 2; |
| 34 } | 34 } |
| 35 | 35 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 transport_config.feedback_ssrc = video_config.incoming_feedback_ssrc; | 79 transport_config.feedback_ssrc = video_config.incoming_feedback_ssrc; |
| 80 transport_config.rtp_payload_type = video_config.rtp_payload_type; | 80 transport_config.rtp_payload_type = video_config.rtp_payload_type; |
| 81 transport_config.stored_frames = max_unacked_frames_; | 81 transport_config.stored_frames = max_unacked_frames_; |
| 82 transport_config.aes_key = video_config.aes_key; | 82 transport_config.aes_key = video_config.aes_key; |
| 83 transport_config.aes_iv_mask = video_config.aes_iv_mask; | 83 transport_config.aes_iv_mask = video_config.aes_iv_mask; |
| 84 | 84 |
| 85 transport_sender->InitializeVideo( | 85 transport_sender->InitializeVideo( |
| 86 transport_config, | 86 transport_config, |
| 87 base::Bind(&VideoSender::OnReceivedCastFeedback, | 87 base::Bind(&VideoSender::OnReceivedCastFeedback, |
| 88 weak_factory_.GetWeakPtr()), | 88 weak_factory_.GetWeakPtr()), |
| 89 base::Bind(&VideoSender::OnReceivedRtt, weak_factory_.GetWeakPtr())); | 89 base::Bind(&VideoSender::OnMeasuredRoundTripTime, |
| 90 weak_factory_.GetWeakPtr())); |
| 90 } | 91 } |
| 91 | 92 |
| 92 VideoSender::~VideoSender() { | 93 VideoSender::~VideoSender() { |
| 93 } | 94 } |
| 94 | 95 |
| 95 void VideoSender::InsertRawVideoFrame( | 96 void VideoSender::InsertRawVideoFrame( |
| 96 const scoped_refptr<media::VideoFrame>& video_frame, | 97 const scoped_refptr<media::VideoFrame>& video_frame, |
| 97 const base::TimeTicks& capture_time) { | 98 const base::TimeTicks& capture_time) { |
| 98 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 99 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 99 if (cast_initialization_status_ != STATUS_VIDEO_INITIALIZED) { | 100 if (cast_initialization_status_ != STATUS_VIDEO_INITIALIZED) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 if (send_target_playout_delay_) { | 211 if (send_target_playout_delay_) { |
| 211 encoded_frame->new_playout_delay_ms = | 212 encoded_frame->new_playout_delay_ms = |
| 212 target_playout_delay_.InMilliseconds(); | 213 target_playout_delay_.InMilliseconds(); |
| 213 } | 214 } |
| 214 transport_sender_->InsertCodedVideoFrame(*encoded_frame); | 215 transport_sender_->InsertCodedVideoFrame(*encoded_frame); |
| 215 } | 216 } |
| 216 | 217 |
| 217 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { | 218 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { |
| 218 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 219 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 219 | 220 |
| 220 base::TimeDelta rtt; | |
| 221 base::TimeDelta avg_rtt; | |
| 222 base::TimeDelta min_rtt; | |
| 223 base::TimeDelta max_rtt; | |
| 224 if (is_rtt_available()) { | 221 if (is_rtt_available()) { |
| 225 rtt = rtt_; | 222 congestion_control_.UpdateRtt(current_round_trip_time()); |
| 226 avg_rtt = avg_rtt_; | |
| 227 min_rtt = min_rtt_; | |
| 228 max_rtt = max_rtt_; | |
| 229 | 223 |
| 230 congestion_control_.UpdateRtt(rtt); | 224 // Having the RTT value implies the receiver sent back a receiver report |
| 231 | |
| 232 // Don't use a RTT lower than our average. | |
| 233 rtt = std::max(rtt, avg_rtt); | |
| 234 | |
| 235 // Having the RTT values implies the receiver sent back a receiver report | |
| 236 // based on it having received a report from here. Therefore, ensure this | 225 // based on it having received a report from here. Therefore, ensure this |
| 237 // sender stops aggressively sending reports. | 226 // sender stops aggressively sending reports. |
| 238 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { | 227 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { |
| 239 VLOG(1) << "No longer a need to send reports aggressively (sent " | 228 VLOG(1) << "No longer a need to send reports aggressively (sent " |
| 240 << num_aggressive_rtcp_reports_sent_ << ")."; | 229 << num_aggressive_rtcp_reports_sent_ << ")."; |
| 241 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart; | 230 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart; |
| 242 ScheduleNextRtcpReport(); | 231 ScheduleNextRtcpReport(); |
| 243 } | 232 } |
| 244 } else { | |
| 245 // We have no measured value use default. | |
| 246 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs); | |
| 247 } | 233 } |
| 248 | 234 |
| 249 if (last_send_time_.is_null()) | 235 if (last_send_time_.is_null()) |
| 250 return; // Cannot get an ACK without having first sent a frame. | 236 return; // Cannot get an ACK without having first sent a frame. |
| 251 | 237 |
| 252 if (cast_feedback.missing_frames_and_packets.empty()) { | 238 if (cast_feedback.missing_frames_and_packets.empty()) { |
| 253 video_encoder_->LatestFrameIdToReference(cast_feedback.ack_frame_id); | 239 video_encoder_->LatestFrameIdToReference(cast_feedback.ack_frame_id); |
| 254 | 240 |
| 255 // We only count duplicate ACKs when we have sent newer frames. | 241 // We only count duplicate ACKs when we have sent newer frames. |
| 256 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && | 242 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 << duration_in_flight.InMicroseconds() << " usec (" | 305 << duration_in_flight.InMicroseconds() << " usec (" |
| 320 << (target_playout_delay_ > base::TimeDelta() ? | 306 << (target_playout_delay_ > base::TimeDelta() ? |
| 321 100 * duration_in_flight / target_playout_delay_ : | 307 100 * duration_in_flight / target_playout_delay_ : |
| 322 kint64max) << "%)"; | 308 kint64max) << "%)"; |
| 323 return frames_in_flight >= max_unacked_frames_ || | 309 return frames_in_flight >= max_unacked_frames_ || |
| 324 duration_in_flight >= target_playout_delay_; | 310 duration_in_flight >= target_playout_delay_; |
| 325 } | 311 } |
| 326 | 312 |
| 327 } // namespace cast | 313 } // namespace cast |
| 328 } // namespace media | 314 } // namespace media |
| OLD | NEW |