From 48284b86d405ee6fdd236a9d1fbbc5b7ec2c821e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Mon, 8 Jul 2019 10:01:12 +0200 Subject: [PATCH] BalancedDegradationSettings: Add option to configure fps based on codec type. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: none Change-Id: I43b3d976b9400a0552fee80a6a65c215c71049ac Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144543 Reviewed-by: Sergey Silkin Commit-Queue: Åsa Persson Cr-Commit-Position: refs/heads/master@{#28503} --- .../balanced_degradation_settings.cc | 172 ++++++++++++------ .../balanced_degradation_settings.h | 47 ++--- .../balanced_degradation_settings_unittest.cc | 162 ++++++++++++++--- video/video_stream_encoder.cc | 6 +- 4 files changed, 281 insertions(+), 106 deletions(-) diff --git a/rtc_base/experiments/balanced_degradation_settings.cc b/rtc_base/experiments/balanced_degradation_settings.cc index a8d7d4d1ca..884a669382 100644 --- a/rtc_base/experiments/balanced_degradation_settings.cc +++ b/rtc_base/experiments/balanced_degradation_settings.cc @@ -23,22 +23,43 @@ constexpr int kMinFps = 1; constexpr int kMaxFps = 100; std::vector DefaultConfigs() { - return {{320 * 240, 7, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, - {480 * 270, 10, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, - {640 * 480, 15, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}; + return {{320 * 240, 7, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + {480 * 270, 10, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + {640 * 480, 15, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; } -bool IsValidThreshold( - const BalancedDegradationSettings::QpThreshold& threshold) { - if (threshold.GetLow().has_value() != threshold.GetHigh().has_value()) { - RTC_LOG(LS_WARNING) << "Neither or both values should be set."; +bool IsValidConfig( + const BalancedDegradationSettings::CodecTypeSpecific& config) { + if (config.GetQpLow().has_value() != config.GetQpHigh().has_value()) { + RTC_LOG(LS_WARNING) << "Neither or both thresholds should be set."; return false; } - if (threshold.GetLow().has_value() && threshold.GetHigh().has_value() && - threshold.GetLow().value() >= threshold.GetHigh().value()) { + if (config.GetQpLow().has_value() && config.GetQpHigh().has_value() && + config.GetQpLow().value() >= config.GetQpHigh().value()) { RTC_LOG(LS_WARNING) << "Invalid threshold value, low >= high threshold."; return false; } + if (config.GetFps().has_value() && (config.GetFps().value() < kMinFps || + config.GetFps().value() > kMaxFps)) { + RTC_LOG(LS_WARNING) << "Unsupported fps setting, value ignored."; + return false; + } + return true; +} + +bool IsValid(const BalancedDegradationSettings::CodecTypeSpecific& config1, + const BalancedDegradationSettings::CodecTypeSpecific& config2) { + bool both_or_none_set = ((config1.qp_low > 0) == (config2.qp_low > 0) && + (config1.qp_high > 0) == (config2.qp_high > 0) && + (config1.fps > 0) == (config2.fps > 0)); + if (!both_or_none_set) { + RTC_LOG(LS_WARNING) << "Invalid value, all/none should be set."; + return false; + } + if (config1.fps > 0 && config1.fps < config2.fps) { + RTC_LOG(LS_WARNING) << "Invalid fps/pixel value provided."; + return false; + } return true; } @@ -59,21 +80,16 @@ bool IsValid(const std::vector& configs) { RTC_LOG(LS_WARNING) << "Invalid fps/pixel value provided."; return false; } - if (((configs[i].vp8.low > 0) != (configs[i - 1].vp8.low > 0)) || - ((configs[i].vp9.low > 0) != (configs[i - 1].vp9.low > 0)) || - ((configs[i].h264.low > 0) != (configs[i - 1].h264.low > 0)) || - ((configs[i].generic.low > 0) != (configs[i - 1].generic.low > 0)) || - ((configs[i].vp8.high > 0) != (configs[i - 1].vp8.high > 0)) || - ((configs[i].vp9.high > 0) != (configs[i - 1].vp9.high > 0)) || - ((configs[i].h264.high > 0) != (configs[i - 1].h264.high > 0)) || - ((configs[i].generic.high > 0) != (configs[i - 1].generic.high > 0))) { - RTC_LOG(LS_WARNING) << "Invalid threshold value, all/none should be set."; + if (!IsValid(configs[i].vp8, configs[i - 1].vp8) || + !IsValid(configs[i].vp9, configs[i - 1].vp9) || + !IsValid(configs[i].h264, configs[i - 1].h264) || + !IsValid(configs[i].generic, configs[i - 1].generic)) { return false; } } for (const auto& config : configs) { - if (!IsValidThreshold(config.vp8) || !IsValidThreshold(config.vp9) || - !IsValidThreshold(config.h264) || !IsValidThreshold(config.generic)) { + if (!IsValidConfig(config.vp8) || !IsValidConfig(config.vp9) || + !IsValidConfig(config.h264) || !IsValidConfig(config.generic)) { return false; } } @@ -96,20 +112,20 @@ absl::optional GetThresholds( switch (type) { case kVideoCodecVP8: - low = config.vp8.GetLow(); - high = config.vp8.GetHigh(); + low = config.vp8.GetQpLow(); + high = config.vp8.GetQpHigh(); break; case kVideoCodecVP9: - low = config.vp9.GetLow(); - high = config.vp9.GetHigh(); + low = config.vp9.GetQpLow(); + high = config.vp9.GetQpHigh(); break; case kVideoCodecH264: - low = config.h264.GetLow(); - high = config.h264.GetHigh(); + low = config.h264.GetQpLow(); + high = config.h264.GetQpHigh(); break; case kVideoCodecGeneric: - low = config.generic.GetLow(); - high = config.generic.GetHigh(); + low = config.generic.GetQpLow(); + high = config.generic.GetQpHigh(); break; default: break; @@ -122,24 +138,58 @@ absl::optional GetThresholds( } return absl::nullopt; } + +int GetFps(VideoCodecType type, + const absl::optional& config) { + if (!config.has_value()) { + return std::numeric_limits::max(); + } + + absl::optional fps; + switch (type) { + case kVideoCodecVP8: + fps = config->vp8.GetFps(); + break; + case kVideoCodecVP9: + fps = config->vp9.GetFps(); + break; + case kVideoCodecH264: + fps = config->h264.GetFps(); + break; + case kVideoCodecGeneric: + fps = config->generic.GetFps(); + break; + default: + break; + } + + return fps.value_or(config->fps); +} } // namespace -absl::optional BalancedDegradationSettings::QpThreshold::GetLow() const { - return (low > 0) ? absl::optional(low) : absl::nullopt; +absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetQpLow() + const { + return (qp_low > 0) ? absl::optional(qp_low) : absl::nullopt; } -absl::optional BalancedDegradationSettings::QpThreshold::GetHigh() const { - return (high > 0) ? absl::optional(high) : absl::nullopt; +absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetQpHigh() + const { + return (qp_high > 0) ? absl::optional(qp_high) : absl::nullopt; +} + +absl::optional BalancedDegradationSettings::CodecTypeSpecific::GetFps() + const { + return (fps > 0) ? absl::optional(fps) : absl::nullopt; } BalancedDegradationSettings::Config::Config() = default; BalancedDegradationSettings::Config::Config(int pixels, int fps, - QpThreshold vp8, - QpThreshold vp9, - QpThreshold h264, - QpThreshold generic) + CodecTypeSpecific vp8, + CodecTypeSpecific vp9, + CodecTypeSpecific h264, + CodecTypeSpecific generic) : pixels(pixels), fps(fps), vp8(vp8), @@ -152,21 +202,27 @@ BalancedDegradationSettings::BalancedDegradationSettings() { {FieldTrialStructMember("pixels", [](Config* c) { return &c->pixels; }), FieldTrialStructMember("fps", [](Config* c) { return &c->fps; }), FieldTrialStructMember("vp8_qp_low", - [](Config* c) { return &c->vp8.low; }), + [](Config* c) { return &c->vp8.qp_low; }), FieldTrialStructMember("vp8_qp_high", - [](Config* c) { return &c->vp8.high; }), + [](Config* c) { return &c->vp8.qp_high; }), + FieldTrialStructMember("vp8_fps", [](Config* c) { return &c->vp8.fps; }), FieldTrialStructMember("vp9_qp_low", - [](Config* c) { return &c->vp9.low; }), + [](Config* c) { return &c->vp9.qp_low; }), FieldTrialStructMember("vp9_qp_high", - [](Config* c) { return &c->vp9.high; }), + [](Config* c) { return &c->vp9.qp_high; }), + FieldTrialStructMember("vp9_fps", [](Config* c) { return &c->vp9.fps; }), FieldTrialStructMember("h264_qp_low", - [](Config* c) { return &c->h264.low; }), + [](Config* c) { return &c->h264.qp_low; }), FieldTrialStructMember("h264_qp_high", - [](Config* c) { return &c->h264.high; }), + [](Config* c) { return &c->h264.qp_high; }), + FieldTrialStructMember("h264_fps", + [](Config* c) { return &c->h264.fps; }), FieldTrialStructMember("generic_qp_low", - [](Config* c) { return &c->generic.low; }), + [](Config* c) { return &c->generic.qp_low; }), FieldTrialStructMember("generic_qp_high", - [](Config* c) { return &c->generic.high; })}, + [](Config* c) { return &c->generic.qp_high; }), + FieldTrialStructMember("generic_fps", + [](Config* c) { return &c->generic.fps; })}, {}); ParseFieldTrial({&configs}, field_trial::FindFullName(kFieldTrial)); @@ -182,20 +238,30 @@ BalancedDegradationSettings::GetConfigs() const { return configs_; } -int BalancedDegradationSettings::MinFps(int pixels) const { - for (const auto& config : configs_) { - if (pixels <= config.pixels) - return config.fps; - } - return std::numeric_limits::max(); +int BalancedDegradationSettings::MinFps(VideoCodecType type, int pixels) const { + return GetFps(type, GetMinFpsConfig(pixels)); } -int BalancedDegradationSettings::MaxFps(int pixels) const { +absl::optional +BalancedDegradationSettings::GetMinFpsConfig(int pixels) const { + for (const auto& config : configs_) { + if (pixels <= config.pixels) + return config; + } + return absl::nullopt; +} + +int BalancedDegradationSettings::MaxFps(VideoCodecType type, int pixels) const { + return GetFps(type, GetMaxFpsConfig(pixels)); +} + +absl::optional +BalancedDegradationSettings::GetMaxFpsConfig(int pixels) const { for (size_t i = 0; i < configs_.size() - 1; ++i) { if (pixels <= configs_[i].pixels) - return configs_[i + 1].fps; + return configs_[i + 1]; } - return std::numeric_limits::max(); + return absl::nullopt; } absl::optional diff --git a/rtc_base/experiments/balanced_degradation_settings.h b/rtc_base/experiments/balanced_degradation_settings.h index ef4b5879df..448dea602d 100644 --- a/rtc_base/experiments/balanced_degradation_settings.h +++ b/rtc_base/experiments/balanced_degradation_settings.h @@ -23,48 +23,51 @@ class BalancedDegradationSettings { BalancedDegradationSettings(); ~BalancedDegradationSettings(); - struct QpThreshold { - QpThreshold() {} - QpThreshold(int low, int high) : low(low), high(high) {} + struct CodecTypeSpecific { + CodecTypeSpecific() {} + CodecTypeSpecific(int qp_low, int qp_high, int fps) + : qp_low(qp_low), qp_high(qp_high), fps(fps) {} - bool operator==(const QpThreshold& o) const { - return low == o.low && high == o.high; + bool operator==(const CodecTypeSpecific& o) const { + return qp_low == o.qp_low && qp_high == o.qp_high && fps == o.fps; } - absl::optional GetLow() const; - absl::optional GetHigh() const; - int low = 0; - int high = 0; + absl::optional GetQpLow() const; + absl::optional GetQpHigh() const; + absl::optional GetFps() const; + int qp_low = 0; + int qp_high = 0; + int fps = 0; }; struct Config { Config(); Config(int pixels, int fps, - QpThreshold vp8, - QpThreshold vp9, - QpThreshold h264, - QpThreshold generic); + CodecTypeSpecific vp8, + CodecTypeSpecific vp9, + CodecTypeSpecific h264, + CodecTypeSpecific generic); bool operator==(const Config& o) const { return pixels == o.pixels && fps == o.fps && vp8 == o.vp8 && vp9 == o.vp9 && h264 == o.h264 && generic == o.generic; } - int pixels = 0; // The video frame size. - int fps = 0; // The framerate and thresholds to be used if the frame - QpThreshold vp8; // size is less than or equal to |pixels|. - QpThreshold vp9; - QpThreshold h264; - QpThreshold generic; + int pixels = 0; // The video frame size. + int fps = 0; // The framerate and thresholds to be used if the + CodecTypeSpecific vp8; // frame size is less than or equal to |pixels|. + CodecTypeSpecific vp9; + CodecTypeSpecific h264; + CodecTypeSpecific generic; }; // Returns configurations from field trial on success (default on failure). std::vector GetConfigs() const; // Gets the min/max framerate from |configs_| based on |pixels|. - int MinFps(int pixels) const; - int MaxFps(int pixels) const; + int MinFps(VideoCodecType type, int pixels) const; + int MaxFps(VideoCodecType type, int pixels) const; // Gets QpThresholds for the codec |type| based on |pixels|. absl::optional GetQpThresholds( @@ -72,6 +75,8 @@ class BalancedDegradationSettings { int pixels) const; private: + absl::optional GetMinFpsConfig(int pixels) const; + absl::optional GetMaxFpsConfig(int pixels) const; Config GetConfig(int pixels) const; std::vector configs_; diff --git a/rtc_base/experiments/balanced_degradation_settings_unittest.cc b/rtc_base/experiments/balanced_degradation_settings_unittest.cc index 8cbadacf90..c604b554f0 100644 --- a/rtc_base/experiments/balanced_degradation_settings_unittest.cc +++ b/rtc_base/experiments/balanced_degradation_settings_unittest.cc @@ -21,13 +21,15 @@ namespace { void VerifyIsDefault( const std::vector& config) { - EXPECT_THAT(config, ::testing::ElementsAre( - BalancedDegradationSettings::Config{ - 320 * 240, 7, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, - BalancedDegradationSettings::Config{ - 480 * 270, 10, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, - BalancedDegradationSettings::Config{ - 640 * 480, 15, {0, 0}, {0, 0}, {0, 0}, {0, 0}})); + EXPECT_THAT( + config, + ::testing::ElementsAre( + BalancedDegradationSettings::Config{ + 320 * 240, 7, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + BalancedDegradationSettings::Config{ + 480 * 270, 10, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + BalancedDegradationSettings::Config{ + 640 * 480, 15, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}})); } } // namespace @@ -50,11 +52,11 @@ TEST(BalancedDegradationSettings, GetsConfig) { EXPECT_THAT(settings.GetConfigs(), ::testing::ElementsAre( BalancedDegradationSettings::Config{ - 11, 5, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + 11, 5, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, BalancedDegradationSettings::Config{ - 22, 15, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + 22, 15, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, BalancedDegradationSettings::Config{ - 33, 25, {0, 0}, {0, 0}, {0, 0}, {0, 0}})); + 33, 25, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}})); } TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroFpsValue) { @@ -81,18 +83,75 @@ TEST(BalancedDegradationSettings, GetsDefaultConfigIfFramerateDecreases) { VerifyIsDefault(settings.GetConfigs()); } +TEST(BalancedDegradationSettings, GetsConfigWithSpecificFps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,vp8_fps:7|8|9,vp9_fps:9|10|11," + "h264_fps:11|12|13,generic_fps:13|14|15/"); + BalancedDegradationSettings settings; + EXPECT_THAT( + settings.GetConfigs(), + ::testing::ElementsAre( + BalancedDegradationSettings::Config{ + 1000, 5, {0, 0, 7}, {0, 0, 9}, {0, 0, 11}, {0, 0, 13}}, + BalancedDegradationSettings::Config{ + 2000, 15, {0, 0, 8}, {0, 0, 10}, {0, 0, 12}, {0, 0, 14}}, + BalancedDegradationSettings::Config{ + 3000, 25, {0, 0, 9}, {0, 0, 11}, {0, 0, 13}, {0, 0, 15}})); +} + +TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroVp8FpsValue) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:7|15|25,vp8_fps:0|15|25/"); + BalancedDegradationSettings settings; + VerifyIsDefault(settings.GetConfigs()); +} + +TEST(BalancedDegradationSettings, GetsDefaultConfigForInvalidFpsValue) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:7|15|25,vp8_fps:10|15|2000/"); + BalancedDegradationSettings settings; + VerifyIsDefault(settings.GetConfigs()); +} + +TEST(BalancedDegradationSettings, GetsDefaultConfigIfVp8FramerateDecreases) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:4|5|25,vp8_fps:5|4|25/"); + BalancedDegradationSettings settings; + VerifyIsDefault(settings.GetConfigs()); +} + TEST(BalancedDegradationSettings, GetsMinFps) { webrtc::test::ScopedFieldTrials field_trials( "WebRTC-Video-BalancedDegradationSettings/" "pixels:1000|2000|3000,fps:5|15|25/"); BalancedDegradationSettings settings; - EXPECT_EQ(5, settings.MinFps(1)); - EXPECT_EQ(5, settings.MinFps(1000)); - EXPECT_EQ(15, settings.MinFps(1000 + 1)); - EXPECT_EQ(15, settings.MinFps(2000)); - EXPECT_EQ(25, settings.MinFps(2000 + 1)); - EXPECT_EQ(25, settings.MinFps(3000)); - EXPECT_EQ(std::numeric_limits::max(), settings.MinFps(3000 + 1)); + EXPECT_EQ(5, settings.MinFps(kVideoCodecVP8, 1)); + EXPECT_EQ(5, settings.MinFps(kVideoCodecVP8, 1000)); + EXPECT_EQ(15, settings.MinFps(kVideoCodecVP8, 1001)); + EXPECT_EQ(15, settings.MinFps(kVideoCodecVP8, 2000)); + EXPECT_EQ(25, settings.MinFps(kVideoCodecVP8, 2001)); + EXPECT_EQ(25, settings.MinFps(kVideoCodecVP8, 3000)); + EXPECT_EQ(std::numeric_limits::max(), + settings.MinFps(kVideoCodecVP8, 3001)); +} + +TEST(BalancedDegradationSettings, GetsVp8MinFps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,vp8_fps:7|10|12/"); + BalancedDegradationSettings settings; + EXPECT_EQ(7, settings.MinFps(kVideoCodecVP8, 1)); + EXPECT_EQ(7, settings.MinFps(kVideoCodecVP8, 1000)); + EXPECT_EQ(10, settings.MinFps(kVideoCodecVP8, 1001)); + EXPECT_EQ(10, settings.MinFps(kVideoCodecVP8, 2000)); + EXPECT_EQ(12, settings.MinFps(kVideoCodecVP8, 2001)); + EXPECT_EQ(12, settings.MinFps(kVideoCodecVP8, 3000)); + EXPECT_EQ(std::numeric_limits::max(), + settings.MinFps(kVideoCodecVP8, 3001)); } TEST(BalancedDegradationSettings, GetsMaxFps) { @@ -100,11 +159,53 @@ TEST(BalancedDegradationSettings, GetsMaxFps) { "WebRTC-Video-BalancedDegradationSettings/" "pixels:1000|2000|3000,fps:5|15|25/"); BalancedDegradationSettings settings; - EXPECT_EQ(15, settings.MaxFps(1)); - EXPECT_EQ(15, settings.MaxFps(1000)); - EXPECT_EQ(25, settings.MaxFps(1000 + 1)); - EXPECT_EQ(25, settings.MaxFps(2000)); - EXPECT_EQ(std::numeric_limits::max(), settings.MaxFps(2000 + 1)); + EXPECT_EQ(15, settings.MaxFps(kVideoCodecVP8, 1)); + EXPECT_EQ(15, settings.MaxFps(kVideoCodecVP8, 1000)); + EXPECT_EQ(25, settings.MaxFps(kVideoCodecVP8, 1001)); + EXPECT_EQ(25, settings.MaxFps(kVideoCodecVP8, 2000)); + EXPECT_EQ(std::numeric_limits::max(), + settings.MaxFps(kVideoCodecVP8, 2001)); +} + +TEST(BalancedDegradationSettings, GetsVp8MaxFps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,vp8_fps:7|10|12/"); + BalancedDegradationSettings settings; + EXPECT_EQ(10, settings.MaxFps(kVideoCodecVP8, 1)); + EXPECT_EQ(10, settings.MaxFps(kVideoCodecVP8, 1000)); + EXPECT_EQ(12, settings.MaxFps(kVideoCodecVP8, 1001)); + EXPECT_EQ(12, settings.MaxFps(kVideoCodecVP8, 2000)); + EXPECT_EQ(std::numeric_limits::max(), + settings.MaxFps(kVideoCodecVP8, 2001)); +} + +TEST(BalancedDegradationSettings, GetsVp9Fps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,vp9_fps:7|10|12/"); + BalancedDegradationSettings settings; + EXPECT_EQ(7, settings.MinFps(kVideoCodecVP9, 1000)); + EXPECT_EQ(10, settings.MaxFps(kVideoCodecVP9, 1000)); +} + +TEST(BalancedDegradationSettings, GetsH264Fps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,h264_fps:8|11|13/"); + BalancedDegradationSettings settings; + EXPECT_EQ(11, settings.MinFps(kVideoCodecH264, 2000)); + EXPECT_EQ(13, settings.MaxFps(kVideoCodecH264, 2000)); +} + +TEST(BalancedDegradationSettings, GetsGenericFps) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-Video-BalancedDegradationSettings/" + "pixels:1000|2000|3000,fps:5|15|25,generic_fps:9|12|14/"); + BalancedDegradationSettings settings; + EXPECT_EQ(14, settings.MinFps(kVideoCodecGeneric, 3000)); + EXPECT_EQ(std::numeric_limits::max(), + settings.MaxFps(kVideoCodecGeneric, 3000)); } TEST(BalancedDegradationSettings, QpThresholdsNotSetByDefault) { @@ -126,14 +227,15 @@ TEST(BalancedDegradationSettings, GetsConfigWithQpThresholds) { "h264_qp_low:12|13|14,h264_qp_high:20|30|40,generic_qp_low:7|6|5," "generic_qp_high:22|23|24/"); BalancedDegradationSettings settings; - EXPECT_THAT(settings.GetConfigs(), - ::testing::ElementsAre( - BalancedDegradationSettings::Config{ - 1000, 5, {89, 90}, {27, 120}, {12, 20}, {7, 22}}, - BalancedDegradationSettings::Config{ - 2000, 15, {90, 91}, {28, 130}, {13, 30}, {6, 23}}, - BalancedDegradationSettings::Config{ - 3000, 25, {88, 92}, {29, 140}, {14, 40}, {5, 24}})); + EXPECT_THAT( + settings.GetConfigs(), + ::testing::ElementsAre( + BalancedDegradationSettings::Config{ + 1000, 5, {89, 90, 0}, {27, 120, 0}, {12, 20, 0}, {7, 22, 0}}, + BalancedDegradationSettings::Config{ + 2000, 15, {90, 91, 0}, {28, 130, 0}, {13, 30, 0}, {6, 23, 0}}, + BalancedDegradationSettings::Config{ + 3000, 25, {88, 92, 0}, {29, 140, 0}, {14, 40, 0}, {5, 24, 0}})); } TEST(BalancedDegradationSettings, GetsDefaultConfigIfOnlyHasLowThreshold) { diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 005d49b735..136164255f 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -1741,7 +1741,8 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) { switch (degradation_preference_) { case DegradationPreference::BALANCED: { // Try scale down framerate, if lower. - int fps = balanced_settings_.MinFps(last_frame_info_->pixel_count()); + int fps = balanced_settings_.MinFps(encoder_config_.codec_type, + last_frame_info_->pixel_count()); if (source_proxy_->RestrictFramerate(fps)) { GetAdaptCounter().IncrementFramerate(reason); break; @@ -1817,7 +1818,8 @@ void VideoStreamEncoder::AdaptUp(AdaptReason reason) { switch (degradation_preference_) { case DegradationPreference::BALANCED: { // Try scale up framerate, if higher. - int fps = balanced_settings_.MaxFps(last_frame_info_->pixel_count()); + int fps = balanced_settings_.MaxFps(encoder_config_.codec_type, + last_frame_info_->pixel_count()); if (source_proxy_->IncreaseFramerate(fps)) { GetAdaptCounter().DecrementFramerate(reason, fps); // Reset framerate in case of fewer fps steps down than up.