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