Add field trial for allowing cropped resolution when limiting max layers.

E.g. 480x270: max_layers:2
     480x268: max_layers:1 -> 2.

Bug: none
Change-Id: Ieb86bc7b04e639d81e73d80aa0940b4c320e4de4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/201730
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33030}
This commit is contained in:
Åsa Persson 2021-01-18 09:15:07 +01:00 committed by Commit Bot
parent 5cf0ef0022
commit 29bd8638ad
2 changed files with 86 additions and 4 deletions

View File

@ -23,6 +23,7 @@
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/min_video_bitrate_experiment.h"
#include "rtc_base/experiments/normalize_simulcast_size_experiment.h"
#include "rtc_base/experiments/rate_control_settings.h"
@ -61,7 +62,7 @@ struct SimulcastFormat {
int width;
int height;
// The maximum number of simulcast layers can be used for
// resolutions at |widthxheigh| for legacy applications.
// resolutions at |widthxheight| for legacy applications.
size_t max_layers;
// The maximum bitrate for encoding stream at |widthxheight|, when we are
// not sending the next higher spatial stream.
@ -162,7 +163,10 @@ int NormalizeSimulcastSize(int size, size_t simulcast_layers) {
return ((size >> base2_exponent) << base2_exponent);
}
SimulcastFormat InterpolateSimulcastFormat(int width, int height) {
SimulcastFormat InterpolateSimulcastFormat(
int width,
int height,
absl::optional<double> max_roundup_rate) {
const int index = FindSimulcastFormatIndex(width, height);
if (index == 0)
return kSimulcastFormats[index];
@ -174,7 +178,10 @@ SimulcastFormat InterpolateSimulcastFormat(int width, int height) {
const float rate = (total_pixels_up - total_pixels) /
static_cast<float>(total_pixels_up - total_pixels_down);
size_t max_layers = kSimulcastFormats[index].max_layers;
// Use upper resolution if |rate| is below the configured threshold.
size_t max_layers = (max_roundup_rate && rate < max_roundup_rate.value())
? kSimulcastFormats[index - 1].max_layers
: kSimulcastFormats[index].max_layers;
webrtc::DataRate max_bitrate =
Interpolate(kSimulcastFormats[index - 1].max_bitrate,
kSimulcastFormats[index].max_bitrate, rate);
@ -188,6 +195,10 @@ SimulcastFormat InterpolateSimulcastFormat(int width, int height) {
return {width, height, max_layers, max_bitrate, target_bitrate, min_bitrate};
}
SimulcastFormat InterpolateSimulcastFormat(int width, int height) {
return InterpolateSimulcastFormat(width, height, absl::nullopt);
}
webrtc::DataRate FindSimulcastMaxBitrate(int width, int height) {
return InterpolateSimulcastFormat(width, height).max_bitrate;
}
@ -235,9 +246,18 @@ size_t LimitSimulcastLayerCount(int width,
const webrtc::WebRtcKeyValueConfig& trials) {
if (!absl::StartsWith(trials.Lookup(kUseLegacySimulcastLayerLimitFieldTrial),
"Disabled")) {
// Max layers from one higher resolution in kSimulcastFormats will be used
// if the ratio (pixels_up - pixels) / (pixels_up - pixels_down) is less
// than configured |max_ratio|. pixels_down is the selected index in
// kSimulcastFormats based on pixels.
webrtc::FieldTrialOptional<double> max_ratio("max_ratio");
webrtc::ParseFieldTrial({&max_ratio},
trials.Lookup("WebRTC-SimulcastLayerLimitRoundUp"));
size_t adaptive_layer_count = std::max(
need_layers,
kSimulcastFormats[FindSimulcastFormatIndex(width, height)].max_layers);
InterpolateSimulcastFormat(width, height, max_ratio.GetOptional())
.max_layers);
if (layer_count > adaptive_layer_count) {
RTC_LOG(LS_WARNING) << "Reducing simulcast layer count from "
<< layer_count << " to " << adaptive_layer_count;

View File

@ -378,4 +378,66 @@ TEST(SimulcastTest, BitratesForCloseToStandardResolution) {
}
}
TEST(SimulcastTest, MaxLayers) {
FieldTrialBasedConfig trials;
const size_t kMinLayers = 1;
const int kMaxLayers = 3;
std::vector<VideoStream> streams;
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(3u, streams.size());
// <960x540: 2 layers
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 539,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(2u, streams.size());
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(2u, streams.size());
// <480x270: 1 layer
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 269,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(1u, streams.size());
}
TEST(SimulcastTest, MaxLayersWithFieldTrial) {
test::ScopedFieldTrials field_trials(
"WebRTC-SimulcastLayerLimitRoundUp/max_ratio:0.1/");
FieldTrialBasedConfig trials;
const size_t kMinLayers = 1;
const int kMaxLayers = 3;
std::vector<VideoStream> streams;
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(3u, streams.size());
// Lowest cropped height where max layers from higher resolution is used.
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 512,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(3u, streams.size());
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 510,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(2u, streams.size());
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(2u, streams.size());
// Lowest cropped height where max layers from higher resolution is used.
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 256,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(2u, streams.size());
streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 254,
kBitratePriority, kQpMax, !kScreenshare,
true, trials);
EXPECT_EQ(1u, streams.size());
}
} // namespace webrtc