diff --git a/doc/APIchanges b/doc/APIchanges index 50b5f0bb53..0fb3f1e3d7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,9 @@ libavutil: 2021-04-27 API changes, most recent first: +2022-01-04 - xxxxxxxxxx - lavu 57.16.100 - frame.h + Add AV_FRAME_DATA_DOVI_METADATA. + 2022-01-03 - 70f318e6b6c - lavf 59.13.100 - avformat.h Add AVFMT_EXPERIMENTAL flag. diff --git a/libavutil/dovi_meta.c b/libavutil/dovi_meta.c index 7bd08f6c54..9c50da561e 100644 --- a/libavutil/dovi_meta.c +++ b/libavutil/dovi_meta.c @@ -33,3 +33,28 @@ AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size) return dovi; } + +typedef struct AVDOVIMetadataInternal { + AVDOVIMetadata metadata; + AVDOVIRpuDataHeader header; + AVDOVIDataMapping mapping; + AVDOVIColorMetadata color; +} AVDOVIMetadataInternal; + +AVDOVIMetadata *av_dovi_metadata_alloc(size_t *size) +{ + AVDOVIMetadataInternal *dovi = av_mallocz(sizeof(AVDOVIMetadataInternal)); + if (!dovi) + return NULL; + + if (size) + *size = sizeof(*dovi); + + dovi->metadata = (struct AVDOVIMetadata) { + .header_offset = offsetof(AVDOVIMetadataInternal, header), + .mapping_offset = offsetof(AVDOVIMetadataInternal, mapping), + .color_offset = offsetof(AVDOVIMetadataInternal, color), + }; + + return &dovi->metadata; +} diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index 299911d434..3d11e02bff 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -29,6 +29,7 @@ #include #include +#include "rational.h" /* * DOVI configuration @@ -67,4 +68,169 @@ typedef struct AVDOVIDecoderConfigurationRecord { */ AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size); +/** + * Dolby Vision RPU data header. + * + * @note sizeof(AVDOVIRpuDataHeader) is not part of the public ABI. + */ +typedef struct AVDOVIRpuDataHeader { + uint8_t rpu_type; + uint16_t rpu_format; + uint8_t vdr_rpu_profile; + uint8_t vdr_rpu_level; + uint8_t chroma_resampling_explicit_filter_flag; + uint8_t coef_data_type; /* informative, lavc always converts to fixed */ + uint8_t coef_log2_denom; + uint8_t vdr_rpu_normalized_idc; + uint8_t bl_video_full_range_flag; + uint8_t bl_bit_depth; /* [8, 16] */ + uint8_t el_bit_depth; /* [8, 16] */ + uint8_t vdr_bit_depth; /* [8, 16] */ + uint8_t spatial_resampling_filter_flag; + uint8_t el_spatial_resampling_filter_flag; + uint8_t disable_residual_flag; +} AVDOVIRpuDataHeader; + +enum AVDOVIMappingMethod { + AV_DOVI_MAPPING_POLYNOMIAL = 0, + AV_DOVI_MAPPING_MMR = 1, +}; + +/** + * Coefficients of a piece-wise function. The pieces of the function span the + * value ranges between two adjacent pivot values. + */ +#define AV_DOVI_MAX_PIECES 8 +typedef struct AVDOVIReshapingCurve { + uint8_t num_pivots; /* [2, 9] */ + uint16_t pivots[AV_DOVI_MAX_PIECES + 1]; /* sorted ascending */ + enum AVDOVIMappingMethod mapping_idc[AV_DOVI_MAX_PIECES]; + /* AV_DOVI_MAPPING_POLYNOMIAL */ + uint8_t poly_order[AV_DOVI_MAX_PIECES]; /* [1, 2] */ + int64_t poly_coef[AV_DOVI_MAX_PIECES][3]; /* x^0, x^1, x^2 */ + /* AV_DOVI_MAPPING_MMR */ + uint8_t mmr_order[AV_DOVI_MAX_PIECES]; /* [1, 3] */ + int64_t mmr_constant[AV_DOVI_MAX_PIECES]; + int64_t mmr_coef[AV_DOVI_MAX_PIECES][3/* order - 1 */][7]; +} AVDOVIReshapingCurve; + +enum AVDOVINLQMethod { + AV_DOVI_NLQ_NONE = -1, + AV_DOVI_NLQ_LINEAR_DZ = 0, +}; + +/** + * Coefficients of the non-linear inverse quantization. For the interpretation + * of these, see ETSI GS CCM 001. + */ +typedef struct AVDOVINLQParams { + uint16_t nlq_offset; + uint64_t vdr_in_max; + /* AV_DOVI_NLQ_LINEAR_DZ */ + uint64_t linear_deadzone_slope; + uint64_t linear_deadzone_threshold; +} AVDOVINLQParams; + +/** + * Dolby Vision RPU data mapping parameters. + * + * @note sizeof(AVDOVIDataMapping) is not part of the public ABI. + */ +typedef struct AVDOVIDataMapping { + uint8_t vdr_rpu_id; + uint8_t mapping_color_space; + uint8_t mapping_chroma_format_idc; + AVDOVIReshapingCurve curves[3]; /* per component */ + + /* Non-linear inverse quantization */ + enum AVDOVINLQMethod nlq_method_idc; + uint32_t num_x_partitions; + uint32_t num_y_partitions; + AVDOVINLQParams nlq[3]; /* per component */ +} AVDOVIDataMapping; + +/** + * Dolby Vision RPU colorspace metadata parameters. + * + * @note sizeof(AVDOVIColorMetadata) is not part of the public ABI. + */ +typedef struct AVDOVIColorMetadata { + uint8_t dm_metadata_id; + uint8_t scene_refresh_flag; + + /** + * Coefficients of the custom Dolby Vision IPT-PQ matrices. These are to be + * used instead of the matrices indicated by the frame's colorspace tags. + * The output of rgb_to_lms_matrix is to be fed into a BT.2020 LMS->RGB + * matrix based on a Hunt-Pointer-Estevez transform, but without any + * crosstalk. (See the definition of the ICtCp colorspace for more + * information.) + */ + AVRational ycc_to_rgb_matrix[9]; /* before PQ linearization */ + AVRational ycc_to_rgb_offset[3]; /* input offset of neutral value */ + AVRational rgb_to_lms_matrix[9]; /* after PQ linearization */ + + /** + * Extra signal metadata (see Dolby patents for more info). + */ + uint16_t signal_eotf; + uint16_t signal_eotf_param0; + uint16_t signal_eotf_param1; + uint32_t signal_eotf_param2; + uint8_t signal_bit_depth; + uint8_t signal_color_space; + uint8_t signal_chroma_format; + uint8_t signal_full_range_flag; /* [0, 3] */ + uint16_t source_min_pq; + uint16_t source_max_pq; + uint16_t source_diagonal; +} AVDOVIColorMetadata; + +/** + * Combined struct representing a combination of header, mapping and color + * metadata, for attaching to frames as side data. + * + * @note The struct must be allocated with av_dovi_metadata_alloc() and + * its size is not a part of the public ABI. + */ + +typedef struct AVDOVIMetadata { + /** + * Offset in bytes from the beginning of this structure at which the + * respective structs start. + */ + size_t header_offset; /* AVDOVIRpuDataHeader */ + size_t mapping_offset; /* AVDOVIDataMapping */ + size_t color_offset; /* AVDOVIColorMetadata */ +} AVDOVIMetadata; + +static av_always_inline AVDOVIRpuDataHeader * +av_dovi_get_header(const AVDOVIMetadata *data) +{ + return (AVDOVIRpuDataHeader *)((uint8_t *) data + data->header_offset); +} + +static av_always_inline AVDOVIDataMapping * +av_dovi_get_mapping(const AVDOVIMetadata *data) +{ + return (AVDOVIDataMapping *)((uint8_t *) data + data->mapping_offset); +} + +static av_always_inline AVDOVIColorMetadata * +av_dovi_get_color(const AVDOVIMetadata *data) +{ + return (AVDOVIColorMetadata *)((uint8_t *) data + data->color_offset); +} + +/** + * Allocate an AVDOVIMetadata structure and initialize its + * fields to default values. + * + * @param size If this parameter is non-NULL, the size in bytes of the + * allocated struct will be written here on success + * + * @return the newly allocated struct or NULL on failure + */ +AVDOVIMetadata *av_dovi_metadata_alloc(size_t *size); + #endif /* AVUTIL_DOVI_META_H */ diff --git a/libavutil/frame.c b/libavutil/frame.c index 0912ad9131..8997c85e35 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -729,6 +729,7 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters"; case AV_FRAME_DATA_DETECTION_BBOXES: return "Bounding boxes for object detection and classification"; case AV_FRAME_DATA_DOVI_RPU_BUFFER: return "Dolby Vision RPU Data"; + case AV_FRAME_DATA_DOVI_METADATA: return "Dolby Vision Metadata"; } return NULL; } diff --git a/libavutil/frame.h b/libavutil/frame.h index 3f295f6b9e..18e239f870 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -189,11 +189,18 @@ enum AVFrameSideDataType { AV_FRAME_DATA_DETECTION_BBOXES, /** - * Dolby Vision RPU data, suitable for passing to x265 + * Dolby Vision RPU raw data, suitable for passing to x265 * or other libraries. Array of uint8_t, with NAL emulation * bytes intact. */ AV_FRAME_DATA_DOVI_RPU_BUFFER, + + /** + * Parsed Dolby Vision metadata, suitable for passing to a software + * implementation. The payload is the AVDOVIMetadata struct defined in + * libavutil/dovi_meta.h. + */ + AV_FRAME_DATA_DOVI_METADATA, }; enum AVActiveFormatDescription { diff --git a/libavutil/version.h b/libavutil/version.h index ca5d34d681..d257e5438d 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 57 -#define LIBAVUTIL_VERSION_MINOR 15 +#define LIBAVUTIL_VERSION_MINOR 16 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \