OLD | NEW |
---|---|
(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 * 1000) { | |
pbos-webrtc
2016/02/22 15:44:18
What#s 8? constant please
tkchin_webrtc
2016/02/22 18:23:18
Done.
| |
31 Reset(); | |
32 } | |
33 | |
34 void BitrateAdjuster::SetTargetBitrateBps(uint32_t bitrate_bps) { | |
35 rtc::CritScope cs(&crit_); | |
36 target_bitrate_bps_ = bitrate_bps; | |
37 // If we haven't had time to determine what adjustment is required yet then | |
38 // just use the target. | |
39 adjusted_bitrate_bps_ = target_bitrate_bps_; | |
40 } | |
41 | |
42 uint32_t BitrateAdjuster::GetTargetBitrateBps() const { | |
43 rtc::CritScope cs(&crit_); | |
44 return target_bitrate_bps_; | |
45 } | |
46 | |
47 uint32_t BitrateAdjuster::GetAdjustedBitrateBps() const { | |
48 rtc::CritScope cs(&crit_); | |
49 return adjusted_bitrate_bps_; | |
50 } | |
51 | |
52 uint32_t BitrateAdjuster::GetEstimatedBitrateBps() { | |
53 rtc::CritScope cs(&crit_); | |
54 return bitrate_tracker_.Rate(clock_->TimeInMilliseconds()); | |
55 } | |
56 | |
57 uint32_t BitrateAdjuster::GetMinAdjustedBitrateBps() const { | |
58 rtc::CritScope cs(&crit_); | |
59 // Half of target bitrate. | |
60 return target_bitrate_bps_ / 2; | |
61 } | |
62 | |
63 uint32_t BitrateAdjuster::GetMaxAdjustedBitrateBps() 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_bps_; | |
pbos-webrtc
2016/02/22 15:44:18
Is it intentional that this thing can only operate
tkchin_webrtc
2016/02/22 18:23:18
As we talked about before, we wanted this for the
pbos-webrtc
2016/02/22 18:37:19
But this reads to me like it's allowed to clamp on
tkchin_webrtc
2016/02/23 00:05:27
Done.
| |
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_bps_ = 0; | |
82 adjusted_bitrate_bps_ = 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 estimated_bitrate_bps = bitrate_tracker_.Rate(current_time_ms); | |
99 float target_bitrate_bps = target_bitrate_bps_; | |
100 float error = target_bitrate_bps - estimated_bitrate_bps; | |
101 | |
102 // Adjust if we've overshot by any amount or if we've undershot too much. | |
103 if (estimated_bitrate_bps > target_bitrate_bps || | |
104 error * 100 > kBitrateTolerancePct * target_bitrate_bps) { | |
pbos-webrtc
2016/02/22 15:44:18
make kBitrateTolerance not be in percent.
tkchin_webrtc
2016/02/22 18:23:18
why? Do you have a particular value in mind?
pbos-webrtc
2016/02/22 18:37:19
Just make it 0.05 instead of 5 to avoid the multip
tkchin_webrtc
2016/02/23 00:05:27
Done.
| |
105 // Adjust the bitrate by a fraction of the error. | |
106 float adjustment = .5 * error; | |
107 float adjusted_bitrate_bps = target_bitrate_bps + adjustment; | |
108 | |
109 // Clamp the adjustment to [0.5 * target, 0.95 * target]. | |
110 float min_bitrate_bps = GetMinAdjustedBitrateBps(); | |
pbos-webrtc
2016/02/22 18:37:19
This takes crit_ recursively, can you put EXCLUSIV
tkchin_webrtc
2016/02/23 00:05:27
Done. But now requires friend class for test.
pbos-webrtc
2016/02/23 15:04:40
Can't you just make sure it's clamped from the out
tkchin_webrtc
2016/02/23 17:03:20
Done.
| |
111 float max_bitrate_bps = GetMaxAdjustedBitrateBps(); | |
112 adjusted_bitrate_bps = std::max(adjusted_bitrate_bps, min_bitrate_bps); | |
113 adjusted_bitrate_bps = std::min(adjusted_bitrate_bps, max_bitrate_bps); | |
114 | |
115 // Set the adjustment if it's not already set. | |
116 float last_adjusted_bitrate_bps = adjusted_bitrate_bps_; | |
117 if (adjusted_bitrate_bps != last_adjusted_bitrate_bps) { | |
118 LOG(LS_INFO) << "Adjusting encoder bitrate:" | |
119 << "\n target_bitrate:" | |
120 << static_cast<uint32_t>(target_bitrate_bps) | |
121 << "\n estimated_bitrate:" | |
122 << static_cast<uint32_t>(estimated_bitrate_bps) | |
123 << "\n last_adjusted_bitrate:" | |
124 << static_cast<uint32_t>(last_adjusted_bitrate_bps) | |
125 << "\n adjusted_bitrate:" | |
126 << static_cast<uint32_t>(adjusted_bitrate_bps); | |
127 adjusted_bitrate_bps_ = adjusted_bitrate_bps; | |
128 } | |
129 } | |
130 last_bitrate_update_time_ms_ = current_time_ms; | |
131 frames_since_last_update_ = 0; | |
132 } | |
133 | |
134 } // namespace webrtc | |
OLD | NEW |