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}
diff --git a/video/alignment_adjuster.cc b/video/alignment_adjuster.cc
index b08f2f1..6b1db92 100644
--- a/video/alignment_adjuster.cc
+++ b/video/alignment_adjuster.cc
@@ -66,7 +66,8 @@
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 @@
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.
diff --git a/video/alignment_adjuster.h b/video/alignment_adjuster.h
index 53d7927..4b72623 100644
--- a/video/alignment_adjuster.h
+++ b/video/alignment_adjuster.h
@@ -28,9 +28,13 @@
// |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
diff --git a/video/alignment_adjuster_unittest.cc b/video/alignment_adjuster_unittest.cc
index 07c7de5..28e4bc0 100644
--- a/video/alignment_adjuster_unittest.cc
+++ b/video/alignment_adjuster_unittest.cc
@@ -86,6 +86,30 @@
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 @@
// 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 @@
// 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(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
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 1cfb280..3d87379 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -726,13 +726,17 @@
// 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