[FFmpeg-devel] [PATCH 25/42] avcodec/hevc/sei: add support for 3D Reference Displays Information SEI

James Almer jamrial at gmail.com
Fri Aug 30 05:57:01 EEST 2024


On 8/27/2024 12:05 PM, Anton Khirnov wrote:
> From: James Almer <jamrial at gmail.com>
> 
> Signed-off-by: James Almer <jamrial at gmail.com>
> ---
>   libavcodec/hevc/sei.c | 55 +++++++++++++++++++++++++++++++++++++++++++
>   libavcodec/hevc/sei.h | 17 +++++++++++++
>   2 files changed, 72 insertions(+)
> 
> diff --git a/libavcodec/hevc/sei.c b/libavcodec/hevc/sei.c
> index e39ac0c38a..6c2b55b43c 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..a233d432cc 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;
> +    uint8_t left_view_id[31];
> +    uint8_t right_view_id[31];

Should be uint16_t, like you found out.

> +    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;



More information about the ffmpeg-devel mailing list