Index: media/cast/video_sender/video_sender.cc |
diff --git a/media/cast/video_sender/video_sender.cc b/media/cast/video_sender/video_sender.cc |
index 29859db18853226b0a775b234c79a27d00f699da..3438d6f21faaa12cbcf79925326bb9709ebf6b17 100644 |
--- a/media/cast/video_sender/video_sender.cc |
+++ b/media/cast/video_sender/video_sender.cc |
@@ -65,6 +65,7 @@ VideoSender::VideoSender( |
duplicate_ack_(0), |
last_skip_count_(0), |
current_requested_bitrate_(video_config.start_bitrate), |
+ current_bitrate_divider_(1), |
congestion_control_(cast_environment->Clock(), |
video_config.congestion_control_back_off, |
video_config.max_bitrate, |
@@ -184,7 +185,8 @@ void VideoSender::SendEncodedVideoFrameMainThread( |
cast_environment_->Logging()->InsertEncodedFrameEvent( |
last_send_time_, kVideoFrameEncoded, encoded_frame->rtp_timestamp, |
frame_id, static_cast<int>(encoded_frame->data.size()), |
- encoded_frame->key_frame, current_requested_bitrate_); |
+ encoded_frame->key_frame, |
+ current_requested_bitrate_); |
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
TRACE_EVENT_INSTANT1( |
@@ -387,8 +389,7 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { |
cast_feedback.ack_frame_id_) { |
uint32 new_bitrate = 0; |
if (congestion_control_.OnAck(rtt, &new_bitrate)) { |
- video_encoder_->SetBitRate(new_bitrate); |
- current_requested_bitrate_ = new_bitrate; |
+ UpdateBitrate(new_bitrate); |
} |
} |
// We only count duplicate ACKs when we have sent newer frames. |
@@ -414,8 +415,7 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { |
false, cast_feedback.missing_frames_and_packets_); |
uint32 new_bitrate = 0; |
if (congestion_control_.OnNack(rtt, &new_bitrate)) { |
- video_encoder_->SetBitRate(new_bitrate); |
- current_requested_bitrate_ = new_bitrate; |
+ UpdateBitrate(new_bitrate); |
} |
} |
ReceivedAck(cast_feedback.ack_frame_id_); |
@@ -451,13 +451,12 @@ void VideoSender::UpdateFramesInFlight() { |
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
if (last_sent_frame_id_ != -1) { |
DCHECK_LE(0, last_sent_frame_id_); |
- uint32 frames_in_flight = 0; |
+ int frames_in_flight = 0; |
if (last_acked_frame_id_ != -1) { |
DCHECK_LE(0, last_acked_frame_id_); |
- frames_in_flight = static_cast<uint32>(last_sent_frame_id_) - |
- static_cast<uint32>(last_acked_frame_id_); |
+ frames_in_flight = last_sent_frame_id_ - last_acked_frame_id_; |
} else { |
- frames_in_flight = static_cast<uint32>(last_sent_frame_id_) + 1; |
+ frames_in_flight = last_sent_frame_id_ + 1; |
} |
frames_in_flight += frames_in_encoder_; |
VLOG(2) << frames_in_flight |
@@ -467,6 +466,12 @@ void VideoSender::UpdateFramesInFlight() { |
if (frames_in_flight >= max_unacked_frames_) { |
video_encoder_->SkipNextFrame(true); |
return; |
+ } else if (frames_in_flight > max_unacked_frames_ * 4 / 5) { |
+ current_bitrate_divider_ = 3; |
+ } else if (frames_in_flight > max_unacked_frames_ * 2 / 3) { |
+ current_bitrate_divider_ = 2; |
+ } else { |
+ current_bitrate_divider_ = 1; |
} |
DCHECK(frames_in_flight <= max_unacked_frames_); |
} |
@@ -482,5 +487,13 @@ void VideoSender::ResendFrame(uint32 resend_frame_id) { |
transport_sender_->ResendPackets(false, missing_frames_and_packets); |
} |
+void VideoSender::UpdateBitrate(int new_bitrate) { |
+ new_bitrate /= current_bitrate_divider_; |
+ // Make sure we don't set the bitrate too insanely low. |
+ DCHECK_GT(new_bitrate, 1000); |
+ video_encoder_->SetBitRate(new_bitrate); |
+ current_requested_bitrate_ = new_bitrate; |
+} |
+ |
} // namespace cast |
} // namespace media |