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

Side by Side Diff: webrtc/modules/video_coding/main/source/media_optimization.cc

Issue 1428473002: Utilize bitrate above codec max to protect video. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase + feedback Created 5 years, 1 month 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 send_codec_type_(kVideoCodecUnknown), 81 send_codec_type_(kVideoCodecUnknown),
82 codec_width_(0), 82 codec_width_(0),
83 codec_height_(0), 83 codec_height_(0),
84 user_frame_rate_(0), 84 user_frame_rate_(0),
85 frame_dropper_(new FrameDropper), 85 frame_dropper_(new FrameDropper),
86 loss_prot_logic_( 86 loss_prot_logic_(
87 new VCMLossProtectionLogic(clock_->TimeInMilliseconds())), 87 new VCMLossProtectionLogic(clock_->TimeInMilliseconds())),
88 fraction_lost_(0), 88 fraction_lost_(0),
89 send_statistics_zero_encode_(0), 89 send_statistics_zero_encode_(0),
90 max_payload_size_(1460), 90 max_payload_size_(1460),
91 target_bit_rate_(0), 91 video_target_bitrate_(0),
92 incoming_frame_rate_(0), 92 incoming_frame_rate_(0),
93 enable_qm_(false), 93 enable_qm_(false),
94 encoded_frame_samples_(), 94 encoded_frame_samples_(),
95 avg_sent_bit_rate_bps_(0), 95 avg_sent_bit_rate_bps_(0),
96 avg_sent_framerate_(0), 96 avg_sent_framerate_(0),
97 key_frame_cnt_(0), 97 key_frame_cnt_(0),
98 delta_frame_cnt_(0), 98 delta_frame_cnt_(0),
99 content_(new VCMContentMetricsProcessing()), 99 content_(new VCMContentMetricsProcessing()),
100 qm_resolution_(new VCMQmResolution()), 100 qm_resolution_(new VCMQmResolution()),
101 last_qm_update_time_(0), 101 last_qm_update_time_(0),
(...skipping 18 matching lines...) Expand all
120 memset(incoming_frame_times_, -1, sizeof(incoming_frame_times_)); 120 memset(incoming_frame_times_, -1, sizeof(incoming_frame_times_));
121 incoming_frame_rate_ = 0.0; 121 incoming_frame_rate_ = 0.0;
122 frame_dropper_->Reset(); 122 frame_dropper_->Reset();
123 loss_prot_logic_->Reset(clock_->TimeInMilliseconds()); 123 loss_prot_logic_->Reset(clock_->TimeInMilliseconds());
124 frame_dropper_->SetRates(0, 0); 124 frame_dropper_->SetRates(0, 0);
125 content_->Reset(); 125 content_->Reset();
126 qm_resolution_->Reset(); 126 qm_resolution_->Reset();
127 loss_prot_logic_->UpdateFrameRate(incoming_frame_rate_); 127 loss_prot_logic_->UpdateFrameRate(incoming_frame_rate_);
128 loss_prot_logic_->Reset(clock_->TimeInMilliseconds()); 128 loss_prot_logic_->Reset(clock_->TimeInMilliseconds());
129 send_statistics_zero_encode_ = 0; 129 send_statistics_zero_encode_ = 0;
130 target_bit_rate_ = 0; 130 video_target_bitrate_ = 0;
131 codec_width_ = 0; 131 codec_width_ = 0;
132 codec_height_ = 0; 132 codec_height_ = 0;
133 user_frame_rate_ = 0; 133 user_frame_rate_ = 0;
134 key_frame_cnt_ = 0; 134 key_frame_cnt_ = 0;
135 delta_frame_cnt_ = 0; 135 delta_frame_cnt_ = 0;
136 last_qm_update_time_ = 0; 136 last_qm_update_time_ = 0;
137 last_change_time_ = 0; 137 last_change_time_ = 0;
138 encoded_frame_samples_.clear(); 138 encoded_frame_samples_.clear();
139 avg_sent_bit_rate_bps_ = 0; 139 avg_sent_bit_rate_bps_ = 0;
140 num_layers_ = 1; 140 num_layers_ = 1;
(...skipping 29 matching lines...) Expand all
170 // Everything codec specific should be reset here since this means the codec 170 // Everything codec specific should be reset here since this means the codec
171 // has changed. If native dimension values have changed, then either user 171 // has changed. If native dimension values have changed, then either user
172 // initiated change, or QM initiated change. Will be able to determine only 172 // initiated change, or QM initiated change. Will be able to determine only
173 // after the processing of the first frame. 173 // after the processing of the first frame.
174 last_change_time_ = clock_->TimeInMilliseconds(); 174 last_change_time_ = clock_->TimeInMilliseconds();
175 content_->Reset(); 175 content_->Reset();
176 content_->UpdateFrameRate(frame_rate); 176 content_->UpdateFrameRate(frame_rate);
177 177
178 max_bit_rate_ = max_bit_rate; 178 max_bit_rate_ = max_bit_rate;
179 send_codec_type_ = send_codec_type; 179 send_codec_type_ = send_codec_type;
180 target_bit_rate_ = target_bitrate; 180 video_target_bitrate_ = target_bitrate;
181 float target_bitrate_kbps = static_cast<float>(target_bitrate) / 1000.0f; 181 float target_bitrate_kbps = static_cast<float>(target_bitrate) / 1000.0f;
182 loss_prot_logic_->UpdateBitRate(target_bitrate_kbps); 182 loss_prot_logic_->UpdateBitRate(target_bitrate_kbps);
183 loss_prot_logic_->UpdateFrameRate(static_cast<float>(frame_rate)); 183 loss_prot_logic_->UpdateFrameRate(static_cast<float>(frame_rate));
184 loss_prot_logic_->UpdateFrameSize(width, height); 184 loss_prot_logic_->UpdateFrameSize(width, height);
185 loss_prot_logic_->UpdateNumLayers(num_layers); 185 loss_prot_logic_->UpdateNumLayers(num_layers);
186 frame_dropper_->Reset(); 186 frame_dropper_->Reset();
187 frame_dropper_->SetRates(target_bitrate_kbps, static_cast<float>(frame_rate)); 187 frame_dropper_->SetRates(target_bitrate_kbps, static_cast<float>(frame_rate));
188 user_frame_rate_ = static_cast<float>(frame_rate); 188 user_frame_rate_ = static_cast<float>(frame_rate);
189 codec_width_ = width; 189 codec_width_ = width;
190 codec_height_ = height; 190 codec_height_ = height;
191 num_layers_ = (num_layers <= 1) ? 1 : num_layers; // Can also be zero. 191 num_layers_ = (num_layers <= 1) ? 1 : num_layers; // Can also be zero.
192 max_payload_size_ = mtu; 192 max_payload_size_ = mtu;
193 qm_resolution_->Initialize(target_bitrate_kbps, 193 qm_resolution_->Initialize(target_bitrate_kbps,
194 user_frame_rate_, 194 user_frame_rate_,
195 codec_width_, 195 codec_width_,
196 codec_height_, 196 codec_height_,
197 num_layers_); 197 num_layers_);
198 } 198 }
199 199
200 uint32_t MediaOptimization::SetTargetRates( 200 uint32_t MediaOptimization::SetTargetRates(
201 uint32_t target_bitrate, 201 uint32_t target_bitrate,
202 uint8_t fraction_lost, 202 uint8_t fraction_lost,
203 int64_t round_trip_time_ms, 203 int64_t round_trip_time_ms,
204 VCMProtectionCallback* protection_callback, 204 VCMProtectionCallback* protection_callback,
205 VCMQMSettingsCallback* qmsettings_callback) { 205 VCMQMSettingsCallback* qmsettings_callback) {
206 CriticalSectionScoped lock(crit_sect_.get()); 206 CriticalSectionScoped lock(crit_sect_.get());
207 // TODO(holmer): Consider putting this threshold only on the video bitrate,
208 // and not on protection.
209 if (max_bit_rate_ > 0 &&
210 target_bitrate > static_cast<uint32_t>(max_bit_rate_)) {
211 target_bitrate = max_bit_rate_;
212 }
213 VCMProtectionMethod* selected_method = loss_prot_logic_->SelectedMethod(); 207 VCMProtectionMethod* selected_method = loss_prot_logic_->SelectedMethod();
214 float target_bitrate_kbps = static_cast<float>(target_bitrate) / 1000.0f; 208 float target_bitrate_kbps = static_cast<float>(target_bitrate) / 1000.0f;
215 loss_prot_logic_->UpdateBitRate(target_bitrate_kbps); 209 loss_prot_logic_->UpdateBitRate(target_bitrate_kbps);
216 loss_prot_logic_->UpdateRtt(round_trip_time_ms); 210 loss_prot_logic_->UpdateRtt(round_trip_time_ms);
217 211
218 // Get frame rate for encoder: this is the actual/sent frame rate. 212 // Get frame rate for encoder: this is the actual/sent frame rate.
219 float actual_frame_rate = SentFrameRateInternal(); 213 float actual_frame_rate = SentFrameRateInternal();
220 214
221 // Sanity check. 215 // Sanity check.
222 if (actual_frame_rate < 1.0) { 216 if (actual_frame_rate < 1.0) {
(...skipping 11 matching lines...) Expand all
234 // filtered value (average or max window filter). 228 // filtered value (average or max window filter).
235 // Use max window filter for now. 229 // Use max window filter for now.
236 FilterPacketLossMode filter_mode = kMaxFilter; 230 FilterPacketLossMode filter_mode = kMaxFilter;
237 uint8_t packet_loss_enc = loss_prot_logic_->FilteredLoss( 231 uint8_t packet_loss_enc = loss_prot_logic_->FilteredLoss(
238 clock_->TimeInMilliseconds(), filter_mode, fraction_lost); 232 clock_->TimeInMilliseconds(), filter_mode, fraction_lost);
239 233
240 // For now use the filtered loss for computing the robustness settings. 234 // For now use the filtered loss for computing the robustness settings.
241 loss_prot_logic_->UpdateFilteredLossPr(packet_loss_enc); 235 loss_prot_logic_->UpdateFilteredLossPr(packet_loss_enc);
242 236
243 // Rate cost of the protection methods. 237 // Rate cost of the protection methods.
244 uint32_t protection_overhead_bps = 0; 238 float protection_overhead_rate = 0.0f;
245 239
246 // Update protection settings, when applicable. 240 // Update protection settings, when applicable.
247 float sent_video_rate_kbps = 0.0f; 241 float sent_video_rate_kbps = 0.0f;
248 if (loss_prot_logic_->SelectedType() != kNone) { 242 if (loss_prot_logic_->SelectedType() != kNone) {
249 // Update protection method with content metrics. 243 // Update protection method with content metrics.
250 selected_method->UpdateContentMetrics(content_->ShortTermAvgData()); 244 selected_method->UpdateContentMetrics(content_->ShortTermAvgData());
251 245
252 // Update method will compute the robustness settings for the given 246 // Update method will compute the robustness settings for the given
253 // protection method and the overhead cost 247 // protection method and the overhead cost
254 // the protection method is set by the user via SetVideoProtection. 248 // the protection method is set by the user via SetVideoProtection.
(...skipping 11 matching lines...) Expand all
266 &sent_video_rate_bps, 260 &sent_video_rate_bps,
267 &sent_nack_rate_bps, 261 &sent_nack_rate_bps,
268 &sent_fec_rate_bps, 262 &sent_fec_rate_bps,
269 protection_callback); 263 protection_callback);
270 } 264 }
271 uint32_t sent_total_rate_bps = 265 uint32_t sent_total_rate_bps =
272 sent_video_rate_bps + sent_nack_rate_bps + sent_fec_rate_bps; 266 sent_video_rate_bps + sent_nack_rate_bps + sent_fec_rate_bps;
273 // Estimate the overhead costs of the next second as staying the same 267 // Estimate the overhead costs of the next second as staying the same
274 // wrt the source bitrate. 268 // wrt the source bitrate.
275 if (sent_total_rate_bps > 0) { 269 if (sent_total_rate_bps > 0) {
276 protection_overhead_bps = static_cast<uint32_t>( 270 protection_overhead_rate =
277 target_bitrate * 271 static_cast<float>(sent_nack_rate_bps + sent_fec_rate_bps) /
278 static_cast<double>(sent_nack_rate_bps + sent_fec_rate_bps) / 272 sent_total_rate_bps;
279 sent_total_rate_bps +
280 0.5);
281 } 273 }
282 // Cap the overhead estimate to 50%. 274 // Cap the overhead estimate to 50%.
283 if (protection_overhead_bps > target_bitrate / 2) 275 if (protection_overhead_rate > 0.5)
284 protection_overhead_bps = target_bitrate / 2; 276 protection_overhead_rate = 0.5;
285 277
286 // Get the effective packet loss for encoder ER when applicable. Should be 278 // Get the effective packet loss for encoder ER when applicable. Should be
287 // passed to encoder via fraction_lost. 279 // passed to encoder via fraction_lost.
288 packet_loss_enc = selected_method->RequiredPacketLossER(); 280 packet_loss_enc = selected_method->RequiredPacketLossER();
289 sent_video_rate_kbps = static_cast<float>(sent_video_rate_bps) / 1000.0f; 281 sent_video_rate_kbps = static_cast<float>(sent_video_rate_bps) / 1000.0f;
290 } 282 }
291 283
292 // Source coding rate: total rate - protection overhead. 284 // Source coding rate: total rate - protection overhead.
293 target_bit_rate_ = target_bitrate - protection_overhead_bps; 285 video_target_bitrate_ = target_bitrate * (1.0 - protection_overhead_rate);
286
287 // Cap target video bitrate to codec maximum.
288 if (max_bit_rate_ > 0 && video_target_bitrate_ > max_bit_rate_) {
289 video_target_bitrate_ = max_bit_rate_;
290 }
294 291
295 // Update encoding rates following protection settings. 292 // Update encoding rates following protection settings.
296 float target_video_bitrate_kbps = 293 float target_video_bitrate_kbps =
297 static_cast<float>(target_bit_rate_) / 1000.0f; 294 static_cast<float>(video_target_bitrate_) / 1000.0f;
298 frame_dropper_->SetRates(target_video_bitrate_kbps, incoming_frame_rate_); 295 frame_dropper_->SetRates(target_video_bitrate_kbps, incoming_frame_rate_);
299 296
300 if (enable_qm_ && qmsettings_callback) { 297 if (enable_qm_ && qmsettings_callback) {
301 // Update QM with rates. 298 // Update QM with rates.
302 qm_resolution_->UpdateRates(target_video_bitrate_kbps, 299 qm_resolution_->UpdateRates(target_video_bitrate_kbps,
303 sent_video_rate_kbps, 300 sent_video_rate_kbps,
304 incoming_frame_rate_, 301 incoming_frame_rate_,
305 fraction_lost_); 302 fraction_lost_);
306 // Check for QM selection. 303 // Check for QM selection.
307 bool select_qm = CheckStatusForQMchange(); 304 bool select_qm = CheckStatusForQMchange();
308 if (select_qm) { 305 if (select_qm) {
309 SelectQuality(qmsettings_callback); 306 SelectQuality(qmsettings_callback);
310 } 307 }
311 // Reset the short-term averaged content data. 308 // Reset the short-term averaged content data.
312 content_->ResetShortTermAvgData(); 309 content_->ResetShortTermAvgData();
313 } 310 }
314 311
315 CheckSuspendConditions(); 312 CheckSuspendConditions();
316 313
317 return target_bit_rate_; 314 return video_target_bitrate_;
318 } 315 }
319 316
320 void MediaOptimization::SetProtectionMethod(VCMProtectionMethodEnum method) { 317 void MediaOptimization::SetProtectionMethod(VCMProtectionMethodEnum method) {
321 CriticalSectionScoped lock(crit_sect_.get()); 318 CriticalSectionScoped lock(crit_sect_.get());
322 loss_prot_logic_->SetMethod(method); 319 loss_prot_logic_->SetMethod(method);
323 } 320 }
324 321
325 uint32_t MediaOptimization::InputFrameRate() { 322 uint32_t MediaOptimization::InputFrameRate() {
326 CriticalSectionScoped lock(crit_sect_.get()); 323 CriticalSectionScoped lock(crit_sect_.get());
327 return InputFrameRateInternal(); 324 return InputFrameRateInternal();
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 const int64_t diff = 618 const int64_t diff =
622 incoming_frame_times_[0] - incoming_frame_times_[num - 1]; 619 incoming_frame_times_[0] - incoming_frame_times_[num - 1];
623 incoming_frame_rate_ = 0.0; // No frame rate estimate available. 620 incoming_frame_rate_ = 0.0; // No frame rate estimate available.
624 if (diff > 0) { 621 if (diff > 0) {
625 incoming_frame_rate_ = nr_of_frames * 1000.0f / static_cast<float>(diff); 622 incoming_frame_rate_ = nr_of_frames * 1000.0f / static_cast<float>(diff);
626 } 623 }
627 } 624 }
628 } 625 }
629 626
630 void MediaOptimization::CheckSuspendConditions() { 627 void MediaOptimization::CheckSuspendConditions() {
631 // Check conditions for SuspendBelowMinBitrate. |target_bit_rate_| is in bps. 628 // Check conditions for SuspendBelowMinBitrate. |video_target_bitrate_| is in
629 // bps.
632 if (suspension_enabled_) { 630 if (suspension_enabled_) {
633 if (!video_suspended_) { 631 if (!video_suspended_) {
634 // Check if we just went below the threshold. 632 // Check if we just went below the threshold.
635 if (target_bit_rate_ < suspension_threshold_bps_) { 633 if (video_target_bitrate_ < suspension_threshold_bps_) {
636 video_suspended_ = true; 634 video_suspended_ = true;
637 } 635 }
638 } else { 636 } else {
639 // Video is already suspended. Check if we just went over the threshold 637 // Video is already suspended. Check if we just went over the threshold
640 // with a margin. 638 // with a margin.
641 if (target_bit_rate_ > 639 if (video_target_bitrate_ >
642 suspension_threshold_bps_ + suspension_window_bps_) { 640 suspension_threshold_bps_ + suspension_window_bps_) {
643 video_suspended_ = false; 641 video_suspended_ = false;
644 } 642 }
645 } 643 }
646 } 644 }
647 } 645 }
648 646
649 } // namespace media_optimization 647 } // namespace media_optimization
650 } // namespace webrtc 648 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698