xref: /aosp_15_r20/external/webrtc/rtc_base/experiments/encoder_info_settings.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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