BalancedDegradationSettings: add codec specific min bitrate settings.

Bug: none
Change-Id: I7875a3c8499c883ffecad519063c0eb82a8a7073
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/165341
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30192}
This commit is contained in:
Åsa Persson 2020-01-09 10:04:53 +01:00 committed by Commit Bot
parent bcbdeedd43
commit f5e71e46dc
4 changed files with 306 additions and 204 deletions

View File

@ -29,31 +29,31 @@ std::vector<BalancedDegradationSettings::Config> DefaultConfigs() {
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
{480 * 270,
10,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
{640 * 480,
15,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}}};
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}}};
}
bool IsValidConfig(
@ -214,6 +214,73 @@ int GetFps(VideoCodecType type,
return (framerate == kMaxFps) ? std::numeric_limits<int>::max() : framerate;
}
absl::optional<int> GetKbps(
VideoCodecType type,
const absl::optional<BalancedDegradationSettings::Config>& config) {
if (!config.has_value())
return absl::nullopt;
absl::optional<int> kbps;
switch (type) {
case kVideoCodecVP8:
kbps = config->vp8.GetKbps();
break;
case kVideoCodecVP9:
kbps = config->vp9.GetKbps();
break;
case kVideoCodecH264:
kbps = config->h264.GetKbps();
break;
case kVideoCodecAV1:
kbps = config->av1.GetKbps();
break;
case kVideoCodecGeneric:
kbps = config->generic.GetKbps();
break;
default:
break;
}
if (kbps.has_value())
return kbps;
return config->kbps > 0 ? absl::optional<int>(config->kbps) : absl::nullopt;
}
absl::optional<int> GetKbpsRes(
VideoCodecType type,
const absl::optional<BalancedDegradationSettings::Config>& config) {
if (!config.has_value())
return absl::nullopt;
absl::optional<int> kbps_res;
switch (type) {
case kVideoCodecVP8:
kbps_res = config->vp8.GetKbpsRes();
break;
case kVideoCodecVP9:
kbps_res = config->vp9.GetKbpsRes();
break;
case kVideoCodecH264:
kbps_res = config->h264.GetKbpsRes();
break;
case kVideoCodecAV1:
kbps_res = config->av1.GetKbpsRes();
break;
case kVideoCodecGeneric:
kbps_res = config->generic.GetKbpsRes();
break;
default:
break;
}
if (kbps_res.has_value())
return kbps_res;
return config->kbps_res > 0 ? absl::optional<int>(config->kbps_res)
: absl::nullopt;
}
} // namespace
absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpLow()
@ -231,6 +298,16 @@ absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetFps()
return (fps > 0) ? absl::optional<int>(fps) : absl::nullopt;
}
absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbps()
const {
return (kbps > 0) ? absl::optional<int>(kbps) : absl::nullopt;
}
absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbpsRes()
const {
return (kbps_res > 0) ? absl::optional<int>(kbps_res) : absl::nullopt;
}
BalancedDegradationSettings::Config::Config() = default;
BalancedDegradationSettings::Config::Config(int pixels,
@ -268,28 +345,48 @@ BalancedDegradationSettings::BalancedDegradationSettings() {
FieldTrialStructMember("vp8_qp_high",
[](Config* c) { return &c->vp8.qp_high; }),
FieldTrialStructMember("vp8_fps", [](Config* c) { return &c->vp8.fps; }),
FieldTrialStructMember("vp8_kbps",
[](Config* c) { return &c->vp8.kbps; }),
FieldTrialStructMember("vp8_kbps_res",
[](Config* c) { return &c->vp8.kbps_res; }),
FieldTrialStructMember("vp9_qp_low",
[](Config* c) { return &c->vp9.qp_low; }),
FieldTrialStructMember("vp9_qp_high",
[](Config* c) { return &c->vp9.qp_high; }),
FieldTrialStructMember("vp9_fps", [](Config* c) { return &c->vp9.fps; }),
FieldTrialStructMember("vp9_kbps",
[](Config* c) { return &c->vp9.kbps; }),
FieldTrialStructMember("vp9_kbps_res",
[](Config* c) { return &c->vp9.kbps_res; }),
FieldTrialStructMember("h264_qp_low",
[](Config* c) { return &c->h264.qp_low; }),
FieldTrialStructMember("h264_qp_high",
[](Config* c) { return &c->h264.qp_high; }),
FieldTrialStructMember("h264_fps",
[](Config* c) { return &c->h264.fps; }),
FieldTrialStructMember("h264_kbps",
[](Config* c) { return &c->h264.kbps; }),
FieldTrialStructMember("h264_kbps_res",
[](Config* c) { return &c->h264.kbps_res; }),
FieldTrialStructMember("av1_qp_low",
[](Config* c) { return &c->av1.qp_low; }),
FieldTrialStructMember("av1_qp_high",
[](Config* c) { return &c->av1.qp_high; }),
FieldTrialStructMember("av1_fps", [](Config* c) { return &c->av1.fps; }),
FieldTrialStructMember("av1_kbps",
[](Config* c) { return &c->av1.kbps; }),
FieldTrialStructMember("av1_kbps_res",
[](Config* c) { return &c->av1.kbps_res; }),
FieldTrialStructMember("generic_qp_low",
[](Config* c) { return &c->generic.qp_low; }),
FieldTrialStructMember("generic_qp_high",
[](Config* c) { return &c->generic.qp_high; }),
FieldTrialStructMember("generic_fps",
[](Config* c) { return &c->generic.fps; })},
[](Config* c) { return &c->generic.fps; }),
FieldTrialStructMember("generic_kbps",
[](Config* c) { return &c->generic.kbps; }),
FieldTrialStructMember("generic_kbps_res",
[](Config* c) { return &c->generic.kbps_res; })},
{});
ParseFieldTrial({&configs}, field_trial::FindFullName(kFieldTrial));
@ -331,50 +428,25 @@ BalancedDegradationSettings::GetMaxFpsConfig(int pixels) const {
return absl::nullopt;
}
absl::optional<int> BalancedDegradationSettings::NextHigherBitrateKbps(
int pixels) const {
for (size_t i = 0; i < configs_.size() - 1; ++i) {
if (pixels <= configs_[i].pixels) {
return (configs_[i + 1].kbps > 0)
? absl::optional<int>(configs_[i + 1].kbps)
: absl::nullopt;
}
}
return absl::nullopt;
}
absl::optional<int>
BalancedDegradationSettings::ResolutionNextHigherBitrateKbps(int pixels) const {
for (size_t i = 0; i < configs_.size() - 1; ++i) {
if (pixels <= configs_[i].pixels) {
return (configs_[i + 1].kbps_res > 0)
? absl::optional<int>(configs_[i + 1].kbps_res)
: absl::nullopt;
}
}
return absl::nullopt;
}
bool BalancedDegradationSettings::CanAdaptUp(int pixels,
bool BalancedDegradationSettings::CanAdaptUp(VideoCodecType type,
int pixels,
uint32_t bitrate_bps) const {
absl::optional<int> next_layer_min_kbps = NextHigherBitrateKbps(pixels);
if (!next_layer_min_kbps.has_value() || bitrate_bps == 0) {
absl::optional<int> min_kbps = GetKbps(type, GetMaxFpsConfig(pixels));
if (!min_kbps.has_value() || bitrate_bps == 0) {
return true; // No limit configured or bitrate provided.
}
return bitrate_bps >=
static_cast<uint32_t>(next_layer_min_kbps.value() * 1000);
return bitrate_bps >= static_cast<uint32_t>(min_kbps.value() * 1000);
}
bool BalancedDegradationSettings::CanAdaptUpResolution(
VideoCodecType type,
int pixels,
uint32_t bitrate_bps) const {
absl::optional<int> next_layer_min_kbps =
ResolutionNextHigherBitrateKbps(pixels);
if (!next_layer_min_kbps.has_value() || bitrate_bps == 0) {
absl::optional<int> min_kbps = GetKbpsRes(type, GetMaxFpsConfig(pixels));
if (!min_kbps.has_value() || bitrate_bps == 0) {
return true; // No limit configured or bitrate provided.
}
return bitrate_bps >=
static_cast<uint32_t>(next_layer_min_kbps.value() * 1000);
return bitrate_bps >= static_cast<uint32_t>(min_kbps.value() * 1000);
}
absl::optional<int> BalancedDegradationSettings::MinFpsDiff(int pixels) const {

View File

@ -27,19 +27,30 @@ class BalancedDegradationSettings {
struct CodecTypeSpecific {
CodecTypeSpecific() {}
CodecTypeSpecific(int qp_low, int qp_high, int fps)
: qp_low(qp_low), qp_high(qp_high), fps(fps) {}
CodecTypeSpecific(int qp_low, int qp_high, int fps, int kbps, int kbps_res)
: qp_low(qp_low),
qp_high(qp_high),
fps(fps),
kbps(kbps),
kbps_res(kbps_res) {}
bool operator==(const CodecTypeSpecific& o) const {
return qp_low == o.qp_low && qp_high == o.qp_high && fps == o.fps;
return qp_low == o.qp_low && qp_high == o.qp_high && fps == o.fps &&
kbps == o.kbps && kbps_res == o.kbps_res;
}
absl::optional<int> GetQpLow() const;
absl::optional<int> GetQpHigh() const;
absl::optional<int> GetFps() const;
absl::optional<int> GetKbps() const;
absl::optional<int> GetKbpsRes() const;
// Optional settings.
int qp_low = 0;
int qp_high = 0;
int fps = 0;
int fps = 0; // If unset, defaults to |fps| in Config.
int kbps = 0; // If unset, defaults to |kbps| in Config.
int kbps_res = 0; // If unset, defaults to |kbps_res| in Config.
};
struct Config {
@ -62,6 +73,26 @@ class BalancedDegradationSettings {
generic == o.generic;
}
// Example:
// WebRTC-Video-BalancedDegradationSettings/pixels:100|200|300,fps:5|15|25/
// pixels <= 100 -> min framerate: 5 fps
// pixels <= 200 -> min framerate: 15 fps
// pixels <= 300 -> min framerate: 25 fps
//
// WebRTC-Video-BalancedDegradationSettings/pixels:100|200|300,
// fps:5|15|25, // Min framerate.
// kbps:0|60|70, // Min bitrate needed to adapt up.
// kbps_res:0|65|75/ // Min bitrate needed to adapt up in resolution.
//
// pixels: fps: kbps: kbps_res:
// 300 30 - -
// 300 25 70 kbps 75 kbps
// 200 25 70 kbps -
// 200 15 60 kbps 65 kbps
// 100 15 60 kbps -
// 100 5
// optional optional
int pixels = 0; // Video frame size.
// If the frame size is less than or equal to |pixels|:
int fps = 0; // Min framerate to be used.
@ -84,13 +115,11 @@ class BalancedDegradationSettings {
int MinFps(VideoCodecType type, int pixels) const;
int MaxFps(VideoCodecType type, int pixels) const;
// Gets the bitrate for the first resolution above |pixels|.
absl::optional<int> NextHigherBitrateKbps(int pixels) const;
absl::optional<int> ResolutionNextHigherBitrateKbps(int pixels) const;
// Checks if quality can be increased based on |pixels| and |bitrate_bps|.
bool CanAdaptUp(int pixels, uint32_t bitrate_bps) const;
bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const;
bool CanAdaptUp(VideoCodecType type, int pixels, uint32_t bitrate_bps) const;
bool CanAdaptUpResolution(VideoCodecType type,
int pixels,
uint32_t bitrate_bps) const;
// Gets the min framerate diff from |configs_| based on |pixels|.
absl::optional<int> MinFpsDiff(int pixels) const;

View File

@ -28,33 +28,33 @@ void VerifyIsDefault(
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
BalancedDegradationSettings::Config{
480 * 270,
10,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
BalancedDegradationSettings::Config{
640 * 480,
15,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}}));
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}}));
}
} // namespace
@ -62,10 +62,9 @@ TEST(BalancedDegradationSettings, GetsDefaultConfigIfNoList) {
webrtc::test::ScopedFieldTrials field_trials("");
BalancedDegradationSettings settings;
VerifyIsDefault(settings.GetConfigs());
EXPECT_FALSE(settings.NextHigherBitrateKbps(1));
EXPECT_FALSE(settings.ResolutionNextHigherBitrateKbps(1));
EXPECT_TRUE(settings.CanAdaptUp(1, /*bitrate_bps*/ 1));
EXPECT_TRUE(settings.CanAdaptUpResolution(1, /*bitrate_bps*/ 1));
EXPECT_TRUE(settings.CanAdaptUp(kVideoCodecVP8, 1, /*bitrate_bps*/ 1));
EXPECT_TRUE(
settings.CanAdaptUpResolution(kVideoCodecVP8, 1, /*bitrate_bps*/ 1));
EXPECT_FALSE(settings.MinFpsDiff(1));
EXPECT_FALSE(settings.GetQpThresholds(kVideoCodecVP8, 1));
EXPECT_FALSE(settings.GetQpThresholds(kVideoCodecVP9, 1));
@ -88,33 +87,33 @@ TEST(BalancedDegradationSettings, GetsConfig) {
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
BalancedDegradationSettings::Config{
22,
15,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}},
BalancedDegradationSettings::Config{
33,
25,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}}));
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}}));
}
TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroFpsValue) {
@ -155,33 +154,33 @@ TEST(BalancedDegradationSettings, GetsConfigWithSpecificFps) {
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 7},
{0, 0, 9},
{0, 0, 11},
{0, 0, 1},
{0, 0, 13}},
{0, 0, 7, 0, 0},
{0, 0, 9, 0, 0},
{0, 0, 11, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 13, 0, 0}},
BalancedDegradationSettings::Config{
2000,
15,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 8},
{0, 0, 10},
{0, 0, 12},
{0, 0, 2},
{0, 0, 14}},
{0, 0, 8, 0, 0},
{0, 0, 10, 0, 0},
{0, 0, 12, 0, 0},
{0, 0, 2, 0, 0},
{0, 0, 14, 0, 0}},
BalancedDegradationSettings::Config{
3000,
25,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 9},
{0, 0, 11},
{0, 0, 13},
{0, 0, 3},
{0, 0, 15}}));
{0, 0, 9, 0, 0},
{0, 0, 11, 0, 0},
{0, 0, 13, 0, 0},
{0, 0, 3, 0, 0},
{0, 0, 15, 0, 0}}));
}
TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroVp8FpsValue) {
@ -307,7 +306,12 @@ TEST(BalancedDegradationSettings, GetsUnlimitedForMaxValidFps) {
TEST(BalancedDegradationSettings, GetsConfigWithBitrate) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:11|22|33,fps:5|15|25,kbps:44|88|99,kbps_res:55|111|222/");
"pixels:11|22|33,fps:5|15|25,kbps:44|88|99,kbps_res:55|111|222,"
"vp8_kbps:11|12|13,vp8_kbps_res:14|15|16,"
"vp9_kbps:21|22|23,vp9_kbps_res:24|25|26,"
"h264_kbps:31|32|33,h264_kbps_res:34|35|36,"
"av1_kbps:41|42|43,av1_kbps_res:44|45|46,"
"generic_kbps:51|52|53,generic_kbps_res:54|55|56/");
BalancedDegradationSettings settings;
EXPECT_THAT(settings.GetConfigs(),
::testing::ElementsAre(
@ -317,33 +321,33 @@ TEST(BalancedDegradationSettings, GetsConfigWithBitrate) {
44,
55,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 11, 14},
{0, 0, 0, 21, 24},
{0, 0, 0, 31, 34},
{0, 0, 0, 41, 44},
{0, 0, 0, 51, 54}},
BalancedDegradationSettings::Config{
22,
15,
88,
111,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
{0, 0, 0, 12, 15},
{0, 0, 0, 22, 25},
{0, 0, 0, 32, 35},
{0, 0, 0, 42, 45},
{0, 0, 0, 52, 55}},
BalancedDegradationSettings::Config{
33,
25,
99,
222,
BalancedDegradationSettings::kNoFpsDiff,
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}}));
{0, 0, 0, 13, 16},
{0, 0, 0, 23, 26},
{0, 0, 0, 33, 36},
{0, 0, 0, 43, 46},
{0, 0, 0, 53, 56}}));
}
TEST(BalancedDegradationSettings, GetsDefaultConfigIfBitrateDecreases) {
@ -363,82 +367,77 @@ TEST(BalancedDegradationSettings,
VerifyIsDefault(settings.GetConfigs());
}
TEST(BalancedDegradationSettings, GetsNextHigherBitrate) {
TEST(BalancedDegradationSettings, CanAdaptUp) {
VideoCodecType vp8 = kVideoCodecVP8;
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000,fps:5|15|25,kbps:44|88|99/");
BalancedDegradationSettings settings;
EXPECT_EQ(88, settings.NextHigherBitrateKbps(1));
EXPECT_EQ(88, settings.NextHigherBitrateKbps(1000));
EXPECT_EQ(99, settings.NextHigherBitrateKbps(1001));
EXPECT_EQ(99, settings.NextHigherBitrateKbps(2000));
EXPECT_FALSE(settings.NextHigherBitrateKbps(2001));
"pixels:1000|2000|3000|4000,fps:5|15|25|30,kbps:0|80|0|90,"
"vp9_kbps:40|50|60|70/");
BalancedDegradationSettings s;
EXPECT_TRUE(s.CanAdaptUp(vp8, 1000, 0)); // No bitrate provided.
EXPECT_FALSE(s.CanAdaptUp(vp8, 1000, 79000));
EXPECT_TRUE(s.CanAdaptUp(vp8, 1000, 80000));
EXPECT_TRUE(s.CanAdaptUp(vp8, 1001, 1)); // No limit configured.
EXPECT_FALSE(s.CanAdaptUp(vp8, 3000, 89000));
EXPECT_TRUE(s.CanAdaptUp(vp8, 3000, 90000));
EXPECT_TRUE(s.CanAdaptUp(vp8, 3001, 1)); // No limit.
}
TEST(BalancedDegradationSettings, GetsNextHigherBitrateWithUnsetValue) {
TEST(BalancedDegradationSettings, CanAdaptUpWithCodecType) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000,fps:5|15|25,kbps:10|0|20/");
BalancedDegradationSettings settings;
EXPECT_FALSE(settings.NextHigherBitrateKbps(1));
EXPECT_FALSE(settings.NextHigherBitrateKbps(1000));
EXPECT_EQ(20, settings.NextHigherBitrateKbps(1001));
EXPECT_EQ(20, settings.NextHigherBitrateKbps(2000));
EXPECT_FALSE(settings.NextHigherBitrateKbps(2001));
"pixels:1000|2000|3000|4000,fps:5|15|25|30,vp8_kbps:0|30|40|50,"
"vp9_kbps:0|60|70|80,h264_kbps:0|55|65|75,av1_kbps:0|77|88|99,"
"generic_kbps:0|25|35|45/");
BalancedDegradationSettings s;
EXPECT_FALSE(s.CanAdaptUp(kVideoCodecVP8, 1000, 29000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecVP8, 1000, 30000));
EXPECT_FALSE(s.CanAdaptUp(kVideoCodecVP9, 1000, 59000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecVP9, 1000, 60000));
EXPECT_FALSE(s.CanAdaptUp(kVideoCodecH264, 1000, 54000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecH264, 1000, 55000));
EXPECT_FALSE(s.CanAdaptUp(kVideoCodecAV1, 1000, 76000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecAV1, 1000, 77000));
EXPECT_FALSE(s.CanAdaptUp(kVideoCodecGeneric, 1000, 24000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecGeneric, 1000, 25000));
EXPECT_TRUE(s.CanAdaptUp(kVideoCodecMultiplex, 1000, 1)); // Not configured.
}
TEST(BalancedDegradationSettings, CanAdaptUpIfBitrateGeNextHigherKbpsLimit) {
TEST(BalancedDegradationSettings, CanAdaptUpResolution) {
VideoCodecType vp8 = kVideoCodecVP8;
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000|4000,fps:5|15|25|30,kbps:0|80|0|90/");
BalancedDegradationSettings settings;
EXPECT_TRUE(settings.CanAdaptUp(1000, 0)); // No bitrate provided.
EXPECT_FALSE(settings.CanAdaptUp(1000, 79000));
EXPECT_TRUE(settings.CanAdaptUp(1000, 80000));
EXPECT_TRUE(settings.CanAdaptUp(1001, 1)); // No limit configured.
EXPECT_FALSE(settings.CanAdaptUp(3000, 89000));
EXPECT_TRUE(settings.CanAdaptUp(3000, 90000));
EXPECT_TRUE(settings.CanAdaptUp(3001, 1)); // No limit.
"pixels:1000|2000|3000|4000,fps:5|15|25|30,kbps_res:0|80|0|90,"
"vp9_kbps_res:40|50|60|70/");
BalancedDegradationSettings s;
EXPECT_TRUE(s.CanAdaptUpResolution(vp8, 1000, 0)); // No bitrate provided.
EXPECT_FALSE(s.CanAdaptUpResolution(vp8, 1000, 79000));
EXPECT_TRUE(s.CanAdaptUpResolution(vp8, 1000, 80000));
EXPECT_TRUE(s.CanAdaptUpResolution(vp8, 1001, 1)); // No limit configured.
EXPECT_FALSE(s.CanAdaptUpResolution(vp8, 3000, 89000));
EXPECT_TRUE(s.CanAdaptUpResolution(vp8, 3000, 90000));
EXPECT_TRUE(s.CanAdaptUpResolution(vp8, 3001, 1)); // No limit.
}
TEST(BalancedDegradationSettings, GetsResolutionNextHigherBitrate) {
TEST(BalancedDegradationSettings, CanAdaptUpResolutionWithCodecType) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000,fps:5|15|25,kbps_res:44|88|99/");
BalancedDegradationSettings settings;
EXPECT_EQ(88, settings.ResolutionNextHigherBitrateKbps(1));
EXPECT_EQ(88, settings.ResolutionNextHigherBitrateKbps(1000));
EXPECT_EQ(99, settings.ResolutionNextHigherBitrateKbps(1001));
EXPECT_EQ(99, settings.ResolutionNextHigherBitrateKbps(2000));
EXPECT_FALSE(settings.ResolutionNextHigherBitrateKbps(2001));
}
TEST(BalancedDegradationSettings,
GetsResolutionNextHigherBitrateWithUnsetValue) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000,fps:5|15|25,kbps_res:10|0|20/");
BalancedDegradationSettings settings;
EXPECT_FALSE(settings.ResolutionNextHigherBitrateKbps(1));
EXPECT_FALSE(settings.ResolutionNextHigherBitrateKbps(1000));
EXPECT_EQ(20, settings.ResolutionNextHigherBitrateKbps(1001));
EXPECT_EQ(20, settings.ResolutionNextHigherBitrateKbps(2000));
EXPECT_FALSE(settings.ResolutionNextHigherBitrateKbps(2001));
}
TEST(BalancedDegradationSettings,
CanAdaptUpResolutionIfBitrateGeNextHigherKbpsLimit) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-Video-BalancedDegradationSettings/"
"pixels:1000|2000|3000|4000,fps:5|15|25|30,kbps_res:0|80|0|90/");
BalancedDegradationSettings settings;
EXPECT_TRUE(settings.CanAdaptUpResolution(1000, 0)); // No bitrate provided.
EXPECT_FALSE(settings.CanAdaptUpResolution(1000, 79000));
EXPECT_TRUE(settings.CanAdaptUpResolution(1000, 80000));
EXPECT_TRUE(settings.CanAdaptUpResolution(1001, 1)); // No limit configured.
EXPECT_FALSE(settings.CanAdaptUpResolution(3000, 89000));
EXPECT_TRUE(settings.CanAdaptUpResolution(3000, 90000));
EXPECT_TRUE(settings.CanAdaptUpResolution(3001, 1)); // No limit.
"pixels:1000|2000|3000|4000,fps:5|15|25|30,vp8_kbps_res:0|30|40|50,"
"vp9_kbps_res:0|60|70|80,h264_kbps_res:0|55|65|75,"
"av1_kbps_res:0|77|88|99,generic_kbps_res:0|25|35|45/");
BalancedDegradationSettings s;
EXPECT_FALSE(s.CanAdaptUpResolution(kVideoCodecVP8, 1000, 29000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecVP8, 1000, 30000));
EXPECT_FALSE(s.CanAdaptUpResolution(kVideoCodecVP9, 1000, 59000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecVP9, 1000, 60000));
EXPECT_FALSE(s.CanAdaptUpResolution(kVideoCodecH264, 1000, 54000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecH264, 1000, 55000));
EXPECT_FALSE(s.CanAdaptUpResolution(kVideoCodecAV1, 1000, 76000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecAV1, 1000, 77000));
EXPECT_FALSE(s.CanAdaptUpResolution(kVideoCodecGeneric, 1000, 24000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecGeneric, 1000, 25000));
EXPECT_TRUE(s.CanAdaptUpResolution(kVideoCodecMultiplex, 1000,
1)); // Not configured.
}
TEST(BalancedDegradationSettings, GetsFpsDiff) {
@ -494,33 +493,33 @@ TEST(BalancedDegradationSettings, GetsConfigWithQpThresholds) {
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{89, 90, 0},
{27, 120, 0},
{12, 20, 0},
{2, 11, 0},
{7, 22, 0}},
{89, 90, 0, 0, 0},
{27, 120, 0, 0, 0},
{12, 20, 0, 0, 0},
{2, 11, 0, 0, 0},
{7, 22, 0, 0, 0}},
BalancedDegradationSettings::Config{
2000,
15,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{90, 91, 0},
{28, 130, 0},
{13, 30, 0},
{3, 33, 0},
{6, 23, 0}},
{90, 91, 0, 0, 0},
{28, 130, 0, 0, 0},
{13, 30, 0, 0, 0},
{3, 33, 0, 0, 0},
{6, 23, 0, 0, 0}},
BalancedDegradationSettings::Config{
3000,
25,
0,
0,
BalancedDegradationSettings::kNoFpsDiff,
{88, 92, 0},
{29, 140, 0},
{14, 40, 0},
{4, 44, 0},
{5, 24, 0}}));
{88, 92, 0, 0, 0},
{29, 140, 0, 0, 0},
{14, 40, 0, 0, 0},
{4, 44, 0, 0, 0},
{5, 24, 0, 0, 0}}));
}
TEST(BalancedDegradationSettings, GetsDefaultConfigIfOnlyHasLowThreshold) {

View File

@ -629,7 +629,8 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
case DegradationPreference::BALANCED: {
// Check if quality should be increased based on bitrate.
if (reason == kQuality &&
!balanced_settings_.CanAdaptUp(*last_frame_pixel_count_,
!balanced_settings_.CanAdaptUp(encoder_config_.codec_type,
*last_frame_pixel_count_,
encoder_start_bitrate_bps_)) {
return;
}
@ -649,7 +650,8 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
// Check if resolution should be increased based on bitrate.
if (reason == kQuality &&
!balanced_settings_.CanAdaptUpResolution(
*last_frame_pixel_count_, encoder_start_bitrate_bps_)) {
encoder_config_.codec_type, *last_frame_pixel_count_,
encoder_start_bitrate_bps_)) {
return;
}
// Scale up resolution.