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

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: Remove unneeded call 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/base/timeutils.h"
16
17 namespace webrtc {
18
19 // 2 seconds.
20 const uint32_t BitrateAdjuster::kBitrateUpdateIntervalMs = 2000;
21
22 // 5 percent of original.
23 const uint32_t BitrateAdjuster::kBitrateTolerancePct = 5;
24
25 BitrateAdjuster::BitrateAdjuster(BitrateAdjusterObserver* observer)
26 : observer_(observer), bitrate_tracker_(30 * 20) {
27 RTC_DCHECK(observer_);
28 Reset();
29 }
30
31 void BitrateAdjuster::SetTargetBitrate(uint32_t bitrate_kbit) {
32 rtc::CritScope cs(&crit_);
33 target_bitrate_kbit_ = bitrate_kbit;
34 }
35
36 uint32_t BitrateAdjuster::GetTargetBitrate() const {
37 rtc::CritScope cs(&crit_);
38 return target_bitrate_kbit_;
39 }
40
41 uint32_t BitrateAdjuster::GetAdjustedBitrate() const {
42 rtc::CritScope cs(&crit_);
43 return adjusted_bitrate_kbit_;
44 }
45
46 void BitrateAdjuster::Update(size_t frame_size) {
47 rtc::CritScope cs(&crit_);
48 uint32_t current_time_ms = rtc::Time();
49 UpdateBitrate(current_time_ms);
50 UpdateBitrateTracker(frame_size, current_time_ms);
51 }
52
53 // Only safe to call this after Update calls have stopped
54 void BitrateAdjuster::Reset() {
55 rtc::CritScope cs(&crit_);
56 target_bitrate_kbit_ = 0;
57 adjusted_bitrate_kbit_ = 0;
58 last_bitrate_update_time_ms_ = 0;
59 last_update_time_ms_ = 0;
60 bitrate_tracker_.Reset();
61 }
62
63 void BitrateAdjuster::UpdateBitrate(uint32_t current_time_ms) {
64 rtc::CritScope cs(&crit_);
65 if (current_time_ms - last_bitrate_update_time_ms_ <
66 kBitrateUpdateIntervalMs) {
67 return;
68 }
69 if (bitrate_tracker_.count() < 60) {
sprang 2016/02/09 10:46:26 Please used a named constant for this, or derive f
tkchin_webrtc 2016/02/11 00:03:20 Done.
70 // Wait for some samples before doing anything. Roughly 2s of samples
71 // at 30fps.
72 return;
73 }
74 float target_bitrate = target_bitrate_kbit_;
75
76 // Compute exponentially weighted average of bitrate samples.
77 // 0.02 means last 60 samples represent about 70% of weight.
78 float bitrate = bitrate_tracker_.ComputeWeightedMean(0.02);
79 float error = target_bitrate - bitrate;
sprang 2016/02/09 10:46:26 Can we perhaps use webrtc::RateStatistics instead
tkchin_webrtc 2016/02/11 00:03:20 Sure, that seems like a good idea. Weird to introd
sprang_webrtc 2016/02/15 08:51:32 That sounds great, thanks!
80
81 // Adjust if we've overshot by any amount or if we've undershot too much.
82 if (bitrate > target_bitrate ||
83 error * 100 > kBitrateTolerancePct * target_bitrate) {
84 // Adjust the bitrate by a fraction of the error.
85 float adjustment = .5 * error;
86 float adjusted_bitrate = target_bitrate + adjustment;
87
88 // Clamp the adjustment to [0.5 * target, 0.95 * target].
89 float min_bitrate = .5 * target_bitrate;
90 float max_bitrate =
91 static_cast<float>((100 - kBitrateTolerancePct) * target_bitrate) /
92 100.;
sprang 2016/02/09 10:46:26 Why do we need to clamp it to below target_bitrate
tkchin_webrtc 2016/02/11 00:03:20 It seemed to reduce oscillations. We know that the
sprang_webrtc 2016/02/15 08:51:32 Fair enough, perhaps a comment to that effect woul
93 adjusted_bitrate = std::max(adjusted_bitrate, min_bitrate);
94 adjusted_bitrate = std::min(adjusted_bitrate, max_bitrate);
95
96 // Set the adjustment if it's not already set.
97 float last_adjusted_bitrate = adjusted_bitrate_kbit_;
98 if (adjusted_bitrate != last_adjusted_bitrate) {
99 LOG(LS_INFO) << "Adjusting encoder bitrate:"
100 << "\n target_bitrate:" << target_bitrate
101 << "\n actual_bitrate:" << bitrate
102 << "\n previous_bitrate:" << (uint32_t)last_adjusted_bitrate
103 << "\n adjusted_bitrate:" << (uint32_t)adjusted_bitrate;
104 adjusted_bitrate_kbit_ = adjusted_bitrate;
105 observer_->OnBitrateAdjusted(adjusted_bitrate);
sprang 2016/02/09 10:46:26 Perhaps we should have a limit on how often this w
tkchin_webrtc 2016/02/11 00:03:20 The update only happens once every t seconds, so i
sprang_webrtc 2016/02/15 08:51:32 Ah, right. I'm fine with either then.
106 }
107 }
108 last_bitrate_update_time_ms_ = current_time_ms;
109 }
110
111 void BitrateAdjuster::UpdateBitrateTracker(size_t frame_size,
112 uint32_t current_time_ms) {
113 rtc::CritScope cs(&crit_);
114 if (current_time_ms > last_update_time_ms_) {
115 // Convert to kbit/s.
116 float bitrate_sample =
117 static_cast<float>(frame_size * 8) /
118 static_cast<float>(current_time_ms - last_update_time_ms_);
119 bitrate_tracker_.AddSample(bitrate_sample);
120 }
121 last_update_time_ms_ = current_time_ms;
122 }
123
124 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698