blob: 0ee25c50b5450d8ba969a4a85439b3bcd66f9601 [file] [log] [blame]
mflodman351424e2017-08-10 02:43:14 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "api/video_codecs/video_encoder.h"
mflodman351424e2017-08-10 02:43:14 -070012
Yves Gerey988cc082018-10-23 12:03:01 +020013#include <string.h>
14
15#include "rtc_base/checks.h"
Erik Språng79685302019-11-27 17:26:58 +010016#include "rtc_base/strings/string_builder.h"
Yves Gerey988cc082018-10-23 12:03:01 +020017
mflodman351424e2017-08-10 02:43:14 -070018namespace webrtc {
19
20// TODO(mflodman): Add default complexity for VP9 and VP9.
21VideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() {
22 VideoCodecVP8 vp8_settings;
23 memset(&vp8_settings, 0, sizeof(vp8_settings));
24
mflodman351424e2017-08-10 02:43:14 -070025 vp8_settings.numberOfTemporalLayers = 1;
26 vp8_settings.denoisingOn = true;
mflodman351424e2017-08-10 02:43:14 -070027 vp8_settings.automaticResizeOn = false;
28 vp8_settings.frameDroppingOn = true;
29 vp8_settings.keyFrameInterval = 3000;
30
31 return vp8_settings;
32}
33
34VideoCodecVP9 VideoEncoder::GetDefaultVp9Settings() {
35 VideoCodecVP9 vp9_settings;
36 memset(&vp9_settings, 0, sizeof(vp9_settings));
37
mflodman351424e2017-08-10 02:43:14 -070038 vp9_settings.numberOfTemporalLayers = 1;
39 vp9_settings.denoisingOn = true;
40 vp9_settings.frameDroppingOn = true;
41 vp9_settings.keyFrameInterval = 3000;
42 vp9_settings.adaptiveQpMode = true;
43 vp9_settings.automaticResizeOn = true;
44 vp9_settings.numberOfSpatialLayers = 1;
45 vp9_settings.flexibleMode = false;
Sergey Silkin6a8f30e2018-04-26 11:03:49 +020046 vp9_settings.interLayerPred = InterLayerPredMode::kOn;
mflodman351424e2017-08-10 02:43:14 -070047
48 return vp9_settings;
49}
50
51VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
52 VideoCodecH264 h264_settings;
53 memset(&h264_settings, 0, sizeof(h264_settings));
54
55 h264_settings.frameDroppingOn = true;
56 h264_settings.keyFrameInterval = 3000;
Johnny Lee1a1c52b2019-02-08 14:25:40 -050057 h264_settings.numberOfTemporalLayers = 1;
mflodman351424e2017-08-10 02:43:14 -070058
59 return h264_settings;
60}
61
Niels Möller225c7872018-02-22 15:03:53 +010062VideoEncoder::ScalingSettings::ScalingSettings() = default;
mflodman351424e2017-08-10 02:43:14 -070063
Niels Möller225c7872018-02-22 15:03:53 +010064VideoEncoder::ScalingSettings::ScalingSettings(KOff) : ScalingSettings() {}
65
66VideoEncoder::ScalingSettings::ScalingSettings(int low, int high)
67 : thresholds(QpThresholds(low, high)) {}
68
69VideoEncoder::ScalingSettings::ScalingSettings(int low,
asapersson142fcc92017-08-17 08:58:54 -070070 int high,
71 int min_pixels)
Niels Möller225c7872018-02-22 15:03:53 +010072 : thresholds(QpThresholds(low, high)), min_pixels_per_frame(min_pixels) {}
asapersson142fcc92017-08-17 08:58:54 -070073
Niels Möller225c7872018-02-22 15:03:53 +010074VideoEncoder::ScalingSettings::ScalingSettings(const ScalingSettings&) =
75 default;
mflodman351424e2017-08-10 02:43:14 -070076
77VideoEncoder::ScalingSettings::~ScalingSettings() {}
78
Niels Möller225c7872018-02-22 15:03:53 +010079// static
80constexpr VideoEncoder::ScalingSettings::KOff
81 VideoEncoder::ScalingSettings::kOff;
Erik Språngdbdd8392019-01-17 15:27:50 +010082// static
83constexpr uint8_t VideoEncoder::EncoderInfo::kMaxFramerateFraction;
mflodman351424e2017-08-10 02:43:14 -070084
Erik Språng79685302019-11-27 17:26:58 +010085bool VideoEncoder::ResolutionBitrateLimits::operator==(
86 const ResolutionBitrateLimits& rhs) const {
87 return frame_size_pixels == rhs.frame_size_pixels &&
88 min_start_bitrate_bps == rhs.min_start_bitrate_bps &&
89 min_bitrate_bps == rhs.min_bitrate_bps &&
90 max_bitrate_bps == rhs.max_bitrate_bps;
91}
92
Erik Språnge2fd86a2018-10-24 11:32:39 +020093VideoEncoder::EncoderInfo::EncoderInfo()
94 : scaling_settings(VideoEncoder::ScalingSettings::kOff),
Rasmus Brandt5cad55b2019-12-19 09:47:11 +010095 requested_resolution_alignment(1),
Erik Språnge2fd86a2018-10-24 11:32:39 +020096 supports_native_handle(false),
Erik Språngd3438aa2018-11-08 16:56:43 +010097 implementation_name("unknown"),
Mirta Dvornicic897a9912018-11-30 13:12:21 +010098 has_trusted_rate_controller(false),
Mirta Dvornicicccc1b572019-01-15 12:42:18 +010099 is_hardware_accelerated(true),
Erik Språngdbdd8392019-01-17 15:27:50 +0100100 has_internal_source(false),
101 fps_allocation{absl::InlinedVector<uint8_t, kMaxTemporalStreams>(
102 1,
Erik Språngf4e0c292019-10-01 18:50:03 +0200103 kMaxFramerateFraction)},
104 supports_simulcast(false) {}
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100105
106VideoEncoder::EncoderInfo::EncoderInfo(const EncoderInfo&) = default;
Erik Språnge2fd86a2018-10-24 11:32:39 +0200107
Erik Språnge2fd86a2018-10-24 11:32:39 +0200108VideoEncoder::EncoderInfo::~EncoderInfo() = default;
109
Erik Språng79685302019-11-27 17:26:58 +0100110std::string VideoEncoder::EncoderInfo::ToString() const {
111 char string_buf[2048];
112 rtc::SimpleStringBuilder oss(string_buf);
113
114 oss << "EncoderInfo { "
115 << "ScalingSettings { ";
116 if (scaling_settings.thresholds) {
117 oss << "Thresholds { "
118 << "low = " << scaling_settings.thresholds->low
119 << ", high = " << scaling_settings.thresholds->high << "}, ";
120 }
121 oss << "min_pixels_per_frame = " << scaling_settings.min_pixels_per_frame
122 << " }";
Rasmus Brandt5cad55b2019-12-19 09:47:11 +0100123 oss << ", requested_resolution_alignment = " << requested_resolution_alignment
124 << ", supports_native_handle = " << supports_native_handle
Erik Språng79685302019-11-27 17:26:58 +0100125 << ", implementation_name = '" << implementation_name << "'"
126 << ", has_trusted_rate_controller = " << has_trusted_rate_controller
127 << ", is_hardware_accelerated = " << is_hardware_accelerated
128 << ", has_internal_source = " << has_internal_source
129 << ", fps_allocation = [";
130 bool first = true;
131 for (size_t i = 0; i < fps_allocation->size(); ++i) {
132 if (!first) {
133 oss << ", ";
134 }
135 const absl::InlinedVector<uint8_t, kMaxTemporalStreams>& fractions =
136 fps_allocation[i];
137 if (!fractions.empty()) {
138 first = false;
139 oss << "[ ";
140 for (size_t i = 0; i < fractions.size(); ++i) {
141 if (i > 0) {
142 oss << ", ";
143 }
144 oss << (static_cast<double>(fractions[i]) / kMaxFramerateFraction);
145 }
146 oss << "] ";
147 }
148 }
149 oss << "]";
150 oss << ", resolution_bitrate_limits = [";
151 for (size_t i = 0; i < resolution_bitrate_limits.size(); ++i) {
152 if (i > 0) {
153 oss << ", ";
154 }
155 ResolutionBitrateLimits l = resolution_bitrate_limits[i];
156 oss << "Limits { "
157 << "frame_size_pixels = " << l.frame_size_pixels
158 << ", min_start_bitrate_bps = " << l.min_start_bitrate_bps
159 << ", min_bitrate_bps = " << l.min_bitrate_bps
160 << ", max_bitrate_bps = " << l.max_bitrate_bps << "} ";
161 }
162 oss << "] "
163 << ", supports_simulcast = " << supports_simulcast << "}";
164 return oss.str();
165}
166
167bool VideoEncoder::EncoderInfo::operator==(const EncoderInfo& rhs) const {
168 if (scaling_settings.thresholds.has_value() !=
169 rhs.scaling_settings.thresholds.has_value()) {
170 return false;
171 }
172 if (scaling_settings.thresholds.has_value()) {
173 QpThresholds l = *scaling_settings.thresholds;
174 QpThresholds r = *rhs.scaling_settings.thresholds;
175 if (l.low != r.low || l.high != r.high) {
176 return false;
177 }
178 }
179 if (scaling_settings.min_pixels_per_frame !=
180 rhs.scaling_settings.min_pixels_per_frame) {
181 return false;
182 }
183
184 if (supports_native_handle != rhs.supports_native_handle ||
185 implementation_name != rhs.implementation_name ||
186 has_trusted_rate_controller != rhs.has_trusted_rate_controller ||
187 is_hardware_accelerated != rhs.is_hardware_accelerated ||
188 has_internal_source != rhs.has_internal_source) {
189 return false;
190 }
191
192 for (size_t i = 0; i < kMaxSpatialLayers; ++i) {
193 if (fps_allocation[i] != rhs.fps_allocation[i]) {
194 return false;
195 }
196 }
197
198 if (resolution_bitrate_limits != rhs.resolution_bitrate_limits ||
199 supports_simulcast != rhs.supports_simulcast) {
200 return false;
201 }
202
203 return true;
204}
205
Erik Språng4c6ca302019-04-08 15:14:01 +0200206VideoEncoder::RateControlParameters::RateControlParameters()
207 : bitrate(VideoBitrateAllocation()),
208 framerate_fps(0.0),
209 bandwidth_allocation(DataRate::Zero()) {}
210
211VideoEncoder::RateControlParameters::RateControlParameters(
212 const VideoBitrateAllocation& bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200213 double framerate_fps)
214 : bitrate(bitrate),
215 framerate_fps(framerate_fps),
216 bandwidth_allocation(DataRate::bps(bitrate.get_sum_bps())) {}
217
218VideoEncoder::RateControlParameters::RateControlParameters(
219 const VideoBitrateAllocation& bitrate,
Erik Språng4c6ca302019-04-08 15:14:01 +0200220 double framerate_fps,
221 DataRate bandwidth_allocation)
222 : bitrate(bitrate),
223 framerate_fps(framerate_fps),
224 bandwidth_allocation(bandwidth_allocation) {}
225
Evan Shrubsole7c079f62019-09-26 09:55:03 +0200226bool VideoEncoder::RateControlParameters::operator==(
227 const VideoEncoder::RateControlParameters& rhs) const {
228 return std::tie(bitrate, framerate_fps, bandwidth_allocation) ==
229 std::tie(rhs.bitrate, rhs.framerate_fps, rhs.bandwidth_allocation);
230}
231
232bool VideoEncoder::RateControlParameters::operator!=(
233 const VideoEncoder::RateControlParameters& rhs) const {
234 return !(rhs == *this);
235}
236
Erik Språng4c6ca302019-04-08 15:14:01 +0200237VideoEncoder::RateControlParameters::~RateControlParameters() = default;
238
Elad Alon8f01c4e2019-06-28 15:19:43 +0200239void VideoEncoder::SetFecControllerOverride(
240 FecControllerOverride* fec_controller_override) {}
241
Elad Alon370f93a2019-06-11 14:57:57 +0200242int32_t VideoEncoder::InitEncode(const VideoCodec* codec_settings,
243 int32_t number_of_cores,
244 size_t max_payload_size) {
245 const VideoEncoder::Capabilities capabilities(/* loss_notification= */ false);
246 const VideoEncoder::Settings settings(capabilities, number_of_cores,
247 max_payload_size);
248 // In theory, this and the other version of InitEncode() could end up calling
249 // each other in a loop until we get a stack overflow.
250 // In practice, any subclass of VideoEncoder would overload at least one
251 // of these, and we have a TODO in the header file to make this pure virtual.
252 return InitEncode(codec_settings, settings);
253}
254
255int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
256 const VideoEncoder::Settings& settings) {
257 // In theory, this and the other version of InitEncode() could end up calling
258 // each other in a loop until we get a stack overflow.
259 // In practice, any subclass of VideoEncoder would overload at least one
260 // of these, and we have a TODO in the header file to make this pure virtual.
261 return InitEncode(codec_settings, settings.number_of_cores,
262 settings.max_payload_size);
263}
264
Elad Aloncde8ab22019-03-20 11:56:20 +0100265void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
266
267void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
268
Elad Alon6c371ca2019-04-04 12:28:51 +0200269void VideoEncoder::OnLossNotification(
270 const LossNotification& loss_notification) {}
271
Erik Språng6ed4f142018-11-26 13:42:39 +0100272// TODO(webrtc:9722): Remove and make pure virtual.
Erik Språnge2fd86a2018-10-24 11:32:39 +0200273VideoEncoder::EncoderInfo VideoEncoder::GetEncoderInfo() const {
Erik Språng6ed4f142018-11-26 13:42:39 +0100274 return EncoderInfo();
Erik Språnge2fd86a2018-10-24 11:32:39 +0200275}
Erik Språng6ed4f142018-11-26 13:42:39 +0100276
mflodman351424e2017-08-10 02:43:14 -0700277} // namespace webrtc