diff options
author | James Almer <jamrial@gmail.com> | 2024-06-06 23:04:14 -0300 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2024-09-23 17:11:40 +0200 |
commit | efa9d3deca30b47616721f60d8e79b1ccdaaefbc (patch) | |
tree | 9f160604e9942dc02629f0bd7a40e95edcb867fc | |
parent | 299d9115d4c7c6c108197f48960e140d7433dae6 (diff) | |
download | ffmpeg-efa9d3deca30b47616721f60d8e79b1ccdaaefbc.tar.gz |
avcodec/hevc/sei: add support for 3D Reference Displays Information SEI
Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
-rw-r--r-- | libavcodec/hevc/sei.c | 55 | ||||
-rw-r--r-- | libavcodec/hevc/sei.h | 17 |
2 files changed, 72 insertions, 0 deletions
diff --git a/libavcodec/hevc/sei.c b/libavcodec/hevc/sei.c index b55ba71a8d..e11a33773c 100644 --- a/libavcodec/hevc/sei.c +++ b/libavcodec/hevc/sei.c @@ -150,6 +150,59 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) return 0; } +static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitContext *gb) +{ + s->prec_ref_display_width = get_ue_golomb(gb); + if (s->prec_ref_display_width > 31) + return AVERROR_INVALIDDATA; + s->ref_viewing_distance_flag = get_bits1(gb); + if (s->ref_viewing_distance_flag) { + s->prec_ref_viewing_dist = get_ue_golomb(gb); + if (s->prec_ref_viewing_dist > 31) + return AVERROR_INVALIDDATA; + } + s->num_ref_displays = get_ue_golomb(gb); + if (s->num_ref_displays > 31) + return AVERROR_INVALIDDATA; + s->num_ref_displays += 1; + + for (int i = 0; i < s->num_ref_displays; i++) { + int length; + s->left_view_id[i] = get_ue_golomb(gb); + s->right_view_id[i] = get_ue_golomb(gb); + s->exponent_ref_display_width[i] = get_bits(gb, 6); + if (s->exponent_ref_display_width[i] > 62) + return AVERROR_INVALIDDATA; + else if (!s->exponent_ref_display_width[i]) + length = FFMAX(0, (int)s->prec_ref_display_width - 30); + else + length = FFMAX(0, (int)s->exponent_ref_display_width[i] + + (int)s->prec_ref_display_width - 31); + s->mantissa_ref_display_width[i] = get_bits_long(gb, length); + if (s->ref_viewing_distance_flag) { + s->exponent_ref_viewing_distance[i] = get_bits(gb, 6); + if (s->exponent_ref_viewing_distance[i] > 62) + return AVERROR_INVALIDDATA; + else if (!s->exponent_ref_viewing_distance[i]) + length = FFMAX(0, (int)s->prec_ref_viewing_dist - 30); + else + length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] + + (int)s->prec_ref_viewing_dist - 31); + s->mantissa_ref_viewing_distance[i] = get_bits_long(gb, length); + } + s->additional_shift_present_flag[i] = get_bits1(gb); + if (s->additional_shift_present_flag[i]) { + s->num_sample_shift[i] = get_bits(gb, 10); + if (s->num_sample_shift[i] > 1023) + return AVERROR_INVALIDDATA; + s->num_sample_shift[i] -= 512; + } + } + s->three_dimensional_reference_displays_extension_flag = get_bits1(gb); + + return 0; +} + static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type) @@ -163,6 +216,8 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, return decode_nal_sei_active_parameter_sets(s, gb, logctx); case SEI_TYPE_TIME_CODE: return decode_nal_sei_timecode(&s->timecode, gb); + case SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO: + return decode_nal_sei_3d_reference_displays_info(&s->tdrdi, gb); default: { int ret = ff_h2645_sei_message_decode(&s->common, type, AV_CODEC_ID_HEVC, gb, gbyte, logctx); diff --git a/libavcodec/hevc/sei.h b/libavcodec/hevc/sei.h index c97d22d423..a9d6a52080 100644 --- a/libavcodec/hevc/sei.h +++ b/libavcodec/hevc/sei.h @@ -79,12 +79,29 @@ typedef struct HEVCSEITimeCode { int32_t time_offset_value[3]; } HEVCSEITimeCode; +typedef struct HEVCSEITDRDI { + uint8_t prec_ref_display_width; + uint8_t ref_viewing_distance_flag; + uint8_t prec_ref_viewing_dist; + uint8_t num_ref_displays; + uint16_t left_view_id[31]; + uint16_t right_view_id[31]; + uint8_t exponent_ref_display_width[31]; + uint8_t mantissa_ref_display_width[31]; + uint8_t exponent_ref_viewing_distance[31]; + uint8_t mantissa_ref_viewing_distance[31]; + uint8_t additional_shift_present_flag[31]; + int16_t num_sample_shift[31]; + uint8_t three_dimensional_reference_displays_extension_flag; +} HEVCSEITDRDI; + typedef struct HEVCSEI { H2645SEI common; HEVCSEIPictureHash picture_hash; HEVCSEIPictureTiming picture_timing; int active_seq_parameter_set_id; HEVCSEITimeCode timecode; + HEVCSEITDRDI tdrdi; } HEVCSEI; struct HEVCParamSets; |