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       apply_alignment_to_all_simulcast_layers(false),
98       supports_native_handle(false),
99       implementation_name("unknown"),
100       has_trusted_rate_controller(false),
101       is_hardware_accelerated(true),
102       has_internal_source(false),
103       fps_allocation{absl::InlinedVector<uint8_t, kMaxTemporalStreams>(
104           1,
105           kMaxFramerateFraction)},
106       supports_simulcast(false) {}
107 
108 VideoEncoder::EncoderInfo::EncoderInfo(const EncoderInfo&) = default;
109 
110 VideoEncoder::EncoderInfo::~EncoderInfo() = default;
111 
ToString() const112 std::string VideoEncoder::EncoderInfo::ToString() const {
113   char string_buf[2048];
114   rtc::SimpleStringBuilder oss(string_buf);
115 
116   oss << "EncoderInfo { "
117          "ScalingSettings { ";
118   if (scaling_settings.thresholds) {
119     oss << "Thresholds { "
120            "low = "
121         << scaling_settings.thresholds->low
122         << ", high = " << scaling_settings.thresholds->high << "}, ";
123   }
124   oss << "min_pixels_per_frame = " << scaling_settings.min_pixels_per_frame
125       << " }";
126   oss << ", requested_resolution_alignment = " << requested_resolution_alignment
127       << ", apply_alignment_to_all_simulcast_layers = "
128       << apply_alignment_to_all_simulcast_layers
129       << ", supports_native_handle = " << supports_native_handle
130       << ", implementation_name = '" << implementation_name
131       << "'"
132          ", has_trusted_rate_controller = "
133       << has_trusted_rate_controller
134       << ", is_hardware_accelerated = " << is_hardware_accelerated
135       << ", has_internal_source = " << has_internal_source
136       << ", fps_allocation = [";
137   bool first = true;
138   for (size_t i = 0; i < fps_allocation->size(); ++i) {
139     if (!first) {
140       oss << ", ";
141     }
142     const absl::InlinedVector<uint8_t, kMaxTemporalStreams>& fractions =
143         fps_allocation[i];
144     if (!fractions.empty()) {
145       first = false;
146       oss << "[ ";
147       for (size_t i = 0; i < fractions.size(); ++i) {
148         if (i > 0) {
149           oss << ", ";
150         }
151         oss << (static_cast<double>(fractions[i]) / kMaxFramerateFraction);
152       }
153       oss << "] ";
154     }
155   }
156   oss << "]";
157   oss << ", resolution_bitrate_limits = [";
158   for (size_t i = 0; i < resolution_bitrate_limits.size(); ++i) {
159     if (i > 0) {
160       oss << ", ";
161     }
162     ResolutionBitrateLimits l = resolution_bitrate_limits[i];
163     oss << "Limits { "
164            "frame_size_pixels = "
165         << l.frame_size_pixels
166         << ", min_start_bitrate_bps = " << l.min_start_bitrate_bps
167         << ", min_bitrate_bps = " << l.min_bitrate_bps
168         << ", max_bitrate_bps = " << l.max_bitrate_bps << "} ";
169   }
170   oss << "] "
171          ", supports_simulcast = "
172       << supports_simulcast << "}";
173   return oss.str();
174 }
175 
operator ==(const EncoderInfo & rhs) const176 bool VideoEncoder::EncoderInfo::operator==(const EncoderInfo& rhs) const {
177   if (scaling_settings.thresholds.has_value() !=
178       rhs.scaling_settings.thresholds.has_value()) {
179     return false;
180   }
181   if (scaling_settings.thresholds.has_value()) {
182     QpThresholds l = *scaling_settings.thresholds;
183     QpThresholds r = *rhs.scaling_settings.thresholds;
184     if (l.low != r.low || l.high != r.high) {
185       return false;
186     }
187   }
188   if (scaling_settings.min_pixels_per_frame !=
189       rhs.scaling_settings.min_pixels_per_frame) {
190     return false;
191   }
192 
193   if (supports_native_handle != rhs.supports_native_handle ||
194       implementation_name != rhs.implementation_name ||
195       has_trusted_rate_controller != rhs.has_trusted_rate_controller ||
196       is_hardware_accelerated != rhs.is_hardware_accelerated ||
197       has_internal_source != rhs.has_internal_source) {
198     return false;
199   }
200 
201   for (size_t i = 0; i < kMaxSpatialLayers; ++i) {
202     if (fps_allocation[i] != rhs.fps_allocation[i]) {
203       return false;
204     }
205   }
206 
207   if (resolution_bitrate_limits != rhs.resolution_bitrate_limits ||
208       supports_simulcast != rhs.supports_simulcast) {
209     return false;
210   }
211 
212   return true;
213 }
214 
215 absl::optional<VideoEncoder::ResolutionBitrateLimits>
GetEncoderBitrateLimitsForResolution(int frame_size_pixels) const216 VideoEncoder::EncoderInfo::GetEncoderBitrateLimitsForResolution(
217     int frame_size_pixels) const {
218   std::vector<ResolutionBitrateLimits> bitrate_limits =
219       resolution_bitrate_limits;
220 
221   // Sort the list of bitrate limits by resolution.
222   sort(bitrate_limits.begin(), bitrate_limits.end(),
223        [](const ResolutionBitrateLimits& lhs,
224           const ResolutionBitrateLimits& rhs) {
225          return lhs.frame_size_pixels < rhs.frame_size_pixels;
226        });
227 
228   for (size_t i = 0; i < bitrate_limits.size(); ++i) {
229     RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps, 0);
230     RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps, 0);
231     RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
232                   bitrate_limits[i].min_bitrate_bps);
233     if (i > 0) {
234       // The bitrate limits aren't expected to decrease with resolution.
235       RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps,
236                     bitrate_limits[i - 1].min_bitrate_bps);
237       RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps,
238                     bitrate_limits[i - 1].min_start_bitrate_bps);
239       RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
240                     bitrate_limits[i - 1].max_bitrate_bps);
241     }
242 
243     if (bitrate_limits[i].frame_size_pixels >= frame_size_pixels) {
244       return absl::optional<ResolutionBitrateLimits>(bitrate_limits[i]);
245     }
246   }
247 
248   return absl::nullopt;
249 }
250 
RateControlParameters()251 VideoEncoder::RateControlParameters::RateControlParameters()
252     : bitrate(VideoBitrateAllocation()),
253       framerate_fps(0.0),
254       bandwidth_allocation(DataRate::Zero()) {}
255 
RateControlParameters(const VideoBitrateAllocation & bitrate,double framerate_fps)256 VideoEncoder::RateControlParameters::RateControlParameters(
257     const VideoBitrateAllocation& bitrate,
258     double framerate_fps)
259     : bitrate(bitrate),
260       framerate_fps(framerate_fps),
261       bandwidth_allocation(DataRate::BitsPerSec(bitrate.get_sum_bps())) {}
262 
RateControlParameters(const VideoBitrateAllocation & bitrate,double framerate_fps,DataRate bandwidth_allocation)263 VideoEncoder::RateControlParameters::RateControlParameters(
264     const VideoBitrateAllocation& bitrate,
265     double framerate_fps,
266     DataRate bandwidth_allocation)
267     : bitrate(bitrate),
268       framerate_fps(framerate_fps),
269       bandwidth_allocation(bandwidth_allocation) {}
270 
operator ==(const VideoEncoder::RateControlParameters & rhs) const271 bool VideoEncoder::RateControlParameters::operator==(
272     const VideoEncoder::RateControlParameters& rhs) const {
273   return std::tie(bitrate, framerate_fps, bandwidth_allocation) ==
274          std::tie(rhs.bitrate, rhs.framerate_fps, rhs.bandwidth_allocation);
275 }
276 
operator !=(const VideoEncoder::RateControlParameters & rhs) const277 bool VideoEncoder::RateControlParameters::operator!=(
278     const VideoEncoder::RateControlParameters& rhs) const {
279   return !(rhs == *this);
280 }
281 
282 VideoEncoder::RateControlParameters::~RateControlParameters() = default;
283 
SetFecControllerOverride(FecControllerOverride * fec_controller_override)284 void VideoEncoder::SetFecControllerOverride(
285     FecControllerOverride* fec_controller_override) {}
286 
InitEncode(const VideoCodec * codec_settings,int32_t number_of_cores,size_t max_payload_size)287 int32_t VideoEncoder::InitEncode(const VideoCodec* codec_settings,
288                                  int32_t number_of_cores,
289                                  size_t max_payload_size) {
290   const VideoEncoder::Capabilities capabilities(/* loss_notification= */ false);
291   const VideoEncoder::Settings settings(capabilities, number_of_cores,
292                                         max_payload_size);
293   // In theory, this and the other version of InitEncode() could end up calling
294   // each other in a loop until we get a stack overflow.
295   // In practice, any subclass of VideoEncoder would overload at least one
296   // of these, and we have a TODO in the header file to make this pure virtual.
297   return InitEncode(codec_settings, settings);
298 }
299 
InitEncode(const VideoCodec * codec_settings,const VideoEncoder::Settings & settings)300 int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
301                              const VideoEncoder::Settings& settings) {
302   // In theory, this and the other version of InitEncode() could end up calling
303   // each other in a loop until we get a stack overflow.
304   // In practice, any subclass of VideoEncoder would overload at least one
305   // of these, and we have a TODO in the header file to make this pure virtual.
306   return InitEncode(codec_settings, settings.number_of_cores,
307                     settings.max_payload_size);
308 }
309 
OnPacketLossRateUpdate(float packet_loss_rate)310 void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
311 
OnRttUpdate(int64_t rtt_ms)312 void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
313 
OnLossNotification(const LossNotification & loss_notification)314 void VideoEncoder::OnLossNotification(
315     const LossNotification& loss_notification) {}
316 
317 // TODO(webrtc:9722): Remove and make pure virtual.
GetEncoderInfo() const318 VideoEncoder::EncoderInfo VideoEncoder::GetEncoderInfo() const {
319   return EncoderInfo();
320 }
321 
322 }  // namespace webrtc
323