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:
parent
5cf0ef0022
commit
29bd8638ad
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user