Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: media/cast/video_sender/video_sender.cc

Issue 326783002: Cast: Updated congestion control (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: bugfix Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/cast/video_sender/video_sender.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_sender/video_sender.h" 5 #include "media/cast/video_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"
(...skipping 15 matching lines...) Expand all
26 VideoSender::VideoSender( 26 VideoSender::VideoSender(
27 scoped_refptr<CastEnvironment> cast_environment, 27 scoped_refptr<CastEnvironment> cast_environment,
28 const VideoSenderConfig& video_config, 28 const VideoSenderConfig& video_config,
29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, 30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
31 transport::CastTransportSender* const transport_sender) 31 transport::CastTransportSender* const transport_sender)
32 : cast_environment_(cast_environment), 32 : cast_environment_(cast_environment),
33 target_playout_delay_(base::TimeDelta::FromMilliseconds( 33 target_playout_delay_(base::TimeDelta::FromMilliseconds(
34 video_config.rtp_config.max_delay_ms)), 34 video_config.rtp_config.max_delay_ms)),
35 transport_sender_(transport_sender), 35 transport_sender_(transport_sender),
36 max_unacked_frames_(std::min( 36 max_unacked_frames_(
37 kMaxUnackedFrames, 37 std::min(kMaxUnackedFrames,
38 1 + static_cast<int>( 38 1 + static_cast<int>(target_playout_delay_ *
39 target_playout_delay_ * video_config.max_frame_rate / 39 video_config.max_frame_rate /
40 base::TimeDelta::FromSeconds(1)))), 40 base::TimeDelta::FromSeconds(1)))),
41 rtcp_(cast_environment_, 41 rtcp_(cast_environment_,
42 this, 42 this,
43 transport_sender_, 43 transport_sender_,
44 NULL, // paced sender. 44 NULL, // paced sender.
45 NULL, 45 NULL,
46 video_config.rtcp_mode, 46 video_config.rtcp_mode,
47 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), 47 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
48 video_config.rtp_config.ssrc, 48 video_config.rtp_config.ssrc,
49 video_config.incoming_feedback_ssrc, 49 video_config.incoming_feedback_ssrc,
50 video_config.rtcp_c_name, 50 video_config.rtcp_c_name,
51 VIDEO_EVENT), 51 VIDEO_EVENT),
52 rtp_timestamp_helper_(kVideoFrequency), 52 rtp_timestamp_helper_(kVideoFrequency),
53 num_aggressive_rtcp_reports_sent_(0), 53 num_aggressive_rtcp_reports_sent_(0),
54 frames_in_encoder_(0), 54 frames_in_encoder_(0),
55 last_sent_frame_id_(0), 55 last_sent_frame_id_(0),
56 latest_acked_frame_id_(0), 56 latest_acked_frame_id_(0),
57 duplicate_ack_counter_(0), 57 duplicate_ack_counter_(0),
58 current_requested_bitrate_(video_config.start_bitrate),
59 congestion_control_(cast_environment->Clock(), 58 congestion_control_(cast_environment->Clock(),
60 video_config.congestion_control_back_off,
61 video_config.max_bitrate, 59 video_config.max_bitrate,
62 video_config.min_bitrate, 60 video_config.min_bitrate,
63 video_config.start_bitrate), 61 max_unacked_frames_),
64 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED), 62 cast_initialization_status_(STATUS_VIDEO_UNINITIALIZED),
65 weak_factory_(this) { 63 weak_factory_(this) {
66 VLOG(1) << "max_unacked_frames " << max_unacked_frames_; 64 VLOG(1) << "max_unacked_frames " << max_unacked_frames_;
67 DCHECK_GT(max_unacked_frames_, 0); 65 DCHECK_GT(max_unacked_frames_, 0);
68 66
69 if (video_config.use_external_encoder) { 67 if (video_config.use_external_encoder) {
70 video_encoder_.reset(new ExternalVideoEncoder(cast_environment, 68 video_encoder_.reset(new ExternalVideoEncoder(cast_environment,
71 video_config, 69 video_config,
72 create_vea_cb, 70 create_vea_cb,
73 create_video_encode_mem_cb)); 71 create_video_encode_mem_cb));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 "cast_perf_test", "InsertRawVideoFrame", 114 "cast_perf_test", "InsertRawVideoFrame",
117 TRACE_EVENT_SCOPE_THREAD, 115 TRACE_EVENT_SCOPE_THREAD,
118 "timestamp", capture_time.ToInternalValue(), 116 "timestamp", capture_time.ToInternalValue(),
119 "rtp_timestamp", rtp_timestamp); 117 "rtp_timestamp", rtp_timestamp);
120 118
121 if (AreTooManyFramesInFlight()) { 119 if (AreTooManyFramesInFlight()) {
122 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; 120 VLOG(1) << "Dropping frame due to too many frames currently in-flight.";
123 return; 121 return;
124 } 122 }
125 123
124 uint32 bitrate = congestion_control_.GetBitrate(
125 capture_time + target_playout_delay_, target_playout_delay_);
126
127 video_encoder_->SetBitRate(bitrate);
128
126 if (video_encoder_->EncodeVideoFrame( 129 if (video_encoder_->EncodeVideoFrame(
127 video_frame, 130 video_frame,
128 capture_time, 131 capture_time,
129 base::Bind(&VideoSender::SendEncodedVideoFrame, 132 base::Bind(&VideoSender::SendEncodedVideoFrame,
130 weak_factory_.GetWeakPtr(), 133 weak_factory_.GetWeakPtr(),
131 current_requested_bitrate_))) { 134 bitrate))) {
132 frames_in_encoder_++; 135 frames_in_encoder_++;
133 } else { 136 } else {
134 VLOG(1) << "Encoder rejected a frame. Skipping..."; 137 VLOG(1) << "Encoder rejected a frame. Skipping...";
135 } 138 }
136 } 139 }
137 140
138 void VideoSender::SendEncodedVideoFrame( 141 void VideoSender::SendEncodedVideoFrame(
139 int requested_bitrate_before_encode, 142 int requested_bitrate_before_encode,
140 scoped_ptr<transport::EncodedFrame> encoded_frame) { 143 scoped_ptr<transport::EncodedFrame> encoded_frame) {
141 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 144 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { 188 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
186 // SendRtcpReport() will schedule future reports to be made if this is the 189 // SendRtcpReport() will schedule future reports to be made if this is the
187 // last "aggressive report." 190 // last "aggressive report."
188 ++num_aggressive_rtcp_reports_sent_; 191 ++num_aggressive_rtcp_reports_sent_;
189 const bool is_last_aggressive_report = 192 const bool is_last_aggressive_report =
190 (num_aggressive_rtcp_reports_sent_ == kNumAggressiveReportsSentAtStart); 193 (num_aggressive_rtcp_reports_sent_ == kNumAggressiveReportsSentAtStart);
191 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report."; 194 VLOG_IF(1, is_last_aggressive_report) << "Sending last aggressive report.";
192 SendRtcpReport(is_last_aggressive_report); 195 SendRtcpReport(is_last_aggressive_report);
193 } 196 }
194 197
198 congestion_control_.SendFrameToTransport(
199 frame_id, encoded_frame->data.size() * 8, last_send_time_);
200
195 transport_sender_->InsertCodedVideoFrame(*encoded_frame); 201 transport_sender_->InsertCodedVideoFrame(*encoded_frame);
196 } 202 }
197 203
198 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { 204 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) {
199 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 205 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
200 rtcp_.IncomingRtcpPacket(&packet->front(), packet->size()); 206 rtcp_.IncomingRtcpPacket(&packet->front(), packet->size());
201 } 207 }
202 208
203 void VideoSender::ScheduleNextRtcpReport() { 209 void VideoSender::ScheduleNextRtcpReport() {
204 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 210 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 270 }
265 271
266 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { 272 void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) {
267 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 273 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
268 274
269 base::TimeDelta rtt; 275 base::TimeDelta rtt;
270 base::TimeDelta avg_rtt; 276 base::TimeDelta avg_rtt;
271 base::TimeDelta min_rtt; 277 base::TimeDelta min_rtt;
272 base::TimeDelta max_rtt; 278 base::TimeDelta max_rtt;
273 if (rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) { 279 if (rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) {
280 congestion_control_.UpdateRtt(rtt);
281
274 // Don't use a RTT lower than our average. 282 // Don't use a RTT lower than our average.
275 rtt = std::max(rtt, avg_rtt); 283 rtt = std::max(rtt, avg_rtt);
276 284
277 // Having the RTT values implies the receiver sent back a receiver report 285 // Having the RTT values implies the receiver sent back a receiver report
278 // based on it having received a report from here. Therefore, ensure this 286 // based on it having received a report from here. Therefore, ensure this
279 // sender stops aggressively sending reports. 287 // sender stops aggressively sending reports.
280 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { 288 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) {
281 VLOG(1) << "No longer a need to send reports aggressively (sent " 289 VLOG(1) << "No longer a need to send reports aggressively (sent "
282 << num_aggressive_rtcp_reports_sent_ << ")."; 290 << num_aggressive_rtcp_reports_sent_ << ").";
283 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart; 291 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart;
284 ScheduleNextRtcpReport(); 292 ScheduleNextRtcpReport();
285 } 293 }
286 } else { 294 } else {
287 // We have no measured value use default. 295 // We have no measured value use default.
288 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs); 296 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs);
289 } 297 }
290 298
291 if (last_send_time_.is_null()) 299 if (last_send_time_.is_null())
292 return; // Cannot get an ACK without having first sent a frame. 300 return; // Cannot get an ACK without having first sent a frame.
293 301
294 if (cast_feedback.missing_frames_and_packets_.empty()) { 302 if (cast_feedback.missing_frames_and_packets_.empty()) {
295 video_encoder_->LatestFrameIdToReference(cast_feedback.ack_frame_id_); 303 video_encoder_->LatestFrameIdToReference(cast_feedback.ack_frame_id_);
296 304
297 if ((latest_acked_frame_id_ + 1) == cast_feedback.ack_frame_id_) {
298 uint32 new_bitrate = 0;
299 if (congestion_control_.OnAck(rtt, &new_bitrate)) {
300 UpdateBitrate(new_bitrate);
301 }
302 }
303 // We only count duplicate ACKs when we have sent newer frames. 305 // We only count duplicate ACKs when we have sent newer frames.
304 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id_ && 306 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id_ &&
305 latest_acked_frame_id_ != last_sent_frame_id_) { 307 latest_acked_frame_id_ != last_sent_frame_id_) {
306 duplicate_ack_counter_++; 308 duplicate_ack_counter_++;
307 } else { 309 } else {
308 duplicate_ack_counter_ = 0; 310 duplicate_ack_counter_ = 0;
309 } 311 }
310 // TODO(miu): The values "2" and "3" should be derived from configuration. 312 // TODO(miu): The values "2" and "3" should be derived from configuration.
311 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) { 313 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) {
312 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_; 314 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_;
313 ResendForKickstart(); 315 ResendForKickstart();
314 } 316 }
315 } else { 317 } else {
316 // Only count duplicated ACKs if there is no NACK request in between. 318 // Only count duplicated ACKs if there is no NACK request in between.
317 // This is to avoid aggresive resend. 319 // This is to avoid aggresive resend.
318 duplicate_ack_counter_ = 0; 320 duplicate_ack_counter_ = 0;
319 transport_sender_->ResendPackets( 321 transport_sender_->ResendPackets(
320 false, cast_feedback.missing_frames_and_packets_); 322 false, cast_feedback.missing_frames_and_packets_);
321 uint32 new_bitrate = 0;
322 if (congestion_control_.OnNack(rtt, &new_bitrate)) {
323 UpdateBitrate(new_bitrate);
324 }
325 } 323 }
326 324
325 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
326 congestion_control_.AckFrame(cast_feedback.ack_frame_id_, now);
327
327 RtpTimestamp rtp_timestamp = 328 RtpTimestamp rtp_timestamp =
328 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id_ & 0xff]; 329 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id_ & 0xff];
329 cast_environment_->Logging()->InsertFrameEvent( 330 cast_environment_->Logging()->InsertFrameEvent(now,
330 cast_environment_->Clock()->NowTicks(), FRAME_ACK_RECEIVED, VIDEO_EVENT, 331 FRAME_ACK_RECEIVED,
331 rtp_timestamp, cast_feedback.ack_frame_id_); 332 VIDEO_EVENT,
333 rtp_timestamp,
334 cast_feedback.ack_frame_id_);
332 335
333 const bool is_acked_out_of_order = 336 const bool is_acked_out_of_order =
334 static_cast<int32>(cast_feedback.ack_frame_id_ - 337 static_cast<int32>(cast_feedback.ack_frame_id_ -
335 latest_acked_frame_id_) < 0; 338 latest_acked_frame_id_) < 0;
336 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") 339 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "")
337 << " for frame " << cast_feedback.ack_frame_id_; 340 << " for frame " << cast_feedback.ack_frame_id_;
338 if (!is_acked_out_of_order) 341 if (!is_acked_out_of_order)
339 latest_acked_frame_id_ = cast_feedback.ack_frame_id_; 342 latest_acked_frame_id_ = cast_feedback.ack_frame_id_;
340 } 343 }
341 344
(...skipping 21 matching lines...) Expand all
363 // packets and frames are missing. 366 // packets and frames are missing.
364 MissingFramesAndPacketsMap missing_frames_and_packets; 367 MissingFramesAndPacketsMap missing_frames_and_packets;
365 PacketIdSet missing; 368 PacketIdSet missing;
366 missing.insert(0); 369 missing.insert(0);
367 missing_frames_and_packets.insert( 370 missing_frames_and_packets.insert(
368 std::make_pair(last_sent_frame_id_, missing)); 371 std::make_pair(last_sent_frame_id_, missing));
369 last_send_time_ = cast_environment_->Clock()->NowTicks(); 372 last_send_time_ = cast_environment_->Clock()->NowTicks();
370 transport_sender_->ResendPackets(false, missing_frames_and_packets); 373 transport_sender_->ResendPackets(false, missing_frames_and_packets);
371 } 374 }
372 375
373 void VideoSender::UpdateBitrate(int new_bitrate) {
374 // Make sure we don't set the bitrate too insanely low.
375 DCHECK_GT(new_bitrate, 1000);
376 video_encoder_->SetBitRate(new_bitrate);
377 current_requested_bitrate_ = new_bitrate;
378 }
379
380 } // namespace cast 376 } // namespace cast
381 } // namespace media 377 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/video_sender/video_sender.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698