AlignmentAdjuster: take reduced layers into account for default downscaling.

Bug: none
Change-Id: Id70f7763d2e1b11c24ad98774f1bf6a661728437
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/202257
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33038}
This commit is contained in:
Åsa Persson 2021-01-19 10:25:10 +01:00 committed by Commit Bot
parent 5c3ff6b60f
commit a24d35eb09
4 changed files with 71 additions and 9 deletions

View File

@ -66,7 +66,8 @@ double RoundToMultiple(int alignment,
int AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
const VideoEncoder::EncoderInfo& encoder_info,
VideoEncoderConfig* config) {
VideoEncoderConfig* config,
absl::optional<size_t> max_layers) {
const int requested_alignment = encoder_info.requested_resolution_alignment;
if (!encoder_info.apply_alignment_to_all_simulcast_layers) {
return requested_alignment;
@ -85,7 +86,11 @@ int AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
if (!has_scale_resolution_down_by) {
// Default resolution downscaling used (scale factors: 1, 2, 4, ...).
return requested_alignment * (1 << (config->simulcast_layers.size() - 1));
size_t size = config->simulcast_layers.size();
if (max_layers && *max_layers > 0 && *max_layers < size) {
size = *max_layers;
}
return requested_alignment * (1 << (size - 1));
}
// Get alignment for downscaled layers.

View File

@ -28,9 +28,13 @@ class AlignmentAdjuster {
// |scale_resolution_down_by| may be adjusted to a common multiple to limit
// the alignment value to avoid largely cropped frames and possibly with an
// aspect ratio far from the original.
// Note: |max_layers| currently only taken into account when using default
// scale factors.
static int GetAlignmentAndMaybeAdjustScaleFactors(
const VideoEncoder::EncoderInfo& info,
VideoEncoderConfig* config);
VideoEncoderConfig* config,
absl::optional<size_t> max_layers);
};
} // namespace webrtc

View File

@ -86,6 +86,30 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<double>{1.5, 2.5},
15))));
class AlignmentAdjusterTestTwoLayers : public AlignmentAdjusterTest {
protected:
const int kMaxLayers = 2;
};
INSTANTIATE_TEST_SUITE_P(
ScaleFactorsAndAlignmentWithMaxLayers,
AlignmentAdjusterTestTwoLayers,
::testing::Combine(
::testing::Values(2), // kRequestedAlignment
::testing::Values(
std::make_tuple(std::vector<double>{-1.0}, // kScaleFactors
std::vector<double>{-1.0}, // kAdjustedScaleFactors
2), // default: {1.0} // kAdjustedAlignment
std::make_tuple(std::vector<double>{-1.0, -1.0},
std::vector<double>{-1.0, -1.0},
4), // default: {1.0, 2.0}
std::make_tuple(std::vector<double>{-1.0, -1.0, -1.0},
std::vector<double>{-1.0, -1.0, -1.0},
4), // default: {1.0, 2.0, 4.0}
std::make_tuple(std::vector<double>{1.0, 2.0, 4.0},
std::vector<double>{1.0, 2.0, 4.0},
8))));
TEST_P(AlignmentAdjusterTest, AlignmentAppliedToAllLayers) {
const bool kApplyAlignmentToAllLayers = true;
@ -100,8 +124,8 @@ TEST_P(AlignmentAdjusterTest, AlignmentAppliedToAllLayers) {
// Verify requested alignment from sink.
VideoEncoder::EncoderInfo info =
GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
int alignment =
AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(info, &config);
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
info, &config, absl::nullopt);
EXPECT_EQ(alignment, kAdjustedAlignment);
// Verify adjusted scale factors.
@ -125,8 +149,8 @@ TEST_P(AlignmentAdjusterTest, AlignmentNotAppliedToAllLayers) {
// Verify requested alignment from sink, alignment is not adjusted.
VideoEncoder::EncoderInfo info =
GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
int alignment =
AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(info, &config);
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
info, &config, absl::nullopt);
EXPECT_EQ(alignment, kRequestedAlignment);
// Verify that scale factors are not adjusted.
@ -136,5 +160,30 @@ TEST_P(AlignmentAdjusterTest, AlignmentNotAppliedToAllLayers) {
}
}
TEST_P(AlignmentAdjusterTestTwoLayers, AlignmentAppliedToAllLayers) {
const bool kApplyAlignmentToAllLayers = true;
// Fill config with the scaling factor by which to reduce encoding size.
const int num_streams = kScaleFactors.size();
VideoEncoderConfig config;
test::FillEncoderConfiguration(kVideoCodecVP8, num_streams, &config);
for (int i = 0; i < num_streams; ++i) {
config.simulcast_layers[i].scale_resolution_down_by = kScaleFactors[i];
}
// Verify requested alignment from sink, alignment is not adjusted.
VideoEncoder::EncoderInfo info =
GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
info, &config, absl::optional<size_t>(kMaxLayers));
EXPECT_EQ(alignment, kAdjustedAlignment);
// Verify adjusted scale factors.
for (int i = 0; i < num_streams; ++i) {
EXPECT_EQ(config.simulcast_layers[i].scale_resolution_down_by,
kAdjustedScaleFactors[i]);
}
}
} // namespace test
} // namespace webrtc

View File

@ -726,13 +726,17 @@ void VideoStreamEncoder::ReconfigureEncoder() {
// Possibly adjusts scale_resolution_down_by in |encoder_config_| to limit the
// alignment value.
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
encoder_->GetEncoderInfo(), &encoder_config_);
AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
encoder_->GetEncoderInfo(), &encoder_config_, absl::nullopt);
std::vector<VideoStream> streams =
encoder_config_.video_stream_factory->CreateEncoderStreams(
last_frame_info_->width, last_frame_info_->height, encoder_config_);
// Get alignment when actual number of layers are known.
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
encoder_->GetEncoderInfo(), &encoder_config_, streams.size());
// Check that the higher layers do not try to set number of temporal layers
// to less than 1.
// TODO(brandtr): Get rid of the wrapping optional as it serves no purpose