diff --git a/rtc_base/experiments/balanced_degradation_settings.cc b/rtc_base/experiments/balanced_degradation_settings.cc index 3afbc3f531..7a1e8913cc 100644 --- a/rtc_base/experiments/balanced_degradation_settings.cc +++ b/rtc_base/experiments/balanced_degradation_settings.cc @@ -29,31 +29,31 @@ std::vector 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::max() : framerate; } + +absl::optional GetKbps( + VideoCodecType type, + const absl::optional& config) { + if (!config.has_value()) + return absl::nullopt; + + absl::optional 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(config->kbps) : absl::nullopt; +} + +absl::optional GetKbpsRes( + VideoCodecType type, + const absl::optional& config) { + if (!config.has_value()) + return absl::nullopt; + + absl::optional 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(config->kbps_res) + : absl::nullopt; +} } // namespace absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetQpLow() @@ -231,6 +298,16 @@ absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetFps() return (fps > 0) ? absl::optional(fps) : absl::nullopt; } +absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetKbps() + const { + return (kbps > 0) ? absl::optional(kbps) : absl::nullopt; +} + +absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetKbpsRes() + const { + return (kbps_res > 0) ? absl::optional(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 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(configs_[i + 1].kbps) - : absl::nullopt; - } - } - return absl::nullopt; -} - -absl::optional -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(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 next_layer_min_kbps = NextHigherBitrateKbps(pixels); - if (!next_layer_min_kbps.has_value() || bitrate_bps == 0) { + absl::optional 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(next_layer_min_kbps.value() * 1000); + return bitrate_bps >= static_cast(min_kbps.value() * 1000); } bool BalancedDegradationSettings::CanAdaptUpResolution( + VideoCodecType type, int pixels, uint32_t bitrate_bps) const { - absl::optional next_layer_min_kbps = - ResolutionNextHigherBitrateKbps(pixels); - if (!next_layer_min_kbps.has_value() || bitrate_bps == 0) { + absl::optional 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(next_layer_min_kbps.value() * 1000); + return bitrate_bps >= static_cast(min_kbps.value() * 1000); } absl::optional BalancedDegradationSettings::MinFpsDiff(int pixels) const { diff --git a/rtc_base/experiments/balanced_degradation_settings.h b/rtc_base/experiments/balanced_degradation_settings.h index 8b5dbdabba..788893af94 100644 --- a/rtc_base/experiments/balanced_degradation_settings.h +++ b/rtc_base/experiments/balanced_degradation_settings.h @@ -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 GetQpLow() const; absl::optional GetQpHigh() const; absl::optional GetFps() const; + absl::optional GetKbps() const; + absl::optional 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 NextHigherBitrateKbps(int pixels) const; - absl::optional 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 MinFpsDiff(int pixels) const; diff --git a/rtc_base/experiments/balanced_degradation_settings_unittest.cc b/rtc_base/experiments/balanced_degradation_settings_unittest.cc index 591476b96d..5721445ee4 100644 --- a/rtc_base/experiments/balanced_degradation_settings_unittest.cc +++ b/rtc_base/experiments/balanced_degradation_settings_unittest.cc @@ -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) { diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc index 2e840380c6..afb4d6fb84 100644 --- a/video/overuse_frame_detector_resource_adaptation_module.cc +++ b/video/overuse_frame_detector_resource_adaptation_module.cc @@ -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.