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

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

Issue 542883004: Cast: Merge common functionality from audio/video sender into frame_sender. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 6 years, 3 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
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 // The purpose of this file is determine what bitrate to use for mirroring. 5 // The purpose of this file is determine what bitrate to use for mirroring.
6 // Ideally this should be as much as possible, without causing any frames to 6 // Ideally this should be as much as possible, without causing any frames to
7 // arrive late. 7 // arrive late.
8 8
9 // The current algorithm is to measure how much bandwidth we've been using 9 // The current algorithm is to measure how much bandwidth we've been using
10 // recently. We also keep track of how much data has been queued up for sending 10 // recently. We also keep track of how much data has been queued up for sending
11 // in a virtual "buffer" (this virtual buffer represents all the buffers between 11 // in a virtual "buffer" (this virtual buffer represents all the buffers between
12 // the sender and the receiver, including retransmissions and so forth.) 12 // the sender and the receiver, including retransmissions and so forth.)
13 // If we estimate that our virtual buffer is mostly empty, we try to use 13 // If we estimate that our virtual buffer is mostly empty, we try to use
14 // more bandwidth than our recent usage, otherwise we use less. 14 // more bandwidth than our recent usage, otherwise we use less.
15 15
16 #include "media/cast/sender/congestion_control.h" 16 #include "media/cast/sender/congestion_control.h"
17 17
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "media/cast/cast_config.h" 19 #include "media/cast/cast_config.h"
20 #include "media/cast/cast_defines.h" 20 #include "media/cast/cast_defines.h"
21 21
22 namespace media { 22 namespace media {
23 namespace cast { 23 namespace cast {
24 24
25 class AdaptiveCongestionControl : public CongestionControl {
26 public:
27 AdaptiveCongestionControl(base::TickClock* clock,
28 uint32 max_bitrate_configured,
29 uint32 min_bitrate_configured,
30 size_t max_unacked_frames);
31
32 virtual ~AdaptiveCongestionControl() OVERRIDE;
33
34 virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE;
35
36 // Called when an encoded frame is sent to the transport.
37 virtual void SendFrameToTransport(uint32 frame_id,
38 size_t frame_size,
39 base::TimeTicks when) OVERRIDE;
40
41 // Called when we receive an ACK for a frame.
42 virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE;
43
44 // Returns the bitrate we should use for the next frame.
45 virtual uint32 GetBitrate(base::TimeTicks playout_time,
46 base::TimeDelta playout_delay) OVERRIDE;
47
48 private:
49 struct FrameStats {
50 FrameStats();
51 // Time this frame was sent to the transport.
52 base::TimeTicks sent_time;
53 // Time this frame was acked.
54 base::TimeTicks ack_time;
55 // Size of encoded frame in bits.
56 size_t frame_size;
57 };
58
59 // Calculate how much "dead air" (idle time) there is between two frames.
60 static base::TimeDelta DeadTime(const FrameStats& a, const FrameStats& b);
61 // Get the FrameStats for a given |frame_id|.
62 // Note: Older FrameStats will be removed automatically.
63 FrameStats* GetFrameStats(uint32 frame_id);
64 // Calculate a safe bitrate. This is based on how much we've been
65 // sending in the past.
66 double CalculateSafeBitrate();
67
68 // For a given frame, calculate when it might be acked.
69 // (Or return the time it was acked, if it was.)
70 base::TimeTicks EstimatedAckTime(uint32 frame_id, double bitrate);
71 // Calculate when we start sending the data for a given frame.
72 // This is done by calculating when we were done sending the previous
73 // frame, but obviously can't be less than |sent_time| (if known).
74 base::TimeTicks EstimatedSendingTime(uint32 frame_id, double bitrate);
75
76 base::TickClock* const clock_; // Not owned by this class.
77 const uint32 max_bitrate_configured_;
78 const uint32 min_bitrate_configured_;
79 std::deque<FrameStats> frame_stats_;
80 uint32 last_frame_stats_;
81 uint32 last_acked_frame_;
82 uint32 last_encoded_frame_;
83 base::TimeDelta rtt_;
84 size_t history_size_;
85 size_t acked_bits_in_history_;
86 base::TimeDelta dead_time_in_history_;
87
88 DISALLOW_COPY_AND_ASSIGN(AdaptiveCongestionControl);
89 };
90
91 class FixedCongestionControl : public CongestionControl {
92 public:
93 FixedCongestionControl(uint32 bitrate) : bitrate_(bitrate) {}
94 virtual ~FixedCongestionControl() OVERRIDE {}
95
96 virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE {
97 }
98
99 // Called when an encoded frame is sent to the transport.
100 virtual void SendFrameToTransport(uint32 frame_id,
101 size_t frame_size,
102 base::TimeTicks when) OVERRIDE {
103 }
104
105 // Called when we receive an ACK for a frame.
106 virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE {
107 }
108
109 // Returns the bitrate we should use for the next frame.
110 virtual uint32 GetBitrate(base::TimeTicks playout_time,
111 base::TimeDelta playout_delay) OVERRIDE {
112 return bitrate_;
113 }
114
115 private:
116 uint32 bitrate_;
117 DISALLOW_COPY_AND_ASSIGN(FixedCongestionControl);
118 };
119
120
121 CongestionControl* NewAdaptiveCongestionControl(
122 base::TickClock* clock,
123 uint32 max_bitrate_configured,
124 uint32 min_bitrate_configured,
125 size_t max_unacked_frames) {
126 return new AdaptiveCongestionControl(clock,
127 max_bitrate_configured,
128 min_bitrate_configured,
129 max_unacked_frames);
130 }
131
132 CongestionControl* NewFixedCongestionControl(uint32 bitrate) {
133 return new FixedCongestionControl(bitrate);
134 }
135
25 // This means that we *try* to keep our buffer 90% empty. 136 // This means that we *try* to keep our buffer 90% empty.
26 // If it is less full, we increase the bandwidth, if it is more 137 // If it is less full, we increase the bandwidth, if it is more
27 // we decrease the bandwidth. Making this smaller makes the 138 // we decrease the bandwidth. Making this smaller makes the
28 // congestion control more aggressive. 139 // congestion control more aggressive.
29 static const double kTargetEmptyBufferFraction = 0.9; 140 static const double kTargetEmptyBufferFraction = 0.9;
30 141
31 // This is the size of our history in frames. Larger values makes the 142 // This is the size of our history in frames. Larger values makes the
32 // congestion control adapt slower. 143 // congestion control adapt slower.
33 static const size_t kHistorySize = 100; 144 static const size_t kHistorySize = 100;
34 145
35 CongestionControl::FrameStats::FrameStats() : frame_size(0) { 146 AdaptiveCongestionControl::FrameStats::FrameStats() : frame_size(0) {
36 } 147 }
37 148
38 CongestionControl::CongestionControl(base::TickClock* clock, 149 AdaptiveCongestionControl::AdaptiveCongestionControl(
39 uint32 max_bitrate_configured, 150 base::TickClock* clock,
40 uint32 min_bitrate_configured, 151 uint32 max_bitrate_configured,
41 size_t max_unacked_frames) 152 uint32 min_bitrate_configured,
153 size_t max_unacked_frames)
42 : clock_(clock), 154 : clock_(clock),
43 max_bitrate_configured_(max_bitrate_configured), 155 max_bitrate_configured_(max_bitrate_configured),
44 min_bitrate_configured_(min_bitrate_configured), 156 min_bitrate_configured_(min_bitrate_configured),
45 last_frame_stats_(static_cast<uint32>(-1)), 157 last_frame_stats_(static_cast<uint32>(-1)),
46 last_acked_frame_(static_cast<uint32>(-1)), 158 last_acked_frame_(static_cast<uint32>(-1)),
47 last_encoded_frame_(static_cast<uint32>(-1)), 159 last_encoded_frame_(static_cast<uint32>(-1)),
48 history_size_(max_unacked_frames + kHistorySize), 160 history_size_(max_unacked_frames + kHistorySize),
49 acked_bits_in_history_(0) { 161 acked_bits_in_history_(0) {
50 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config"; 162 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config";
51 frame_stats_.resize(2); 163 frame_stats_.resize(2);
52 base::TimeTicks now = clock->NowTicks(); 164 base::TimeTicks now = clock->NowTicks();
53 frame_stats_[0].ack_time = now; 165 frame_stats_[0].ack_time = now;
54 frame_stats_[0].sent_time = now; 166 frame_stats_[0].sent_time = now;
55 frame_stats_[1].ack_time = now; 167 frame_stats_[1].ack_time = now;
56 DCHECK(!frame_stats_[0].ack_time.is_null()); 168 DCHECK(!frame_stats_[0].ack_time.is_null());
57 } 169 }
58 170
59 CongestionControl::~CongestionControl() {} 171 CongestionControl::~CongestionControl() {}
172 AdaptiveCongestionControl::~AdaptiveCongestionControl() {}
60 173
61 void CongestionControl::UpdateRtt(base::TimeDelta rtt) { 174 void AdaptiveCongestionControl::UpdateRtt(base::TimeDelta rtt) {
62 rtt_ = (7 * rtt_ + rtt) / 8; 175 rtt_ = (7 * rtt_ + rtt) / 8;
63 } 176 }
64 177
65 // Calculate how much "dead air" there is between two frames. 178 // Calculate how much "dead air" there is between two frames.
66 base::TimeDelta CongestionControl::DeadTime(const FrameStats& a, 179 base::TimeDelta AdaptiveCongestionControl::DeadTime(const FrameStats& a,
67 const FrameStats& b) { 180 const FrameStats& b) {
68 if (b.sent_time > a.ack_time) { 181 if (b.sent_time > a.ack_time) {
69 return b.sent_time - a.ack_time; 182 return b.sent_time - a.ack_time;
70 } else { 183 } else {
71 return base::TimeDelta(); 184 return base::TimeDelta();
72 } 185 }
73 } 186 }
74 187
75 double CongestionControl::CalculateSafeBitrate() { 188 double AdaptiveCongestionControl::CalculateSafeBitrate() {
76 double transmit_time = 189 double transmit_time =
77 (GetFrameStats(last_acked_frame_)->ack_time - 190 (GetFrameStats(last_acked_frame_)->ack_time -
78 frame_stats_.front().sent_time - dead_time_in_history_).InSecondsF(); 191 frame_stats_.front().sent_time - dead_time_in_history_).InSecondsF();
79 192
80 if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) { 193 if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) {
81 return min_bitrate_configured_; 194 return min_bitrate_configured_;
82 } 195 }
83 return acked_bits_in_history_ / std::max(transmit_time, 1E-3); 196 return acked_bits_in_history_ / std::max(transmit_time, 1E-3);
84 } 197 }
85 198
86 CongestionControl::FrameStats* CongestionControl::GetFrameStats( 199 AdaptiveCongestionControl::FrameStats*
87 uint32 frame_id) { 200 AdaptiveCongestionControl::GetFrameStats(uint32 frame_id) {
88 int32 offset = static_cast<int32>(frame_id - last_frame_stats_); 201 int32 offset = static_cast<int32>(frame_id - last_frame_stats_);
89 DCHECK_LT(offset, static_cast<int32>(kHistorySize)); 202 DCHECK_LT(offset, static_cast<int32>(kHistorySize));
90 if (offset > 0) { 203 if (offset > 0) {
91 frame_stats_.resize(frame_stats_.size() + offset); 204 frame_stats_.resize(frame_stats_.size() + offset);
92 last_frame_stats_ += offset; 205 last_frame_stats_ += offset;
93 offset = 0; 206 offset = 0;
94 } 207 }
95 while (frame_stats_.size() > history_size_) { 208 while (frame_stats_.size() > history_size_) {
96 DCHECK_GT(frame_stats_.size(), 1UL); 209 DCHECK_GT(frame_stats_.size(), 1UL);
97 DCHECK(!frame_stats_[0].ack_time.is_null()); 210 DCHECK(!frame_stats_[0].ack_time.is_null());
98 acked_bits_in_history_ -= frame_stats_[0].frame_size; 211 acked_bits_in_history_ -= frame_stats_[0].frame_size;
99 dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]); 212 dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]);
100 DCHECK_GE(acked_bits_in_history_, 0UL); 213 DCHECK_GE(acked_bits_in_history_, 0UL);
101 VLOG(2) << "DT: " << dead_time_in_history_.InSecondsF(); 214 VLOG(2) << "DT: " << dead_time_in_history_.InSecondsF();
102 DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0); 215 DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0);
103 frame_stats_.pop_front(); 216 frame_stats_.pop_front();
104 } 217 }
105 offset += frame_stats_.size() - 1; 218 offset += frame_stats_.size() - 1;
106 if (offset < 0 || offset >= static_cast<int32>(frame_stats_.size())) { 219 if (offset < 0 || offset >= static_cast<int32>(frame_stats_.size())) {
107 return NULL; 220 return NULL;
108 } 221 }
109 return &frame_stats_[offset]; 222 return &frame_stats_[offset];
110 } 223 }
111 224
112 void CongestionControl::AckFrame(uint32 frame_id, base::TimeTicks when) { 225 void AdaptiveCongestionControl::AckFrame(uint32 frame_id,
226 base::TimeTicks when) {
113 FrameStats* frame_stats = GetFrameStats(last_acked_frame_); 227 FrameStats* frame_stats = GetFrameStats(last_acked_frame_);
114 while (IsNewerFrameId(frame_id, last_acked_frame_)) { 228 while (IsNewerFrameId(frame_id, last_acked_frame_)) {
115 FrameStats* last_frame_stats = frame_stats; 229 FrameStats* last_frame_stats = frame_stats;
116 frame_stats = GetFrameStats(last_acked_frame_ + 1); 230 frame_stats = GetFrameStats(last_acked_frame_ + 1);
117 DCHECK(frame_stats); 231 DCHECK(frame_stats);
118 if (frame_stats->sent_time.is_null()) { 232 if (frame_stats->sent_time.is_null()) {
119 // Can't ack a frame that hasn't been sent yet. 233 // Can't ack a frame that hasn't been sent yet.
120 return; 234 return;
121 } 235 }
122 last_acked_frame_++; 236 last_acked_frame_++;
123 if (when < frame_stats->sent_time) 237 if (when < frame_stats->sent_time)
124 when = frame_stats->sent_time; 238 when = frame_stats->sent_time;
125 239
126 frame_stats->ack_time = when; 240 frame_stats->ack_time = when;
127 acked_bits_in_history_ += frame_stats->frame_size; 241 acked_bits_in_history_ += frame_stats->frame_size;
128 dead_time_in_history_ += DeadTime(*last_frame_stats, *frame_stats); 242 dead_time_in_history_ += DeadTime(*last_frame_stats, *frame_stats);
129 } 243 }
130 } 244 }
131 245
132 void CongestionControl::SendFrameToTransport(uint32 frame_id, 246 void AdaptiveCongestionControl::SendFrameToTransport(uint32 frame_id,
133 size_t frame_size, 247 size_t frame_size,
134 base::TimeTicks when) { 248 base::TimeTicks when) {
135 last_encoded_frame_ = frame_id; 249 last_encoded_frame_ = frame_id;
136 FrameStats* frame_stats = GetFrameStats(frame_id); 250 FrameStats* frame_stats = GetFrameStats(frame_id);
137 DCHECK(frame_stats); 251 DCHECK(frame_stats);
138 frame_stats->frame_size = frame_size; 252 frame_stats->frame_size = frame_size;
139 frame_stats->sent_time = when; 253 frame_stats->sent_time = when;
140 } 254 }
141 255
142 base::TimeTicks CongestionControl::EstimatedAckTime(uint32 frame_id, 256 base::TimeTicks AdaptiveCongestionControl::EstimatedAckTime(uint32 frame_id,
143 double bitrate) { 257 double bitrate) {
144 FrameStats* frame_stats = GetFrameStats(frame_id); 258 FrameStats* frame_stats = GetFrameStats(frame_id);
145 DCHECK(frame_stats); 259 DCHECK(frame_stats);
146 if (frame_stats->ack_time.is_null()) { 260 if (frame_stats->ack_time.is_null()) {
147 DCHECK(frame_stats->frame_size) << "frame_id: " << frame_id; 261 DCHECK(frame_stats->frame_size) << "frame_id: " << frame_id;
148 base::TimeTicks ret = EstimatedSendingTime(frame_id, bitrate); 262 base::TimeTicks ret = EstimatedSendingTime(frame_id, bitrate);
149 ret += base::TimeDelta::FromSecondsD(frame_stats->frame_size / bitrate); 263 ret += base::TimeDelta::FromSecondsD(frame_stats->frame_size / bitrate);
150 ret += rtt_; 264 ret += rtt_;
151 base::TimeTicks now = clock_->NowTicks(); 265 base::TimeTicks now = clock_->NowTicks();
152 if (ret < now) { 266 if (ret < now) {
153 // This is a little counter-intuitive, but it seems to work. 267 // This is a little counter-intuitive, but it seems to work.
154 // Basically, when we estimate that the ACK should have already happened, 268 // Basically, when we estimate that the ACK should have already happened,
155 // we figure out how long ago it should have happened and guess that the 269 // we figure out how long ago it should have happened and guess that the
156 // ACK will happen half of that time in the future. This will cause some 270 // ACK will happen half of that time in the future. This will cause some
157 // over-estimation when acks are late, which is actually what we want. 271 // over-estimation when acks are late, which is actually what we want.
158 return now + (now - ret) / 2; 272 return now + (now - ret) / 2;
159 } else { 273 } else {
160 return ret; 274 return ret;
161 } 275 }
162 } else { 276 } else {
163 return frame_stats->ack_time; 277 return frame_stats->ack_time;
164 } 278 }
165 } 279 }
166 280
167 base::TimeTicks CongestionControl::EstimatedSendingTime(uint32 frame_id, 281 base::TimeTicks AdaptiveCongestionControl::EstimatedSendingTime(
168 double bitrate) { 282 uint32 frame_id,
283 double bitrate) {
169 FrameStats* frame_stats = GetFrameStats(frame_id); 284 FrameStats* frame_stats = GetFrameStats(frame_id);
170 DCHECK(frame_stats); 285 DCHECK(frame_stats);
171 base::TimeTicks ret = EstimatedAckTime(frame_id - 1, bitrate) - rtt_; 286 base::TimeTicks ret = EstimatedAckTime(frame_id - 1, bitrate) - rtt_;
172 if (frame_stats->sent_time.is_null()) { 287 if (frame_stats->sent_time.is_null()) {
173 // Not sent yet, but we can't start sending it in the past. 288 // Not sent yet, but we can't start sending it in the past.
174 return std::max(ret, clock_->NowTicks()); 289 return std::max(ret, clock_->NowTicks());
175 } else { 290 } else {
176 return std::max(ret, frame_stats->sent_time); 291 return std::max(ret, frame_stats->sent_time);
177 } 292 }
178 } 293 }
179 294
180 uint32 CongestionControl::GetBitrate(base::TimeTicks playout_time, 295 uint32 AdaptiveCongestionControl::GetBitrate(base::TimeTicks playout_time,
181 base::TimeDelta playout_delay) { 296 base::TimeDelta playout_delay) {
182 double safe_bitrate = CalculateSafeBitrate(); 297 double safe_bitrate = CalculateSafeBitrate();
183 // Estimate when we might start sending the next frame. 298 // Estimate when we might start sending the next frame.
184 base::TimeDelta time_to_catch_up = 299 base::TimeDelta time_to_catch_up =
185 playout_time - 300 playout_time -
186 EstimatedSendingTime(last_encoded_frame_ + 1, safe_bitrate); 301 EstimatedSendingTime(last_encoded_frame_ + 1, safe_bitrate);
187 302
188 double empty_buffer_fraction = 303 double empty_buffer_fraction =
189 time_to_catch_up.InSecondsF() / playout_delay.InSecondsF(); 304 time_to_catch_up.InSecondsF() / playout_delay.InSecondsF();
190 empty_buffer_fraction = std::min(empty_buffer_fraction, 1.0); 305 empty_buffer_fraction = std::min(empty_buffer_fraction, 1.0);
191 empty_buffer_fraction = std::max(empty_buffer_fraction, 0.0); 306 empty_buffer_fraction = std::max(empty_buffer_fraction, 0.0);
192 307
193 uint32 bits_per_second = static_cast<uint32>( 308 uint32 bits_per_second = static_cast<uint32>(
194 safe_bitrate * empty_buffer_fraction / kTargetEmptyBufferFraction); 309 safe_bitrate * empty_buffer_fraction / kTargetEmptyBufferFraction);
195 VLOG(3) << " FBR:" << (bits_per_second / 1E6) 310 VLOG(3) << " FBR:" << (bits_per_second / 1E6)
196 << " EBF:" << empty_buffer_fraction 311 << " EBF:" << empty_buffer_fraction
197 << " SBR:" << (safe_bitrate / 1E6); 312 << " SBR:" << (safe_bitrate / 1E6);
198 bits_per_second = std::max(bits_per_second, min_bitrate_configured_); 313 bits_per_second = std::max(bits_per_second, min_bitrate_configured_);
199 bits_per_second = std::min(bits_per_second, max_bitrate_configured_); 314 bits_per_second = std::min(bits_per_second, max_bitrate_configured_);
200 return bits_per_second; 315 return bits_per_second;
201 } 316 }
202 317
203 } // namespace cast 318 } // namespace cast
204 } // namespace media 319 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/congestion_control.h ('k') | media/cast/sender/congestion_control_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698