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

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: fixed test compile 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
« no previous file with comments | « media/cast/sender/frame_sender.cc ('k') | media/cast/sender/video_sender_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 } 301 }
302 // TODO(miu): The values "2" and "3" should be derived from configuration. 302 // TODO(miu): The values "2" and "3" should be derived from configuration.
303 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) { 303 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) {
304 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_; 304 VLOG(1) << "Received duplicate ACK for frame " << latest_acked_frame_id_;
305 ResendForKickstart(); 305 ResendForKickstart();
306 } 306 }
307 } else { 307 } else {
308 // Only count duplicated ACKs if there is no NACK request in between. 308 // Only count duplicated ACKs if there is no NACK request in between.
309 // This is to avoid aggresive resend. 309 // This is to avoid aggresive resend.
310 duplicate_ack_counter_ = 0; 310 duplicate_ack_counter_ = 0;
311
312 // A NACK is also used to cancel pending re-transmissions.
313 transport_sender_->ResendPackets(
314 false, cast_feedback.missing_frames_and_packets, true, rtt);
315 } 311 }
316 312
317 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 313 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
318 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now); 314 congestion_control_.AckFrame(cast_feedback.ack_frame_id, now);
319 315
320 RtpTimestamp rtp_timestamp = 316 RtpTimestamp rtp_timestamp =
321 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id & 0xff]; 317 frame_id_to_rtp_timestamp_[cast_feedback.ack_frame_id & 0xff];
322 cast_environment_->Logging()->InsertFrameEvent(now, 318 cast_environment_->Logging()->InsertFrameEvent(now,
323 FRAME_ACK_RECEIVED, 319 FRAME_ACK_RECEIVED,
324 VIDEO_EVENT, 320 VIDEO_EVENT,
325 rtp_timestamp, 321 rtp_timestamp,
326 cast_feedback.ack_frame_id); 322 cast_feedback.ack_frame_id);
327 323
328 const bool is_acked_out_of_order = 324 const bool is_acked_out_of_order =
329 static_cast<int32>(cast_feedback.ack_frame_id - 325 static_cast<int32>(cast_feedback.ack_frame_id -
330 latest_acked_frame_id_) < 0; 326 latest_acked_frame_id_) < 0;
331 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") 327 VLOG(2) << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "")
332 << " for frame " << cast_feedback.ack_frame_id; 328 << " for frame " << cast_feedback.ack_frame_id;
333 if (!is_acked_out_of_order) { 329 if (!is_acked_out_of_order) {
334 // Cancel resends of acked frames. 330 // Cancel resends of acked frames.
335 MissingFramesAndPacketsMap missing_frames_and_packets; 331 std::vector<uint32> cancel_sending_frames;
336 PacketIdSet missing;
337 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { 332 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) {
338 latest_acked_frame_id_++; 333 latest_acked_frame_id_++;
339 missing_frames_and_packets[latest_acked_frame_id_] = missing; 334 cancel_sending_frames.push_back(latest_acked_frame_id_);
340 } 335 }
341 transport_sender_->ResendPackets( 336 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames);
342 false, missing_frames_and_packets, true, rtt);
343 latest_acked_frame_id_ = cast_feedback.ack_frame_id; 337 latest_acked_frame_id_ = cast_feedback.ack_frame_id;
344 } 338 }
345 } 339 }
346 340
347 bool VideoSender::AreTooManyFramesInFlight() const { 341 bool VideoSender::AreTooManyFramesInFlight() const {
348 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 342 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
349 int frames_in_flight = frames_in_encoder_; 343 int frames_in_flight = frames_in_encoder_;
350 if (!last_send_time_.is_null()) { 344 if (!last_send_time_.is_null()) {
351 frames_in_flight += 345 frames_in_flight +=
352 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); 346 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_);
353 } 347 }
354 VLOG(2) << frames_in_flight 348 VLOG(2) << frames_in_flight
355 << " frames in flight; last sent: " << last_sent_frame_id_ 349 << " frames in flight; last sent: " << last_sent_frame_id_
356 << " latest acked: " << latest_acked_frame_id_ 350 << " latest acked: " << latest_acked_frame_id_
357 << " frames in encoder: " << frames_in_encoder_; 351 << " frames in encoder: " << frames_in_encoder_;
358 return frames_in_flight >= max_unacked_frames_; 352 return frames_in_flight >= max_unacked_frames_;
359 } 353 }
360 354
361 void VideoSender::ResendForKickstart() { 355 void VideoSender::ResendForKickstart() {
362 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 356 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
363 DCHECK(!last_send_time_.is_null()); 357 DCHECK(!last_send_time_.is_null());
364 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ 358 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_
365 << " to kick-start."; 359 << " to kick-start.";
366 // Send the first packet of the last encoded frame to kick start
367 // retransmission. This gives enough information to the receiver what
368 // packets and frames are missing.
369 MissingFramesAndPacketsMap missing_frames_and_packets;
370 PacketIdSet missing;
371 missing.insert(kRtcpCastLastPacket);
372 missing_frames_and_packets.insert(
373 std::make_pair(last_sent_frame_id_, missing));
374 last_send_time_ = cast_environment_->Clock()->NowTicks(); 360 last_send_time_ = cast_environment_->Clock()->NowTicks();
375 361 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_);
376 // Sending this extra packet is to kick-start the session. There is
377 // no need to optimize re-transmission for this case.
378 transport_sender_->ResendPackets(false, missing_frames_and_packets,
379 false, rtt_);
380 } 362 }
381 363
382 } // namespace cast 364 } // namespace cast
383 } // namespace media 365 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/frame_sender.cc ('k') | media/cast/sender/video_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698