| 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/frame_sender.h" | 5 #include "media/cast/sender/frame_sender.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 animated_playout_delay_(animated_playout_delay == base::TimeDelta() | 52 animated_playout_delay_(animated_playout_delay == base::TimeDelta() |
| 53 ? max_playout_delay | 53 ? max_playout_delay |
| 54 : animated_playout_delay), | 54 : animated_playout_delay), |
| 55 send_target_playout_delay_(false), | 55 send_target_playout_delay_(false), |
| 56 max_frame_rate_(max_frame_rate), | 56 max_frame_rate_(max_frame_rate), |
| 57 num_aggressive_rtcp_reports_sent_(0), | 57 num_aggressive_rtcp_reports_sent_(0), |
| 58 last_sent_frame_id_(0), | 58 last_sent_frame_id_(0), |
| 59 latest_acked_frame_id_(0), | 59 latest_acked_frame_id_(0), |
| 60 duplicate_ack_counter_(0), | 60 duplicate_ack_counter_(0), |
| 61 congestion_control_(congestion_control), | 61 congestion_control_(congestion_control), |
| 62 picture_lost_at_receiver_(false), |
| 62 rtp_timebase_(rtp_timebase), | 63 rtp_timebase_(rtp_timebase), |
| 63 is_audio_(is_audio), | 64 is_audio_(is_audio), |
| 64 weak_factory_(this) { | 65 weak_factory_(this) { |
| 65 DCHECK(transport_sender_); | 66 DCHECK(transport_sender_); |
| 66 DCHECK_GT(rtp_timebase_, 0); | 67 DCHECK_GT(rtp_timebase_, 0); |
| 67 DCHECK(congestion_control_); | 68 DCHECK(congestion_control_); |
| 68 // We assume animated content to begin with since that is the common use | 69 // We assume animated content to begin with since that is the common use |
| 69 // case today. | 70 // case today. |
| 70 VLOG(1) << SENDER_SSRC << "min latency " | 71 VLOG(1) << SENDER_SSRC << "min latency " |
| 71 << min_playout_delay_.InMilliseconds() << "max latency " | 72 << min_playout_delay_.InMilliseconds() << "max latency " |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 213 |
| 213 void FrameSender::SendEncodedFrame( | 214 void FrameSender::SendEncodedFrame( |
| 214 int requested_bitrate_before_encode, | 215 int requested_bitrate_before_encode, |
| 215 scoped_ptr<SenderEncodedFrame> encoded_frame) { | 216 scoped_ptr<SenderEncodedFrame> encoded_frame) { |
| 216 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 217 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 217 | 218 |
| 218 VLOG(2) << SENDER_SSRC << "About to send another frame: last_sent=" | 219 VLOG(2) << SENDER_SSRC << "About to send another frame: last_sent=" |
| 219 << last_sent_frame_id_ << ", latest_acked=" << latest_acked_frame_id_; | 220 << last_sent_frame_id_ << ", latest_acked=" << latest_acked_frame_id_; |
| 220 | 221 |
| 221 const uint32_t frame_id = encoded_frame->frame_id; | 222 const uint32_t frame_id = encoded_frame->frame_id; |
| 223 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); |
| 222 | 224 |
| 223 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); | 225 if (picture_lost_at_receiver_ && |
| 226 (encoded_frame->dependency == EncodedFrame::KEY)) { |
| 227 picture_lost_at_receiver_ = false; |
| 228 DCHECK(frame_id > latest_acked_frame_id_); |
| 229 // Cancel sending remaining frames. |
| 230 std::vector<uint32_t> cancel_sending_frames; |
| 231 for (uint32_t id = latest_acked_frame_id_ + 1; id < frame_id; ++id) { |
| 232 cancel_sending_frames.push_back(id); |
| 233 } |
| 234 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); |
| 235 } |
| 236 |
| 224 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 237 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
| 225 last_sent_frame_id_ = frame_id; | 238 last_sent_frame_id_ = frame_id; |
| 226 // If this is the first frame about to be sent, fake the value of | 239 // If this is the first frame about to be sent, fake the value of |
| 227 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. | 240 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. |
| 228 // Also, schedule the periodic frame re-send checks. | 241 // Also, schedule the periodic frame re-send checks. |
| 229 if (is_first_frame_to_be_sent) { | 242 if (is_first_frame_to_be_sent) { |
| 230 latest_acked_frame_id_ = frame_id - 1; | 243 latest_acked_frame_id_ = frame_id - 1; |
| 231 ScheduleNextResendCheck(); | 244 ScheduleNextResendCheck(); |
| 232 } | 245 } |
| 233 | 246 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 TRACE_EVENT_ASYNC_END1("cast.stream", | 393 TRACE_EVENT_ASYNC_END1("cast.stream", |
| 381 is_audio_ ? "Audio Transport" : "Video Transport", | 394 is_audio_ ? "Audio Transport" : "Video Transport", |
| 382 cast_feedback.ack_frame_id, | 395 cast_feedback.ack_frame_id, |
| 383 "RTT_usecs", current_round_trip_time_.InMicroseconds()); | 396 "RTT_usecs", current_round_trip_time_.InMicroseconds()); |
| 384 } | 397 } |
| 385 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); | 398 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); |
| 386 latest_acked_frame_id_ = cast_feedback.ack_frame_id; | 399 latest_acked_frame_id_ = cast_feedback.ack_frame_id; |
| 387 } | 400 } |
| 388 } | 401 } |
| 389 | 402 |
| 403 void FrameSender::OnReceivedPli() { |
| 404 picture_lost_at_receiver_ = true; |
| 405 } |
| 406 |
| 390 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { | 407 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { |
| 391 // Check that accepting the next frame won't cause more frames to become | 408 // Check that accepting the next frame won't cause more frames to become |
| 392 // in-flight than the system's design limit. | 409 // in-flight than the system's design limit. |
| 393 const int count_frames_in_flight = | 410 const int count_frames_in_flight = |
| 394 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); | 411 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); |
| 395 if (count_frames_in_flight >= kMaxUnackedFrames) { | 412 if (count_frames_in_flight >= kMaxUnackedFrames) { |
| 396 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; | 413 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; |
| 397 return true; | 414 return true; |
| 398 } | 415 } |
| 399 | 416 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 427 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; | 444 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; |
| 428 return true; | 445 return true; |
| 429 } | 446 } |
| 430 | 447 |
| 431 // Next frame is accepted. | 448 // Next frame is accepted. |
| 432 return false; | 449 return false; |
| 433 } | 450 } |
| 434 | 451 |
| 435 } // namespace cast | 452 } // namespace cast |
| 436 } // namespace media | 453 } // namespace media |
| OLD | NEW |