|  | /* | 
|  | * 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. | 
|  | */ | 
|  |  | 
|  | // Experimental multilayer metadata defined in CWG-E050. | 
|  |  | 
|  | #ifndef AOM_EXAMPLES_MULTILAYER_METADATA_H_ | 
|  | #define AOM_EXAMPLES_MULTILAYER_METADATA_H_ | 
|  |  | 
|  | #include <cstdint> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | namespace libaom_examples { | 
|  |  | 
|  | // std::pair<T, bool> is used to indicate presence of a field, | 
|  | // like an std::optional (which cannot be used because it's C++17). | 
|  | // If the boolean is true, then the value is present. | 
|  |  | 
|  | struct ColorProperties { | 
|  | bool color_range;  // true for full range values | 
|  | uint8_t color_primaries; | 
|  | uint8_t transfer_characteristics; | 
|  | uint8_t matrix_coefficients; | 
|  | }; | 
|  |  | 
|  | enum AlphaUse { | 
|  | ALPHA_STRAIGHT = 0, | 
|  | ALPHA_PREMULTIPLIED = 1, | 
|  | ALPHA_UNSPECIFIED = 2, | 
|  | // 3 is reserved. | 
|  | }; | 
|  |  | 
|  | struct AlphaInformation { | 
|  | AlphaUse alpha_use_idc;   // [0, 3] | 
|  | bool alpha_simple_flag;   // If true, all fields below are ignored. | 
|  | uint8_t alpha_bit_depth;  // [8, 15] | 
|  | uint8_t alpha_clip_idc;   // [0, 3] | 
|  | bool alpha_incr_flag; | 
|  | uint16_t alpha_transparent_value;  // [0, 1<<(alpha_bit_depth+1)) | 
|  | uint16_t alpha_opaque_value;       // [0, 1<<(alpha_bit_depth+1)) | 
|  | std::pair<ColorProperties, bool> alpha_color_description; | 
|  | }; | 
|  |  | 
|  | struct DepthRepresentationElement { | 
|  | bool sign_flag; | 
|  | uint8_t exponent;      // [0, 126] (biased exponent) | 
|  | uint8_t mantissa_len;  // [1, 32] | 
|  | uint32_t mantissa; | 
|  | }; | 
|  |  | 
|  | struct DepthInformation { | 
|  | std::pair<DepthRepresentationElement, bool> z_near; | 
|  | std::pair<DepthRepresentationElement, bool> z_far; | 
|  | std::pair<DepthRepresentationElement, bool> d_min; | 
|  | std::pair<DepthRepresentationElement, bool> d_max; | 
|  | uint8_t depth_representation_type;  // [0, 2]. Values 3 to 15 are reserved. | 
|  | // Only relevant if d_min or d_max are present. | 
|  | uint8_t disparity_ref_view_id;  // [0, 3] | 
|  | }; | 
|  |  | 
|  | enum MultilayerUseCase { | 
|  | MULTILAYER_USE_CASE_UNSPECIFIED = 0, | 
|  | MULTILAYER_USE_CASE_GLOBAL_ALPHA = 1, | 
|  | MULTILAYER_USE_CASE_GLOBAL_DEPTH = 2, | 
|  | MULTILAYER_USE_CASE_ALPHA = 3, | 
|  | MULTILAYER_USE_CASE_DEPTH = 4, | 
|  | MULTILAYER_USE_CASE_STEREO = 5, | 
|  | MULTILAYER_USE_CASE_STEREO_GLOBAL_ALPHA = 6, | 
|  | MULTILAYER_USE_CASE_STEREO_GLOBAL_DEPTH = 7, | 
|  | MULTILAYER_USE_CASE_STEREO_ALPHA = 8, | 
|  | MULTILAYER_USE_CASE_STEREO_DEPTH = 9, | 
|  | MULTILAYER_USE_CASE_444_GLOBAL_ALPHA = 10, | 
|  | MULTILAYER_USE_CASE_444_GLOBAL_DEPTH = 11, | 
|  | MULTILAYER_USE_CASE_444 = 12, | 
|  | MULTILAYER_USE_CASE_420_444 = 13, | 
|  | // 14 to 63 are reserved. | 
|  | }; | 
|  |  | 
|  | enum LayerType { | 
|  | MULTILAYER_LAYER_TYPE_UNSPECIFIED = 0, | 
|  | MULTILAYER_LAYER_TYPE_TEXTURE = 1, | 
|  | MULTILAYER_LAYER_TYPE_TEXTURE_1 = 2, | 
|  | MULTILAYER_LAYER_TYPE_TEXTURE_2 = 3, | 
|  | MULTILAYER_LAYER_TYPE_TEXTURE_3 = 4, | 
|  | MULTILAYER_LAYER_TYPE_ALPHA = 5, | 
|  | MULTILAYER_LAYER_TYPE_DEPTH = 6, | 
|  | // 7 to 31 are reserved. | 
|  | }; | 
|  |  | 
|  | enum MultilayerMetadataScope { | 
|  | SCOPE_UNSPECIFIED = 0, | 
|  | SCOPE_LOCAL = 1, | 
|  | SCOPE_GLOBAL = 2, | 
|  | SCOPE_MIXED = 3, | 
|  | }; | 
|  |  | 
|  | enum MultilayerViewType { | 
|  | VIEW_UNSPECIFIED = 0, | 
|  | VIEW_CENTER = 1, | 
|  | VIEW_LEFT = 2, | 
|  | VIEW_RIGHT = 3, | 
|  | // 4 to 7 are reserved. | 
|  | }; | 
|  |  | 
|  | struct FrameLocalMetadata { | 
|  | long frame_idx; | 
|  | // Relevant for MULTILAYER_LAYER_TYPE_ALPHA with scope != SCOPE_GLOBAL. | 
|  | AlphaInformation alpha; | 
|  | // Relevant for MULTILAYER_LAYER_TYPE_DEPTH with scope != SCOPE_GLOBAL. | 
|  | DepthInformation depth; | 
|  | }; | 
|  |  | 
|  | struct LayerMetadata { | 
|  | LayerType layer_type;  // [0, 31] | 
|  | bool luma_plane_only_flag; | 
|  | MultilayerViewType layer_view_type;            // [0, 7] | 
|  | uint8_t group_id;                              // [0, 3] | 
|  | uint8_t layer_dependency_idc;                  // [0, 7] | 
|  | MultilayerMetadataScope layer_metadata_scope;  // [0, 3] | 
|  |  | 
|  | std::pair<ColorProperties, bool> layer_color_description; | 
|  |  | 
|  | // Relevant for MULTILAYER_LAYER_TYPE_ALPHA with scope >= SCOPE_GLOBAL. | 
|  | AlphaInformation alpha; | 
|  | // Relevant for MULTILAYER_LAYER_TYPE_DEPTH with scope >= SCOPE_GLOBAL. | 
|  | DepthInformation depth; | 
|  |  | 
|  | // Relevant when scope != SCOPE_GLOBAL. | 
|  | std::vector<FrameLocalMetadata> local_metadata; | 
|  | }; | 
|  |  | 
|  | struct MultilayerMetadata { | 
|  | MultilayerUseCase use_case;         // [0, 63] | 
|  | std::vector<LayerMetadata> layers;  // max size 4 | 
|  | }; | 
|  |  | 
|  | // Parses a multilayer metadata file. | 
|  | // The metadata is expected to be in a subset of the YAML format supporting | 
|  | // simple lists and maps with integer values, and comments. | 
|  | // Checks that the metadata is valid and terminates the process in case of | 
|  | // error. | 
|  | bool parse_multilayer_file(const char *metadata_path, | 
|  | MultilayerMetadata *multilayer); | 
|  |  | 
|  | // Prints the multilayer metadata to stdout for debugging. | 
|  | void print_multilayer_metadata(const MultilayerMetadata &multilayer); | 
|  |  | 
|  | // Converts a double value to a DepthRepresentationElement struct. | 
|  | bool double_to_depth_representation_element( | 
|  | double v, DepthRepresentationElement *element); | 
|  | // Converts a DepthRepresentationElement struct to a double value. | 
|  | double depth_representation_element_to_double( | 
|  | const DepthRepresentationElement &e); | 
|  |  | 
|  | }  // namespace libaom_examples | 
|  |  | 
|  | #endif  // AOM_EXAMPLES_MULTILAYER_METADATA_H_ |