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