Keep SVC max bitrate if number of spatial layers are reduced.

Bug: chromium:1423361
Change-Id: I02bcb11f2ac456db79ed835dd38d4d7621a49608
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298446
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39614}
This commit is contained in:
Åsa Persson 2023-03-21 09:49:32 +01:00 committed by WebRTC LUCI CQ
parent aa17f2f0a9
commit 014b244fa0
4 changed files with 123 additions and 6 deletions

View File

@ -203,12 +203,7 @@ std::vector<SpatialLayer> GetVp9SvcConfig(VideoCodec& codec) {
codec.GetScalabilityMode() ? info : absl::nullopt);
RTC_DCHECK(!spatial_layers.empty());
// Use codec bitrate limits if spatial layering is not requested.
if (info->num_spatial_layers == 1) {
spatial_layers.back().minBitrate = codec.minBitrate;
spatial_layers.back().targetBitrate = codec.maxBitrate;
spatial_layers.back().maxBitrate = codec.maxBitrate;
}
spatial_layers[0].minBitrate = kMinVp9SvcBitrateKbps;
return spatial_layers;
}

View File

@ -237,6 +237,13 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
spatial_layers = GetVp9SvcConfig(video_codec);
if (spatial_layers.empty())
break;
// Use codec bitrate limits if spatial layering is not requested.
if (config.simulcast_layers.size() <= 1 &&
ScalabilityModeToNumSpatialLayers(*scalability_mode) == 1) {
spatial_layers.back().minBitrate = video_codec.minBitrate;
spatial_layers.back().targetBitrate = video_codec.maxBitrate;
spatial_layers.back().maxBitrate = video_codec.maxBitrate;
}
} else {
size_t first_active_layer = 0;
for (size_t spatial_idx = 0;

View File

@ -331,6 +331,22 @@ TEST_F(VideoCodecInitializerTest,
kDefaultMaxBitrateBps / 1000);
}
TEST_F(VideoCodecInitializerTest,
Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrateWithL1T1) {
SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 1, 1, false);
VideoStream stream = DefaultStream();
stream.num_temporal_layers = 1;
stream.scalability_mode = ScalabilityMode::kL1T1;
streams_.push_back(stream);
EXPECT_TRUE(InitializeCodec());
EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
EXPECT_EQ(codec_out_.spatialLayers[0].minBitrate,
kDefaultMinBitrateBps / 1000);
EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
kDefaultMaxBitrateBps / 1000);
}
TEST_F(VideoCodecInitializerTest,
Vp9SingleSpatialLayerTargetBitrateIsEqualToCodecMaxBitrate) {
SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 1, 1, true);
@ -360,6 +376,27 @@ TEST_F(VideoCodecInitializerTest,
kDefaultMaxBitrateBps / 1000);
}
TEST_F(VideoCodecInitializerTest,
Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOneWithL3T1) {
// Request 3 spatial layers for 320x180 input. Actual number of layers will be
// reduced to 1 due to low input resolution but SVC bitrate limits should be
// applied.
SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 3, 1, false);
VideoStream stream = DefaultStream();
stream.width = 320;
stream.height = 180;
stream.num_temporal_layers = 1;
stream.scalability_mode = ScalabilityMode::kL3T1;
streams_.push_back(stream);
EXPECT_TRUE(InitializeCodec());
EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
EXPECT_LT(codec_out_.spatialLayers[0].minBitrate,
kDefaultMinBitrateBps / 1000);
EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
kDefaultMaxBitrateBps / 1000);
}
TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) {
SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 1, false);
VideoStream stream = DefaultStream();
@ -537,4 +574,55 @@ TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersOneDeactivated) {
EXPECT_FALSE(codec.spatialLayers[1].active);
}
TEST_F(VideoCodecInitializerTest, Vp9SingleSpatialLayerBitratesAreConsistent) {
VideoEncoderConfig config;
config.simulcast_layers.resize(3);
config.simulcast_layers[0].active = true;
config.simulcast_layers[1].active = false;
config.simulcast_layers[2].active = false;
config.codec_type = VideoCodecType::kVideoCodecVP9;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = ScalabilityMode::kL1T2;
VideoCodec codec;
EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
EXPECT_EQ(1u, codec.VP9()->numberOfSpatialLayers);
EXPECT_GE(codec.spatialLayers[0].targetBitrate,
codec.spatialLayers[0].minBitrate);
EXPECT_LE(codec.spatialLayers[0].targetBitrate,
codec.spatialLayers[0].maxBitrate);
EXPECT_LT(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000);
}
TEST_F(VideoCodecInitializerTest, Vp9TwoSpatialLayersBitratesAreConsistent) {
VideoEncoderConfig config;
config.simulcast_layers.resize(3);
config.simulcast_layers[0].active = true;
config.simulcast_layers[1].active = false;
config.simulcast_layers[2].active = false;
config.codec_type = VideoCodecType::kVideoCodecVP9;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = ScalabilityMode::kL2T2;
VideoCodec codec;
EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
EXPECT_EQ(2u, codec.VP9()->numberOfSpatialLayers);
EXPECT_GE(codec.spatialLayers[0].targetBitrate,
codec.spatialLayers[0].minBitrate);
EXPECT_LE(codec.spatialLayers[0].targetBitrate,
codec.spatialLayers[0].maxBitrate);
EXPECT_LT(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000);
EXPECT_GE(codec.spatialLayers[1].targetBitrate,
codec.spatialLayers[1].minBitrate);
EXPECT_LE(codec.spatialLayers[1].targetBitrate,
codec.spatialLayers[1].maxBitrate);
EXPECT_GT(codec.spatialLayers[1].minBitrate,
codec.spatialLayers[0].maxBitrate);
}
} // namespace webrtc

View File

@ -228,6 +228,33 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsApplied) {
RunBaseTest(&test);
}
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
OneStreamDefaultMaxBitrateAppliedForOneSpatialLayer) {
InitEncodeTest test("VP9",
{{.active = true,
.bitrate = {DataRate::KilobitsPerSec(30),
DataRate::KilobitsPerSec(3000)},
.scalability_mode = ScalabilityMode::kL1T1}},
// Expectations:
{{.pixels = 1280 * 720,
.eq_bitrate = {DataRate::KilobitsPerSec(30),
DataRate::KilobitsPerSec(3000)}}});
RunBaseTest(&test);
}
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
OneStreamSvcMaxBitrateAppliedForTwoSpatialLayers) {
InitEncodeTest test(
"VP9",
{{.active = true,
.bitrate = {DataRate::KilobitsPerSec(30),
DataRate::KilobitsPerSec(3000)},
.scalability_mode = ScalabilityMode::kL2T1}},
// Expectations:
{{.pixels = 1280 * 720,
.ne_bitrate = {absl::nullopt, DataRate::KilobitsPerSec(3000)}}});
RunBaseTest(&test);
}
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
OneStreamLimitsAppliedForOneSpatialLayer) {
webrtc::test::ScopedFieldTrials field_trials(