blob: dedfdf0d6b47937ae291e96e6188c0a47484f05b [file] [log] [blame]
/*
* Copyright (c) 2024, Alliance for Open Media. All rights reserved.
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <cmath>
#include "gtest/gtest.h"
#include "examples/multilayer_metadata.h"
#include "test/video_source.h"
namespace libaom_examples {
namespace {
TEST(MultilayerMetadataTest, ParseAlpha) {
const std::string metadata = R"(
use_case: 1 # global alpha
layers:
- layer_type: 5 # alpha
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
alpha:
alpha_use_idc: 2 # segmentation
alpha_bit_depth: 8
alpha_transparent_value: 0
alpha_opaque_value: 4
label_type_id:
- 5
- 3
- 9
- 128
- 42
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 2 # global
layer_color_description:
color_range: 1
color_primaries: 1
transfer_characteristics: 13
matrix_coefficients: 6
)";
libaom_test::TempOutFile tmp_file;
fprintf(tmp_file.file(), "%s", metadata.c_str());
fflush(tmp_file.file());
MultilayerMetadata multilayer;
EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
EXPECT_EQ(multilayer.use_case, 1);
ASSERT_EQ(multilayer.layers.size(), 2);
EXPECT_EQ(multilayer.layers[0].layer_type, 5);
EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_use_idc, 2);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_bit_depth, 8);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_transparent_value, 0);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_opaque_value, 4);
ASSERT_EQ(multilayer.layers[0].global_alpha_info.label_type_id.size(), 5);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[0], 5);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[1], 3);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[2], 9);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[3], 128);
EXPECT_EQ(multilayer.layers[0].global_alpha_info.label_type_id[4], 42);
EXPECT_EQ(multilayer.layers[1].layer_type, 1);
EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
1);
EXPECT_EQ(multilayer.layers[1]
.layer_color_description.first.transfer_characteristics,
13);
EXPECT_EQ(
multilayer.layers[1].layer_color_description.first.matrix_coefficients,
6);
}
TEST(MultilayerMetadataTest, ParseDepth) {
const std::string metadata = R"(
use_case: 2 # global depth
layers:
- layer_type: 6 # depth
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
depth:
z_near: 1.456
z_far: 9.786
depth_representation_type: 3
depth_nonlinear_precision: 8
depth_nonlinear_representation_model:
- 12
- 23
- 5
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 2 # global
layer_color_description:
color_range: 1
color_primaries: 1
transfer_characteristics: 13
matrix_coefficients: 6
)";
libaom_test::TempOutFile tmp_file;
fprintf(tmp_file.file(), "%s", metadata.c_str());
fflush(tmp_file.file());
MultilayerMetadata multilayer;
EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
EXPECT_EQ(multilayer.use_case, 2);
ASSERT_EQ(multilayer.layers.size(), 2);
EXPECT_EQ(multilayer.layers[0].layer_type, 6);
EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_near.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0].global_depth_info.z_near.first),
1.456, 0.00001);
EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_far.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0].global_depth_info.z_far.first),
9.786, 0.00001);
EXPECT_EQ(multilayer.layers[0].global_depth_info.depth_representation_type,
3);
EXPECT_EQ(multilayer.layers[0].global_depth_info.depth_nonlinear_precision,
8);
ASSERT_EQ(multilayer.layers[0]
.global_depth_info.depth_nonlinear_representation_model.size(),
3);
EXPECT_EQ(multilayer.layers[0]
.global_depth_info.depth_nonlinear_representation_model[0],
12);
EXPECT_EQ(multilayer.layers[0]
.global_depth_info.depth_nonlinear_representation_model[1],
23);
EXPECT_EQ(multilayer.layers[0]
.global_depth_info.depth_nonlinear_representation_model[2],
5);
EXPECT_EQ(multilayer.layers[1].layer_type, 1);
EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
1);
EXPECT_EQ(multilayer.layers[1]
.layer_color_description.first.transfer_characteristics,
13);
EXPECT_EQ(
multilayer.layers[1].layer_color_description.first.matrix_coefficients,
6);
}
TEST(MultilayerMetadataTest, ParseInvalid) {
const std::string metadata = R"(
use_case: 1 # global alpha
layers:
- layer_type: 5 # alpha
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 2 # global
- layer_type: 6 # depth => bad layer type
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
)";
libaom_test::TempOutFile tmp_file;
fprintf(tmp_file.file(), "%s", metadata.c_str());
fflush(tmp_file.file());
MultilayerMetadata multilayer;
// Invalid: has a depth layer even though use_case is alpha
EXPECT_FALSE(
parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}
TEST(MultilayerMetadataTest, ParseBadIndent) {
const std::string metadata = R"(
use_case: 1 # global alpha
layers:
- layer_type: 5 # alpha
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 2 # global
)";
libaom_test::TempOutFile tmp_file;
fprintf(tmp_file.file(), "%s", metadata.c_str());
fflush(tmp_file.file());
MultilayerMetadata multilayer;
// Invalid indentation.
EXPECT_FALSE(
parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}
TEST(MultilayerMetadataTest, ParseUnknownField) {
const std::string metadata = R"(
use_case: 1 # global alpha
layers:
- layer_type: 5 # alpha
luma_plane_only_flag: 1
layer_metadata_scope: 2 # global
foobar: 42
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 2 # global
)";
libaom_test::TempOutFile tmp_file;
fprintf(tmp_file.file(), "%s", metadata.c_str());
fflush(tmp_file.file());
MultilayerMetadata multilayer;
// Unkonwn field 'foobar'.
EXPECT_FALSE(
parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}
void TestConversion(double v) {
DepthRepresentationElement e;
ASSERT_TRUE(double_to_depth_representation_element(v, &e)) << v;
EXPECT_NEAR(depth_representation_element_to_double(e), v, 0.000000001);
}
TEST(MultilayerMetadataTest, DoubleConversion) {
TestConversion(0.0);
TestConversion(1.789456e-5);
TestConversion(-1.789456e-5);
TestConversion(42);
TestConversion(6.7894564456);
TestConversion(6.7894564456e10);
TestConversion(-6.7894564456e10);
DepthRepresentationElement e;
// Too small.
ASSERT_FALSE(double_to_depth_representation_element(1e-10, &e));
// Too big.
ASSERT_FALSE(double_to_depth_representation_element(1e+30, &e));
}
} // namespace
} // namespace libaom_examples