| 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 TRACE_EVENT_ASYNC_END1("cast.stream", | 387 TRACE_EVENT_ASYNC_END1("cast.stream", |
| 375 is_audio_ ? "Audio Transport" : "Video Transport", | 388 is_audio_ ? "Audio Transport" : "Video Transport", |
| 376 cast_feedback.ack_frame_id, | 389 cast_feedback.ack_frame_id, |
| 377 "RTT_usecs", current_round_trip_time_.InMicroseconds()); | 390 "RTT_usecs", current_round_trip_time_.InMicroseconds()); |
| 378 } | 391 } |
| 379 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); | 392 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); |
| 380 latest_acked_frame_id_ = cast_feedback.ack_frame_id; | 393 latest_acked_frame_id_ = cast_feedback.ack_frame_id; |
| 381 } | 394 } |
| 382 } | 395 } |
| 383 | 396 |
| 397 void FrameSender::OnReceivedPli() { |
| 398 picture_lost_at_receiver_ = true; |
| 399 } |
| 400 |
| 384 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { | 401 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { |
| 385 // Check that accepting the next frame won't cause more frames to become | 402 // Check that accepting the next frame won't cause more frames to become |
| 386 // in-flight than the system's design limit. | 403 // in-flight than the system's design limit. |
| 387 const int count_frames_in_flight = | 404 const int count_frames_in_flight = |
| 388 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); | 405 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); |
| 389 if (count_frames_in_flight >= kMaxUnackedFrames) { | 406 if (count_frames_in_flight >= kMaxUnackedFrames) { |
| 390 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; | 407 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; |
| 391 return true; | 408 return true; |
| 392 } | 409 } |
| 393 | 410 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 421 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; | 438 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; |
| 422 return true; | 439 return true; |
| 423 } | 440 } |
| 424 | 441 |
| 425 // Next frame is accepted. | 442 // Next frame is accepted. |
| 426 return false; | 443 return false; |
| 427 } | 444 } |
| 428 | 445 |
| 429 } // namespace cast | 446 } // namespace cast |
| 430 } // namespace media | 447 } // namespace media |
| OLD | NEW |