1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "video/alignment_adjuster.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <tuple>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker
17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/safe_conversions.h"
18*d9f75844SAndroid Build Coastguard Worker #include "test/encoder_settings.h"
19*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
20*d9f75844SAndroid Build Coastguard Worker
21*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
22*d9f75844SAndroid Build Coastguard Worker namespace test {
23*d9f75844SAndroid Build Coastguard Worker namespace {
GetEncoderInfo(int alignment,bool apply)24*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo GetEncoderInfo(int alignment, bool apply) {
25*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo info;
26*d9f75844SAndroid Build Coastguard Worker info.requested_resolution_alignment = alignment;
27*d9f75844SAndroid Build Coastguard Worker info.apply_alignment_to_all_simulcast_layers = apply;
28*d9f75844SAndroid Build Coastguard Worker return info;
29*d9f75844SAndroid Build Coastguard Worker }
30*d9f75844SAndroid Build Coastguard Worker } // namespace
31*d9f75844SAndroid Build Coastguard Worker
32*d9f75844SAndroid Build Coastguard Worker class AlignmentAdjusterTest
33*d9f75844SAndroid Build Coastguard Worker : public ::testing::TestWithParam<::testing::tuple<
34*d9f75844SAndroid Build Coastguard Worker int,
35*d9f75844SAndroid Build Coastguard Worker std::tuple<std::vector<double>, std::vector<double>, int>>> {
36*d9f75844SAndroid Build Coastguard Worker protected:
AlignmentAdjusterTest()37*d9f75844SAndroid Build Coastguard Worker AlignmentAdjusterTest()
38*d9f75844SAndroid Build Coastguard Worker : kRequestedAlignment(std::get<0>(GetParam())),
39*d9f75844SAndroid Build Coastguard Worker kScaleFactors(std::get<0>(std::get<1>(GetParam()))),
40*d9f75844SAndroid Build Coastguard Worker kAdjustedScaleFactors(std::get<1>(std::get<1>(GetParam()))),
41*d9f75844SAndroid Build Coastguard Worker kAdjustedAlignment(std::get<2>(std::get<1>(GetParam()))) {}
42*d9f75844SAndroid Build Coastguard Worker
43*d9f75844SAndroid Build Coastguard Worker const int kRequestedAlignment;
44*d9f75844SAndroid Build Coastguard Worker const std::vector<double> kScaleFactors;
45*d9f75844SAndroid Build Coastguard Worker const std::vector<double> kAdjustedScaleFactors;
46*d9f75844SAndroid Build Coastguard Worker const int kAdjustedAlignment;
47*d9f75844SAndroid Build Coastguard Worker };
48*d9f75844SAndroid Build Coastguard Worker
49*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
50*d9f75844SAndroid Build Coastguard Worker ScaleFactorsAndAlignment,
51*d9f75844SAndroid Build Coastguard Worker AlignmentAdjusterTest,
52*d9f75844SAndroid Build Coastguard Worker ::testing::Combine(
53*d9f75844SAndroid Build Coastguard Worker ::testing::Values(2), // kRequestedAlignment
54*d9f75844SAndroid Build Coastguard Worker ::testing::Values(
55*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0}, // kScaleFactors
56*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0}, // kAdjustedScaleFactors
57*d9f75844SAndroid Build Coastguard Worker 2), // default: {1.0} // kAdjustedAlignment
58*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0, -1.0},
59*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0, -1.0},
60*d9f75844SAndroid Build Coastguard Worker 4), // default: {1.0, 2.0}
61*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0, -1.0, -1.0},
62*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0, -1.0, -1.0},
63*d9f75844SAndroid Build Coastguard Worker 8), // default: {1.0, 2.0, 4.0}
64*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{1.0, 2.0, 4.0},
65*d9f75844SAndroid Build Coastguard Worker std::vector<double>{1.0, 2.0, 4.0},
66*d9f75844SAndroid Build Coastguard Worker 8),
67*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{9999.0, -1.0, 1.0},
68*d9f75844SAndroid Build Coastguard Worker std::vector<double>{8.0, 1.0, 1.0},
69*d9f75844SAndroid Build Coastguard Worker 16), // kMaxAlignment
70*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{3.99, 2.01, 1.0},
71*d9f75844SAndroid Build Coastguard Worker std::vector<double>{4.0, 2.0, 1.0},
72*d9f75844SAndroid Build Coastguard Worker 8),
73*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{2.9, 2.1},
74*d9f75844SAndroid Build Coastguard Worker std::vector<double>{6.0 / 2.0, 6.0 / 3.0},
75*d9f75844SAndroid Build Coastguard Worker 12),
76*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{4.9, 1.7, 1.2},
77*d9f75844SAndroid Build Coastguard Worker std::vector<double>{5.0, 5.0 / 3.0, 5.0 / 4.0},
78*d9f75844SAndroid Build Coastguard Worker 10),
79*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{1.0, 1.3},
80*d9f75844SAndroid Build Coastguard Worker std::vector<double>{4.0 / 4.0, 4.0 / 3.0},
81*d9f75844SAndroid Build Coastguard Worker 8),
82*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{1.75, 3.5},
83*d9f75844SAndroid Build Coastguard Worker std::vector<double>{7.0 / 4.0, 7.0 / 2.0},
84*d9f75844SAndroid Build Coastguard Worker 7),
85*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{1.5, 2.5},
86*d9f75844SAndroid Build Coastguard Worker std::vector<double>{1.5, 2.5},
87*d9f75844SAndroid Build Coastguard Worker 15))));
88*d9f75844SAndroid Build Coastguard Worker
89*d9f75844SAndroid Build Coastguard Worker class AlignmentAdjusterTestTwoLayers : public AlignmentAdjusterTest {
90*d9f75844SAndroid Build Coastguard Worker protected:
91*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 2;
92*d9f75844SAndroid Build Coastguard Worker };
93*d9f75844SAndroid Build Coastguard Worker
94*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
95*d9f75844SAndroid Build Coastguard Worker ScaleFactorsAndAlignmentWithMaxLayers,
96*d9f75844SAndroid Build Coastguard Worker AlignmentAdjusterTestTwoLayers,
97*d9f75844SAndroid Build Coastguard Worker ::testing::Combine(
98*d9f75844SAndroid Build Coastguard Worker ::testing::Values(2), // kRequestedAlignment
99*d9f75844SAndroid Build Coastguard Worker ::testing::Values(
100*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0}, // kScaleFactors
101*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0}, // kAdjustedScaleFactors
102*d9f75844SAndroid Build Coastguard Worker 2), // default: {1.0} // kAdjustedAlignment
103*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0, -1.0},
104*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0, -1.0},
105*d9f75844SAndroid Build Coastguard Worker 4), // default: {1.0, 2.0}
106*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{-1.0, -1.0, -1.0},
107*d9f75844SAndroid Build Coastguard Worker std::vector<double>{-1.0, -1.0, -1.0},
108*d9f75844SAndroid Build Coastguard Worker 4), // default: {1.0, 2.0, 4.0}
109*d9f75844SAndroid Build Coastguard Worker std::make_tuple(std::vector<double>{1.0, 2.0, 4.0},
110*d9f75844SAndroid Build Coastguard Worker std::vector<double>{1.0, 2.0, 4.0},
111*d9f75844SAndroid Build Coastguard Worker 8))));
112*d9f75844SAndroid Build Coastguard Worker
TEST_P(AlignmentAdjusterTest,AlignmentAppliedToAllLayers)113*d9f75844SAndroid Build Coastguard Worker TEST_P(AlignmentAdjusterTest, AlignmentAppliedToAllLayers) {
114*d9f75844SAndroid Build Coastguard Worker const bool kApplyAlignmentToAllLayers = true;
115*d9f75844SAndroid Build Coastguard Worker
116*d9f75844SAndroid Build Coastguard Worker // Fill config with the scaling factor by which to reduce encoding size.
117*d9f75844SAndroid Build Coastguard Worker const int num_streams = kScaleFactors.size();
118*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig config;
119*d9f75844SAndroid Build Coastguard Worker test::FillEncoderConfiguration(kVideoCodecVP8, num_streams, &config);
120*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
121*d9f75844SAndroid Build Coastguard Worker config.simulcast_layers[i].scale_resolution_down_by = kScaleFactors[i];
122*d9f75844SAndroid Build Coastguard Worker }
123*d9f75844SAndroid Build Coastguard Worker
124*d9f75844SAndroid Build Coastguard Worker // Verify requested alignment from sink.
125*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo info =
126*d9f75844SAndroid Build Coastguard Worker GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
127*d9f75844SAndroid Build Coastguard Worker int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
128*d9f75844SAndroid Build Coastguard Worker info, &config, absl::nullopt);
129*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(alignment, kAdjustedAlignment);
130*d9f75844SAndroid Build Coastguard Worker
131*d9f75844SAndroid Build Coastguard Worker // Verify adjusted scale factors.
132*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
133*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(config.simulcast_layers[i].scale_resolution_down_by,
134*d9f75844SAndroid Build Coastguard Worker kAdjustedScaleFactors[i]);
135*d9f75844SAndroid Build Coastguard Worker }
136*d9f75844SAndroid Build Coastguard Worker }
137*d9f75844SAndroid Build Coastguard Worker
TEST_P(AlignmentAdjusterTest,AlignmentNotAppliedToAllLayers)138*d9f75844SAndroid Build Coastguard Worker TEST_P(AlignmentAdjusterTest, AlignmentNotAppliedToAllLayers) {
139*d9f75844SAndroid Build Coastguard Worker const bool kApplyAlignmentToAllLayers = false;
140*d9f75844SAndroid Build Coastguard Worker
141*d9f75844SAndroid Build Coastguard Worker // Fill config with the scaling factor by which to reduce encoding size.
142*d9f75844SAndroid Build Coastguard Worker const int num_streams = kScaleFactors.size();
143*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig config;
144*d9f75844SAndroid Build Coastguard Worker test::FillEncoderConfiguration(kVideoCodecVP8, num_streams, &config);
145*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
146*d9f75844SAndroid Build Coastguard Worker config.simulcast_layers[i].scale_resolution_down_by = kScaleFactors[i];
147*d9f75844SAndroid Build Coastguard Worker }
148*d9f75844SAndroid Build Coastguard Worker
149*d9f75844SAndroid Build Coastguard Worker // Verify requested alignment from sink, alignment is not adjusted.
150*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo info =
151*d9f75844SAndroid Build Coastguard Worker GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
152*d9f75844SAndroid Build Coastguard Worker int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
153*d9f75844SAndroid Build Coastguard Worker info, &config, absl::nullopt);
154*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(alignment, kRequestedAlignment);
155*d9f75844SAndroid Build Coastguard Worker
156*d9f75844SAndroid Build Coastguard Worker // Verify that scale factors are not adjusted.
157*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
158*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(config.simulcast_layers[i].scale_resolution_down_by,
159*d9f75844SAndroid Build Coastguard Worker kScaleFactors[i]);
160*d9f75844SAndroid Build Coastguard Worker }
161*d9f75844SAndroid Build Coastguard Worker }
162*d9f75844SAndroid Build Coastguard Worker
TEST_P(AlignmentAdjusterTestTwoLayers,AlignmentAppliedToAllLayers)163*d9f75844SAndroid Build Coastguard Worker TEST_P(AlignmentAdjusterTestTwoLayers, AlignmentAppliedToAllLayers) {
164*d9f75844SAndroid Build Coastguard Worker const bool kApplyAlignmentToAllLayers = true;
165*d9f75844SAndroid Build Coastguard Worker
166*d9f75844SAndroid Build Coastguard Worker // Fill config with the scaling factor by which to reduce encoding size.
167*d9f75844SAndroid Build Coastguard Worker const int num_streams = kScaleFactors.size();
168*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig config;
169*d9f75844SAndroid Build Coastguard Worker test::FillEncoderConfiguration(kVideoCodecVP8, num_streams, &config);
170*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
171*d9f75844SAndroid Build Coastguard Worker config.simulcast_layers[i].scale_resolution_down_by = kScaleFactors[i];
172*d9f75844SAndroid Build Coastguard Worker }
173*d9f75844SAndroid Build Coastguard Worker
174*d9f75844SAndroid Build Coastguard Worker // Verify requested alignment from sink, alignment is not adjusted.
175*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo info =
176*d9f75844SAndroid Build Coastguard Worker GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
177*d9f75844SAndroid Build Coastguard Worker int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
178*d9f75844SAndroid Build Coastguard Worker info, &config, absl::optional<size_t>(kMaxLayers));
179*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(alignment, kAdjustedAlignment);
180*d9f75844SAndroid Build Coastguard Worker
181*d9f75844SAndroid Build Coastguard Worker // Verify adjusted scale factors.
182*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_streams; ++i) {
183*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(config.simulcast_layers[i].scale_resolution_down_by,
184*d9f75844SAndroid Build Coastguard Worker kAdjustedScaleFactors[i]);
185*d9f75844SAndroid Build Coastguard Worker }
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker
188*d9f75844SAndroid Build Coastguard Worker } // namespace test
189*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
190