From 0c0e7ec81e9f05aa09db5c730e2661d0b2eeb72c Mon Sep 17 00:00:00 2001 From: Cosmin Stejerean Date: Wed, 22 May 2024 15:50:45 +0000 Subject: [PATCH] avcodec/dovi_rpu: correctly read el_bit_depth_minus8 and ext_mapping_idc These two fields are coded together into a single 16 bit integer with upper 8 bits for ext_mapping_idc and lower 8 bits for el_bit_depth_minus8. Furthermore ext_mapping_idc has two components, upper 3 bits and lower 5 bits. Co-authored-by: Niklas Haas Signed-off-by: Niklas Haas --- libavcodec/dovi_rpudec.c | 8 +++++++- libavcodec/dovi_rpuenc.c | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index cae4dc4c3c..8cafdcf5e6 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -58,7 +58,7 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) /* Copy only the parts of these structs known to us at compiler-time. */ #define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last)) - COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, disable_residual_flag); + COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7); COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots); COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); @@ -423,11 +423,17 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, int el_bit_depth_minus8 = get_ue_golomb_31(gb); int vdr_bit_depth_minus8 = get_ue_golomb_31(gb); int reserved_zero_3bits; + /* ext_mapping_idc is in the upper 8 bits of el_bit_depth_minus8 */ + int ext_mapping_idc = el_bit_depth_minus8 >> 8; + el_bit_depth_minus8 = el_bit_depth_minus8 & 0xFF; VALIDATE(bl_bit_depth_minus8, 0, 8); VALIDATE(el_bit_depth_minus8, 0, 8); + VALIDATE(ext_mapping_idc, 0, 0xFF); VALIDATE(vdr_bit_depth_minus8, 0, 8); hdr->bl_bit_depth = bl_bit_depth_minus8 + 8; hdr->el_bit_depth = el_bit_depth_minus8 + 8; + hdr->ext_mapping_idc_0_4 = ext_mapping_idc & 0x1f; /* 5 bits */ + hdr->ext_mapping_idc_5_7 = ext_mapping_idc >> 5; hdr->vdr_bit_depth = vdr_bit_depth_minus8 + 8; hdr->spatial_resampling_filter_flag = get_bits1(gb); reserved_zero_3bits = get_bits(gb, 3); diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index a6262844d4..a14c9cc181 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -552,8 +552,9 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, put_bits(pb, 2, hdr->vdr_rpu_normalized_idc); put_bits(pb, 1, hdr->bl_video_full_range_flag); if ((hdr->rpu_format & 0x700) == 0) { + int ext_mapping_idc = (hdr->ext_mapping_idc_5_7 << 5) | hdr->ext_mapping_idc_0_4; set_ue_golomb(pb, hdr->bl_bit_depth - 8); - set_ue_golomb(pb, hdr->el_bit_depth - 8); + set_ue_golomb(pb, (ext_mapping_idc << 8) | (hdr->el_bit_depth - 8)); set_ue_golomb(pb, hdr->vdr_bit_depth - 8); put_bits(pb, 1, hdr->spatial_resampling_filter_flag); put_bits(pb, 3, 0); /* reserved_zero_3bits */