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

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

Issue 445933002: Cast: Move retransmission to the transport (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: IPC Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
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"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 275 }
276 // TODO(miu): The values "2" and "3" should be derived from configuration. 276 // TODO(miu): The values "2" and "3" should be derived from configuration.
277 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) { 277 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) {
278 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_; 278 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_;
279 ResendForKickstart(); 279 ResendForKickstart();
280 } 280 }
281 } else { 281 } else {
282 // Only count duplicated ACKs if there is no NACK request in between. 282 // Only count duplicated ACKs if there is no NACK request in between.
283 // This is to avoid aggresive resend. 283 // This is to avoid aggresive resend.
284 duplicate_ack_counter_ = 0; 284 duplicate_ack_counter_ = 0;
285
286 // A NACK is also used to cancel pending re-transmissions.
287 transport_sender_->ResendPackets(
288 false, cast_feedback.missing_frames_and_packets, true, rtt);
289 } 285 }
290 286
291 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 287 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
292 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now); 288 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now);
293 289
294 RtpTimestamp rtp_timestamp = 290 RtpTimestamp rtp_timestamp =
295 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id & 0xff]; 291 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id & 0xff];
296 cast_environment_->Logging()->InsertFrameEvent(now, 292 cast_environment_->Logging()->InsertFrameEvent(now,
297 FRAME_ACK_RECEIVED, 293 FRAME_ACK_RECEIVED,
298 VIDEO_EVENT, 294 VIDEO_EVENT,
299 rtp_timestamp, 295 rtp_timestamp,
300 cast_feedback.ack_frame_id); 296 cast_feedback.ack_frame_id);
301 297
302 const bool is_acked_out_of_order = 298 const bool is_acked_out_of_order =
303 static_cast<int32>(cast_feedback.ack_frame_id - 299 static_cast<int32>(cast_feedback.ack_frame_id -
304 latest_acked_frame_id_) < 0; 300 latest_acked_frame_id_) < 0;
305 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") 301 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "")
306 << " for frame " << cast_feedback.ack_frame_id; 302 << " for frame " << cast_feedback.ack_frame_id;
307 if (!is_acked_out_of_order) { 303 if (!is_acked_out_of_order) {
308 // Cancel resends of acked frames. 304 // Cancel resends of acked frames.
309 MissingFramesAndPacketsMap missing_frames_and_packets; 305 std::set<uint32> cancel_sending_frames;
hubbe 2014/08/11 19:11:50 Seems like a vector would be sufficient here.
310 PacketIdSet missing;
311 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { 306 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) {
312 latest_acked_frame_id_++; 307 latest_acked_frame_id_++;
313 missing_frames_and_packets[latest_acked_frame_id_] = missing; 308 cancel_sending_frames.insert(latest_acked_frame_id_);
314 } 309 }
315 transport_sender_->ResendPackets( 310 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames);
316 false, missing_frames_and_packets, true, rtt);
317 latest_acked_frame_id_ = cast_feedback.ack_frame_id; 311 latest_acked_frame_id_ = cast_feedback.ack_frame_id;
318 } 312 }
319 } 313 }
320 314
321 bool VideoSender::AreTooManyFramesInFlight() const { 315 bool VideoSender::AreTooManyFramesInFlight() const {
322 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 316 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
323 int frames_in_flight = frames_in_encoder_; 317 int frames_in_flight = frames_in_encoder_;
324 if (!last_send_time_.is_null()) { 318 if (!last_send_time_.is_null()) {
325 frames_in_flight += 319 frames_in_flight +=
326 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); 320 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_);
327 } 321 }
328 VLOG(2) << frames_in_flight 322 VLOG(2) << frames_in_flight
329 << " frames in flight; last sent: " << last_sent_frame_id_ 323 << " frames in flight; last sent: " << last_sent_frame_id_
330 << " latest acked: " << latest_acked_frame_id_ 324 << " latest acked: " << latest_acked_frame_id_
331 << " frames in encoder: " << frames_in_encoder_; 325 << " frames in encoder: " << frames_in_encoder_;
332 return frames_in_flight >= max_unacked_frames_; 326 return frames_in_flight >= max_unacked_frames_;
333 } 327 }
334 328
335 void VideoSender::ResendForKickstart() { 329 void VideoSender::ResendForKickstart() {
336 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 330 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
337 DCHECK(!last_send_time_.is_null()); 331 DCHECK(!last_send_time_.is_null());
338 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ 332 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_
339 << " to kick-start."; 333 << " to kick-start.";
340 // Send the first packet of the last encoded frame to kick start
341 // retransmission. This gives enough information to the receiver what
342 // packets and frames are missing.
343 MissingFramesAndPacketsMap missing_frames_and_packets;
344 PacketIdSet missing;
345 missing.insert(kRtcpCastLastPacket);
346 missing_frames_and_packets.insert(
347 std::make_pair(last_sent_frame_id_, missing));
348 last_send_time_ = cast_environment_->Clock()->NowTicks(); 334 last_send_time_ = cast_environment_->Clock()->NowTicks();
349 335 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_);
350 // Sending this extra packet is to kick-start the session. There is
351 // no need to optimize re-transmission for this case.
352 transport_sender_->ResendPackets(false, missing_frames_and_packets,
353 false, rtt_);
354 } 336 }
355 337
356 } // namespace cast 338 } // namespace cast
357 } // namespace media 339 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698