xref: /aosp_15_r20/external/libgav1/src/dsp/dsp_test.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1 // Copyright 2020 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/dsp/dsp.h"
16 
17 #include <algorithm>
18 #include <cstddef>
19 #include <cstdint>
20 
21 #include "absl/strings/str_cat.h"
22 #include "gtest/gtest.h"
23 #include "src/dsp/constants.h"
24 #include "src/utils/constants.h"
25 #include "src/utils/cpu.h"
26 
27 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
28 #include "tests/utils.h"
29 #endif
30 
31 namespace libgav1 {
32 namespace dsp {
33 namespace {
34 
35 // Maps 1D transform to the maximum valid size for the corresponding transform.
36 constexpr int kMaxTransform1dSize[kNumTransform1ds] = {
37     kTransform1dSize64,  // Dct.
38     kTransform1dSize16,  // Adst.
39     kTransform1dSize32,  // Identity.
40     kTransform1dSize4,   // Wht.
41 };
42 
CheckTables(bool c_only)43 void CheckTables(bool c_only) {
44 #if LIBGAV1_MAX_BITDEPTH == 12
45   static constexpr int kBitdepths[] = {kBitdepth8, kBitdepth10, kBitdepth12};
46 #elif LIBGAV1_MAX_BITDEPTH >= 10
47   static constexpr int kBitdepths[] = {kBitdepth8, kBitdepth10};
48 #else
49   static constexpr int kBitdepths[] = {kBitdepth8};
50 #endif
51 
52   for (const auto& bitdepth : kBitdepths) {
53     const Dsp* const dsp = GetDspTable(bitdepth);
54     ASSERT_NE(dsp, nullptr);
55     SCOPED_TRACE(absl::StrCat("bitdepth: ", bitdepth));
56     for (int i = 0; i < kNumTransformSizes; ++i) {
57       for (int j = 0; j < kNumIntraPredictors; ++j) {
58         EXPECT_NE(dsp->intra_predictors[i][j], nullptr)
59             << "index [" << i << "][" << j << "]";
60       }
61     }
62     EXPECT_NE(dsp->directional_intra_predictor_zone1, nullptr);
63     EXPECT_NE(dsp->directional_intra_predictor_zone2, nullptr);
64     EXPECT_NE(dsp->directional_intra_predictor_zone3, nullptr);
65     EXPECT_NE(dsp->filter_intra_predictor, nullptr);
66     for (int i = 0; i < kNumTransformSizes; ++i) {
67       if (std::max(kTransformWidth[i], kTransformHeight[i]) == 64) {
68         EXPECT_EQ(dsp->cfl_intra_predictors[i], nullptr)
69             << "index [" << i << "]";
70         for (int j = 0; j < kNumSubsamplingTypes; ++j) {
71           EXPECT_EQ(dsp->cfl_subsamplers[i][j], nullptr)
72               << "index [" << i << "][" << j << "]";
73         }
74       } else {
75         EXPECT_NE(dsp->cfl_intra_predictors[i], nullptr)
76             << "index [" << i << "]";
77         for (int j = 0; j < kNumSubsamplingTypes; ++j) {
78           EXPECT_NE(dsp->cfl_subsamplers[i][j], nullptr)
79               << "index [" << i << "][" << j << "]";
80         }
81       }
82     }
83     EXPECT_NE(dsp->intra_edge_filter, nullptr);
84     EXPECT_NE(dsp->intra_edge_upsampler, nullptr);
85     for (int i = 0; i < kNumTransform1ds; ++i) {
86       for (int j = 0; j < kNumTransform1dSizes; ++j) {
87         for (int k = 0; k < 2; ++k) {
88           if (j <= kMaxTransform1dSize[i]) {
89             EXPECT_NE(dsp->inverse_transforms[i][j][k], nullptr)
90                 << "index [" << i << "][" << j << "][" << k << "]";
91           } else {
92             EXPECT_EQ(dsp->inverse_transforms[i][j][k], nullptr)
93                 << "index [" << i << "][" << j << "][" << k << "]";
94           }
95         }
96       }
97     }
98     for (int i = 0; i < kNumLoopFilterSizes; ++i) {
99       for (int j = 0; j < kNumLoopFilterTypes; ++j) {
100         EXPECT_NE(dsp->loop_filters[i][j], nullptr)
101             << "index [" << i << "][" << j << "]";
102       }
103     }
104     for (int i = 0; i < 2; ++i) {
105       EXPECT_NE(dsp->loop_restorations[i], nullptr) << "index [" << i << "]";
106     }
107 
108     bool super_res_coefficients_is_nonnull = LIBGAV1_ENABLE_NEON;
109 #if LIBGAV1_ENABLE_SSE4_1
110     const uint32_t cpu_features = GetCpuInfo();
111     super_res_coefficients_is_nonnull = (cpu_features & kSSE4_1) != 0;
112 #endif
113     if (c_only || bitdepth == kBitdepth12) {
114       super_res_coefficients_is_nonnull = false;
115     }
116     if (super_res_coefficients_is_nonnull) {
117       EXPECT_NE(dsp->super_res_coefficients, nullptr);
118     } else {
119       EXPECT_EQ(dsp->super_res_coefficients, nullptr);
120     }
121 
122     EXPECT_NE(dsp->super_res, nullptr);
123     EXPECT_NE(dsp->cdef_direction, nullptr);
124     for (int i = 0; i < 2; ++i) {
125       for (int j = 0; j < 3; ++j) {
126         EXPECT_NE(dsp->cdef_filters[i][j], nullptr)
127             << "index [" << i << "][" << j << "]";
128       }
129     }
130     for (auto convolve_func : dsp->convolve_scale) {
131       EXPECT_NE(convolve_func, nullptr);
132     }
133     for (int j = 0; j < 2; ++j) {
134       for (int k = 0; k < 2; ++k) {
135         for (int l = 0; l < 2; ++l) {
136           for (int m = 0; m < 2; ++m) {
137             if (j == 1 && k == 1) {
138               EXPECT_EQ(dsp->convolve[j][k][l][m], nullptr);
139             } else {
140               EXPECT_NE(dsp->convolve[j][k][l][m], nullptr);
141             }
142           }
143         }
144       }
145     }
146     for (const auto& m : dsp->mask_blend) {
147       for (int i = 0; i < 2; ++i) {
148         if (i == 0 || bitdepth >= 10) {
149           EXPECT_NE(m[i], nullptr);
150         } else {
151           EXPECT_EQ(m[i], nullptr);
152         }
153       }
154     }
155     for (const auto& m : dsp->inter_intra_mask_blend_8bpp) {
156       if (bitdepth == 8) {
157         EXPECT_NE(m, nullptr);
158       } else {
159         EXPECT_EQ(m, nullptr);
160       }
161     }
162     for (int i = kBlock4x4; i < kMaxBlockSizes; ++i) {
163       const int width_index = k4x4WidthLog2[i] - 1;
164       const int height_index = k4x4HeightLog2[i] - 1;
165       // Only block sizes >= 8x8 are handled with this function.
166       if (width_index < 0 || height_index < 0) continue;
167 
168       for (size_t j = 0; j < 2; ++j) {
169         EXPECT_NE(dsp->weight_mask[width_index][height_index][j], nullptr)
170             << ToString(static_cast<BlockSize>(i)) << " index [" << width_index
171             << "]"
172             << "[" << height_index << "][" << j << "]";
173       }
174     }
175 
176     EXPECT_NE(dsp->average_blend, nullptr);
177     EXPECT_NE(dsp->distance_weighted_blend, nullptr);
178     for (int i = 0; i < kNumObmcDirections; ++i) {
179       EXPECT_NE(dsp->obmc_blend[i], nullptr)
180           << "index [" << ToString(static_cast<ObmcDirection>(i)) << "]";
181     }
182     EXPECT_NE(dsp->warp, nullptr);
183     EXPECT_NE(dsp->warp_compound, nullptr);
184 
185     for (int i = 0; i < kNumAutoRegressionLags - 1; ++i) {
186       EXPECT_NE(dsp->film_grain.luma_auto_regression[i], nullptr)
187           << "index [" << i << "]";
188     }
189     for (int i = 0; i < 2; ++i) {
190       for (int j = 0; j < kNumAutoRegressionLags; ++j) {
191         if (i == 0 && j == 0) {
192           EXPECT_EQ(dsp->film_grain.chroma_auto_regression[i][j], nullptr)
193               << " index [" << i << "]"
194               << "[" << j << "]";
195         } else {
196           EXPECT_NE(dsp->film_grain.chroma_auto_regression[i][j], nullptr)
197               << " index [" << i << "]"
198               << "[" << j << "]";
199         }
200       }
201       EXPECT_NE(dsp->film_grain.construct_noise_stripes[i], nullptr)
202           << "index [" << i << "]";
203       EXPECT_NE(dsp->film_grain.blend_noise_chroma[i], nullptr)
204           << "index [" << i << "]";
205     }
206     EXPECT_NE(dsp->film_grain.construct_noise_image_overlap, nullptr);
207     EXPECT_NE(dsp->film_grain.initialize_scaling_lut, nullptr);
208     EXPECT_NE(dsp->film_grain.blend_noise_luma, nullptr);
209 
210     if (bitdepth == 8) {
211       EXPECT_NE(dsp->motion_field_projection_kernel, nullptr);
212       EXPECT_NE(dsp->mv_projection_compound[0], nullptr);
213       EXPECT_NE(dsp->mv_projection_compound[1], nullptr);
214       EXPECT_NE(dsp->mv_projection_compound[2], nullptr);
215       EXPECT_NE(dsp->mv_projection_single[0], nullptr);
216       EXPECT_NE(dsp->mv_projection_single[1], nullptr);
217       EXPECT_NE(dsp->mv_projection_single[2], nullptr);
218     } else {
219       EXPECT_EQ(dsp->motion_field_projection_kernel, nullptr);
220       EXPECT_EQ(dsp->mv_projection_compound[0], nullptr);
221       EXPECT_EQ(dsp->mv_projection_compound[1], nullptr);
222       EXPECT_EQ(dsp->mv_projection_compound[2], nullptr);
223       EXPECT_EQ(dsp->mv_projection_single[0], nullptr);
224       EXPECT_EQ(dsp->mv_projection_single[1], nullptr);
225       EXPECT_EQ(dsp->mv_projection_single[2], nullptr);
226     }
227   }
228 }
229 
TEST(Dsp,TablesArePopulated)230 TEST(Dsp, TablesArePopulated) {
231   DspInit();
232   CheckTables(/*c_only=*/false);
233 }
234 
235 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
TEST(Dsp,TablesArePopulatedCOnly)236 TEST(Dsp, TablesArePopulatedCOnly) {
237   test_utils::ResetDspTable(kBitdepth8);
238 #if LIBGAV1_MAX_BITDEPTH >= 10
239   test_utils::ResetDspTable(kBitdepth10);
240 #endif
241 #if LIBGAV1_MAX_BITDEPTH == 12
242   test_utils::ResetDspTable(kBitdepth12);
243 #endif
244   dsp_internal::DspInit_C();
245   CheckTables(/*c_only=*/true);
246 }
247 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
248 
TEST(Dsp,GetDspTable)249 TEST(Dsp, GetDspTable) {
250   EXPECT_EQ(GetDspTable(1), nullptr);
251   EXPECT_NE(GetDspTable(kBitdepth8), nullptr);
252   EXPECT_EQ(dsp_internal::GetWritableDspTable(1), nullptr);
253   EXPECT_NE(dsp_internal::GetWritableDspTable(kBitdepth8), nullptr);
254 #if LIBGAV1_MAX_BITDEPTH >= 10
255   EXPECT_NE(GetDspTable(kBitdepth10), nullptr);
256   EXPECT_NE(dsp_internal::GetWritableDspTable(kBitdepth10), nullptr);
257 #else
258   EXPECT_EQ(GetDspTable(kBitdepth10), nullptr);
259   EXPECT_EQ(dsp_internal::GetWritableDspTable(kBitdepth10), nullptr);
260 #endif
261 #if LIBGAV1_MAX_BITDEPTH == 12
262   EXPECT_NE(GetDspTable(kBitdepth12), nullptr);
263   EXPECT_NE(dsp_internal::GetWritableDspTable(kBitdepth12), nullptr);
264 #else
265   EXPECT_EQ(GetDspTable(kBitdepth12), nullptr);
266   EXPECT_EQ(dsp_internal::GetWritableDspTable(kBitdepth12), nullptr);
267 #endif
268 }
269 
270 }  // namespace
271 }  // namespace dsp
272 }  // namespace libgav1
273