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