• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include <cmath>
13 
14 #include "gtest/gtest.h"
15 
16 #include "examples/multilayer_metadata.h"
17 #include "test/video_source.h"
18 
19 namespace libaom_examples {
20 namespace {
21 
TEST(MultilayerMetadataTest,ParseAlpha)22 TEST(MultilayerMetadataTest, ParseAlpha) {
23   const std::string metadata = R"(
24 
25 use_case: 1 # global alpha
26 layers:
27   - layer_type: 5 # alpha
28     luma_plane_only_flag: 1
29     layer_metadata_scope: 2 # global
30     alpha:
31       alpha_use_idc: 2 # segmentation
32       alpha_bit_depth: 8
33       alpha_transparent_value: 0
34       alpha_opaque_value: 4
35       label_type_id:
36         - 5
37         - 3
38         - 9
39         - 128
40         - 42
41 
42   - layer_type: 1 # texture
43     luma_plane_only_flag: 0
44     layer_metadata_scope: 2 # global
45     layer_color_description:
46       color_range: 1
47       color_primaries: 1
48       transfer_characteristics: 13
49       matrix_coefficients: 6
50 
51     )";
52   libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
53   fprintf(tmp_file.file(), "%s", metadata.c_str());
54   fflush(tmp_file.file());
55 
56   MultilayerMetadata multilayer;
57   EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
58 
59   EXPECT_EQ(multilayer.use_case, 1);
60   ASSERT_EQ(multilayer.layers.size(), 2);
61   EXPECT_EQ(multilayer.layers[0].layer_type, 5);
62   EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
63   EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
64   EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_use_idc, 2);
65   EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_bit_depth, 8);
66   EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_transparent_value, 0);
67   EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_opaque_value, 4);
68   ASSERT_EQ(multilayer.layers[0].global_alpha_info.label_type_id.size(), 5);
69   EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[0], 5);
70   EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[1], 3);
71   EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[2], 9);
72   EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[3], 128);
73   EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[4], 42);
74   EXPECT_EQ(multilayer.layers[1].layer_type, 1);
75   EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
76   EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
77   EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
78   EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
79   EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
80             1);
81   EXPECT_EQ(multilayer.layers[1]
82                 .layer_color_description.first.transfer_characteristics,
83             13);
84   EXPECT_EQ(
85       multilayer.layers[1].layer_color_description.first.matrix_coefficients,
86       6);
87 }
88 
TEST(MultilayerMetadataTest,ParseDepth)89 TEST(MultilayerMetadataTest, ParseDepth) {
90   const std::string metadata = R"(
91 use_case: 2 # global depth
92 layers:
93   - layer_type: 6 # depth
94     luma_plane_only_flag: 1
95     layer_metadata_scope: 2 # global
96     depth:
97       z_near: 1.456
98       z_far: 9.786
99       depth_representation_type: 3
100       depth_nonlinear_precision: 8
101       depth_nonlinear_representation_model:
102          - 12
103          - 23
104          - 5
105 
106   - layer_type: 1 # texture
107     luma_plane_only_flag: 0
108     layer_metadata_scope: 2 # global
109     layer_color_description:
110       color_range: 1
111       color_primaries: 1
112       transfer_characteristics: 13
113       matrix_coefficients: 6
114 
115     )";
116   libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
117   fprintf(tmp_file.file(), "%s", metadata.c_str());
118   fflush(tmp_file.file());
119 
120   MultilayerMetadata multilayer;
121   EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
122   EXPECT_EQ(multilayer.use_case, 2);
123   ASSERT_EQ(multilayer.layers.size(), 2);
124   EXPECT_EQ(multilayer.layers[0].layer_type, 6);
125   EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
126   EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
127   EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_near.second);
128   EXPECT_NEAR(depth_representation_element_to_double(
129                   multilayer.layers[0].global_depth_info.z_near.first),
130               1.456, 0.00001);
131   EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_far.second);
132   EXPECT_NEAR(depth_representation_element_to_double(
133                   multilayer.layers[0].global_depth_info.z_far.first),
134               9.786, 0.00001);
135   EXPECT_EQ(multilayer.layers[0].global_depth_info.depth_representation_type,
136             3);
137   EXPECT_EQ(multilayer.layers[0].global_depth_info.depth_nonlinear_precision,
138             8);
139   ASSERT_EQ(multilayer.layers[0]
140                 .global_depth_info.depth_nonlinear_representation_model.size(),
141             3);
142   EXPECT_EQ(multilayer.layers[0]
143                 .global_depth_info.depth_nonlinear_representation_model[0],
144             12);
145   EXPECT_EQ(multilayer.layers[0]
146                 .global_depth_info.depth_nonlinear_representation_model[1],
147             23);
148   EXPECT_EQ(multilayer.layers[0]
149                 .global_depth_info.depth_nonlinear_representation_model[2],
150             5);
151   EXPECT_EQ(multilayer.layers[1].layer_type, 1);
152   EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
153   EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
154   EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
155   EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
156   EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
157             1);
158   EXPECT_EQ(multilayer.layers[1]
159                 .layer_color_description.first.transfer_characteristics,
160             13);
161   EXPECT_EQ(
162       multilayer.layers[1].layer_color_description.first.matrix_coefficients,
163       6);
164 }
165 
TEST(MultilayerMetadataTest,ParseInvalid)166 TEST(MultilayerMetadataTest, ParseInvalid) {
167   const std::string metadata = R"(
168 
169 use_case: 1 # global alpha
170 layers:
171   - layer_type: 5 # alpha
172     luma_plane_only_flag: 1
173     layer_metadata_scope: 2 # global
174 
175   - layer_type: 1 # texture
176     luma_plane_only_flag: 0
177     layer_metadata_scope: 2 # global
178 
179   - layer_type: 6 # depth => bad layer type
180     luma_plane_only_flag: 1
181     layer_metadata_scope: 2 # global
182     )";
183   libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
184   fprintf(tmp_file.file(), "%s", metadata.c_str());
185   fflush(tmp_file.file());
186 
187   MultilayerMetadata multilayer;
188   // Invalid: has a depth layer even though use_case is alpha
189   EXPECT_FALSE(
190       parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
191 }
192 
TEST(MultilayerMetadataTest,ParseBadIndent)193 TEST(MultilayerMetadataTest, ParseBadIndent) {
194   const std::string metadata = R"(
195 
196 use_case: 1 # global alpha
197 layers:
198   - layer_type: 5 # alpha
199     luma_plane_only_flag: 1
200       layer_metadata_scope: 2 # global
201 
202   - layer_type: 1 # texture
203     luma_plane_only_flag: 0
204     layer_metadata_scope: 2 # global
205     )";
206   libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
207   fprintf(tmp_file.file(), "%s", metadata.c_str());
208   fflush(tmp_file.file());
209 
210   MultilayerMetadata multilayer;
211   // Invalid indentation.
212   EXPECT_FALSE(
213       parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
214 }
215 
TEST(MultilayerMetadataTest,ParseUnknownField)216 TEST(MultilayerMetadataTest, ParseUnknownField) {
217   const std::string metadata = R"(
218 
219 use_case: 1 # global alpha
220 layers:
221   - layer_type: 5 # alpha
222     luma_plane_only_flag: 1
223     layer_metadata_scope: 2 # global
224     foobar: 42
225 
226   - layer_type: 1 # texture
227     luma_plane_only_flag: 0
228     layer_metadata_scope: 2 # global
229     )";
230   libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
231   fprintf(tmp_file.file(), "%s", metadata.c_str());
232   fflush(tmp_file.file());
233 
234   MultilayerMetadata multilayer;
235   // Unkonwn field 'foobar'.
236   EXPECT_FALSE(
237       parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
238 }
239 
TestConversion(double v)240 void TestConversion(double v) {
241   DepthRepresentationElement e;
242   ASSERT_TRUE(double_to_depth_representation_element(v, &e)) << v;
243   EXPECT_NEAR(depth_representation_element_to_double(e), v, 0.000000001);
244 }
245 
TEST(MultilayerMetadataTest,DoubleConversion)246 TEST(MultilayerMetadataTest, DoubleConversion) {
247   TestConversion(0.0);
248   TestConversion(1.789456e-5);
249   TestConversion(-1.789456e-5);
250   TestConversion(42);
251   TestConversion(6.7894564456);
252   TestConversion(6.7894564456e10);
253   TestConversion(-6.7894564456e10);
254 
255   DepthRepresentationElement e;
256   // Too small.
257   ASSERT_FALSE(double_to_depth_representation_element(1e-10, &e));
258   // Too big.
259   ASSERT_FALSE(double_to_depth_representation_element(1e+30, &e));
260 }
261 
262 }  // namespace
263 }  // namespace libaom_examples
264