/*
* 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: 1 # premultiplied
alpha_bit_depth: 8
alpha_transparent_value: 0
alpha_opaque_value: 4
- 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(/*text_mode=*/true);
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 ].alpha.alpha_use_idc, 1 );
EXPECT_EQ(multilayer.layers[0 ].alpha.alpha_bit_depth, 8 );
EXPECT_EQ(multilayer.layers[0 ].alpha.alpha_transparent_value, 0 );
EXPECT_EQ(multilayer.layers[0 ].alpha.alpha_opaque_value, 4 );
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: 2
- 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(/*text_mode=*/true);
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 ].depth.z_near.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].depth.z_near.first),
1 .456 , 0 .00001 );
EXPECT_TRUE(multilayer.layers[0 ].depth.z_far.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].depth.z_far.first),
9 .786 , 0 .00001 );
EXPECT_EQ(multilayer.layers[0 ].depth.depth_representation_type, 2 );
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, ParseLocalDepth) {
const std::string metadata = R"(
use_case: 4 # depth
layers:
- layer_type: 6 # depth
luma_plane_only_flag: 1
layer_metadata_scope: 3 # mixed
depth:
z_near: 1 .456
z_far: 9 .786
depth_representation_type: 2
local_metadata:
- frame_idx: 4
depth:
z_near: 2 .78933
z_far: 20 .663
depth_representation_type: 0
- frame_idx: 100
depth:
z_near: 0
z_far: 24
depth_representation_type: 0
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 3 # mixed
layer_color_description:
color_range: 1
color_primaries: 1
transfer_characteristics: 13
matrix_coefficients: 6
)";
libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
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, 4 );
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, 3 );
EXPECT_TRUE(multilayer.layers[0 ].depth.z_near.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].depth.z_near.first),
1 .456 , 0 .00001 );
EXPECT_TRUE(multilayer.layers[0 ].depth.z_far.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].depth.z_far.first),
9 .786 , 0 .00001 );
EXPECT_EQ(multilayer.layers[0 ].depth.depth_representation_type, 2 );
ASSERT_EQ(multilayer.layers[0 ].local_metadata.size(), 2 );
EXPECT_EQ(multilayer.layers[0 ].local_metadata[0 ].frame_idx, 4 );
EXPECT_TRUE(multilayer.layers[0 ].local_metadata[0 ].depth.z_near.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].local_metadata[0 ].depth.z_near.first),
2 .78933 , 0 .00001 );
EXPECT_TRUE(multilayer.layers[0 ].local_metadata[0 ].depth.z_far.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].local_metadata[0 ].depth.z_far.first),
20 .663 , 0 .00001 );
EXPECT_EQ(
multilayer.layers[0 ].local_metadata[0 ].depth.depth_representation_type,
0 );
EXPECT_EQ(multilayer.layers[0 ].local_metadata[1 ].frame_idx, 100 );
EXPECT_TRUE(multilayer.layers[0 ].local_metadata[1 ].depth.z_near.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].local_metadata[1 ].depth.z_near.first),
0 , 0 .00001 );
EXPECT_TRUE(multilayer.layers[0 ].local_metadata[1 ].depth.z_far.second);
EXPECT_NEAR(depth_representation_element_to_double(
multilayer.layers[0 ].local_metadata[1 ].depth.z_far.first),
24 , 0 .00001 );
EXPECT_EQ(
multilayer.layers[0 ].local_metadata[1 ].depth.depth_representation_type,
0 );
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, 3 );
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 );
EXPECT_EQ(multilayer.layers[1 ].local_metadata.size(), 0 );
}
TEST(MultilayerMetadataTest, ParseInvalid) {
const std::string metadata = R"(
use_case: 3 # alpha
layers:
- layer_type: 5 # alpha
luma_plane_only_flag: 1
layer_metadata_scope: 3 # mixed
- layer_type: 1 # texture
luma_plane_only_flag: 0
layer_metadata_scope: 3 # mixed
- layer_type: 6 # depth => bad layer type
luma_plane_only_flag: 1
layer_metadata_scope: 3 # mixed
)";
libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
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(/*text_mode=*/true);
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(/*text_mode=*/true);
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 .789456 e-5 );
TestConversion(-1 .789456 e-5 );
TestConversion(42 );
TestConversion(6 .7894564456 );
TestConversion(6 .7894564456 e10);
TestConversion(-6 .7894564456 e10);
DepthRepresentationElement e;
// Too small.
ASSERT_FALSE(double_to_depth_representation_element(1 e-10 , &e));
// Too big.
ASSERT_FALSE(double_to_depth_representation_element(1 e+30 , &e));
}
} // namespace
} // namespace libaom_examples
Messung V0.5 in Prozent C=96 H=100 G=97
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland