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

Side by Side Diff: webrtc/video/video_encoder_hardware.cc

Issue 1660963002: Bitrate controller for VideoToolbox encoder. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase 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
« no previous file with comments | « webrtc/video/BUILD.gn ('k') | webrtc/video/webrtc_video.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <cmath>
12
13 #include "webrtc/base/checks.h"
14 #include "webrtc/base/logging.h"
15 #include "webrtc/base/timeutils.h"
16 #include "webrtc/video_encoder.h"
17
18 namespace internal {
19
20 class HardwareEncodedImageCallbackWrapper
21 : public webrtc::EncodedImageCallback {
22 public:
23 HardwareEncodedImageCallbackWrapper(
24 webrtc::HardwareVideoEncoderWrapper* encoder)
25 : encoder_(encoder) {
26 RTC_CHECK(encoder_);
27 }
28
29 virtual ~HardwareEncodedImageCallbackWrapper() { encoder_ = nullptr; }
30
31 virtual int32_t Encoded(const webrtc::EncodedImage& encoded_image,
32 const webrtc::CodecSpecificInfo* codec_specific_info,
33 const webrtc::RTPFragmentationHeader* fragmentation) {
34 return encoder_->OnFrameEncoded(encoded_image, codec_specific_info,
35 fragmentation);
36 }
37
38 private:
39 webrtc::HardwareVideoEncoderWrapper* encoder_;
40 };
41
42 } // namespace internal
43
44 namespace webrtc {
45
46 HardwareVideoEncoderWrapper::HardwareVideoEncoderWrapper(
47 webrtc::VideoEncoder* encoder)
48 : encoder_(encoder),
49 bitrate_tracker_(30 * 20),
50 original_bitrate_(0),
51 original_frame_rate_(0),
52 adjusted_bitrate_(0),
53 last_bitrate_update_time_ms_(0),
54 last_frame_time_ms_(0) {
55 RTC_DCHECK(encoder->IsHardwareEncoder());
56 wrapped_callback_.reset(
57 new internal::HardwareEncodedImageCallbackWrapper(this));
58 }
59
60 int32_t HardwareVideoEncoderWrapper::InitEncode(
61 const VideoCodec* codec_settings,
62 int32_t number_of_cores,
63 size_t max_payload_size) {
64 return encoder_->InitEncode(codec_settings, number_of_cores,
65 max_payload_size);
66 }
67
68 int32_t HardwareVideoEncoderWrapper::RegisterEncodeCompleteCallback(
69 EncodedImageCallback* callback) {
70 callback_ = callback;
71 return encoder_->RegisterEncodeCompleteCallback(wrapped_callback_.get());
72 }
73
74 int32_t HardwareVideoEncoderWrapper::Release() {
75 return encoder_->Release();
76 }
77
78 int32_t HardwareVideoEncoderWrapper::Encode(
79 const VideoFrame& frame,
80 const CodecSpecificInfo* codec_specific_info,
81 const std::vector<FrameType>* frame_types) {
82 return encoder_->Encode(frame, codec_specific_info, frame_types);
83 }
84
85 int32_t HardwareVideoEncoderWrapper::SetChannelParameters(uint32_t packet_loss,
86 int64_t rtt) {
87 return encoder_->SetChannelParameters(packet_loss, rtt);
88 }
89
90 int32_t HardwareVideoEncoderWrapper::SetRates(uint32_t bitrate,
pbos-webrtc 2016/02/03 15:52:22 This one is permitted to be called often so you sh
91 uint32_t framerate) {
92 original_bitrate_ = bitrate * 1000;
93 adjusted_bitrate_ = original_bitrate_;
94 original_frame_rate_ = framerate;
95 bitrate_tracker_.Reset();
96 return encoder_->SetRates(bitrate, framerate);
97 }
98
99 void HardwareVideoEncoderWrapper::OnDroppedFrame() {
100 encoder_->OnDroppedFrame();
101 }
102
103 int HardwareVideoEncoderWrapper::GetTargetFramerate() {
104 return encoder_->GetTargetFramerate();
105 }
106
107 bool HardwareVideoEncoderWrapper::SupportsNativeHandle() const {
108 return encoder_->SupportsNativeHandle();
109 }
110
111 bool HardwareVideoEncoderWrapper::IsHardwareEncoder() const {
112 return encoder_->IsHardwareEncoder();
113 }
114
115 const char* HardwareVideoEncoderWrapper::ImplementationName() const {
116 return encoder_->ImplementationName();
117 }
118
119 int32_t HardwareVideoEncoderWrapper::OnFrameEncoded(
120 const EncodedImage& encoded_image,
121 const CodecSpecificInfo* codec_specific_info,
122 const RTPFragmentationHeader* fragmentation) {
123 uint32_t current_time_ms = rtc::Time();
124 UpdateBitrate(current_time_ms);
125 UpdateBitrateTracker(encoded_image._size, current_time_ms);
126 return callback_->Encoded(encoded_image, codec_specific_info, fragmentation);
127 }
128
129 void HardwareVideoEncoderWrapper::UpdateBitrateTracker(
130 size_t frame_size,
131 uint32_t current_time_ms) {
132 if (last_frame_time_ms_) {
133 RTC_DCHECK_LT(last_frame_time_ms_, current_time_ms);
134 float bitrate_sample =
135 static_cast<float>(frame_size * 8 * 1000) /
136 static_cast<float>(current_time_ms - last_frame_time_ms_);
137 bitrate_tracker_.AddSample(bitrate_sample);
138 }
139 last_frame_time_ms_ = current_time_ms;
140 }
141
142 void HardwareVideoEncoderWrapper::UpdateBitrate(uint32_t current_time_ms) {
143 if (current_time_ms - last_bitrate_update_time_ms_ <
144 kBitrateUpdateIntervalMs) {
145 return;
146 }
147 if (bitrate_tracker_.count() < 30) {
148 // Wait for some samples before doing anything. Roughly 1s of samples
149 // at 30fps.
150 return;
151 }
152 // Compute exponentially weighted average of bitrate samples.
153 float bitrate = bitrate_tracker_.ComputeWeightedMean(0.17);
154 float error = original_bitrate_ - bitrate;
155
156 // Adjust if we've overshot by any amount or if we've undershot too much.
157 if (bitrate > original_bitrate_ ||
158 error * 100 > kBitrateTolerancePct * original_bitrate_) {
159 // Adjust the bitrate by a fraction of the error.
160 float adjustment = .5 * error;
161 float adjusted_bitrate = original_bitrate_ + adjustment;
162
163 // Clamp the adjustment.
164 float min_bitrate =
165 static_cast<float>(kBitrateTolerancePct * original_bitrate_) / 100.;
166 float max_bitrate =
167 static_cast<float>((100 - kBitrateTolerancePct) * original_bitrate_) /
168 100.;
169 adjusted_bitrate = std::max(adjusted_bitrate, min_bitrate);
170 adjusted_bitrate = std::min(adjusted_bitrate, max_bitrate);
171
172 // Set the adjustment if it's not already set.
173 if (adjusted_bitrate_ != adjusted_bitrate) {
174 encoder_->SetRates(adjusted_bitrate * 1e-3, original_frame_rate_);
175 LOG(LS_INFO) << "Adjusting encoder bitrate:"
176 << "\n target_bitrate:" << original_bitrate_
177 << "\n actual_bitrate:" << bitrate
178 << "\n previous_bitrate:" << adjusted_bitrate_
179 << "\n adjusted_bitrate:" << (uint32_t)adjusted_bitrate;
180 adjusted_bitrate_ = adjusted_bitrate;
181 }
182 }
183 last_bitrate_update_time_ms_ = current_time_ms;
184 }
185
186 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/BUILD.gn ('k') | webrtc/video/webrtc_video.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698