Use resolution bitrate limits if one spatial layer is configured via scalability mode.
Bug: webrtc:13960 Change-Id: Ie9238f3352b0d9d92fda97a250de0792e6bbfc9a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261721 Commit-Queue: Åsa Persson <asapersson@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36948}
This commit is contained in:
parent
6fb674ea5a
commit
2ee3e4db22
@ -47,6 +47,7 @@ rtc_library("video_adaptation") {
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../call/adaptation:resource_adaptation",
|
||||
"../../modules/video_coding:video_coding_utility",
|
||||
"../../modules/video_coding/svc:scalability_mode_util",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:event_tracer",
|
||||
"../../rtc_base:logging",
|
||||
@ -96,6 +97,7 @@ if (rtc_include_tests) {
|
||||
"../../api/video:encoded_image",
|
||||
"../../api/video:video_adaptation",
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video_codecs:scalability_mode",
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../call/adaptation:resource_adaptation",
|
||||
"../../call/adaptation:resource_adaptation_test_utilities",
|
||||
|
||||
@ -37,6 +37,10 @@ void BitrateConstraint::OnEncoderTargetBitrateUpdated(
|
||||
encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
|
||||
}
|
||||
|
||||
// Checks if resolution is allowed to adapt up based on the current bitrate and
|
||||
// ResolutionBitrateLimits.min_start_bitrate_bps for the next higher resolution.
|
||||
// Bitrate limits usage is restricted to a single active stream/layer (e.g. when
|
||||
// quality scaling is enabled).
|
||||
bool BitrateConstraint::IsAdaptationUpAllowed(
|
||||
const VideoStreamInputState& input_state,
|
||||
const VideoSourceRestrictions& restrictions_before,
|
||||
@ -53,7 +57,7 @@ bool BitrateConstraint::IsAdaptationUpAllowed(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (VideoStreamEncoderResourceManager::IsSimulcast(
|
||||
if (VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers(
|
||||
encoder_settings_->encoder_config())) {
|
||||
// Resolution bitrate limits usage is restricted to singlecast.
|
||||
return true;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/scalability_mode.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "call/adaptation/encoder_settings.h"
|
||||
#include "call/adaptation/test/fake_frame_rate_provider.h"
|
||||
@ -23,6 +24,9 @@
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
const VideoSourceRestrictions k180p{/*max_pixels_per_frame=*/320 * 180,
|
||||
/*target_pixels_per_frame=*/320 * 180,
|
||||
/*max_frame_rate=*/30};
|
||||
const VideoSourceRestrictions k360p{/*max_pixels_per_frame=*/640 * 360,
|
||||
/*target_pixels_per_frame=*/640 * 360,
|
||||
/*max_frame_rate=*/30};
|
||||
@ -30,39 +34,50 @@ const VideoSourceRestrictions k720p{/*max_pixels_per_frame=*/1280 * 720,
|
||||
/*target_pixels_per_frame=*/1280 * 720,
|
||||
/*max_frame_rate=*/30};
|
||||
|
||||
struct TestParams {
|
||||
bool active;
|
||||
absl::optional<ScalabilityMode> scalability_mode;
|
||||
};
|
||||
|
||||
void FillCodecConfig(VideoCodec* video_codec,
|
||||
VideoEncoderConfig* encoder_config,
|
||||
int width_px,
|
||||
int height_px,
|
||||
std::vector<bool> active_flags) {
|
||||
size_t num_layers = active_flags.size();
|
||||
const std::vector<TestParams>& params,
|
||||
bool svc) {
|
||||
size_t num_layers = params.size();
|
||||
video_codec->codecType = kVideoCodecVP8;
|
||||
video_codec->numberOfSimulcastStreams = num_layers;
|
||||
|
||||
encoder_config->number_of_streams = num_layers;
|
||||
encoder_config->number_of_streams = svc ? 1 : num_layers;
|
||||
encoder_config->simulcast_layers.resize(num_layers);
|
||||
|
||||
for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) {
|
||||
int layer_width_px = width_px >> (num_layers - 1 - layer_idx);
|
||||
int layer_height_px = height_px >> (num_layers - 1 - layer_idx);
|
||||
|
||||
video_codec->simulcastStream[layer_idx].active = active_flags[layer_idx];
|
||||
if (params[layer_idx].scalability_mode)
|
||||
video_codec->SetScalabilityMode(*params[layer_idx].scalability_mode);
|
||||
video_codec->simulcastStream[layer_idx].active = params[layer_idx].active;
|
||||
video_codec->simulcastStream[layer_idx].width = layer_width_px;
|
||||
video_codec->simulcastStream[layer_idx].height = layer_height_px;
|
||||
|
||||
encoder_config->simulcast_layers[layer_idx].scalability_mode =
|
||||
params[layer_idx].scalability_mode;
|
||||
encoder_config->simulcast_layers[layer_idx].active =
|
||||
active_flags[layer_idx];
|
||||
params[layer_idx].active;
|
||||
encoder_config->simulcast_layers[layer_idx].width = layer_width_px;
|
||||
encoder_config->simulcast_layers[layer_idx].height = layer_height_px;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int kStartBitrateBps360p = 500000;
|
||||
constexpr int kStartBitrateBps720p = 1000000;
|
||||
|
||||
VideoEncoder::EncoderInfo MakeEncoderInfo() {
|
||||
VideoEncoder::EncoderInfo encoder_info;
|
||||
encoder_info.resolution_bitrate_limits = {
|
||||
{640 * 360, 500000, 0, 5000000},
|
||||
{640 * 360, kStartBitrateBps360p, 0, 5000000},
|
||||
{1280 * 720, kStartBitrateBps720p, 0, 5000000},
|
||||
{1920 * 1080, 2000000, 0, 5000000}};
|
||||
return encoder_info;
|
||||
@ -78,11 +93,12 @@ class BitrateConstraintTest : public ::testing::Test {
|
||||
protected:
|
||||
void OnEncoderSettingsUpdated(int width_px,
|
||||
int height_px,
|
||||
std::vector<bool> active_flags) {
|
||||
const std::vector<TestParams>& params,
|
||||
bool svc = false) {
|
||||
VideoCodec video_codec;
|
||||
VideoEncoderConfig encoder_config;
|
||||
FillCodecConfig(&video_codec, &encoder_config, width_px, height_px,
|
||||
active_flags);
|
||||
FillCodecConfig(&video_codec, &encoder_config, width_px, height_px, params,
|
||||
svc);
|
||||
|
||||
EncoderSettings encoder_settings(MakeEncoderInfo(),
|
||||
std::move(encoder_config), video_codec);
|
||||
@ -97,7 +113,7 @@ class BitrateConstraintTest : public ::testing::Test {
|
||||
|
||||
TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSinglecastIfBitrateIsEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{true});
|
||||
{{.active = true}});
|
||||
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
|
||||
|
||||
@ -110,7 +126,7 @@ TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSinglecastIfBitrateIsEnough) {
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{true});
|
||||
{{.active = true}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
@ -121,10 +137,56 @@ TEST_F(BitrateConstraintTest,
|
||||
/*restrictions_after=*/k720p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedAtSinglecastIfBitrateIsEnoughForOneSpatialLayer) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T1}});
|
||||
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k360p,
|
||||
/*restrictions_after=*/k720p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnoughForOneSpatialLayer) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T1}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
|
||||
EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k360p,
|
||||
/*restrictions_after=*/k720p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedAtSinglecastIfBitrateIsNotEnoughForMultipleSpatialLayers) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL2T1}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k360p,
|
||||
/*restrictions_after=*/k720p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedAtSinglecastUpperLayerActiveIfBitrateIsEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{false, true});
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = false, .scalability_mode = ScalabilityMode::kL2T1},
|
||||
{.active = true}});
|
||||
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
|
||||
|
||||
@ -136,8 +198,10 @@ TEST_F(BitrateConstraintTest,
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpDisallowedAtSinglecastUpperLayerActiveIfBitrateIsNotEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{false, true});
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = false, .scalability_mode = ScalabilityMode::kL2T1},
|
||||
{.active = true}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
@ -148,23 +212,88 @@ TEST_F(BitrateConstraintTest,
|
||||
/*restrictions_after=*/k720p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedAtSinglecastLowestLayerActiveIfBitrateIsNotEnough) {
|
||||
TEST_F(BitrateConstraintTest, AdaptUpAllowedLowestActiveIfBitrateIsNotEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{true, false});
|
||||
{{.active = true}, {.active = false}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
// 1 bps less than needed for 360p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k360p,
|
||||
/*restrictions_after=*/k720p));
|
||||
/*restrictions_before=*/k180p,
|
||||
/*restrictions_after=*/k360p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayer) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T2},
|
||||
{.active = false}});
|
||||
|
||||
// 1 bps less than needed for 360p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k180p,
|
||||
/*restrictions_after=*/k360p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedLowestActiveIfBitrateIsEnoughForOneSpatialLayerSvc) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T1},
|
||||
{.active = false}},
|
||||
/*svc=*/true);
|
||||
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k180p,
|
||||
/*restrictions_after=*/k360p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpDisallowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayerSvc) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T1},
|
||||
{.active = false}},
|
||||
/*svc=*/true);
|
||||
|
||||
// 1 bps less than needed for 360p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
|
||||
|
||||
EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k180p,
|
||||
/*restrictions_after=*/k360p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForTwoSpatialLayersSvc) {
|
||||
OnEncoderSettingsUpdated(
|
||||
/*width_px=*/640, /*height_px=*/360,
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL2T1},
|
||||
{.active = false}},
|
||||
/*svc=*/true);
|
||||
|
||||
// 1 bps less than needed for 360p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
|
||||
|
||||
EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
|
||||
input_state_provider_.InputState(),
|
||||
/*restrictions_before=*/k180p,
|
||||
/*restrictions_after=*/k360p));
|
||||
}
|
||||
|
||||
TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSimulcastIfBitrateIsNotEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{true, true});
|
||||
{{.active = true}, {.active = true}});
|
||||
|
||||
// 1 bps less than needed for 720p.
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
|
||||
@ -178,7 +307,7 @@ TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSimulcastIfBitrateIsNotEnough) {
|
||||
TEST_F(BitrateConstraintTest,
|
||||
AdaptUpInFpsAllowedAtNoResolutionIncreaseIfBitrateIsNotEnough) {
|
||||
OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
|
||||
/*active_flags=*/{true});
|
||||
{{.active = true}});
|
||||
|
||||
bitrate_constraint_.OnEncoderTargetBitrateUpdated(1);
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "api/video/video_adaptation_reason.h"
|
||||
#include "api/video/video_source_interface.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
#include "modules/video_coding/svc/scalability_mode_util.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
@ -815,15 +816,29 @@ void VideoStreamEncoderResourceManager::OnQualityRampUp() {
|
||||
quality_rampup_experiment_.reset();
|
||||
}
|
||||
|
||||
bool VideoStreamEncoderResourceManager::IsSimulcast(
|
||||
bool VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers(
|
||||
const VideoEncoderConfig& encoder_config) {
|
||||
const std::vector<VideoStream>& simulcast_layers =
|
||||
encoder_config.simulcast_layers;
|
||||
if (simulcast_layers.size() <= 1) {
|
||||
if (simulcast_layers.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (simulcast_layers[0].active) {
|
||||
absl::optional<int> num_spatial_layers;
|
||||
if (simulcast_layers[0].scalability_mode.has_value() &&
|
||||
encoder_config.number_of_streams == 1) {
|
||||
num_spatial_layers = ScalabilityModeToNumSpatialLayers(
|
||||
*simulcast_layers[0].scalability_mode);
|
||||
}
|
||||
|
||||
if (simulcast_layers.size() == 1) {
|
||||
// Check if multiple spatial layers are used.
|
||||
return num_spatial_layers && *num_spatial_layers > 1;
|
||||
}
|
||||
|
||||
bool svc_with_one_spatial_layer =
|
||||
num_spatial_layers && *num_spatial_layers == 1;
|
||||
if (simulcast_layers[0].active && !svc_with_one_spatial_layer) {
|
||||
// We can't distinguish between simulcast and singlecast when only the
|
||||
// lowest spatial layer is active. Treat this case as simulcast.
|
||||
return true;
|
||||
|
||||
@ -153,7 +153,8 @@ class VideoStreamEncoderResourceManager
|
||||
// QualityRampUpExperimentListener implementation.
|
||||
void OnQualityRampUp() override;
|
||||
|
||||
static bool IsSimulcast(const VideoEncoderConfig& encoder_config);
|
||||
static bool IsSimulcastOrMultipleSpatialLayers(
|
||||
const VideoEncoderConfig& encoder_config);
|
||||
|
||||
private:
|
||||
class InitialFrameDropper;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "media/engine/webrtc_video_engine.h"
|
||||
#include "modules/video_coding/svc/scalability_mode_util.h"
|
||||
#include "rtc_base/experiments/encoder_info_settings.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/fake_encoder.h"
|
||||
@ -62,6 +63,8 @@ BitrateLimits GetLayerBitrateLimits(int pixels, const VideoCodec& codec) {
|
||||
|
||||
} // namespace
|
||||
|
||||
class ResolutionBitrateLimitsWithScalabilityModeTest : public test::CallTest {};
|
||||
|
||||
class ResolutionBitrateLimitsTest
|
||||
: public test::CallTest,
|
||||
public ::testing::WithParamInterface<std::string> {
|
||||
@ -73,7 +76,10 @@ class ResolutionBitrateLimitsTest
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(PayloadName,
|
||||
ResolutionBitrateLimitsTest,
|
||||
::testing::Values("VP8", "VP9"));
|
||||
::testing::Values("VP8", "VP9"),
|
||||
[](const ::testing::TestParamInfo<std::string>& info) {
|
||||
return info.param;
|
||||
});
|
||||
|
||||
class InitEncodeTest : public test::EndToEndTest,
|
||||
public test::FrameGeneratorCapturer::SinkWantsObserver,
|
||||
@ -86,6 +92,7 @@ class InitEncodeTest : public test::EndToEndTest,
|
||||
struct TestConfig {
|
||||
const bool active;
|
||||
const Bitrate bitrate;
|
||||
const absl::optional<ScalabilityMode> scalability_mode;
|
||||
};
|
||||
struct Expectation {
|
||||
const uint32_t pixels = 0;
|
||||
@ -141,6 +148,7 @@ class InitEncodeTest : public test::EndToEndTest,
|
||||
for (int i = configs_.size() - 1; i >= 0; --i) {
|
||||
VideoStream& stream = encoder_config->simulcast_layers[i];
|
||||
stream.active = configs_[i].active;
|
||||
stream.scalability_mode = configs_[i].scalability_mode;
|
||||
if (configs_[i].bitrate.min)
|
||||
stream.min_bitrate_bps = configs_[i].bitrate.min->bps();
|
||||
if (configs_[i].bitrate.max)
|
||||
@ -203,6 +211,45 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsApplied) {
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
OneStreamLimitsAppliedForOneSpatialLayer) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:921600,"
|
||||
"min_start_bitrate_bps:0,"
|
||||
"min_bitrate_bps:32000,"
|
||||
"max_bitrate_bps:3333000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
"VP9", {{.active = true, .scalability_mode = ScalabilityMode::kL1T1}},
|
||||
// Expectations:
|
||||
{{.pixels = 1280 * 720,
|
||||
.eq_bitrate = {DataRate::KilobitsPerSec(32),
|
||||
DataRate::KilobitsPerSec(3333)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
OneStreamLimitsNotAppliedForMultipleSpatialLayers) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:230400|921600,"
|
||||
"min_start_bitrate_bps:0|0,"
|
||||
"min_bitrate_bps:21000|32000,"
|
||||
"max_bitrate_bps:2222000|3333000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
"VP9", {{.active = true, .scalability_mode = ScalabilityMode::kL2T1}},
|
||||
// Expectations:
|
||||
{{.pixels = 640 * 360,
|
||||
.ne_bitrate = {DataRate::KilobitsPerSec(31),
|
||||
DataRate::KilobitsPerSec(2222)}},
|
||||
{.pixels = 1280 * 720,
|
||||
.ne_bitrate = {DataRate::KilobitsPerSec(32),
|
||||
DataRate::KilobitsPerSec(3333)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, EncodingsApplied) {
|
||||
InitEncodeTest test(payload_name_,
|
||||
{{.active = true,
|
||||
@ -248,7 +295,6 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsAppliedMiddleActive) {
|
||||
{{.pixels = 640 * 360,
|
||||
.eq_bitrate = {DataRate::KilobitsPerSec(21),
|
||||
DataRate::KilobitsPerSec(2222)}}});
|
||||
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -287,7 +333,26 @@ TEST_P(ResolutionBitrateLimitsTest, DefaultLimitsAppliedMiddleActive) {
|
||||
DataRate::BitsPerSec(kDefaultSinglecastLimits360p->min_bitrate_bps),
|
||||
DataRate::BitsPerSec(
|
||||
kDefaultSinglecastLimits360p->max_bitrate_bps)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
DefaultLimitsAppliedForOneSpatialLayer) {
|
||||
const absl::optional<VideoEncoder::ResolutionBitrateLimits>
|
||||
kDefaultSinglecastLimits720p =
|
||||
EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
|
||||
PayloadStringToCodecType("VP9"), 1280 * 720);
|
||||
|
||||
InitEncodeTest test(
|
||||
"VP9",
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T3},
|
||||
{.active = false}},
|
||||
// Expectations:
|
||||
{{.pixels = 1280 * 720,
|
||||
.eq_bitrate = {
|
||||
DataRate::BitsPerSec(kDefaultSinglecastLimits720p->min_bitrate_bps),
|
||||
DataRate::BitsPerSec(
|
||||
kDefaultSinglecastLimits720p->max_bitrate_bps)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -348,6 +413,49 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsNotAppliedLowestActive) {
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
LimitsAppliedForVp9OneSpatialLayer) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:230400|921600,"
|
||||
"min_start_bitrate_bps:0|0,"
|
||||
"min_bitrate_bps:31000|32000,"
|
||||
"max_bitrate_bps:2222000|3333000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
"VP9",
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T1},
|
||||
{.active = false}},
|
||||
// Expectations:
|
||||
{{.pixels = 1280 * 720,
|
||||
.eq_bitrate = {DataRate::KilobitsPerSec(32),
|
||||
DataRate::KilobitsPerSec(3333)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
LimitsNotAppliedForVp9MultipleSpatialLayers) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:230400|921600,"
|
||||
"min_start_bitrate_bps:0|0,"
|
||||
"min_bitrate_bps:31000|32000,"
|
||||
"max_bitrate_bps:2222000|3333000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
"VP9",
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL2T1},
|
||||
{.active = false}},
|
||||
// Expectations:
|
||||
{{.pixels = 640 * 360,
|
||||
.ne_bitrate = {DataRate::KilobitsPerSec(31),
|
||||
DataRate::KilobitsPerSec(2222)}},
|
||||
{.pixels = 1280 * 720,
|
||||
.ne_bitrate = {DataRate::KilobitsPerSec(32),
|
||||
DataRate::KilobitsPerSec(3333)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, LimitsNotAppliedSimulcast) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
|
||||
@ -64,12 +64,21 @@ class QualityScalingTest : public test::CallTest {
|
||||
EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
|
||||
kVideoCodecVP9,
|
||||
640 * 360);
|
||||
const absl::optional<VideoEncoder::ResolutionBitrateLimits>
|
||||
kSinglecastLimits720pVp9 =
|
||||
EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
|
||||
kVideoCodecVP9,
|
||||
1280 * 720);
|
||||
};
|
||||
|
||||
class ScalingObserver : public test::SendTest {
|
||||
protected:
|
||||
struct TestParams {
|
||||
bool active;
|
||||
absl::optional<ScalabilityMode> scalability_mode;
|
||||
};
|
||||
ScalingObserver(const std::string& payload_name,
|
||||
const std::vector<bool>& streams_active,
|
||||
const std::vector<TestParams>& test_params,
|
||||
int start_bps,
|
||||
bool automatic_resize,
|
||||
bool expect_scaling)
|
||||
@ -86,7 +95,7 @@ class ScalingObserver : public test::SendTest {
|
||||
return nullptr;
|
||||
}),
|
||||
payload_name_(payload_name),
|
||||
streams_active_(streams_active),
|
||||
test_params_(test_params),
|
||||
start_bps_(start_bps),
|
||||
automatic_resize_(automatic_resize),
|
||||
expect_scaling_(expect_scaling) {}
|
||||
@ -105,7 +114,7 @@ class ScalingObserver : public test::SendTest {
|
||||
}
|
||||
|
||||
size_t GetNumVideoStreams() const override {
|
||||
return (payload_name_ == "VP9") ? 1 : streams_active_.size();
|
||||
return (payload_name_ == "VP9") ? 1 : test_params_.size();
|
||||
}
|
||||
|
||||
void ModifyVideoConfigs(
|
||||
@ -122,27 +131,28 @@ class ScalingObserver : public test::SendTest {
|
||||
std::max(start_bps_, encoder_config->max_bitrate_bps);
|
||||
if (payload_name_ == "VP9") {
|
||||
// Simulcast layers indicates which spatial layers are active.
|
||||
encoder_config->simulcast_layers.resize(streams_active_.size());
|
||||
encoder_config->simulcast_layers.resize(test_params_.size());
|
||||
encoder_config->simulcast_layers[0].max_bitrate_bps =
|
||||
encoder_config->max_bitrate_bps;
|
||||
}
|
||||
double scale_factor = 1.0;
|
||||
for (int i = streams_active_.size() - 1; i >= 0; --i) {
|
||||
for (int i = test_params_.size() - 1; i >= 0; --i) {
|
||||
VideoStream& stream = encoder_config->simulcast_layers[i];
|
||||
stream.active = streams_active_[i];
|
||||
stream.active = test_params_[i].active;
|
||||
stream.scalability_mode = test_params_[i].scalability_mode;
|
||||
stream.scale_resolution_down_by = scale_factor;
|
||||
scale_factor *= (payload_name_ == "VP9") ? 1.0 : 2.0;
|
||||
}
|
||||
encoder_config->frame_drop_enabled = true;
|
||||
SetEncoderSpecific(encoder_config, codec_type, automatic_resize_,
|
||||
streams_active_.size());
|
||||
test_params_.size());
|
||||
}
|
||||
|
||||
void PerformTest() override { EXPECT_EQ(expect_scaling_, Wait()); }
|
||||
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
const std::string payload_name_;
|
||||
const std::vector<bool> streams_active_;
|
||||
const std::vector<TestParams> test_params_;
|
||||
const int start_bps_;
|
||||
const bool automatic_resize_;
|
||||
const bool expect_scaling_;
|
||||
@ -153,12 +163,12 @@ class DownscalingObserver
|
||||
public test::FrameGeneratorCapturer::SinkWantsObserver {
|
||||
public:
|
||||
DownscalingObserver(const std::string& payload_name,
|
||||
const std::vector<bool>& streams_active,
|
||||
const std::vector<TestParams>& test_params,
|
||||
int start_bps,
|
||||
bool automatic_resize,
|
||||
bool expect_downscale)
|
||||
: ScalingObserver(payload_name,
|
||||
streams_active,
|
||||
test_params,
|
||||
start_bps,
|
||||
automatic_resize,
|
||||
expect_downscale) {}
|
||||
@ -182,12 +192,12 @@ class UpscalingObserver
|
||||
public test::FrameGeneratorCapturer::SinkWantsObserver {
|
||||
public:
|
||||
UpscalingObserver(const std::string& payload_name,
|
||||
const std::vector<bool>& streams_active,
|
||||
const std::vector<TestParams>& test_params,
|
||||
int start_bps,
|
||||
bool automatic_resize,
|
||||
bool expect_upscale)
|
||||
: ScalingObserver(payload_name,
|
||||
streams_active,
|
||||
test_params,
|
||||
start_bps,
|
||||
automatic_resize,
|
||||
expect_upscale) {}
|
||||
@ -220,7 +230,7 @@ TEST_F(QualityScalingTest, AdaptsDownForHighQp_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,1,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
@ -231,7 +241,7 @@ TEST_F(QualityScalingTest, NoAdaptDownForHighQpIfScalingOff_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,1,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/false,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -242,7 +252,7 @@ TEST_F(QualityScalingTest, NoAdaptDownForNormalQp_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -253,7 +263,7 @@ TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true}, kLowStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}}, kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
@ -267,8 +277,7 @@ TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrateAndThenUp) {
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:230400|921600,fps:20|30,kbps:300|500/"); // should not affect
|
||||
|
||||
UpscalingObserver test("VP8", /*streams_active=*/{true},
|
||||
kDefaultVgaMinStartBps - 1,
|
||||
UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
|
||||
/*automatic_resize=*/true, /*expect_upscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
@ -280,8 +289,7 @@ TEST_F(QualityScalingTest, AdaptsDownAndThenUpWithBalanced) {
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:230400|921600,fps:20|30,kbps:300|499/");
|
||||
|
||||
UpscalingObserver test("VP8", /*streams_active=*/{true},
|
||||
kDefaultVgaMinStartBps - 1,
|
||||
UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
|
||||
/*automatic_resize=*/true, /*expect_upscale=*/true);
|
||||
test.SetDegradationPreference(DegradationPreference::BALANCED);
|
||||
RunBaseTest(&test);
|
||||
@ -294,8 +302,7 @@ TEST_F(QualityScalingTest, AdaptsDownButNotUpWithBalancedIfBitrateNotEnough) {
|
||||
"WebRTC-Video-BalancedDegradationSettings/"
|
||||
"pixels:230400|921600,fps:20|30,kbps:300|500/");
|
||||
|
||||
UpscalingObserver test("VP8", /*streams_active=*/{true},
|
||||
kDefaultVgaMinStartBps - 1,
|
||||
UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
|
||||
/*automatic_resize=*/true, /*expect_upscale=*/false);
|
||||
test.SetDegradationPreference(DegradationPreference::BALANCED);
|
||||
RunBaseTest(&test);
|
||||
@ -306,7 +313,8 @@ TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrate_Simulcast) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true, true}, kLowStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}, {.active = true}},
|
||||
kLowStartBps,
|
||||
/*automatic_resize=*/false,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -317,10 +325,11 @@ TEST_F(QualityScalingTest, AdaptsDownForHighQp_HighestStreamActive_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,1,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{false, false, true},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = false}, {.active = false}, {.active = true}},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -330,10 +339,11 @@ TEST_F(QualityScalingTest,
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{false, false, true},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = false}, {.active = false}, {.active = true}},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -342,7 +352,7 @@ TEST_F(QualityScalingTest, AdaptsDownButNotUpWithMinStartBitrateLimit) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "127,127,0,0,0,0" + kEnd);
|
||||
|
||||
UpscalingObserver test("VP8", /*streams_active=*/{false, true},
|
||||
UpscalingObserver test("VP8", {{.active = false}, {.active = true}},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true, /*expect_upscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -353,10 +363,11 @@ TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{false, false, true},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = false}, {.active = false}, {.active = true}},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -367,10 +378,11 @@ TEST_F(QualityScalingTest,
|
||||
field_trials_, kPrefix + "1,127,0,0,0,0" + kEnd +
|
||||
"WebRTC-DefaultBitrateLimitsKillSwitch/Enabled/");
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{false, false, true},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = false}, {.active = false}, {.active = true}},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -380,7 +392,7 @@ TEST_F(QualityScalingTest,
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true},
|
||||
DownscalingObserver test("VP8", {{.active = true}},
|
||||
kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
@ -392,10 +404,11 @@ TEST_F(QualityScalingTest, NoAdaptDownForHighQp_LowestStreamActive_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,1,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true, false, false},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = true}, {.active = false}, {.active = false}},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -405,10 +418,11 @@ TEST_F(QualityScalingTest,
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true, false, false},
|
||||
kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP8", {{.active = true}, {.active = false}, {.active = false}},
|
||||
kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -417,7 +431,7 @@ TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfScalingOff_Vp8) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "1,127,0,0,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP8", /*streams_active=*/{true}, kLowStartBps,
|
||||
DownscalingObserver test("VP8", {{.active = true}}, kLowStartBps,
|
||||
/*automatic_resize=*/false,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -425,11 +439,10 @@ TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfScalingOff_Vp8) {
|
||||
|
||||
TEST_F(QualityScalingTest, AdaptsDownForHighQp_Vp9) {
|
||||
// qp_low:1, qp_high:1 -> kHighQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("VP9", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
@ -441,7 +454,7 @@ TEST_F(QualityScalingTest, NoAdaptDownForHighQpIfScalingOff_Vp9) {
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd + "WebRTC-VP9QualityScaler/Disabled/");
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("VP9", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
@ -449,11 +462,10 @@ TEST_F(QualityScalingTest, NoAdaptDownForHighQpIfScalingOff_Vp9) {
|
||||
|
||||
TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_Vp9) {
|
||||
// qp_low:1, qp_high:255 -> kNormalQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{true}, kLowStartBps,
|
||||
DownscalingObserver test("VP9", {{.active = true}}, kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
@ -461,68 +473,100 @@ TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_Vp9) {
|
||||
|
||||
TEST_F(QualityScalingTest, NoAdaptDownForHighQp_LowestStreamActive_Vp9) {
|
||||
// qp_low:1, qp_high:1 -> kHighQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{true, false, false},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP9", {{.active = true}, {.active = false}, {.active = false}},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest,
|
||||
NoAdaptDownForLowStartBitrate_LowestStreamActive_Vp9) {
|
||||
// qp_low:1, qp_high:255 -> kNormalQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{true, false, false},
|
||||
kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP9", {{.active = true}, {.active = false}, {.active = false}},
|
||||
kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest, AdaptsDownForHighQp_MiddleStreamActive_Vp9) {
|
||||
// qp_low:1, qp_high:1 -> kHighQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,1,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{false, true, false},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
DownscalingObserver test(
|
||||
"VP9", {{.active = false}, {.active = true}, {.active = false}},
|
||||
kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest,
|
||||
AdaptsDownForLowStartBitrate_MiddleStreamActive_Vp9) {
|
||||
// qp_low:1, qp_high:255 -> kNormalQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{false, true, false},
|
||||
kSinglecastLimits360pVp9->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
DownscalingObserver test(
|
||||
"VP9", {{.active = false}, {.active = true}, {.active = false}},
|
||||
kSinglecastLimits360pVp9->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp9) {
|
||||
// qp_low:1, qp_high:255 -> kNormalQp
|
||||
test::ScopedKeyValueConfig field_trials(
|
||||
field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd + "WebRTC-VP9QualityScaler/Enabled/");
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test("VP9", /*streams_active=*/{false, true, false},
|
||||
kSinglecastLimits360pVp9->min_start_bitrate_bps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
DownscalingObserver test(
|
||||
"VP9", {{.active = false}, {.active = true}, {.active = false}},
|
||||
kSinglecastLimits360pVp9->min_start_bitrate_bps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest,
|
||||
AdaptsDownButNotUpWithMinStartBitrateLimitWithScalabilityMode_VP9) {
|
||||
// qp_low:255, qp_high:255 -> kLowQp
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,255,255,0,0" + kEnd);
|
||||
|
||||
UpscalingObserver test(
|
||||
"VP9",
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T3},
|
||||
{.active = false}},
|
||||
kSinglecastLimits720pVp9->min_start_bitrate_bps - 1,
|
||||
/*automatic_resize=*/true, /*expect_upscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(QualityScalingTest,
|
||||
NoAdaptDownForLowStartBitrateIfBitrateEnoughWithScalabilityMode_Vp9) {
|
||||
// qp_low:1, qp_high:255 -> kNormalQp
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,1,255,0,0" + kEnd);
|
||||
|
||||
DownscalingObserver test(
|
||||
"VP9",
|
||||
{{.active = true, .scalability_mode = ScalabilityMode::kL1T3},
|
||||
{.active = false},
|
||||
{.active = false}},
|
||||
kSinglecastLimits720pVp9->min_start_bitrate_bps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/false);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -532,7 +576,7 @@ TEST_F(QualityScalingTest, AdaptsDownForHighQp_H264) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,0,0,1,1" + kEnd);
|
||||
|
||||
DownscalingObserver test("H264", /*streams_active=*/{true}, kHighStartBps,
|
||||
DownscalingObserver test("H264", {{.active = true}}, kHighStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
@ -543,7 +587,7 @@ TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_H264) {
|
||||
test::ScopedKeyValueConfig field_trials(field_trials_,
|
||||
kPrefix + "0,0,0,0,1,51" + kEnd);
|
||||
|
||||
DownscalingObserver test("H264", /*streams_active=*/{true}, kLowStartBps,
|
||||
DownscalingObserver test("H264", {{.active = true}}, kLowStartBps,
|
||||
/*automatic_resize=*/true,
|
||||
/*expect_downscale=*/true);
|
||||
RunBaseTest(&test);
|
||||
|
||||
@ -381,7 +381,8 @@ void ApplyVp9BitrateLimits(const VideoEncoder::EncoderInfo& encoder_info,
|
||||
VideoCodec* codec) {
|
||||
if (codec->codecType != VideoCodecType::kVideoCodecVP9 ||
|
||||
encoder_config.simulcast_layers.size() <= 1 ||
|
||||
VideoStreamEncoderResourceManager::IsSimulcast(encoder_config)) {
|
||||
VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers(
|
||||
encoder_config)) {
|
||||
// Resolution bitrate limits usage is restricted to singlecast.
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user