1 /*
2 * Copyright 2021 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 "rtc_base/experiments/encoder_info_settings.h"
12
13 #include <stdio.h>
14
15 #include "absl/strings/string_view.h"
16 #include "rtc_base/experiments/field_trial_list.h"
17 #include "rtc_base/logging.h"
18 #include "system_wrappers/include/field_trial.h"
19
20 namespace webrtc {
21 namespace {
22
ToResolutionBitrateLimits(const std::vector<EncoderInfoSettings::BitrateLimit> & limits)23 std::vector<VideoEncoder::ResolutionBitrateLimits> ToResolutionBitrateLimits(
24 const std::vector<EncoderInfoSettings::BitrateLimit>& limits) {
25 std::vector<VideoEncoder::ResolutionBitrateLimits> result;
26 for (const auto& limit : limits) {
27 result.push_back(VideoEncoder::ResolutionBitrateLimits(
28 limit.frame_size_pixels, limit.min_start_bitrate_bps,
29 limit.min_bitrate_bps, limit.max_bitrate_bps));
30 }
31 return result;
32 }
33 constexpr float kDefaultMinBitratebps = 30000;
34 } // namespace
35
36 // Default bitrate limits for simulcast with one active stream:
37 // {frame_size_pixels, min_start_bitrate_bps, min_bitrate_bps, max_bitrate_bps}.
38 std::vector<VideoEncoder::ResolutionBitrateLimits>
GetDefaultSinglecastBitrateLimits(VideoCodecType codec_type)39 EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
40 VideoCodecType codec_type) {
41 // Specific limits for VP9. Other codecs use VP8 limits.
42 if (codec_type == kVideoCodecVP9) {
43 return {{320 * 180, 0, 30000, 150000},
44 {480 * 270, 120000, 30000, 300000},
45 {640 * 360, 190000, 30000, 420000},
46 {960 * 540, 350000, 30000, 1000000},
47 {1280 * 720, 480000, 30000, 1500000}};
48 }
49
50 return {{320 * 180, 0, 30000, 300000},
51 {480 * 270, 200000, 30000, 500000},
52 {640 * 360, 300000, 30000, 800000},
53 {960 * 540, 500000, 30000, 1500000},
54 {1280 * 720, 900000, 30000, 2500000}};
55 }
56
57 absl::optional<VideoEncoder::ResolutionBitrateLimits>
GetDefaultSinglecastBitrateLimitsForResolution(VideoCodecType codec_type,int frame_size_pixels)58 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
59 VideoCodecType codec_type,
60 int frame_size_pixels) {
61 VideoEncoder::EncoderInfo info;
62 info.resolution_bitrate_limits =
63 GetDefaultSinglecastBitrateLimits(codec_type);
64 return info.GetEncoderBitrateLimitsForResolution(frame_size_pixels);
65 }
66
67 // Return the suitable bitrate limits for specified resolution when qp is
68 // untrusted, they are experimental values.
69 // TODO(bugs.webrtc.org/12942): Maybe we need to add other codecs(VP8/VP9)
70 // experimental values.
71 std::vector<VideoEncoder::ResolutionBitrateLimits>
GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted()72 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted() {
73 // Specific limits for H264/AVC
74 return {{0 * 0, 0, 0, 0},
75 {320 * 180, 0, 30000, 300000},
76 {480 * 270, 300000, 30000, 500000},
77 {640 * 360, 500000, 30000, 800000},
78 {960 * 540, 800000, 30000, 1500000},
79 {1280 * 720, 1500000, 30000, 2500000},
80 {1920 * 1080, 2500000, 30000, 4000000}};
81 }
82
83 // Through linear interpolation, return the bitrate limit corresponding to the
84 // specified |frame_size_pixels|.
85 absl::optional<VideoEncoder::ResolutionBitrateLimits>
GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(absl::optional<int> frame_size_pixels,const std::vector<VideoEncoder::ResolutionBitrateLimits> & resolution_bitrate_limits)86 EncoderInfoSettings::GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
87 absl::optional<int> frame_size_pixels,
88 const std::vector<VideoEncoder::ResolutionBitrateLimits>&
89 resolution_bitrate_limits) {
90 if (!frame_size_pixels.has_value() || frame_size_pixels.value() <= 0) {
91 return absl::nullopt;
92 }
93
94 std::vector<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
95 resolution_bitrate_limits;
96
97 // Sort the list of bitrate limits by resolution.
98 sort(bitrate_limits.begin(), bitrate_limits.end(),
99 [](const VideoEncoder::ResolutionBitrateLimits& lhs,
100 const VideoEncoder::ResolutionBitrateLimits& rhs) {
101 return lhs.frame_size_pixels < rhs.frame_size_pixels;
102 });
103
104 if (bitrate_limits.empty()) {
105 return absl::nullopt;
106 }
107
108 int interpolation_index = -1;
109 for (size_t i = 0; i < bitrate_limits.size(); ++i) {
110 if (bitrate_limits[i].frame_size_pixels >= frame_size_pixels.value()) {
111 interpolation_index = i;
112 break;
113 }
114 }
115
116 // -1 means that the maximum resolution is exceeded, we will select the
117 // largest data as the return result.
118 if (interpolation_index == -1) {
119 return *bitrate_limits.rbegin();
120 }
121
122 // If we have a matching resolution, return directly without interpolation.
123 if (bitrate_limits[interpolation_index].frame_size_pixels ==
124 frame_size_pixels.value()) {
125 return bitrate_limits[interpolation_index];
126 }
127
128 // No matching resolution, do a linear interpolate.
129 int lower_pixel_count =
130 bitrate_limits[interpolation_index - 1].frame_size_pixels;
131 int upper_pixel_count = bitrate_limits[interpolation_index].frame_size_pixels;
132 float alpha = (frame_size_pixels.value() - lower_pixel_count) * 1.0 /
133 (upper_pixel_count - lower_pixel_count);
134 int min_start_bitrate_bps = static_cast<int>(
135 bitrate_limits[interpolation_index].min_start_bitrate_bps * alpha +
136 bitrate_limits[interpolation_index - 1].min_start_bitrate_bps *
137 (1.0 - alpha));
138 int max_bitrate_bps = static_cast<int>(
139 bitrate_limits[interpolation_index].max_bitrate_bps * alpha +
140 bitrate_limits[interpolation_index - 1].max_bitrate_bps * (1.0 - alpha));
141
142 if (max_bitrate_bps >= min_start_bitrate_bps) {
143 return VideoEncoder::ResolutionBitrateLimits(
144 frame_size_pixels.value(), min_start_bitrate_bps, kDefaultMinBitratebps,
145 max_bitrate_bps);
146 } else {
147 RTC_LOG(LS_WARNING)
148 << "BitRate interpolation calculating result is abnormal. "
149 << " lower_pixel_count = " << lower_pixel_count
150 << " upper_pixel_count = " << upper_pixel_count
151 << " frame_size_pixels = " << frame_size_pixels.value()
152 << " min_start_bitrate_bps = " << min_start_bitrate_bps
153 << " min_bitrate_bps = " << kDefaultMinBitratebps
154 << " max_bitrate_bps = " << max_bitrate_bps;
155 return absl::nullopt;
156 }
157 }
158
EncoderInfoSettings(absl::string_view name)159 EncoderInfoSettings::EncoderInfoSettings(absl::string_view name)
160 : requested_resolution_alignment_("requested_resolution_alignment"),
161 apply_alignment_to_all_simulcast_layers_(
162 "apply_alignment_to_all_simulcast_layers") {
163 FieldTrialStructList<BitrateLimit> bitrate_limits(
164 {FieldTrialStructMember(
165 "frame_size_pixels",
166 [](BitrateLimit* b) { return &b->frame_size_pixels; }),
167 FieldTrialStructMember(
168 "min_start_bitrate_bps",
169 [](BitrateLimit* b) { return &b->min_start_bitrate_bps; }),
170 FieldTrialStructMember(
171 "min_bitrate_bps",
172 [](BitrateLimit* b) { return &b->min_bitrate_bps; }),
173 FieldTrialStructMember(
174 "max_bitrate_bps",
175 [](BitrateLimit* b) { return &b->max_bitrate_bps; })},
176 {});
177
178 std::string name_str(name);
179 if (field_trial::FindFullName(name_str).empty()) {
180 // Encoder name not found, use common string applying to all encoders.
181 name_str = "WebRTC-GetEncoderInfoOverride";
182 }
183
184 ParseFieldTrial({&bitrate_limits, &requested_resolution_alignment_,
185 &apply_alignment_to_all_simulcast_layers_},
186 field_trial::FindFullName(name_str));
187
188 resolution_bitrate_limits_ = ToResolutionBitrateLimits(bitrate_limits.Get());
189 }
190
requested_resolution_alignment() const191 absl::optional<int> EncoderInfoSettings::requested_resolution_alignment()
192 const {
193 if (requested_resolution_alignment_ &&
194 requested_resolution_alignment_.Value() < 1) {
195 RTC_LOG(LS_WARNING) << "Unsupported alignment value, ignored.";
196 return absl::nullopt;
197 }
198 return requested_resolution_alignment_.GetOptional();
199 }
200
~EncoderInfoSettings()201 EncoderInfoSettings::~EncoderInfoSettings() {}
202
203 SimulcastEncoderAdapterEncoderInfoSettings::
SimulcastEncoderAdapterEncoderInfoSettings()204 SimulcastEncoderAdapterEncoderInfoSettings()
205 : EncoderInfoSettings(
206 "WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride") {}
207
LibvpxVp8EncoderInfoSettings()208 LibvpxVp8EncoderInfoSettings::LibvpxVp8EncoderInfoSettings()
209 : EncoderInfoSettings("WebRTC-VP8-GetEncoderInfoOverride") {}
210
LibvpxVp9EncoderInfoSettings()211 LibvpxVp9EncoderInfoSettings::LibvpxVp9EncoderInfoSettings()
212 : EncoderInfoSettings("WebRTC-VP9-GetEncoderInfoOverride") {}
213
214 } // namespace webrtc
215