1 /*
2 * Copyright (c) 2017 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 "api/video_codecs/video_encoder.h"
12
13 #include <string.h>
14 #include <algorithm>
15
16 #include "rtc_base/checks.h"
17 #include "rtc_base/strings/string_builder.h"
18
19 namespace webrtc {
20
21 // TODO(mflodman): Add default complexity for VP9 and VP9.
GetDefaultVp8Settings()22 VideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() {
23 VideoCodecVP8 vp8_settings;
24 memset(&vp8_settings, 0, sizeof(vp8_settings));
25
26 vp8_settings.numberOfTemporalLayers = 1;
27 vp8_settings.denoisingOn = true;
28 vp8_settings.automaticResizeOn = false;
29 vp8_settings.frameDroppingOn = true;
30 vp8_settings.keyFrameInterval = 3000;
31
32 return vp8_settings;
33 }
34
GetDefaultVp9Settings()35 VideoCodecVP9 VideoEncoder::GetDefaultVp9Settings() {
36 VideoCodecVP9 vp9_settings;
37 memset(&vp9_settings, 0, sizeof(vp9_settings));
38
39 vp9_settings.numberOfTemporalLayers = 1;
40 vp9_settings.denoisingOn = true;
41 vp9_settings.frameDroppingOn = true;
42 vp9_settings.keyFrameInterval = 3000;
43 vp9_settings.adaptiveQpMode = true;
44 vp9_settings.automaticResizeOn = true;
45 vp9_settings.numberOfSpatialLayers = 1;
46 vp9_settings.flexibleMode = false;
47 vp9_settings.interLayerPred = InterLayerPredMode::kOn;
48
49 return vp9_settings;
50 }
51
GetDefaultH264Settings()52 VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
53 VideoCodecH264 h264_settings;
54 memset(&h264_settings, 0, sizeof(h264_settings));
55
56 h264_settings.frameDroppingOn = true;
57 h264_settings.keyFrameInterval = 3000;
58 h264_settings.numberOfTemporalLayers = 1;
59
60 return h264_settings;
61 }
62
63 VideoEncoder::ScalingSettings::ScalingSettings() = default;
64
ScalingSettings(KOff)65 VideoEncoder::ScalingSettings::ScalingSettings(KOff) : ScalingSettings() {}
66
ScalingSettings(int low,int high)67 VideoEncoder::ScalingSettings::ScalingSettings(int low, int high)
68 : thresholds(QpThresholds(low, high)) {}
69
ScalingSettings(int low,int high,int min_pixels)70 VideoEncoder::ScalingSettings::ScalingSettings(int low,
71 int high,
72 int min_pixels)
73 : thresholds(QpThresholds(low, high)), min_pixels_per_frame(min_pixels) {}
74
75 VideoEncoder::ScalingSettings::ScalingSettings(const ScalingSettings&) =
76 default;
77
~ScalingSettings()78 VideoEncoder::ScalingSettings::~ScalingSettings() {}
79
80 // static
81 constexpr VideoEncoder::ScalingSettings::KOff
82 VideoEncoder::ScalingSettings::kOff;
83 // static
84 constexpr uint8_t VideoEncoder::EncoderInfo::kMaxFramerateFraction;
85
operator ==(const ResolutionBitrateLimits & rhs) const86 bool VideoEncoder::ResolutionBitrateLimits::operator==(
87 const ResolutionBitrateLimits& rhs) const {
88 return frame_size_pixels == rhs.frame_size_pixels &&
89 min_start_bitrate_bps == rhs.min_start_bitrate_bps &&
90 min_bitrate_bps == rhs.min_bitrate_bps &&
91 max_bitrate_bps == rhs.max_bitrate_bps;
92 }
93
EncoderInfo()94 VideoEncoder::EncoderInfo::EncoderInfo()
95 : scaling_settings(VideoEncoder::ScalingSettings::kOff),
96 requested_resolution_alignment(1),
97 supports_native_handle(false),
98 implementation_name("unknown"),
99 has_trusted_rate_controller(false),
100 is_hardware_accelerated(true),
101 has_internal_source(false),
102 fps_allocation{absl::InlinedVector<uint8_t, kMaxTemporalStreams>(
103 1,
104 kMaxFramerateFraction)},
105 supports_simulcast(false) {}
106
107 VideoEncoder::EncoderInfo::EncoderInfo(const EncoderInfo&) = default;
108
109 VideoEncoder::EncoderInfo::~EncoderInfo() = default;
110
ToString() const111 std::string VideoEncoder::EncoderInfo::ToString() const {
112 char string_buf[2048];
113 rtc::SimpleStringBuilder oss(string_buf);
114
115 oss << "EncoderInfo { "
116 "ScalingSettings { ";
117 if (scaling_settings.thresholds) {
118 oss << "Thresholds { "
119 "low = "
120 << scaling_settings.thresholds->low
121 << ", high = " << scaling_settings.thresholds->high << "}, ";
122 }
123 oss << "min_pixels_per_frame = " << scaling_settings.min_pixels_per_frame
124 << " }";
125 oss << ", requested_resolution_alignment = " << requested_resolution_alignment
126 << ", supports_native_handle = " << supports_native_handle
127 << ", implementation_name = '" << implementation_name
128 << "'"
129 ", has_trusted_rate_controller = "
130 << has_trusted_rate_controller
131 << ", is_hardware_accelerated = " << is_hardware_accelerated
132 << ", has_internal_source = " << has_internal_source
133 << ", fps_allocation = [";
134 bool first = true;
135 for (size_t i = 0; i < fps_allocation->size(); ++i) {
136 if (!first) {
137 oss << ", ";
138 }
139 const absl::InlinedVector<uint8_t, kMaxTemporalStreams>& fractions =
140 fps_allocation[i];
141 if (!fractions.empty()) {
142 first = false;
143 oss << "[ ";
144 for (size_t i = 0; i < fractions.size(); ++i) {
145 if (i > 0) {
146 oss << ", ";
147 }
148 oss << (static_cast<double>(fractions[i]) / kMaxFramerateFraction);
149 }
150 oss << "] ";
151 }
152 }
153 oss << "]";
154 oss << ", resolution_bitrate_limits = [";
155 for (size_t i = 0; i < resolution_bitrate_limits.size(); ++i) {
156 if (i > 0) {
157 oss << ", ";
158 }
159 ResolutionBitrateLimits l = resolution_bitrate_limits[i];
160 oss << "Limits { "
161 "frame_size_pixels = "
162 << l.frame_size_pixels
163 << ", min_start_bitrate_bps = " << l.min_start_bitrate_bps
164 << ", min_bitrate_bps = " << l.min_bitrate_bps
165 << ", max_bitrate_bps = " << l.max_bitrate_bps << "} ";
166 }
167 oss << "] "
168 ", supports_simulcast = "
169 << supports_simulcast << "}";
170 return oss.str();
171 }
172
operator ==(const EncoderInfo & rhs) const173 bool VideoEncoder::EncoderInfo::operator==(const EncoderInfo& rhs) const {
174 if (scaling_settings.thresholds.has_value() !=
175 rhs.scaling_settings.thresholds.has_value()) {
176 return false;
177 }
178 if (scaling_settings.thresholds.has_value()) {
179 QpThresholds l = *scaling_settings.thresholds;
180 QpThresholds r = *rhs.scaling_settings.thresholds;
181 if (l.low != r.low || l.high != r.high) {
182 return false;
183 }
184 }
185 if (scaling_settings.min_pixels_per_frame !=
186 rhs.scaling_settings.min_pixels_per_frame) {
187 return false;
188 }
189
190 if (supports_native_handle != rhs.supports_native_handle ||
191 implementation_name != rhs.implementation_name ||
192 has_trusted_rate_controller != rhs.has_trusted_rate_controller ||
193 is_hardware_accelerated != rhs.is_hardware_accelerated ||
194 has_internal_source != rhs.has_internal_source) {
195 return false;
196 }
197
198 for (size_t i = 0; i < kMaxSpatialLayers; ++i) {
199 if (fps_allocation[i] != rhs.fps_allocation[i]) {
200 return false;
201 }
202 }
203
204 if (resolution_bitrate_limits != rhs.resolution_bitrate_limits ||
205 supports_simulcast != rhs.supports_simulcast) {
206 return false;
207 }
208
209 return true;
210 }
211
212 absl::optional<VideoEncoder::ResolutionBitrateLimits>
GetEncoderBitrateLimitsForResolution(int frame_size_pixels) const213 VideoEncoder::EncoderInfo::GetEncoderBitrateLimitsForResolution(
214 int frame_size_pixels) const {
215 std::vector<ResolutionBitrateLimits> bitrate_limits =
216 resolution_bitrate_limits;
217
218 // Sort the list of bitrate limits by resolution.
219 sort(bitrate_limits.begin(), bitrate_limits.end(),
220 [](const ResolutionBitrateLimits& lhs,
221 const ResolutionBitrateLimits& rhs) {
222 return lhs.frame_size_pixels < rhs.frame_size_pixels;
223 });
224
225 for (size_t i = 0; i < bitrate_limits.size(); ++i) {
226 RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps, 0);
227 RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps, 0);
228 RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
229 bitrate_limits[i].min_bitrate_bps);
230 if (i > 0) {
231 // The bitrate limits aren't expected to decrease with resolution.
232 RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps,
233 bitrate_limits[i - 1].min_bitrate_bps);
234 RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps,
235 bitrate_limits[i - 1].min_start_bitrate_bps);
236 RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
237 bitrate_limits[i - 1].max_bitrate_bps);
238 }
239
240 if (bitrate_limits[i].frame_size_pixels >= frame_size_pixels) {
241 return absl::optional<ResolutionBitrateLimits>(bitrate_limits[i]);
242 }
243 }
244
245 return absl::nullopt;
246 }
247
RateControlParameters()248 VideoEncoder::RateControlParameters::RateControlParameters()
249 : bitrate(VideoBitrateAllocation()),
250 framerate_fps(0.0),
251 bandwidth_allocation(DataRate::Zero()) {}
252
RateControlParameters(const VideoBitrateAllocation & bitrate,double framerate_fps)253 VideoEncoder::RateControlParameters::RateControlParameters(
254 const VideoBitrateAllocation& bitrate,
255 double framerate_fps)
256 : bitrate(bitrate),
257 framerate_fps(framerate_fps),
258 bandwidth_allocation(DataRate::BitsPerSec(bitrate.get_sum_bps())) {}
259
RateControlParameters(const VideoBitrateAllocation & bitrate,double framerate_fps,DataRate bandwidth_allocation)260 VideoEncoder::RateControlParameters::RateControlParameters(
261 const VideoBitrateAllocation& bitrate,
262 double framerate_fps,
263 DataRate bandwidth_allocation)
264 : bitrate(bitrate),
265 framerate_fps(framerate_fps),
266 bandwidth_allocation(bandwidth_allocation) {}
267
operator ==(const VideoEncoder::RateControlParameters & rhs) const268 bool VideoEncoder::RateControlParameters::operator==(
269 const VideoEncoder::RateControlParameters& rhs) const {
270 return std::tie(bitrate, framerate_fps, bandwidth_allocation) ==
271 std::tie(rhs.bitrate, rhs.framerate_fps, rhs.bandwidth_allocation);
272 }
273
operator !=(const VideoEncoder::RateControlParameters & rhs) const274 bool VideoEncoder::RateControlParameters::operator!=(
275 const VideoEncoder::RateControlParameters& rhs) const {
276 return !(rhs == *this);
277 }
278
279 VideoEncoder::RateControlParameters::~RateControlParameters() = default;
280
SetFecControllerOverride(FecControllerOverride * fec_controller_override)281 void VideoEncoder::SetFecControllerOverride(
282 FecControllerOverride* fec_controller_override) {}
283
InitEncode(const VideoCodec * codec_settings,int32_t number_of_cores,size_t max_payload_size)284 int32_t VideoEncoder::InitEncode(const VideoCodec* codec_settings,
285 int32_t number_of_cores,
286 size_t max_payload_size) {
287 const VideoEncoder::Capabilities capabilities(/* loss_notification= */ false);
288 const VideoEncoder::Settings settings(capabilities, number_of_cores,
289 max_payload_size);
290 // In theory, this and the other version of InitEncode() could end up calling
291 // each other in a loop until we get a stack overflow.
292 // In practice, any subclass of VideoEncoder would overload at least one
293 // of these, and we have a TODO in the header file to make this pure virtual.
294 return InitEncode(codec_settings, settings);
295 }
296
InitEncode(const VideoCodec * codec_settings,const VideoEncoder::Settings & settings)297 int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
298 const VideoEncoder::Settings& settings) {
299 // In theory, this and the other version of InitEncode() could end up calling
300 // each other in a loop until we get a stack overflow.
301 // In practice, any subclass of VideoEncoder would overload at least one
302 // of these, and we have a TODO in the header file to make this pure virtual.
303 return InitEncode(codec_settings, settings.number_of_cores,
304 settings.max_payload_size);
305 }
306
OnPacketLossRateUpdate(float packet_loss_rate)307 void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
308
OnRttUpdate(int64_t rtt_ms)309 void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
310
OnLossNotification(const LossNotification & loss_notification)311 void VideoEncoder::OnLossNotification(
312 const LossNotification& loss_notification) {}
313
314 // TODO(webrtc:9722): Remove and make pure virtual.
GetEncoderInfo() const315 VideoEncoder::EncoderInfo VideoEncoder::GetEncoderInfo() const {
316 return EncoderInfo();
317 }
318
319 } // namespace webrtc
320