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:
parent
aa17f2f0a9
commit
014b244fa0
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user