Use encoding max bitrate if configured when applying bitrate limits.
Currently the min of the default bitrate and configured bitrate is used. Add default bitrate limits for 1080p. Bug: b/396641469 Change-Id: Iabf243627a6dcbaa1e2f14d4f201c9482f3958d5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/377123 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43923}
This commit is contained in:
parent
b891194657
commit
04d06457f5
@ -46,11 +46,10 @@ EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
|
||||
// The min bitrate limits are not used in singlecast (used in SVC/simulcast
|
||||
// to de-/activate spatial layers) and are set to zero. Send resolution in
|
||||
// singlecast is assumed to be regulated by QP-based quality scaler.
|
||||
return {{320 * 180, 0, 0, 256000},
|
||||
{480 * 270, 176000, 0, 384000},
|
||||
{640 * 360, 256000, 0, 512000},
|
||||
{960 * 540, 384000, 0, 1024000},
|
||||
{1280 * 720, 576000, 0, 1536000}};
|
||||
return {
|
||||
{320 * 180, 0, 0, 256000}, {480 * 270, 176000, 0, 384000},
|
||||
{640 * 360, 256000, 0, 512000}, {960 * 540, 384000, 0, 1024000},
|
||||
{1280 * 720, 576000, 0, 1536000}, {1920 * 1080, 1000000, 0, 3700000}};
|
||||
}
|
||||
|
||||
if (codec_type == kVideoCodecVP9 || codec_type == kVideoCodecH265) {
|
||||
@ -64,7 +63,8 @@ EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
|
||||
{480 * 270, 120000, 30000, 300000},
|
||||
{640 * 360, 190000, 30000, 420000},
|
||||
{960 * 540, 350000, 30000, 1000000},
|
||||
{1280 * 720, 480000, 30000, 1500000}};
|
||||
{1280 * 720, 480000, 30000, 1500000},
|
||||
{1920 * 1080, 1000000, 30000, 3700000}};
|
||||
}
|
||||
|
||||
// VP8 and other codecs.
|
||||
@ -72,7 +72,8 @@ EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
|
||||
{480 * 270, 200000, 30000, 500000},
|
||||
{640 * 360, 300000, 30000, 800000},
|
||||
{960 * 540, 500000, 30000, 1500000},
|
||||
{1280 * 720, 900000, 30000, 2500000}};
|
||||
{1280 * 720, 900000, 30000, 2500000},
|
||||
{1920 * 1080, 2000000, 30000, 5000000}};
|
||||
}
|
||||
|
||||
std::optional<VideoEncoder::ResolutionBitrateLimits>
|
||||
|
||||
@ -409,7 +409,8 @@ EncoderStreamFactory::CreateDefaultVideoStreams(
|
||||
RTC_DCHECK_GE(sum_max_bitrates_kbps, 0);
|
||||
if (!api_max_bitrate_bps.has_value()) {
|
||||
max_bitrate_bps = sum_max_bitrates_kbps * 1000;
|
||||
} else {
|
||||
} else if (encoder_config.simulcast_layers[0].max_bitrate_bps <= 0) {
|
||||
// Encoding max bitrate is kept if configured.
|
||||
max_bitrate_bps =
|
||||
std::min(max_bitrate_bps, sum_max_bitrates_kbps * 1000);
|
||||
}
|
||||
|
||||
@ -488,4 +488,20 @@ TEST(EncoderStreamFactory, H265TemporalLayerCountTransferToStreamSettings) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(EncoderStreamFactory, VP9SetsMaxBitrateToConfiguredEncodingValue) {
|
||||
VideoEncoderConfig encoder_config;
|
||||
VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
|
||||
encoder_config.encoder_specific_settings =
|
||||
rtc::make_ref_counted<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
|
||||
vp9_settings);
|
||||
encoder_config.codec_type = VideoCodecType::kVideoCodecVP9;
|
||||
encoder_config.number_of_streams = 1;
|
||||
encoder_config.simulcast_layers.resize(3);
|
||||
encoder_config.simulcast_layers[0].max_bitrate_bps = 5000000;
|
||||
auto streams = CreateEncoderStreams(ExplicitKeyValueConfig(""), {1280, 720},
|
||||
encoder_config);
|
||||
ASSERT_THAT(streams, SizeIs(1));
|
||||
EXPECT_EQ(streams[0].max_bitrate_bps, 5000000);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -344,15 +344,14 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsAppliedMiddleActive) {
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, EncodingMinBitrateAppliedMiddleActive) {
|
||||
TEST_P(ResolutionBitrateLimitsTest, EncodingMinMaxBitrateAppliedMiddleActive) {
|
||||
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/");
|
||||
"max_bitrate_bps:1111000|3333000/");
|
||||
|
||||
// Max bitrate: min of encoding and bitrate limits used.
|
||||
InitEncodeTest test(env(), payload_name_,
|
||||
{{.active = false,
|
||||
.bitrate = {DataRate::KilobitsPerSec(28),
|
||||
@ -368,6 +367,49 @@ TEST_P(ResolutionBitrateLimitsTest, EncodingMinBitrateAppliedMiddleActive) {
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, MinBitrateNotAboveEncodingMax) {
|
||||
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:1111000|3333000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
env(), payload_name_,
|
||||
{{.active = false},
|
||||
{.active = true,
|
||||
.bitrate = {std::nullopt, DataRate::KilobitsPerSec(25)}},
|
||||
{.active = false}},
|
||||
// Expectations:
|
||||
{{.pixels = 640 * 360,
|
||||
.eq_bitrate = {DataRate::KilobitsPerSec(25),
|
||||
DataRate::KilobitsPerSec(25)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, MaxBitrateNotBelowEncodingMin) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:230400|921600,"
|
||||
"min_start_bitrate_bps:0|0,"
|
||||
"min_bitrate_bps:21000|22000,"
|
||||
"max_bitrate_bps:31000|32000/");
|
||||
|
||||
InitEncodeTest test(
|
||||
env(), payload_name_,
|
||||
{{.active = false,
|
||||
.bitrate = {DataRate::KilobitsPerSec(50), std::nullopt}},
|
||||
{.active = true,
|
||||
.bitrate = {DataRate::KilobitsPerSec(50), std::nullopt}},
|
||||
{.active = false}},
|
||||
// Expectations:
|
||||
{{.pixels = 640 * 360,
|
||||
.eq_bitrate = {DataRate::KilobitsPerSec(50),
|
||||
DataRate::KilobitsPerSec(50)}}});
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, DefaultLimitsAppliedMiddleActive) {
|
||||
const std::optional<VideoEncoder::ResolutionBitrateLimits>
|
||||
kDefaultSinglecastLimits360p =
|
||||
@ -423,15 +465,14 @@ TEST_P(ResolutionBitrateLimitsTest, LimitsAppliedHighestActive) {
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(ResolutionBitrateLimitsTest, EncodingMinBitrateAppliedHighestActive) {
|
||||
TEST_P(ResolutionBitrateLimitsTest, EncodingMinMaxBitrateAppliedHighestActive) {
|
||||
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/");
|
||||
"max_bitrate_bps:555000|1111000/");
|
||||
|
||||
// Max bitrate: min of encoding and bitrate limits used.
|
||||
InitEncodeTest test(env(), payload_name_,
|
||||
{{.active = false,
|
||||
.bitrate = {DataRate::KilobitsPerSec(28),
|
||||
@ -552,15 +593,14 @@ TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
}
|
||||
|
||||
TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
|
||||
EncodingMinBitrateAppliedForAv1SingleSpatialLayer) {
|
||||
EncodingMinMaxBitrateAppliedForAv1SingleSpatialLayer) {
|
||||
webrtc::test::ScopedFieldTrials field_trials(
|
||||
"WebRTC-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:921600,"
|
||||
"min_start_bitrate_bps:0,"
|
||||
"min_bitrate_bps:32000,"
|
||||
"max_bitrate_bps:133000/");
|
||||
"max_bitrate_bps:99000/");
|
||||
|
||||
// Max bitrate: min of encoding and bitrate limits used.
|
||||
InitEncodeTest test(env(), "AV1",
|
||||
{{.active = true,
|
||||
.bitrate = {DataRate::KilobitsPerSec(28),
|
||||
|
||||
@ -468,15 +468,15 @@ void ApplySpatialLayerBitrateLimits(
|
||||
if (encoder_config.simulcast_layers[*index].max_bitrate_bps <= 0) {
|
||||
max_bitrate_bps = bitrate_limits->max_bitrate_bps;
|
||||
} else {
|
||||
max_bitrate_bps =
|
||||
std::min(bitrate_limits->max_bitrate_bps,
|
||||
encoder_config.simulcast_layers[*index].max_bitrate_bps);
|
||||
max_bitrate_bps = encoder_config.simulcast_layers[*index].max_bitrate_bps;
|
||||
}
|
||||
if (min_bitrate_bps >= max_bitrate_bps) {
|
||||
RTC_LOG(LS_WARNING) << "Bitrate limits not used, min_bitrate_bps "
|
||||
<< min_bitrate_bps << " >= max_bitrate_bps "
|
||||
<< max_bitrate_bps;
|
||||
return;
|
||||
|
||||
if (encoder_config.simulcast_layers[*index].min_bitrate_bps > 0) {
|
||||
// Ensure max is not below configured min.
|
||||
max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
|
||||
} else {
|
||||
// Ensure min is not above max.
|
||||
min_bitrate_bps = std::min(min_bitrate_bps, max_bitrate_bps);
|
||||
}
|
||||
|
||||
for (int i = 0; i < GetNumSpatialLayers(*codec); ++i) {
|
||||
@ -484,7 +484,8 @@ void ApplySpatialLayerBitrateLimits(
|
||||
codec->spatialLayers[i].minBitrate = min_bitrate_bps / 1000;
|
||||
codec->spatialLayers[i].maxBitrate = max_bitrate_bps / 1000;
|
||||
codec->spatialLayers[i].targetBitrate =
|
||||
std::min(codec->spatialLayers[i].targetBitrate,
|
||||
std::clamp(codec->spatialLayers[i].targetBitrate,
|
||||
codec->spatialLayers[i].minBitrate,
|
||||
codec->spatialLayers[i].maxBitrate);
|
||||
break;
|
||||
}
|
||||
@ -531,25 +532,21 @@ void ApplyEncoderBitrateLimitsIfSingleActiveStream(
|
||||
if (encoder_config_layers[index].max_bitrate_bps <= 0) {
|
||||
max_bitrate_bps = encoder_bitrate_limits->max_bitrate_bps;
|
||||
} else {
|
||||
max_bitrate_bps = std::min(encoder_bitrate_limits->max_bitrate_bps,
|
||||
(*streams)[index].max_bitrate_bps);
|
||||
max_bitrate_bps = (*streams)[index].max_bitrate_bps;
|
||||
}
|
||||
if (min_bitrate_bps >= max_bitrate_bps) {
|
||||
RTC_LOG(LS_WARNING) << "Encoder bitrate limits"
|
||||
<< " (min=" << encoder_bitrate_limits->min_bitrate_bps
|
||||
<< ", max=" << encoder_bitrate_limits->max_bitrate_bps
|
||||
<< ") do not intersect with stream limits"
|
||||
<< " (min=" << (*streams)[index].min_bitrate_bps
|
||||
<< ", max=" << (*streams)[index].max_bitrate_bps
|
||||
<< "). Encoder bitrate limits not used.";
|
||||
return;
|
||||
|
||||
if (encoder_config_layers[index].min_bitrate_bps > 0) {
|
||||
// Ensure max is not below configured min.
|
||||
max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
|
||||
} else {
|
||||
// Ensure min is not above max.
|
||||
min_bitrate_bps = std::min(min_bitrate_bps, max_bitrate_bps);
|
||||
}
|
||||
|
||||
(*streams)[index].min_bitrate_bps = min_bitrate_bps;
|
||||
(*streams)[index].max_bitrate_bps = max_bitrate_bps;
|
||||
(*streams)[index].target_bitrate_bps =
|
||||
std::min((*streams)[index].target_bitrate_bps,
|
||||
encoder_bitrate_limits->max_bitrate_bps);
|
||||
(*streams)[index].target_bitrate_bps = std::clamp(
|
||||
(*streams)[index].target_bitrate_bps, min_bitrate_bps, max_bitrate_bps);
|
||||
}
|
||||
|
||||
std::optional<int> ParseVp9LowTierCoreCountThreshold(
|
||||
|
||||
@ -2685,16 +2685,18 @@ TEST_F(VideoStreamEncoderTest,
|
||||
config.video_stream_factory = nullptr;
|
||||
video_stream_encoder_->ConfigureEncoder(config.Copy(), kMaxPayloadLength);
|
||||
|
||||
// The encoder bitrate limits for 270p should be used.
|
||||
// The max configured bitrate should be used.
|
||||
// The encoder bitrate limits for 270p should be used for min bitrate
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(1, 480, 270));
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
EXPECT_EQ(fake_encoder_.config().numberOfSimulcastStreams, kNumStreams);
|
||||
EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits270p.min_bitrate_bps),
|
||||
fake_encoder_.config().simulcastStream[1].minBitrate * 1000);
|
||||
EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits270p.max_bitrate_bps),
|
||||
EXPECT_EQ(static_cast<uint32_t>(kMaxBitrateBps),
|
||||
fake_encoder_.config().simulcastStream[1].maxBitrate * 1000);
|
||||
|
||||
// The max configured bitrate is less than the encoder limit for 360p.
|
||||
// The max configured bitrate should be used.
|
||||
// The encoder bitrate limits for 360p should be used for min bitrate
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits360p.min_bitrate_bps),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user