BalancedDegradationSettings: add option to configure a min framerate diff.
If a framerate reduction (input fps - restricted fps) is less than the configured diff, shorten interval to next qp check. Bug: none Change-Id: Ia0b9e0638e5ba75cdc20a1bb45bfcb7d858c5f89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149040 Commit-Queue: Åsa Persson <asapersson@webrtc.org> Reviewed-by: Magnus Flodman <mflodman@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28880}
This commit is contained in:
parent
df625f46c0
commit
f5e5d250bc
@ -96,7 +96,8 @@ QualityScaler::QualityScaler(rtc::TaskQueue* task_queue,
|
||||
.value_or(kSamplePeriodScaleFactor)),
|
||||
scale_factor_(
|
||||
QualityScalerSettings::ParseFromFieldTrials().ScaleFactor()),
|
||||
last_adapted_(false) {
|
||||
adapt_called_(false),
|
||||
adapt_failed_(false) {
|
||||
RTC_DCHECK_RUN_ON(&task_checker_);
|
||||
if (experiment_enabled_) {
|
||||
config_ = QualityScalingExperiment::GetConfig();
|
||||
@ -127,8 +128,12 @@ int64_t QualityScaler::GetSamplingPeriodMs() const {
|
||||
// Use half the interval while waiting for enough frames.
|
||||
return sampling_period_ms_ / 2;
|
||||
}
|
||||
if (scale_factor_ && !last_adapted_) {
|
||||
// Last check did not result in a AdaptDown/Up, possibly reduce interval.
|
||||
if (adapt_failed_) {
|
||||
// Check shortly again.
|
||||
return sampling_period_ms_ / 8;
|
||||
}
|
||||
if (scale_factor_ && !adapt_called_) {
|
||||
// Last CheckQp did not call AdaptDown/Up, possibly reduce interval.
|
||||
return sampling_period_ms_ * scale_factor_.value();
|
||||
}
|
||||
return sampling_period_ms_ * initial_scale_factor_;
|
||||
@ -165,7 +170,8 @@ void QualityScaler::CheckQp() {
|
||||
RTC_DCHECK_RUN_ON(&task_checker_);
|
||||
// Should be set through InitEncode -> Should be set by now.
|
||||
RTC_DCHECK_GE(thresholds_.low, 0);
|
||||
last_adapted_ = false;
|
||||
adapt_failed_ = false;
|
||||
adapt_called_ = false;
|
||||
|
||||
// If we have not observed at least this many frames we can't make a good
|
||||
// scaling decision.
|
||||
@ -215,18 +221,24 @@ void QualityScaler::ReportQpLow() {
|
||||
RTC_DCHECK_RUN_ON(&task_checker_);
|
||||
ClearSamples();
|
||||
observer_->AdaptUp(AdaptationObserverInterface::AdaptReason::kQuality);
|
||||
last_adapted_ = true;
|
||||
adapt_called_ = true;
|
||||
}
|
||||
|
||||
void QualityScaler::ReportQpHigh() {
|
||||
RTC_DCHECK_RUN_ON(&task_checker_);
|
||||
ClearSamples();
|
||||
observer_->AdaptDown(AdaptationObserverInterface::AdaptReason::kQuality);
|
||||
|
||||
if (observer_->AdaptDown(
|
||||
AdaptationObserverInterface::AdaptReason::kQuality)) {
|
||||
ClearSamples();
|
||||
} else {
|
||||
adapt_failed_ = true;
|
||||
}
|
||||
|
||||
// If we've scaled down, wait longer before scaling up again.
|
||||
if (fast_rampup_) {
|
||||
fast_rampup_ = false;
|
||||
}
|
||||
last_adapted_ = true;
|
||||
adapt_called_ = true;
|
||||
}
|
||||
|
||||
void QualityScaler::ClearSamples() {
|
||||
|
||||
@ -37,7 +37,9 @@ class AdaptationObserverInterface {
|
||||
// Called to signal that we can handle larger or more frequent frames.
|
||||
virtual void AdaptUp(AdaptReason reason) = 0;
|
||||
// Called to signal that the source should reduce the resolution or framerate.
|
||||
virtual void AdaptDown(AdaptReason reason) = 0;
|
||||
// Returns false if a downgrade was requested but the request did not result
|
||||
// in a new limiting resolution or fps.
|
||||
virtual bool AdaptDown(AdaptReason reason) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~AdaptationObserverInterface() {}
|
||||
@ -101,7 +103,8 @@ class QualityScaler {
|
||||
const size_t min_frames_needed_;
|
||||
const double initial_scale_factor_;
|
||||
const absl::optional<double> scale_factor_;
|
||||
bool last_adapted_ RTC_GUARDED_BY(&task_checker_);
|
||||
bool adapt_called_ RTC_GUARDED_BY(&task_checker_);
|
||||
bool adapt_failed_ RTC_GUARDED_BY(&task_checker_);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -36,9 +36,10 @@ class MockAdaptationObserver : public AdaptationObserverInterface {
|
||||
adapt_up_events_++;
|
||||
event.Set();
|
||||
}
|
||||
void AdaptDown(AdaptReason r) override {
|
||||
bool AdaptDown(AdaptReason r) override {
|
||||
adapt_down_events_++;
|
||||
event.Set();
|
||||
return true;
|
||||
}
|
||||
|
||||
rtc::Event event;
|
||||
|
||||
@ -24,9 +24,30 @@ constexpr int kMinFps = 1;
|
||||
constexpr int kMaxFps = 100; // 100 means unlimited fps.
|
||||
|
||||
std::vector<BalancedDegradationSettings::Config> DefaultConfigs() {
|
||||
return {{320 * 240, 7, 0, {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, 0}},
|
||||
{640 * 480, 15, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}};
|
||||
return {{320 * 240,
|
||||
7,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{480 * 270,
|
||||
10,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
{640 * 480,
|
||||
15,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}}};
|
||||
}
|
||||
|
||||
bool IsValidConfig(
|
||||
@ -200,6 +221,7 @@ BalancedDegradationSettings::Config::Config() = default;
|
||||
BalancedDegradationSettings::Config::Config(int pixels,
|
||||
int fps,
|
||||
int kbps,
|
||||
int fps_diff,
|
||||
CodecTypeSpecific vp8,
|
||||
CodecTypeSpecific vp9,
|
||||
CodecTypeSpecific h264,
|
||||
@ -207,6 +229,7 @@ BalancedDegradationSettings::Config::Config(int pixels,
|
||||
: pixels(pixels),
|
||||
fps(fps),
|
||||
kbps(kbps),
|
||||
fps_diff(fps_diff),
|
||||
vp8(vp8),
|
||||
vp9(vp9),
|
||||
h264(h264),
|
||||
@ -217,6 +240,8 @@ BalancedDegradationSettings::BalancedDegradationSettings() {
|
||||
{FieldTrialStructMember("pixels", [](Config* c) { return &c->pixels; }),
|
||||
FieldTrialStructMember("fps", [](Config* c) { return &c->fps; }),
|
||||
FieldTrialStructMember("kbps", [](Config* c) { return &c->kbps; }),
|
||||
FieldTrialStructMember("fps_diff",
|
||||
[](Config* c) { return &c->fps_diff; }),
|
||||
FieldTrialStructMember("vp8_qp_low",
|
||||
[](Config* c) { return &c->vp8.qp_low; }),
|
||||
FieldTrialStructMember("vp8_qp_high",
|
||||
@ -292,6 +317,17 @@ absl::optional<int> BalancedDegradationSettings::NextHigherBitrateKbps(
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<int> BalancedDegradationSettings::MinFpsDiff(int pixels) const {
|
||||
for (const auto& config : configs_) {
|
||||
if (pixels <= config.pixels) {
|
||||
return (config.fps_diff > kNoFpsDiff)
|
||||
? absl::optional<int>(config.fps_diff)
|
||||
: absl::nullopt;
|
||||
}
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<VideoEncoder::QpThresholds>
|
||||
BalancedDegradationSettings::GetQpThresholds(VideoCodecType type,
|
||||
int pixels) const {
|
||||
|
||||
@ -20,6 +20,8 @@ namespace webrtc {
|
||||
|
||||
class BalancedDegradationSettings {
|
||||
public:
|
||||
static constexpr int kNoFpsDiff = -100;
|
||||
|
||||
BalancedDegradationSettings();
|
||||
~BalancedDegradationSettings();
|
||||
|
||||
@ -45,6 +47,7 @@ class BalancedDegradationSettings {
|
||||
Config(int pixels,
|
||||
int fps,
|
||||
int kbps,
|
||||
int fps_diff,
|
||||
CodecTypeSpecific vp8,
|
||||
CodecTypeSpecific vp9,
|
||||
CodecTypeSpecific h264,
|
||||
@ -52,14 +55,17 @@ class BalancedDegradationSettings {
|
||||
|
||||
bool operator==(const Config& o) const {
|
||||
return pixels == o.pixels && fps == o.fps && kbps == o.kbps &&
|
||||
vp8 == o.vp8 && vp9 == o.vp9 && h264 == o.h264 &&
|
||||
generic == o.generic;
|
||||
fps_diff == o.fps_diff && vp8 == o.vp8 && vp9 == o.vp9 &&
|
||||
h264 == o.h264 && generic == o.generic;
|
||||
}
|
||||
|
||||
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.
|
||||
int kbps = 0; // Min bitrate needed to adapt up to this resolution.
|
||||
int fps_diff = kNoFpsDiff; // Min fps reduction needed (input fps - |fps|)
|
||||
// w/o triggering a new subsequent downgrade
|
||||
// check.
|
||||
CodecTypeSpecific vp8;
|
||||
CodecTypeSpecific vp9;
|
||||
CodecTypeSpecific h264;
|
||||
@ -76,6 +82,9 @@ class BalancedDegradationSettings {
|
||||
// Gets the bitrate for the first resolution above |pixels|.
|
||||
absl::optional<int> NextHigherBitrateKbps(int pixels) const;
|
||||
|
||||
// Gets the min framerate diff from |configs_| based on |pixels|.
|
||||
absl::optional<int> MinFpsDiff(int pixels) const;
|
||||
|
||||
// Gets QpThresholds for the codec |type| based on |pixels|.
|
||||
absl::optional<VideoEncoder::QpThresholds> GetQpThresholds(
|
||||
VideoCodecType type,
|
||||
|
||||
@ -21,15 +21,34 @@ namespace {
|
||||
|
||||
void VerifyIsDefault(
|
||||
const std::vector<BalancedDegradationSettings::Config>& config) {
|
||||
EXPECT_THAT(
|
||||
config,
|
||||
::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
320 * 240, 7, 0, {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, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
640 * 480, 15, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}));
|
||||
EXPECT_THAT(config, ::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
320 * 240,
|
||||
7,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
480 * 270,
|
||||
10,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
640 * 480,
|
||||
15,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}}));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@ -38,6 +57,7 @@ TEST(BalancedDegradationSettings, GetsDefaultConfigIfNoList) {
|
||||
BalancedDegradationSettings settings;
|
||||
VerifyIsDefault(settings.GetConfigs());
|
||||
EXPECT_FALSE(settings.NextHigherBitrateKbps(1));
|
||||
EXPECT_FALSE(settings.MinFpsDiff(1));
|
||||
EXPECT_FALSE(settings.GetQpThresholds(kVideoCodecVP8, 1));
|
||||
EXPECT_FALSE(settings.GetQpThresholds(kVideoCodecVP9, 1));
|
||||
EXPECT_FALSE(settings.GetQpThresholds(kVideoCodecH264, 1));
|
||||
@ -53,11 +73,32 @@ TEST(BalancedDegradationSettings, GetsConfig) {
|
||||
EXPECT_THAT(settings.GetConfigs(),
|
||||
::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
11, 5, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
11,
|
||||
5,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
22, 15, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
22,
|
||||
15,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
33, 25, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}));
|
||||
33,
|
||||
25,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}}));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroFpsValue) {
|
||||
@ -90,15 +131,35 @@ TEST(BalancedDegradationSettings, GetsConfigWithSpecificFps) {
|
||||
"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, 0, 7}, {0, 0, 9}, {0, 0, 11}, {0, 0, 13}},
|
||||
BalancedDegradationSettings::Config{
|
||||
2000, 15, 0, {0, 0, 8}, {0, 0, 10}, {0, 0, 12}, {0, 0, 14}},
|
||||
BalancedDegradationSettings::Config{
|
||||
3000, 25, 0, {0, 0, 9}, {0, 0, 11}, {0, 0, 13}, {0, 0, 15}}));
|
||||
EXPECT_THAT(settings.GetConfigs(),
|
||||
::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
1000,
|
||||
5,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 7},
|
||||
{0, 0, 9},
|
||||
{0, 0, 11},
|
||||
{0, 0, 13}},
|
||||
BalancedDegradationSettings::Config{
|
||||
2000,
|
||||
15,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 8},
|
||||
{0, 0, 10},
|
||||
{0, 0, 12},
|
||||
{0, 0, 14}},
|
||||
BalancedDegradationSettings::Config{
|
||||
3000,
|
||||
25,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 9},
|
||||
{0, 0, 11},
|
||||
{0, 0, 13},
|
||||
{0, 0, 15}}));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsDefaultConfigForZeroVp8FpsValue) {
|
||||
@ -229,11 +290,32 @@ TEST(BalancedDegradationSettings, GetsConfigWithBitrate) {
|
||||
EXPECT_THAT(settings.GetConfigs(),
|
||||
::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
11, 5, 44, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
11,
|
||||
5,
|
||||
44,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
22, 15, 88, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
22,
|
||||
15,
|
||||
88,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
33, 25, 99, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}));
|
||||
33,
|
||||
25,
|
||||
99,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}}));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsDefaultConfigIfBitrateDecreases) {
|
||||
@ -277,6 +359,31 @@ TEST(BalancedDegradationSettings, GetsNextHigherBitrateWithUnsetValue) {
|
||||
EXPECT_FALSE(settings.NextHigherBitrateKbps(2001));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsFpsDiff) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:1000|2000|3000,fps:5|15|25,fps_diff:0|-2|3/");
|
||||
BalancedDegradationSettings settings;
|
||||
EXPECT_EQ(0, settings.MinFpsDiff(1));
|
||||
EXPECT_EQ(0, settings.MinFpsDiff(1000));
|
||||
EXPECT_EQ(-2, settings.MinFpsDiff(1001));
|
||||
EXPECT_EQ(-2, settings.MinFpsDiff(2000));
|
||||
EXPECT_EQ(3, settings.MinFpsDiff(2001));
|
||||
EXPECT_EQ(3, settings.MinFpsDiff(3000));
|
||||
EXPECT_FALSE(settings.MinFpsDiff(3001));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsNoFpsDiffIfValueBelowMinSetting) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:1000|2000|3000,fps:5|15|25,fps_diff:-100|-99|-101/");
|
||||
// Min valid fps_diff setting: -99.
|
||||
BalancedDegradationSettings settings;
|
||||
EXPECT_FALSE(settings.MinFpsDiff(1000));
|
||||
EXPECT_EQ(-99, settings.MinFpsDiff(2000));
|
||||
EXPECT_FALSE(settings.MinFpsDiff(3000));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, QpThresholdsNotSetByDefault) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
@ -292,19 +399,39 @@ TEST(BalancedDegradationSettings, GetsConfigWithQpThresholds) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:1000|2000|3000,fps:5|15|25,vp8_qp_low:89|90|88,"
|
||||
"vp8_qp_high:90|91|92,vp9_qp_low:27|28|29,vp9_qp_high:82|83|84,"
|
||||
"vp8_qp_high:90|91|92,vp9_qp_low:27|28|29,vp9_qp_high:120|130|140,"
|
||||
"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, 0, {89, 90, 0}, {27, 82, 0}, {12, 20, 0}, {7, 22, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
2000, 15, 0, {90, 91, 0}, {28, 83, 0}, {13, 30, 0}, {6, 23, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
3000, 25, 0, {88, 92, 0}, {29, 84, 0}, {14, 40, 0}, {5, 24, 0}}));
|
||||
EXPECT_THAT(settings.GetConfigs(),
|
||||
::testing::ElementsAre(
|
||||
BalancedDegradationSettings::Config{
|
||||
1000,
|
||||
5,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{89, 90, 0},
|
||||
{27, 120, 0},
|
||||
{12, 20, 0},
|
||||
{7, 22, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
2000,
|
||||
15,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{90, 91, 0},
|
||||
{28, 130, 0},
|
||||
{13, 30, 0},
|
||||
{6, 23, 0}},
|
||||
BalancedDegradationSettings::Config{
|
||||
3000,
|
||||
25,
|
||||
0,
|
||||
BalancedDegradationSettings::kNoFpsDiff,
|
||||
{88, 92, 0},
|
||||
{29, 140, 0},
|
||||
{14, 40, 0},
|
||||
{5, 24, 0}}));
|
||||
}
|
||||
|
||||
TEST(BalancedDegradationSettings, GetsDefaultConfigIfOnlyHasLowThreshold) {
|
||||
|
||||
@ -42,7 +42,7 @@ class MockCpuOveruseObserver : public AdaptationObserverInterface {
|
||||
virtual ~MockCpuOveruseObserver() {}
|
||||
|
||||
MOCK_METHOD1(AdaptUp, void(AdaptReason));
|
||||
MOCK_METHOD1(AdaptDown, void(AdaptReason));
|
||||
MOCK_METHOD1(AdaptDown, bool(AdaptReason));
|
||||
};
|
||||
|
||||
class CpuOveruseObserverImpl : public AdaptationObserverInterface {
|
||||
@ -50,7 +50,10 @@ class CpuOveruseObserverImpl : public AdaptationObserverInterface {
|
||||
CpuOveruseObserverImpl() : overuse_(0), normaluse_(0) {}
|
||||
virtual ~CpuOveruseObserverImpl() {}
|
||||
|
||||
void AdaptDown(AdaptReason) { ++overuse_; }
|
||||
bool AdaptDown(AdaptReason) {
|
||||
++overuse_;
|
||||
return true;
|
||||
}
|
||||
void AdaptUp(AdaptReason) { ++normaluse_; }
|
||||
|
||||
int overuse_;
|
||||
|
||||
@ -1781,7 +1781,7 @@ bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
bool VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
AdaptationRequest adaptation_request = {
|
||||
last_frame_info_->pixel_count(),
|
||||
@ -1792,6 +1792,8 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
last_adaptation_request_ &&
|
||||
last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown;
|
||||
|
||||
bool did_adapt = true;
|
||||
|
||||
switch (degradation_preference_) {
|
||||
case DegradationPreference::BALANCED:
|
||||
break;
|
||||
@ -1801,7 +1803,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
last_adaptation_request_->input_pixel_count_) {
|
||||
// Don't request lower resolution if the current resolution is not
|
||||
// lower than the last time we asked for the resolution to be lowered.
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DegradationPreference::MAINTAIN_RESOLUTION:
|
||||
@ -1814,11 +1816,11 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
// we have to estimate, and can fluctuate naturally over time, don't
|
||||
// make the same kind of limitations as for resolution, but trust the
|
||||
// overuse detector to not trigger too often.
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DegradationPreference::DISABLED:
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (degradation_preference_) {
|
||||
@ -1828,6 +1830,15 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
last_frame_info_->pixel_count());
|
||||
if (source_proxy_->RestrictFramerate(fps)) {
|
||||
GetAdaptCounter().IncrementFramerate(reason);
|
||||
// Check if requested fps is higher (or close to) input fps.
|
||||
absl::optional<int> min_diff =
|
||||
balanced_settings_.MinFpsDiff(last_frame_info_->pixel_count());
|
||||
if (min_diff && adaptation_request.framerate_fps_ > 0) {
|
||||
int fps_diff = adaptation_request.framerate_fps_ - fps;
|
||||
if (fps_diff < min_diff.value()) {
|
||||
did_adapt = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Scale down resolution.
|
||||
@ -1842,7 +1853,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
&min_pixels_reached)) {
|
||||
if (min_pixels_reached)
|
||||
encoder_stats_observer_->OnMinPixelLimitReached();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
GetAdaptCounter().IncrementResolution(reason);
|
||||
break;
|
||||
@ -1852,7 +1863,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
const int requested_framerate = source_proxy_->RequestFramerateLowerThan(
|
||||
adaptation_request.framerate_fps_);
|
||||
if (requested_framerate == -1)
|
||||
return;
|
||||
return true;
|
||||
RTC_DCHECK_NE(max_framerate_, -1);
|
||||
overuse_detector_->OnTargetFramerateUpdated(
|
||||
std::min(max_framerate_, requested_framerate));
|
||||
@ -1868,6 +1879,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
UpdateAdaptationStats(reason);
|
||||
|
||||
RTC_LOG(LS_INFO) << GetConstAdaptCounter().ToString();
|
||||
return did_adapt;
|
||||
}
|
||||
|
||||
void VideoStreamEncoder::AdaptUp(AdaptReason reason) {
|
||||
|
||||
@ -103,7 +103,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
||||
// AdaptationObserverInterface implementation.
|
||||
// These methods are protected for easier testing.
|
||||
void AdaptUp(AdaptReason reason) override;
|
||||
void AdaptDown(AdaptReason reason) override;
|
||||
bool AdaptDown(AdaptReason reason) override;
|
||||
|
||||
private:
|
||||
class VideoSourceProxy;
|
||||
|
||||
@ -148,7 +148,10 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
||||
void PostTaskAndWait(bool down, AdaptReason reason) {
|
||||
rtc::Event event;
|
||||
encoder_queue()->PostTask([this, &event, reason, down] {
|
||||
down ? AdaptDown(reason) : AdaptUp(reason);
|
||||
if (down)
|
||||
AdaptDown(reason);
|
||||
else
|
||||
AdaptUp(reason);
|
||||
event.Set();
|
||||
});
|
||||
ASSERT_TRUE(event.Wait(5000));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user