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

Side by Side Diff: webrtc/modules/video_coding/bitrate_adjuster.cc

Issue 1660963002: Bitrate controller for VideoToolbox encoder. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: CR comments Created 4 years, 10 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
(Empty)
1 /*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/video_coding/include/bitrate_adjuster.h"
12
13 #include "webrtc/base/checks.h"
14 #include "webrtc/base/logging.h"
15 #include "webrtc/system_wrappers/include/clock.h"
16
17 namespace webrtc {
18
19 // Update bitrate at most once every second.
20 const uint32_t BitrateAdjuster::kBitrateUpdateIntervalMs = 1000;
21
22 // Update bitrate at most once every 30 frames.
23 const uint32_t BitrateAdjuster::kBitrateUpdateFrameInterval = 30;
24
25 // 5 percent of original.
26 const uint32_t BitrateAdjuster::kBitrateTolerancePct = 5;
27
28 BitrateAdjuster::BitrateAdjuster(Clock* clock)
29 : clock_(clock),
30 bitrate_tracker_(1.5 * kBitrateUpdateIntervalMs, 8) {
31 Reset();
32 }
33
34 void BitrateAdjuster::SetTargetBitrate(uint32_t bitrate_kbit) {
35 rtc::CritScope cs(&crit_);
36 target_bitrate_kbit_ = bitrate_kbit;
37 // If we haven't had time to determine what adjustment is required yet then
38 // just use the target.
39 adjusted_bitrate_kbit_ = target_bitrate_kbit_;
40 }
41
42 uint32_t BitrateAdjuster::GetTargetBitrate() const {
43 rtc::CritScope cs(&crit_);
44 return target_bitrate_kbit_;
45 }
46
47 uint32_t BitrateAdjuster::GetAdjustedBitrate() const {
48 rtc::CritScope cs(&crit_);
49 return adjusted_bitrate_kbit_;
50 }
51
52 uint32_t BitrateAdjuster::GetEstimatedBitrate() {
53 rtc::CritScope cs(&crit_);
54 return bitrate_tracker_.Rate(clock_->TimeInMilliseconds());
55 }
56
57 uint32_t BitrateAdjuster::GetMinAdjustedBitrate() const {
58 rtc::CritScope cs(&crit_);
59 // Half of target bitrate.
60 return target_bitrate_kbit_ / 2;
61 }
62
63 uint32_t BitrateAdjuster::GetMaxAdjustedBitrate() const {
64 rtc::CritScope cs(&crit_);
65 // 95% of target bitrate. In practice we know that the VideoToolbox encoder
66 // on iOS overshoots regularly. Setting it to 95% seems to reduce
67 // oscillations.
68 return .95 * target_bitrate_kbit_;
69 }
70
71 void BitrateAdjuster::Update(size_t frame_size) {
72 rtc::CritScope cs(&crit_);
73 uint32_t current_time_ms = clock_->TimeInMilliseconds();
74 bitrate_tracker_.Update(frame_size, current_time_ms);
75 UpdateBitrate(current_time_ms);
76 }
77
78 // Only safe to call this after Update calls have stopped
79 void BitrateAdjuster::Reset() {
80 rtc::CritScope cs(&crit_);
81 target_bitrate_kbit_ = 0;
pbos-webrtc 2016/02/19 11:26:39 Can this whole thing operate on bps_ instead?
tkchin_webrtc 2016/02/19 23:30:05 Done.
82 adjusted_bitrate_kbit_ = 0;
83 last_bitrate_update_time_ms_ = 0;
84 frames_since_last_update_ = 0;
85 bitrate_tracker_.Reset();
86 }
87
88 void BitrateAdjuster::UpdateBitrate(uint32_t current_time_ms) {
89 rtc::CritScope cs(&crit_);
90 uint32_t time_since_last_update_ms =
91 current_time_ms - last_bitrate_update_time_ms_;
92 // Don't attempt to update bitrate unless enough time and frames have passed.
93 ++frames_since_last_update_;
94 if (time_since_last_update_ms < kBitrateUpdateIntervalMs ||
95 frames_since_last_update_ < kBitrateUpdateFrameInterval) {
96 return;
97 }
98 float bitrate = bitrate_tracker_.Rate(current_time_ms);
99 float target_bitrate = target_bitrate_kbit_;
100 float error = target_bitrate - bitrate;
101
102 // Adjust if we've overshot by any amount or if we've undershot too much.
103 if (bitrate > target_bitrate ||
104 error * 100 > kBitrateTolerancePct * target_bitrate) {
105 // Adjust the bitrate by a fraction of the error.
106 float adjustment = .5 * error;
107 float adjusted_bitrate = target_bitrate + adjustment;
108
109 // Clamp the adjustment to [0.5 * target, 0.95 * target].
110 float min_bitrate = GetMinAdjustedBitrate();
111 float max_bitrate = GetMaxAdjustedBitrate();
112 adjusted_bitrate = std::max(adjusted_bitrate, min_bitrate);
pbos-webrtc 2016/02/19 11:26:39 units on all of these (_bps preferred)
tkchin_webrtc 2016/02/19 23:30:05 Done.
113 adjusted_bitrate = std::min(adjusted_bitrate, max_bitrate);
114
115 // Set the adjustment if it's not already set.
116 float last_adjusted_bitrate = adjusted_bitrate_kbit_;
117 if (adjusted_bitrate != last_adjusted_bitrate) {
118 LOG(LS_VERBOSE) << "Adjusting encoder bitrate:"
119 << "\n target_bitrate:" << target_bitrate
120 << "\n actual_bitrate:" << bitrate
121 << "\n last_adjusted_bitrate:"
122 << static_cast<uint32_t>(last_adjusted_bitrate)
123 << "\n adjusted_bitrate:"
124 << static_cast<uint32_t>(adjusted_bitrate);
125 adjusted_bitrate_kbit_ = adjusted_bitrate;
126 }
127 }
128 last_bitrate_update_time_ms_ = current_time_ms;
129 frames_since_last_update_ = 0;
130 }
131
132 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698