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 "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 | 8 |
9 namespace media { | 9 namespace media { |
10 namespace cast { | 10 namespace cast { |
11 namespace { | 11 namespace { |
12 | 12 |
13 const int kMinSchedulingDelayMs = 1; | 13 const int kMinSchedulingDelayMs = 1; |
14 const int kNumAggressiveReportsSentAtStart = 100; | 14 const int kNumAggressiveReportsSentAtStart = 100; |
15 | 15 |
16 } // namespace | 16 } // namespace |
17 | 17 |
18 FrameSender::FrameSender(scoped_refptr<CastEnvironment> cast_environment, | 18 FrameSender::FrameSender(scoped_refptr<CastEnvironment> cast_environment, |
19 bool is_audio, | 19 bool is_audio, |
20 CastTransportSender* const transport_sender, | 20 CastTransportSender* const transport_sender, |
21 base::TimeDelta rtcp_interval, | 21 base::TimeDelta rtcp_interval, |
22 int rtp_timebase, | 22 int rtp_timebase, |
23 uint32 ssrc, | 23 uint32 ssrc, |
24 double max_frame_rate, | 24 double max_frame_rate, |
25 base::TimeDelta playout_delay, | 25 base::TimeDelta playout_delay, |
26 CongestionControl* congestion_control) | 26 CongestionControl* congestion_control) |
27 : cast_environment_(cast_environment), | 27 : cast_environment_(cast_environment), |
28 transport_sender_(transport_sender), | 28 transport_sender_(transport_sender), |
29 ssrc_(ssrc), | 29 ssrc_(ssrc), |
30 rtt_available_(false), | |
31 rtcp_interval_(rtcp_interval), | 30 rtcp_interval_(rtcp_interval), |
32 max_frame_rate_(max_frame_rate), | 31 max_frame_rate_(max_frame_rate), |
33 frames_in_encoder_(0), | 32 frames_in_encoder_(0), |
34 num_aggressive_rtcp_reports_sent_(0), | 33 num_aggressive_rtcp_reports_sent_(0), |
35 last_sent_frame_id_(0), | 34 last_sent_frame_id_(0), |
36 latest_acked_frame_id_(0), | 35 latest_acked_frame_id_(0), |
37 duplicate_ack_counter_(0), | 36 duplicate_ack_counter_(0), |
38 rtp_timebase_(rtp_timebase), | 37 rtp_timebase_(rtp_timebase), |
39 congestion_control_(congestion_control), | 38 congestion_control_(congestion_control), |
40 is_audio_(is_audio), | 39 is_audio_(is_audio), |
41 weak_factory_(this) { | 40 weak_factory_(this) { |
| 41 DCHECK(transport_sender_); |
42 DCHECK_GT(rtp_timebase_, 0); | 42 DCHECK_GT(rtp_timebase_, 0); |
| 43 DCHECK(congestion_control_); |
43 SetTargetPlayoutDelay(playout_delay); | 44 SetTargetPlayoutDelay(playout_delay); |
44 send_target_playout_delay_ = false; | 45 send_target_playout_delay_ = false; |
45 memset(frame_rtp_timestamps_, 0, sizeof(frame_rtp_timestamps_)); | 46 memset(frame_rtp_timestamps_, 0, sizeof(frame_rtp_timestamps_)); |
46 } | 47 } |
47 | 48 |
48 FrameSender::~FrameSender() { | 49 FrameSender::~FrameSender() { |
49 } | 50 } |
50 | 51 |
51 void FrameSender::ScheduleNextRtcpReport() { | 52 void FrameSender::ScheduleNextRtcpReport() { |
52 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 53 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
(...skipping 28 matching lines...) Expand all Loading... |
81 const int64 rtp_delta = TimeDeltaToRtpDelta(time_delta, rtp_timebase_); | 82 const int64 rtp_delta = TimeDeltaToRtpDelta(time_delta, rtp_timebase_); |
82 const uint32 now_as_rtp_timestamp = | 83 const uint32 now_as_rtp_timestamp = |
83 GetRecordedRtpTimestamp(last_sent_frame_id_) + | 84 GetRecordedRtpTimestamp(last_sent_frame_id_) + |
84 static_cast<uint32>(rtp_delta); | 85 static_cast<uint32>(rtp_delta); |
85 transport_sender_->SendSenderReport(ssrc_, now, now_as_rtp_timestamp); | 86 transport_sender_->SendSenderReport(ssrc_, now, now_as_rtp_timestamp); |
86 | 87 |
87 if (schedule_future_reports) | 88 if (schedule_future_reports) |
88 ScheduleNextRtcpReport(); | 89 ScheduleNextRtcpReport(); |
89 } | 90 } |
90 | 91 |
91 void FrameSender::OnReceivedRtt(base::TimeDelta rtt, | 92 void FrameSender::OnMeasuredRoundTripTime(base::TimeDelta rtt) { |
92 base::TimeDelta avg_rtt, | 93 DCHECK(rtt > base::TimeDelta()); |
93 base::TimeDelta min_rtt, | 94 current_round_trip_time_ = rtt; |
94 base::TimeDelta max_rtt) { | |
95 rtt_available_ = true; | |
96 rtt_ = rtt; | |
97 avg_rtt_ = avg_rtt; | |
98 min_rtt_ = min_rtt; | |
99 max_rtt_ = max_rtt; | |
100 } | 95 } |
101 | 96 |
102 void FrameSender::SetTargetPlayoutDelay( | 97 void FrameSender::SetTargetPlayoutDelay( |
103 base::TimeDelta new_target_playout_delay) { | 98 base::TimeDelta new_target_playout_delay) { |
104 target_playout_delay_ = new_target_playout_delay; | 99 target_playout_delay_ = new_target_playout_delay; |
105 max_unacked_frames_ = | 100 max_unacked_frames_ = |
106 std::min(kMaxUnackedFrames, | 101 std::min(kMaxUnackedFrames, |
107 1 + static_cast<int>(target_playout_delay_ * | 102 1 + static_cast<int>(target_playout_delay_ * |
108 max_frame_rate_ / | 103 max_frame_rate_ / |
109 base::TimeDelta::FromSeconds(1))); | 104 base::TimeDelta::FromSeconds(1))); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 if (send_target_playout_delay_) { | 229 if (send_target_playout_delay_) { |
235 encoded_frame->new_playout_delay_ms = | 230 encoded_frame->new_playout_delay_ms = |
236 target_playout_delay_.InMilliseconds(); | 231 target_playout_delay_.InMilliseconds(); |
237 } | 232 } |
238 transport_sender_->InsertFrame(ssrc_, *encoded_frame); | 233 transport_sender_->InsertFrame(ssrc_, *encoded_frame); |
239 } | 234 } |
240 | 235 |
241 void FrameSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { | 236 void FrameSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { |
242 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 237 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
243 | 238 |
244 base::TimeDelta rtt; | 239 const bool have_valid_rtt = current_round_trip_time_ > base::TimeDelta(); |
245 base::TimeDelta avg_rtt; | 240 if (have_valid_rtt) { |
246 base::TimeDelta min_rtt; | 241 congestion_control_->UpdateRtt(current_round_trip_time_); |
247 base::TimeDelta max_rtt; | |
248 if (is_rtt_available()) { | |
249 rtt = rtt_; | |
250 avg_rtt = avg_rtt_; | |
251 min_rtt = min_rtt_; | |
252 max_rtt = max_rtt_; | |
253 | 242 |
254 congestion_control_->UpdateRtt(rtt); | 243 // Having the RTT value implies the receiver sent back a receiver report |
255 | |
256 // Don't use a RTT lower than our average. | |
257 rtt = std::max(rtt, avg_rtt); | |
258 | |
259 // Having the RTT values implies the receiver sent back a receiver report | |
260 // based on it having received a report from here. Therefore, ensure this | 244 // based on it having received a report from here. Therefore, ensure this |
261 // sender stops aggressively sending reports. | 245 // sender stops aggressively sending reports. |
262 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { | 246 if (num_aggressive_rtcp_reports_sent_ < kNumAggressiveReportsSentAtStart) { |
263 VLOG(1) << "No longer a need to send reports aggressively (sent " | 247 VLOG(1) << "No longer a need to send reports aggressively (sent " |
264 << num_aggressive_rtcp_reports_sent_ << ")."; | 248 << num_aggressive_rtcp_reports_sent_ << ")."; |
265 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart; | 249 num_aggressive_rtcp_reports_sent_ = kNumAggressiveReportsSentAtStart; |
266 ScheduleNextRtcpReport(); | 250 ScheduleNextRtcpReport(); |
267 } | 251 } |
268 } else { | |
269 // We have no measured value use default. | |
270 rtt = base::TimeDelta::FromMilliseconds(kStartRttMs); | |
271 } | 252 } |
272 | 253 |
273 if (last_send_time_.is_null()) | 254 if (last_send_time_.is_null()) |
274 return; // Cannot get an ACK without having first sent a frame. | 255 return; // Cannot get an ACK without having first sent a frame. |
275 | 256 |
276 if (cast_feedback.missing_frames_and_packets.empty()) { | 257 if (cast_feedback.missing_frames_and_packets.empty()) { |
277 OnAck(cast_feedback.ack_frame_id); | 258 OnAck(cast_feedback.ack_frame_id); |
278 | 259 |
279 // We only count duplicate ACKs when we have sent newer frames. | 260 // We only count duplicate ACKs when we have sent newer frames. |
280 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && | 261 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 << duration_in_flight.InMicroseconds() << " usec (" | 324 << duration_in_flight.InMicroseconds() << " usec (" |
344 << (target_playout_delay_ > base::TimeDelta() ? | 325 << (target_playout_delay_ > base::TimeDelta() ? |
345 100 * duration_in_flight / target_playout_delay_ : | 326 100 * duration_in_flight / target_playout_delay_ : |
346 kint64max) << "%)"; | 327 kint64max) << "%)"; |
347 return frames_in_flight >= max_unacked_frames_ || | 328 return frames_in_flight >= max_unacked_frames_ || |
348 duration_in_flight >= target_playout_delay_; | 329 duration_in_flight >= target_playout_delay_; |
349 } | 330 } |
350 | 331 |
351 } // namespace cast | 332 } // namespace cast |
352 } // namespace media | 333 } // namespace media |
OLD | NEW |