blob: 28e4bc0550fb6a93e344b7ebec3c78c261bfc203 [file] [log] [blame]
/*
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/alignment_adjuster.h"
#include <memory>
#include <tuple>
#include <vector>
#include "rtc_base/numerics/safe_conversions.h"
#include "test/encoder_settings.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
VideoEncoder::EncoderInfo GetEncoderInfo(int alignment, bool apply) {
VideoEncoder::EncoderInfo info;
info.requested_resolution_alignment = alignment;
info.apply_alignment_to_all_simulcast_layers = apply;
return info;
}
} // namespace
class AlignmentAdjusterTest
: public ::testing::TestWithParam<::testing::tuple<
int,
std::tuple<std::vector<double>, std::vector<double>, int>>> {
protected:
AlignmentAdjusterTest()
: kRequestedAlignment(std::get<0>(GetParam())),
kScaleFactors(std::get<0>(std::get<1>(GetParam()))),
kAdjustedScaleFactors(std::get<1>(std::get<1>(GetParam()))),
kAdjustedAlignment(std::get<2>(std::get<1>(GetParam()))) {}
const int kRequestedAlignment;
const std::vector<double> kScaleFactors;
const std::vector<double> kAdjustedScaleFactors;
const int kAdjustedAlignment;
};
INSTANTIATE_TEST_SUITE_P(
ScaleFactorsAndAlignment,
AlignmentAdjusterTest,
::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},
8), // 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),
std::make_tuple(std::vector<double>{9999.0, -1.0, 1.0},
std::vector<double>{8.0, 1.0, 1.0},
16), // kMaxAlignment
std::make_tuple(std::vector<double>{3.99, 2.01, 1.0},
std::vector<double>{4.0, 2.0, 1.0},
8),
std::make_tuple(std::vector<double>{2.9, 2.1},
std::vector<double>{6.0 / 2.0, 6.0 / 3.0},
12),
std::make_tuple(std::vector<double>{4.9, 1.7, 1.2},
std::vector<double>{5.0, 5.0 / 3.0, 5.0 / 4.0},
10),
std::make_tuple(std::vector<double>{1.0, 1.3},
std::vector<double>{4.0 / 4.0, 4.0 / 3.0},
8),
std::make_tuple(std::vector<double>{1.75, 3.5},
std::vector<double>{7.0 / 4.0, 7.0 / 2.0},
7),
std::make_tuple(std::vector<double>{1.5, 2.5},
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;
// 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.
VideoEncoder::EncoderInfo info =
GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
info, &config, absl::nullopt);
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]);
}
}
TEST_P(AlignmentAdjusterTest, AlignmentNotAppliedToAllLayers) {
const bool kApplyAlignmentToAllLayers = false;
// 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::nullopt);
EXPECT_EQ(alignment, kRequestedAlignment);
// Verify that scale factors are not adjusted.
for (int i = 0; i < num_streams; ++i) {
EXPECT_EQ(config.simulcast_layers[i].scale_resolution_down_by,
kScaleFactors[i]);
}
}
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