[FFmpeg-devel] [PATCH 04/10] avcodec/evc_parse: split off Parameter Set parsing into its own file

Dawid Kozinski/Multimedia (PLT) /SRPOL/Staff Engineer/Samsung Electronics d.kozinski at samsung.com
Tue Jun 20 10:37:59 EEST 2023


Why have you split off the parameter set parsing into its own file? Just
asking what's the reason.



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces at ffmpeg.org> On Behalf Of James
> Almer
> Sent: niedziela, 18 czerwca 2023 00:00
> To: ffmpeg-devel at ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH 04/10] avcodec/evc_parse: split off
Parameter
> Set parsing into its own file
> 
> Signed-off-by: James Almer <jamrial at gmail.com>
> ---
>  libavcodec/Makefile              |   2 +-
>  libavcodec/evc_frame_merge_bsf.c |   4 +-
>  libavcodec/evc_parse.c           | 371 +-----------------------------
>  libavcodec/evc_parse.h           | 198 +---------------
>  libavcodec/evc_parser.c          |   2 +-
>  libavcodec/evc_ps.c              | 381 +++++++++++++++++++++++++++++++
>  libavcodec/evc_ps.h              | 228 ++++++++++++++++++
>  7 files changed, 621 insertions(+), 565 deletions(-)
>  create mode 100644 libavcodec/evc_ps.c
>  create mode 100644 libavcodec/evc_ps.h
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 0ce8fe5b9c..723bfa25c7 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -84,7 +84,7 @@ OBJS-$(CONFIG_DCT)                     += dct.o
dct32_fixed.o
> dct32_float.o
>  OBJS-$(CONFIG_DEFLATE_WRAPPER)         += zlib_wrapper.o
>  OBJS-$(CONFIG_DOVI_RPU)                += dovi_rpu.o
>  OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
> -OBJS-$(CONFIG_EVCPARSE)                += evc_parse.o
> +OBJS-$(CONFIG_EVCPARSE)                += evc_parse.o evc_ps.o
>  OBJS-$(CONFIG_EXIF)                    += exif.o tiff_common.o
>  OBJS-$(CONFIG_FAANDCT)                 += faandct.o
>  OBJS-$(CONFIG_FAANIDCT)                += faanidct.o
> diff --git a/libavcodec/evc_frame_merge_bsf.c
> b/libavcodec/evc_frame_merge_bsf.c
> index 540bb63631..f497780afb 100644
> --- a/libavcodec/evc_frame_merge_bsf.c
> +++ b/libavcodec/evc_frame_merge_bsf.c
> @@ -58,7 +58,7 @@ static void evc_frame_merge_flush(AVBSFContext *bsf)
>  {
>      EVCFMergeContext *ctx = bsf->priv_data;
> 
> -    ff_evc_parse_free(&ctx->parser_ctx);
> +    ff_evc_ps_free(&ctx->parser_ctx.ps);
>      av_packet_unref(ctx->in);
>      ctx->au_buffer.data_size = 0;
>  }
> @@ -147,7 +147,7 @@ static void evc_frame_merge_close(AVBSFContext *bsf)
>      EVCFMergeContext *ctx = bsf->priv_data;
> 
>      av_packet_free(&ctx->in);
> -    ff_evc_parse_free(&ctx->parser_ctx);
> +    ff_evc_ps_free(&ctx->parser_ctx.ps);
> 
>      ctx->au_buffer.capacity = 0;
>      av_freep(&ctx->au_buffer.data);
> diff --git a/libavcodec/evc_parse.c b/libavcodec/evc_parse.c
> index 44be5c5291..a8e6356b96 100644
> --- a/libavcodec/evc_parse.c
> +++ b/libavcodec/evc_parse.c
> @@ -21,8 +21,6 @@
>  #include "evc.h"
>  #include "evc_parse.h"
> 
> -#define EXTENDED_SAR            255
> -
>  #define NUM_CHROMA_FORMATS      4   // @see ISO_IEC_23094-1 section 6.2
> table 2
> 
>  static const enum AVPixelFormat pix_fmts_8bit[NUM_CHROMA_FORMATS] = {
> @@ -71,355 +69,6 @@ int ff_evc_get_temporal_id(const uint8_t *bits, int
> bits_size, void *logctx)
>      return temporal_id;
>  }
> 
> -// @see ISO_IEC_23094-1 (7.3.7 Reference picture list structure syntax)
> -static int ref_pic_list_struct(GetBitContext *gb, RefPicListStruct *rpl)
> -{
> -    uint32_t delta_poc_st, strp_entry_sign_flag = 0;
> -    rpl->ref_pic_num = get_ue_golomb(gb);
> -    if (rpl->ref_pic_num > 0) {
> -        delta_poc_st = get_ue_golomb(gb);
> -
> -        rpl->ref_pics[0] = delta_poc_st;
> -        if (rpl->ref_pics[0] != 0) {
> -            strp_entry_sign_flag = get_bits(gb, 1);
> -
> -            rpl->ref_pics[0] *= 1 - (strp_entry_sign_flag << 1);
> -        }
> -    }
> -
> -    for (int i = 1; i < rpl->ref_pic_num; ++i) {
> -        delta_poc_st = get_ue_golomb(gb);
> -        if (delta_poc_st != 0)
> -            strp_entry_sign_flag = get_bits(gb, 1);
> -        rpl->ref_pics[i] = rpl->ref_pics[i - 1] + delta_poc_st * (1 -
> (strp_entry_sign_flag << 1));
> -    }
> -
> -    return 0;
> -}
> -
> -// @see  ISO_IEC_23094-1 (E.2.2 HRD parameters syntax)
> -static int hrd_parameters(GetBitContext *gb, HRDParameters *hrd)
> -{
> -    hrd->cpb_cnt_minus1 = get_ue_golomb(gb);
> -    hrd->bit_rate_scale = get_bits(gb, 4);
> -    hrd->cpb_size_scale = get_bits(gb, 4);
> -    for (int SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1;
SchedSelIdx++)
> {
> -        hrd->bit_rate_value_minus1[SchedSelIdx] = get_ue_golomb(gb);
> -        hrd->cpb_size_value_minus1[SchedSelIdx] = get_ue_golomb(gb);
> -        hrd->cbr_flag[SchedSelIdx] = get_bits(gb, 1);
> -    }
> -    hrd->initial_cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> -    hrd->cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> -    hrd->cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> -    hrd->time_offset_length = get_bits(gb, 5);
> -
> -    return 0;
> -}
> -
> -// @see  ISO_IEC_23094-1 (E.2.1 VUI parameters syntax)
> -static int vui_parameters(GetBitContext *gb, VUIParameters *vui)
> -{
> -    vui->aspect_ratio_info_present_flag = get_bits(gb, 1);
> -    if (vui->aspect_ratio_info_present_flag) {
> -        vui->aspect_ratio_idc = get_bits(gb, 8);
> -        if (vui->aspect_ratio_idc == EXTENDED_SAR) {
> -            vui->sar_width = get_bits(gb, 16);
> -            vui->sar_height = get_bits(gb, 16);
> -        }
> -    }
> -    vui->overscan_info_present_flag = get_bits(gb, 1);
> -    if (vui->overscan_info_present_flag)
> -        vui->overscan_appropriate_flag = get_bits(gb, 1);
> -    vui->video_signal_type_present_flag = get_bits(gb, 1);
> -    if (vui->video_signal_type_present_flag) {
> -        vui->video_format = get_bits(gb, 3);
> -        vui->video_full_range_flag = get_bits(gb, 1);
> -        vui->colour_description_present_flag = get_bits(gb, 1);
> -        if (vui->colour_description_present_flag) {
> -            vui->colour_primaries = get_bits(gb, 8);
> -            vui->transfer_characteristics = get_bits(gb, 8);
> -            vui->matrix_coefficients = get_bits(gb, 8);
> -        }
> -    }
> -    vui->chroma_loc_info_present_flag = get_bits(gb, 1);
> -    if (vui->chroma_loc_info_present_flag) {
> -        vui->chroma_sample_loc_type_top_field = get_ue_golomb(gb);
> -        vui->chroma_sample_loc_type_bottom_field = get_ue_golomb(gb);
> -    }
> -    vui->neutral_chroma_indication_flag = get_bits(gb, 1);
> -
> -    vui->field_seq_flag = get_bits(gb, 1);
> -
> -    vui->timing_info_present_flag = get_bits(gb, 1);
> -    if (vui->timing_info_present_flag) {
> -        vui->num_units_in_tick = get_bits(gb, 32);
> -        vui->time_scale = get_bits(gb, 32);
> -        vui->fixed_pic_rate_flag = get_bits(gb, 1);
> -    }
> -    vui->nal_hrd_parameters_present_flag = get_bits(gb, 1);
> -    if (vui->nal_hrd_parameters_present_flag)
> -        hrd_parameters(gb, &vui->hrd_parameters);
> -    vui->vcl_hrd_parameters_present_flag = get_bits(gb, 1);
> -    if (vui->vcl_hrd_parameters_present_flag)
> -        hrd_parameters(gb, &vui->hrd_parameters);
> -    if (vui->nal_hrd_parameters_present_flag || vui-
> >vcl_hrd_parameters_present_flag)
> -        vui->low_delay_hrd_flag = get_bits(gb, 1);
> -    vui->pic_struct_present_flag = get_bits(gb, 1);
> -    vui->bitstream_restriction_flag = get_bits(gb, 1);
> -    if (vui->bitstream_restriction_flag) {
> -        vui->motion_vectors_over_pic_boundaries_flag = get_bits(gb, 1);
> -        vui->max_bytes_per_pic_denom = get_ue_golomb(gb);
> -        vui->max_bits_per_mb_denom = get_ue_golomb(gb);
> -        vui->log2_max_mv_length_horizontal = get_ue_golomb(gb);
> -        vui->log2_max_mv_length_vertical = get_ue_golomb(gb);
> -        vui->num_reorder_pics = get_ue_golomb(gb);
> -        vui->max_dec_pic_buffering = get_ue_golomb(gb);
> -    }
> -
> -    return 0;
> -}
> -
> -// @see ISO_IEC_23094-1 (7.3.2.1 SPS RBSP syntax)
> -EVCParserSPS *ff_evc_parse_sps(EVCParserContext *ctx, const uint8_t *bs,
int
> bs_size)
> -{
> -    GetBitContext gb;
> -    EVCParserSPS *sps;
> -    int sps_seq_parameter_set_id;
> -
> -    if (init_get_bits8(&gb, bs, bs_size) < 0)
> -        return NULL;
> -
> -    sps_seq_parameter_set_id = get_ue_golomb(&gb);
> -
> -    if (sps_seq_parameter_set_id >= EVC_MAX_SPS_COUNT)
> -        return NULL;
> -
> -    if(!ctx->sps[sps_seq_parameter_set_id]) {
> -        if((ctx->sps[sps_seq_parameter_set_id] =
av_malloc(sizeof(EVCParserSPS)))
> == NULL)
> -            return NULL;
> -    }
> -
> -    sps = ctx->sps[sps_seq_parameter_set_id];
> -    memset(sps, 0, sizeof(*sps));
> -
> -    sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id;
> -
> -    // the Baseline profile is indicated by profile_idc eqal to 0
> -    // the Main profile is indicated by profile_idc eqal to 1
> -    sps->profile_idc = get_bits(&gb, 8);
> -
> -    sps->level_idc = get_bits(&gb, 8);
> -
> -    skip_bits_long(&gb, 32); /* skip toolset_idc_h */
> -    skip_bits_long(&gb, 32); /* skip toolset_idc_l */
> -
> -    // 0 - monochrome
> -    // 1 - 4:2:0
> -    // 2 - 4:2:2
> -    // 3 - 4:4:4
> -    sps->chroma_format_idc = get_ue_golomb(&gb);
> -
> -    sps->pic_width_in_luma_samples = get_ue_golomb(&gb);
> -    sps->pic_height_in_luma_samples = get_ue_golomb(&gb);
> -
> -    sps->bit_depth_luma_minus8 = get_ue_golomb(&gb);
> -    sps->bit_depth_chroma_minus8 = get_ue_golomb(&gb);
> -
> -    sps->sps_btt_flag = get_bits(&gb, 1);
> -    if (sps->sps_btt_flag) {
> -        sps->log2_ctu_size_minus5 = get_ue_golomb(&gb);
> -        sps->log2_min_cb_size_minus2 = get_ue_golomb(&gb);
> -        sps->log2_diff_ctu_max_14_cb_size = get_ue_golomb(&gb);
> -        sps->log2_diff_ctu_max_tt_cb_size = get_ue_golomb(&gb);
> -        sps->log2_diff_min_cb_min_tt_cb_size_minus2 = get_ue_golomb(&gb);
> -    }
> -
> -    sps->sps_suco_flag = get_bits(&gb, 1);
> -    if (sps->sps_suco_flag) {
> -        sps->log2_diff_ctu_size_max_suco_cb_size = get_ue_golomb(&gb);
> -        sps->log2_diff_max_suco_min_suco_cb_size = get_ue_golomb(&gb);
> -    }
> -
> -    sps->sps_admvp_flag = get_bits(&gb, 1);
> -    if (sps->sps_admvp_flag) {
> -        sps->sps_affine_flag = get_bits(&gb, 1);
> -        sps->sps_amvr_flag = get_bits(&gb, 1);
> -        sps->sps_dmvr_flag = get_bits(&gb, 1);
> -        sps->sps_mmvd_flag = get_bits(&gb, 1);
> -        sps->sps_hmvp_flag = get_bits(&gb, 1);
> -    }
> -
> -    sps->sps_eipd_flag =  get_bits(&gb, 1);
> -    if (sps->sps_eipd_flag) {
> -        sps->sps_ibc_flag = get_bits(&gb, 1);
> -        if (sps->sps_ibc_flag)
> -            sps->log2_max_ibc_cand_size_minus2 = get_ue_golomb(&gb);
> -    }
> -
> -    sps->sps_cm_init_flag = get_bits(&gb, 1);
> -    if (sps->sps_cm_init_flag)
> -        sps->sps_adcc_flag = get_bits(&gb, 1);
> -
> -    sps->sps_iqt_flag = get_bits(&gb, 1);
> -    if (sps->sps_iqt_flag)
> -        sps->sps_ats_flag = get_bits(&gb, 1);
> -
> -    sps->sps_addb_flag = get_bits(&gb, 1);
> -    sps->sps_alf_flag = get_bits(&gb, 1);
> -    sps->sps_htdf_flag = get_bits(&gb, 1);
> -    sps->sps_rpl_flag = get_bits(&gb, 1);
> -    sps->sps_pocs_flag = get_bits(&gb, 1);
> -    sps->sps_dquant_flag = get_bits(&gb, 1);
> -    sps->sps_dra_flag = get_bits(&gb, 1);
> -
> -    if (sps->sps_pocs_flag)
> -        sps->log2_max_pic_order_cnt_lsb_minus4 = get_ue_golomb(&gb);
> -
> -    if (!sps->sps_pocs_flag || !sps->sps_rpl_flag) {
> -        sps->log2_sub_gop_length = get_ue_golomb(&gb);
> -        if (sps->log2_sub_gop_length == 0)
> -            sps->log2_ref_pic_gap_length = get_ue_golomb(&gb);
> -    }
> -
> -    if (!sps->sps_rpl_flag)
> -        sps->max_num_tid0_ref_pics = get_ue_golomb(&gb);
> -    else {
> -        sps->sps_max_dec_pic_buffering_minus1 = get_ue_golomb(&gb);
> -        sps->long_term_ref_pic_flag = get_bits(&gb, 1);
> -        sps->rpl1_same_as_rpl0_flag = get_bits(&gb, 1);
> -        sps->num_ref_pic_list_in_sps[0] = get_ue_golomb(&gb);
> -
> -        for (int i = 0; i < sps->num_ref_pic_list_in_sps[0]; ++i)
> -            ref_pic_list_struct(&gb, &sps->rpls[0][i]);
> -
> -        if (!sps->rpl1_same_as_rpl0_flag) {
> -            sps->num_ref_pic_list_in_sps[1] = get_ue_golomb(&gb);
> -            for (int i = 0; i < sps->num_ref_pic_list_in_sps[1]; ++i)
> -                ref_pic_list_struct(&gb, &sps->rpls[1][i]);
> -        }
> -    }
> -
> -    sps->picture_cropping_flag = get_bits(&gb, 1);
> -
> -    if (sps->picture_cropping_flag) {
> -        sps->picture_crop_left_offset = get_ue_golomb(&gb);
> -        sps->picture_crop_right_offset = get_ue_golomb(&gb);
> -        sps->picture_crop_top_offset = get_ue_golomb(&gb);
> -        sps->picture_crop_bottom_offset = get_ue_golomb(&gb);
> -    }
> -
> -    if (sps->chroma_format_idc != 0) {
> -        sps->chroma_qp_table_struct.chroma_qp_table_present_flag =
> get_bits(&gb, 1);
> -
> -        if (sps->chroma_qp_table_struct.chroma_qp_table_present_flag) {
> -            sps->chroma_qp_table_struct.same_qp_table_for_chroma =
> get_bits(&gb, 1);
> -            sps->chroma_qp_table_struct.global_offset_flag =
get_bits(&gb, 1);
> -            for (int i = 0; i < (sps-
> >chroma_qp_table_struct.same_qp_table_for_chroma ? 1 : 2); i++) {
> -
sps->chroma_qp_table_struct.num_points_in_qp_table_minus1[i] =
> get_ue_golomb(&gb);;
> -                for (int j = 0; j <= sps-
> >chroma_qp_table_struct.num_points_in_qp_table_minus1[i]; j++) {
> -
sps->chroma_qp_table_struct.delta_qp_in_val_minus1[i][j] =
> get_bits(&gb, 6);
> -                    sps->chroma_qp_table_struct.delta_qp_out_val[i][j] =
> get_se_golomb(&gb);
> -                }
> -            }
> -        }
> -    }
> -
> -    sps->vui_parameters_present_flag = get_bits(&gb, 1);
> -    if (sps->vui_parameters_present_flag)
> -        vui_parameters(&gb, &(sps->vui_parameters));
> -
> -    // @note
> -    // If necessary, add the missing fields to the EVCParserSPS structure
> -    // and then extend parser implementation
> -
> -    return sps;
> -}
> -
> -// @see ISO_IEC_23094-1 (7.3.2.2 SPS RBSP syntax)
> -//
> -// @note
> -// The current implementation of parse_sps function doesn't handle VUI
> parameters parsing.
> -// If it will be needed, parse_sps function could be extended to handle
VUI
> parameters parsing
> -// to initialize fields of the AVCodecContex i.e. color_primaries,
> color_trc,color_range
> -//
> -EVCParserPPS *ff_evc_parse_pps(EVCParserContext *ctx, const uint8_t *bs,
int
> bs_size)
> -{
> -    GetBitContext gb;
> -    EVCParserPPS *pps;
> -
> -    int pps_pic_parameter_set_id;
> -
> -    if (init_get_bits8(&gb, bs, bs_size) < 0)
> -        return NULL;
> -
> -    pps_pic_parameter_set_id = get_ue_golomb(&gb);
> -    if (pps_pic_parameter_set_id > EVC_MAX_PPS_COUNT)
> -        return NULL;
> -
> -    if(!ctx->pps[pps_pic_parameter_set_id]) {
> -        if ((ctx->pps[pps_pic_parameter_set_id] =
> av_malloc(sizeof(EVCParserPPS))) == NULL)
> -            return NULL;
> -    }
> -
> -    pps = ctx->pps[pps_pic_parameter_set_id];
> -    memset(pps, 0, sizeof(*pps));
> -
> -    pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id;
> -
> -    pps->pps_seq_parameter_set_id = get_ue_golomb(&gb);
> -    if (pps->pps_seq_parameter_set_id >= EVC_MAX_SPS_COUNT) {
> -        av_freep(&ctx->pps[pps_pic_parameter_set_id]);
> -        return NULL;
> -    }
> -
> -    pps->num_ref_idx_default_active_minus1[0] = get_ue_golomb(&gb);
> -    pps->num_ref_idx_default_active_minus1[1] = get_ue_golomb(&gb);
> -    pps->additional_lt_poc_lsb_len = get_ue_golomb(&gb);
> -    pps->rpl1_idx_present_flag = get_bits(&gb, 1);
> -    pps->single_tile_in_pic_flag = get_bits(&gb, 1);
> -
> -    if (!pps->single_tile_in_pic_flag) {
> -        pps->num_tile_columns_minus1 = get_ue_golomb(&gb);
> -        pps->num_tile_rows_minus1 = get_ue_golomb(&gb);
> -        pps->uniform_tile_spacing_flag = get_bits(&gb, 1);
> -
> -        if (!pps->uniform_tile_spacing_flag) {
> -            for (int i = 0; i < pps->num_tile_columns_minus1; i++)
> -                pps->tile_column_width_minus1[i] = get_ue_golomb(&gb);
> -
> -            for (int i = 0; i < pps->num_tile_rows_minus1; i++)
> -                pps->tile_row_height_minus1[i] = get_ue_golomb(&gb);
> -        }
> -        pps->loop_filter_across_tiles_enabled_flag = get_bits(&gb, 1);
> -        pps->tile_offset_len_minus1 = get_ue_golomb(&gb);
> -    }
> -
> -    pps->tile_id_len_minus1 = get_ue_golomb(&gb);
> -    pps->explicit_tile_id_flag = get_bits(&gb, 1);
> -
> -    if (pps->explicit_tile_id_flag) {
> -        for (int i = 0; i <= pps->num_tile_rows_minus1; i++) {
> -            for (int j = 0; j <= pps->num_tile_columns_minus1; j++)
> -                pps->tile_id_val[i][j] = get_bits(&gb,
pps->tile_id_len_minus1 + 1);
> -        }
> -    }
> -
> -    pps->pic_dra_enabled_flag = 0;
> -    pps->pic_dra_enabled_flag = get_bits(&gb, 1);
> -
> -    if (pps->pic_dra_enabled_flag)
> -        pps->pic_dra_aps_id = get_bits(&gb, 5);
> -
> -    pps->arbitrary_slice_present_flag = get_bits(&gb, 1);
> -    pps->constrained_intra_pred_flag = get_bits(&gb, 1);
> -    pps->cu_qp_delta_enabled_flag = get_bits(&gb, 1);
> -
> -    if (pps->cu_qp_delta_enabled_flag)
> -        pps->log2_cu_qp_delta_area_minus6 = get_ue_golomb(&gb);
> -
> -    return pps;
> -}
> -
>  // @see ISO_IEC_23094-1 (7.3.2.6 Slice layer RBSP syntax)
>  static int evc_parse_slice_header(EVCParserContext *ctx,
> EVCParserSliceHeader *sh, const uint8_t *bs, int bs_size)
>  {
> @@ -439,11 +88,11 @@ static int evc_parse_slice_header(EVCParserContext
> *ctx, EVCParserSliceHeader *s
>      if (slice_pic_parameter_set_id < 0 || slice_pic_parameter_set_id >=
> EVC_MAX_PPS_COUNT)
>          return AVERROR_INVALIDDATA;
> 
> -    pps = ctx->pps[slice_pic_parameter_set_id];
> +    pps = ctx->ps.pps[slice_pic_parameter_set_id];
>      if(!pps)
>          return AVERROR_INVALIDDATA;
> 
> -    sps = ctx->sps[pps->pps_seq_parameter_set_id];
> +    sps = ctx->ps.sps[pps->pps_seq_parameter_set_id];
>      if(!sps)
>          return AVERROR_INVALIDDATA;
> 
> @@ -579,7 +228,7 @@ int ff_evc_parse_nal_unit(EVCParserContext *ctx, const
> uint8_t *buf, int buf_siz
>          int SubGopLength;
>          int bit_depth;
> 
> -        sps = ff_evc_parse_sps(ctx, data, nalu_size);
> +        sps = ff_evc_parse_sps(&ctx->ps, data, nalu_size);
>          if (!sps) {
>              av_log(logctx, AV_LOG_ERROR, "SPS parsing error\n");
>              return AVERROR_INVALIDDATA;
> @@ -642,7 +291,7 @@ int ff_evc_parse_nal_unit(EVCParserContext *ctx, const
> uint8_t *buf, int buf_siz
>      case EVC_PPS_NUT: {
>          EVCParserPPS *pps;
> 
> -        pps = ff_evc_parse_pps(ctx, data, nalu_size);
> +        pps = ff_evc_parse_pps(&ctx->ps, data, nalu_size);
>          if (!pps) {
>              av_log(logctx, AV_LOG_ERROR, "PPS parsing error\n");
>              return AVERROR_INVALIDDATA;
> @@ -688,8 +337,8 @@ int ff_evc_parse_nal_unit(EVCParserContext *ctx, const
> uint8_t *buf, int buf_siz
> 
>          // POC (picture order count of the current picture) derivation
>          // @see ISO/IEC 23094-1:2020(E) 8.3.1 Decoding process for
picture order
> count
> -        pps = ctx->pps[sh.slice_pic_parameter_set_id];
> -        sps = ctx->sps[pps->pps_seq_parameter_set_id];
> +        pps = ctx->ps.pps[sh.slice_pic_parameter_set_id];
> +        sps = ctx->ps.sps[pps->pps_seq_parameter_set_id];
>          av_assert0(sps && pps);
> 
>          if (sps->sps_pocs_flag) {
> @@ -764,11 +413,3 @@ int ff_evc_parse_nal_unit(EVCParserContext *ctx,
> const uint8_t *buf, int buf_siz
> 
>      return 0;
>  }
> -
> -void ff_evc_parse_free(EVCParserContext *ctx) {
> -    for (int i = 0; i < EVC_MAX_SPS_COUNT; i++)
> -        av_freep(&ctx->sps[i]);
> -
> -    for (int i = 0; i < EVC_MAX_PPS_COUNT; i++)
> -        av_freep(&ctx->pps[i]);
> -}
> diff --git a/libavcodec/evc_parse.h b/libavcodec/evc_parse.h
> index ee4b6c5708..b5462f5711 100644
> --- a/libavcodec/evc_parse.h
> +++ b/libavcodec/evc_parse.h
> @@ -30,190 +30,7 @@
>  #include "libavutil/log.h"
>  #include "libavutil/rational.h"
>  #include "evc.h"
> -
> -#define EVC_MAX_QP_TABLE_SIZE   58
> -#define NUM_CPB                 32
> -
> -// rpl structure
> -typedef struct RefPicListStruct {
> -    int poc;
> -    int tid;
> -    int ref_pic_num;
> -    int ref_pic_active_num;
> -    int ref_pics[EVC_MAX_NUM_REF_PICS];
> -    char pic_type;
> -
> -} RefPicListStruct;
> -
> -// chromaQP table structure to be signalled in SPS
> -typedef struct ChromaQpTable {
> -    int chroma_qp_table_present_flag;       // u(1)
> -    int same_qp_table_for_chroma;           // u(1)
> -    int global_offset_flag;                 // u(1)
> -    int num_points_in_qp_table_minus1[2];   // ue(v)
> -    int delta_qp_in_val_minus1[2][EVC_MAX_QP_TABLE_SIZE];   // u(6)
> -    int delta_qp_out_val[2][EVC_MAX_QP_TABLE_SIZE];         // se(v)
> -} ChromaQpTable;
> -
> -// Hypothetical Reference Decoder (HRD) parameters, part of VUI
> -typedef struct HRDParameters {
> -    int cpb_cnt_minus1;                             // ue(v)
> -    int bit_rate_scale;                             // u(4)
> -    int cpb_size_scale;                             // u(4)
> -    int bit_rate_value_minus1[NUM_CPB];             // ue(v)
> -    int cpb_size_value_minus1[NUM_CPB];             // ue(v)
> -    int cbr_flag[NUM_CPB];                          // u(1)
> -    int initial_cpb_removal_delay_length_minus1;    // u(5)
> -    int cpb_removal_delay_length_minus1;            // u(5)
> -    int dpb_output_delay_length_minus1;             // u(5)
> -    int time_offset_length;                         // u(5)
> -} HRDParameters;
> -
> -// video usability information (VUI) part of SPS
> -typedef struct VUIParameters {
> -    int aspect_ratio_info_present_flag;             // u(1)
> -    int aspect_ratio_idc;                           // u(8)
> -    int sar_width;                                  // u(16)
> -    int sar_height;                                 // u(16)
> -    int overscan_info_present_flag;                 // u(1)
> -    int overscan_appropriate_flag;                  // u(1)
> -    int video_signal_type_present_flag;             // u(1)
> -    int video_format;                               // u(3)
> -    int video_full_range_flag;                      // u(1)
> -    int colour_description_present_flag;            // u(1)
> -    int colour_primaries;                           // u(8)
> -    int transfer_characteristics;                   // u(8)
> -    int matrix_coefficients;                        // u(8)
> -    int chroma_loc_info_present_flag;               // u(1)
> -    int chroma_sample_loc_type_top_field;           // ue(v)
> -    int chroma_sample_loc_type_bottom_field;        // ue(v)
> -    int neutral_chroma_indication_flag;             // u(1)
> -    int field_seq_flag;                             // u(1)
> -    int timing_info_present_flag;                   // u(1)
> -    int num_units_in_tick;                          // u(32)
> -    int time_scale;                                 // u(32)
> -    int fixed_pic_rate_flag;                        // u(1)
> -    int nal_hrd_parameters_present_flag;            // u(1)
> -    int vcl_hrd_parameters_present_flag;            // u(1)
> -    int low_delay_hrd_flag;                         // u(1)
> -    int pic_struct_present_flag;                    // u(1)
> -    int bitstream_restriction_flag;                 // u(1)
> -    int motion_vectors_over_pic_boundaries_flag;    // u(1)
> -    int max_bytes_per_pic_denom;                    // ue(v)
> -    int max_bits_per_mb_denom;                      // ue(v)
> -    int log2_max_mv_length_horizontal;              // ue(v)
> -    int log2_max_mv_length_vertical;                // ue(v)
> -    int num_reorder_pics;                           // ue(v)
> -    int max_dec_pic_buffering;                      // ue(v)
> -
> -    HRDParameters hrd_parameters;
> -} VUIParameters;
> -
> -// The sturcture reflects SPS RBSP(raw byte sequence payload) layout
> -// @see ISO_IEC_23094-1 section 7.3.2.1
> -//
> -// The following descriptors specify the parsing process of each element
> -// u(n) - unsigned integer using n bits
> -// ue(v) - unsigned integer 0-th order Exp_Golomb-coded syntax element
with
> the left bit first
> -typedef struct EVCParserSPS {
> -    int sps_seq_parameter_set_id;   // ue(v)
> -    int profile_idc;                // u(8)
> -    int level_idc;                  // u(8)
> -    int toolset_idc_h;              // u(32)
> -    int toolset_idc_l;              // u(32)
> -    int chroma_format_idc;          // ue(v)
> -    int pic_width_in_luma_samples;  // ue(v)
> -    int pic_height_in_luma_samples; // ue(v)
> -    int bit_depth_luma_minus8;      // ue(v)
> -    int bit_depth_chroma_minus8;    // ue(v)
> -
> -    int sps_btt_flag;                           // u(1)
> -    int log2_ctu_size_minus5;                   // ue(v)
> -    int log2_min_cb_size_minus2;                // ue(v)
> -    int log2_diff_ctu_max_14_cb_size;           // ue(v)
> -    int log2_diff_ctu_max_tt_cb_size;           // ue(v)
> -    int log2_diff_min_cb_min_tt_cb_size_minus2; // ue(v)
> -
> -    int sps_suco_flag;                       // u(1)
> -    int log2_diff_ctu_size_max_suco_cb_size; // ue(v)
> -    int log2_diff_max_suco_min_suco_cb_size; // ue(v)
> -
> -    int sps_admvp_flag;     // u(1)
> -    int sps_affine_flag;    // u(1)
> -    int sps_amvr_flag;      // u(1)
> -    int sps_dmvr_flag;      // u(1)
> -    int sps_mmvd_flag;      // u(1)
> -    int sps_hmvp_flag;      // u(1)
> -
> -    int sps_eipd_flag;                 // u(1)
> -    int sps_ibc_flag;                  // u(1)
> -    int log2_max_ibc_cand_size_minus2; // ue(v)
> -
> -    int sps_cm_init_flag; // u(1)
> -    int sps_adcc_flag;    // u(1)
> -
> -    int sps_iqt_flag; // u(1)
> -    int sps_ats_flag; // u(1)
> -
> -    int sps_addb_flag;   // u(1)
> -    int sps_alf_flag;    // u(1)
> -    int sps_htdf_flag;   // u(1)
> -    int sps_rpl_flag;    // u(1)
> -    int sps_pocs_flag;   // u(1)
> -    int sps_dquant_flag; // u(1)
> -    int sps_dra_flag;    // u(1)
> -
> -    int log2_max_pic_order_cnt_lsb_minus4; // ue(v)
> -    int log2_sub_gop_length;               // ue(v)
> -    int log2_ref_pic_gap_length;           // ue(v)
> -
> -    int max_num_tid0_ref_pics; // ue(v)
> -
> -    int sps_max_dec_pic_buffering_minus1; // ue(v)
> -    int long_term_ref_pic_flag;           // u(1)
> -    int rpl1_same_as_rpl0_flag;           // u(1)
> -    int num_ref_pic_list_in_sps[2];       // ue(v)
> -    struct RefPicListStruct rpls[2][EVC_MAX_NUM_RPLS];
> -
> -    int picture_cropping_flag;      // u(1)
> -    int picture_crop_left_offset;   // ue(v)
> -    int picture_crop_right_offset;  // ue(v)
> -    int picture_crop_top_offset;    // ue(v)
> -    int picture_crop_bottom_offset; // ue(v)
> -
> -    struct ChromaQpTable chroma_qp_table_struct;
> -
> -    int vui_parameters_present_flag;    // u(1)
> -
> -    struct VUIParameters vui_parameters;
> -
> -} EVCParserSPS;
> -
> -typedef struct EVCParserPPS {
> -    int pps_pic_parameter_set_id;                           // ue(v)
> -    int pps_seq_parameter_set_id;                           // ue(v)
> -    int num_ref_idx_default_active_minus1[2];               // ue(v)
> -    int additional_lt_poc_lsb_len;                          // ue(v)
> -    int rpl1_idx_present_flag;                              // u(1)
> -    int single_tile_in_pic_flag;                            // u(1)
> -    int num_tile_columns_minus1;                            // ue(v)
> -    int num_tile_rows_minus1;                               // ue(v)
> -    int uniform_tile_spacing_flag;                          // u(1)
> -    int tile_column_width_minus1[EVC_MAX_TILE_ROWS];        // ue(v)
> -    int tile_row_height_minus1[EVC_MAX_TILE_COLUMNS];          // ue(v)
> -    int loop_filter_across_tiles_enabled_flag;              // u(1)
> -    int tile_offset_len_minus1;                             // ue(v)
> -    int tile_id_len_minus1;                                 // ue(v)
> -    int explicit_tile_id_flag;                              // u(1)
> -    int tile_id_val[EVC_MAX_TILE_ROWS][EVC_MAX_TILE_COLUMNS];  // u(v)
> -    int pic_dra_enabled_flag;                               // u(1)
> -    int pic_dra_aps_id;                                     // u(5)
> -    int arbitrary_slice_present_flag;                       // u(1)
> -    int constrained_intra_pred_flag;                        // u(1)
> -    int cu_qp_delta_enabled_flag;                           // u(1)
> -    int log2_cu_qp_delta_area_minus6;                       // ue(v)
> -
> -} EVCParserPPS;
> +#include "evc_ps.h"
> 
>  // The sturcture reflects Slice Header RBSP(raw byte sequence payload)
layout
>  // @see ISO_IEC_23094-1 section 7.3.2.6
> @@ -265,10 +82,7 @@ typedef struct EVCParserPoc {
>  } EVCParserPoc;
> 
>  typedef struct EVCParserContext {
> -    //ParseContext pc;
> -    EVCParserSPS *sps[EVC_MAX_SPS_COUNT];
> -    EVCParserPPS *pps[EVC_MAX_PPS_COUNT];
> -
> +    EVCParamSets ps;
>      EVCParserPoc poc;
> 
>      int nuh_temporal_id;            // the value of TemporalId (shall be
the same for
> all VCL NAL units of an Access Unit)
> @@ -349,14 +163,6 @@ static inline uint32_t evc_read_nal_unit_length(const
> uint8_t *bits, int bits_si
>  // nuh_temporal_id specifies a temporal identifier for the NAL unit
>  int ff_evc_get_temporal_id(const uint8_t *bits, int bits_size, void
*logctx);
> 
> -// @see ISO_IEC_23094-1 (7.3.2.1 SPS RBSP syntax)
> -EVCParserSPS *ff_evc_parse_sps(EVCParserContext *ctx, const uint8_t *bs,
int
> bs_size);
> -
> -// @see ISO_IEC_23094-1 (7.3.2.2 SPS RBSP syntax)
> -EVCParserPPS *ff_evc_parse_pps(EVCParserContext *ctx, const uint8_t *bs,
int
> bs_size);
> -
>  int ff_evc_parse_nal_unit(EVCParserContext *ctx, const uint8_t *buf, int
> buf_size, void *logctx);
> 
> -void ff_evc_parse_free(EVCParserContext *ctx);
> -
>  #endif /* AVCODEC_EVC_PARSE_H */
> diff --git a/libavcodec/evc_parser.c b/libavcodec/evc_parser.c
> index c85b8f89e7..1fd8aac1dc 100644
> --- a/libavcodec/evc_parser.c
> +++ b/libavcodec/evc_parser.c
> @@ -202,7 +202,7 @@ static void evc_parser_close(AVCodecParserContext *s)
>  {
>      EVCParserContext *ctx = s->priv_data;
> 
> -    ff_evc_parse_free(ctx);
> +    ff_evc_ps_free(&ctx->ps);
>  }
> 
>  const AVCodecParser ff_evc_parser = {
> diff --git a/libavcodec/evc_ps.c b/libavcodec/evc_ps.c
> new file mode 100644
> index 0000000000..af74ba46b0
> --- /dev/null
> +++ b/libavcodec/evc_ps.c
> @@ -0,0 +1,381 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
> + */
> +
> +#include "golomb.h"
> +#include "parser.h"
> +#include "evc.h"
> +#include "evc_ps.h"
> +
> +#define EXTENDED_SAR 255
> +
> +// @see ISO_IEC_23094-1 (7.3.7 Reference picture list structure syntax)
> +static int ref_pic_list_struct(GetBitContext *gb, RefPicListStruct *rpl)
> +{
> +    uint32_t delta_poc_st, strp_entry_sign_flag = 0;
> +    rpl->ref_pic_num = get_ue_golomb(gb);
> +    if (rpl->ref_pic_num > 0) {
> +        delta_poc_st = get_ue_golomb(gb);
> +
> +        rpl->ref_pics[0] = delta_poc_st;
> +        if (rpl->ref_pics[0] != 0) {
> +            strp_entry_sign_flag = get_bits(gb, 1);
> +
> +            rpl->ref_pics[0] *= 1 - (strp_entry_sign_flag << 1);
> +        }
> +    }
> +
> +    for (int i = 1; i < rpl->ref_pic_num; ++i) {
> +        delta_poc_st = get_ue_golomb(gb);
> +        if (delta_poc_st != 0)
> +            strp_entry_sign_flag = get_bits(gb, 1);
> +        rpl->ref_pics[i] = rpl->ref_pics[i - 1] + delta_poc_st * (1 -
> (strp_entry_sign_flag << 1));
> +    }
> +
> +    return 0;
> +}
> +
> +// @see  ISO_IEC_23094-1 (E.2.2 HRD parameters syntax)
> +static int hrd_parameters(GetBitContext *gb, HRDParameters *hrd)
> +{
> +    hrd->cpb_cnt_minus1 = get_ue_golomb(gb);
> +    hrd->bit_rate_scale = get_bits(gb, 4);
> +    hrd->cpb_size_scale = get_bits(gb, 4);
> +    for (int SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1;
SchedSelIdx++)
> {
> +        hrd->bit_rate_value_minus1[SchedSelIdx] = get_ue_golomb(gb);
> +        hrd->cpb_size_value_minus1[SchedSelIdx] = get_ue_golomb(gb);
> +        hrd->cbr_flag[SchedSelIdx] = get_bits(gb, 1);
> +    }
> +    hrd->initial_cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> +    hrd->cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> +    hrd->cpb_removal_delay_length_minus1 = get_bits(gb, 5);
> +    hrd->time_offset_length = get_bits(gb, 5);
> +
> +    return 0;
> +}
> +
> +// @see  ISO_IEC_23094-1 (E.2.1 VUI parameters syntax)
> +static int vui_parameters(GetBitContext *gb, VUIParameters *vui)
> +{
> +    vui->aspect_ratio_info_present_flag = get_bits(gb, 1);
> +    if (vui->aspect_ratio_info_present_flag) {
> +        vui->aspect_ratio_idc = get_bits(gb, 8);
> +        if (vui->aspect_ratio_idc == EXTENDED_SAR) {
> +            vui->sar_width = get_bits(gb, 16);
> +            vui->sar_height = get_bits(gb, 16);
> +        }
> +    }
> +    vui->overscan_info_present_flag = get_bits(gb, 1);
> +    if (vui->overscan_info_present_flag)
> +        vui->overscan_appropriate_flag = get_bits(gb, 1);
> +    vui->video_signal_type_present_flag = get_bits(gb, 1);
> +    if (vui->video_signal_type_present_flag) {
> +        vui->video_format = get_bits(gb, 3);
> +        vui->video_full_range_flag = get_bits(gb, 1);
> +        vui->colour_description_present_flag = get_bits(gb, 1);
> +        if (vui->colour_description_present_flag) {
> +            vui->colour_primaries = get_bits(gb, 8);
> +            vui->transfer_characteristics = get_bits(gb, 8);
> +            vui->matrix_coefficients = get_bits(gb, 8);
> +        }
> +    }
> +    vui->chroma_loc_info_present_flag = get_bits(gb, 1);
> +    if (vui->chroma_loc_info_present_flag) {
> +        vui->chroma_sample_loc_type_top_field = get_ue_golomb(gb);
> +        vui->chroma_sample_loc_type_bottom_field = get_ue_golomb(gb);
> +    }
> +    vui->neutral_chroma_indication_flag = get_bits(gb, 1);
> +
> +    vui->field_seq_flag = get_bits(gb, 1);
> +
> +    vui->timing_info_present_flag = get_bits(gb, 1);
> +    if (vui->timing_info_present_flag) {
> +        vui->num_units_in_tick = get_bits(gb, 32);
> +        vui->time_scale = get_bits(gb, 32);
> +        vui->fixed_pic_rate_flag = get_bits(gb, 1);
> +    }
> +    vui->nal_hrd_parameters_present_flag = get_bits(gb, 1);
> +    if (vui->nal_hrd_parameters_present_flag)
> +        hrd_parameters(gb, &vui->hrd_parameters);
> +    vui->vcl_hrd_parameters_present_flag = get_bits(gb, 1);
> +    if (vui->vcl_hrd_parameters_present_flag)
> +        hrd_parameters(gb, &vui->hrd_parameters);
> +    if (vui->nal_hrd_parameters_present_flag || vui-
> >vcl_hrd_parameters_present_flag)
> +        vui->low_delay_hrd_flag = get_bits(gb, 1);
> +    vui->pic_struct_present_flag = get_bits(gb, 1);
> +    vui->bitstream_restriction_flag = get_bits(gb, 1);
> +    if (vui->bitstream_restriction_flag) {
> +        vui->motion_vectors_over_pic_boundaries_flag = get_bits(gb, 1);
> +        vui->max_bytes_per_pic_denom = get_ue_golomb(gb);
> +        vui->max_bits_per_mb_denom = get_ue_golomb(gb);
> +        vui->log2_max_mv_length_horizontal = get_ue_golomb(gb);
> +        vui->log2_max_mv_length_vertical = get_ue_golomb(gb);
> +        vui->num_reorder_pics = get_ue_golomb(gb);
> +        vui->max_dec_pic_buffering = get_ue_golomb(gb);
> +    }
> +
> +    return 0;
> +}
> +
> +// @see ISO_IEC_23094-1 (7.3.2.1 SPS RBSP syntax)
> +EVCParserSPS *ff_evc_parse_sps(EVCParamSets *ps, const uint8_t *bs, int
> bs_size)
> +{
> +    GetBitContext gb;
> +    EVCParserSPS *sps;
> +    int sps_seq_parameter_set_id;
> +
> +    if (init_get_bits8(&gb, bs, bs_size) < 0)
> +        return NULL;
> +
> +    sps_seq_parameter_set_id = get_ue_golomb(&gb);
> +
> +    if (sps_seq_parameter_set_id >= EVC_MAX_SPS_COUNT)
> +        return NULL;
> +
> +    if(!ps->sps[sps_seq_parameter_set_id]) {
> +        if((ps->sps[sps_seq_parameter_set_id] =
av_malloc(sizeof(EVCParserSPS)))
> == NULL)
> +            return NULL;
> +    }
> +
> +    sps = ps->sps[sps_seq_parameter_set_id];
> +    memset(sps, 0, sizeof(*sps));
> +
> +    sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id;
> +
> +    // the Baseline profile is indicated by profile_idc eqal to 0
> +    // the Main profile is indicated by profile_idc eqal to 1
> +    sps->profile_idc = get_bits(&gb, 8);
> +
> +    sps->level_idc = get_bits(&gb, 8);
> +
> +    skip_bits_long(&gb, 32); /* skip toolset_idc_h */
> +    skip_bits_long(&gb, 32); /* skip toolset_idc_l */
> +
> +    // 0 - monochrome
> +    // 1 - 4:2:0
> +    // 2 - 4:2:2
> +    // 3 - 4:4:4
> +    sps->chroma_format_idc = get_ue_golomb(&gb);
> +
> +    sps->pic_width_in_luma_samples = get_ue_golomb(&gb);
> +    sps->pic_height_in_luma_samples = get_ue_golomb(&gb);
> +
> +    sps->bit_depth_luma_minus8 = get_ue_golomb(&gb);
> +    sps->bit_depth_chroma_minus8 = get_ue_golomb(&gb);
> +
> +    sps->sps_btt_flag = get_bits(&gb, 1);
> +    if (sps->sps_btt_flag) {
> +        sps->log2_ctu_size_minus5 = get_ue_golomb(&gb);
> +        sps->log2_min_cb_size_minus2 = get_ue_golomb(&gb);
> +        sps->log2_diff_ctu_max_14_cb_size = get_ue_golomb(&gb);
> +        sps->log2_diff_ctu_max_tt_cb_size = get_ue_golomb(&gb);
> +        sps->log2_diff_min_cb_min_tt_cb_size_minus2 = get_ue_golomb(&gb);
> +    }
> +
> +    sps->sps_suco_flag = get_bits(&gb, 1);
> +    if (sps->sps_suco_flag) {
> +        sps->log2_diff_ctu_size_max_suco_cb_size = get_ue_golomb(&gb);
> +        sps->log2_diff_max_suco_min_suco_cb_size = get_ue_golomb(&gb);
> +    }
> +
> +    sps->sps_admvp_flag = get_bits(&gb, 1);
> +    if (sps->sps_admvp_flag) {
> +        sps->sps_affine_flag = get_bits(&gb, 1);
> +        sps->sps_amvr_flag = get_bits(&gb, 1);
> +        sps->sps_dmvr_flag = get_bits(&gb, 1);
> +        sps->sps_mmvd_flag = get_bits(&gb, 1);
> +        sps->sps_hmvp_flag = get_bits(&gb, 1);
> +    }
> +
> +    sps->sps_eipd_flag =  get_bits(&gb, 1);
> +    if (sps->sps_eipd_flag) {
> +        sps->sps_ibc_flag = get_bits(&gb, 1);
> +        if (sps->sps_ibc_flag)
> +            sps->log2_max_ibc_cand_size_minus2 = get_ue_golomb(&gb);
> +    }
> +
> +    sps->sps_cm_init_flag = get_bits(&gb, 1);
> +    if (sps->sps_cm_init_flag)
> +        sps->sps_adcc_flag = get_bits(&gb, 1);
> +
> +    sps->sps_iqt_flag = get_bits(&gb, 1);
> +    if (sps->sps_iqt_flag)
> +        sps->sps_ats_flag = get_bits(&gb, 1);
> +
> +    sps->sps_addb_flag = get_bits(&gb, 1);
> +    sps->sps_alf_flag = get_bits(&gb, 1);
> +    sps->sps_htdf_flag = get_bits(&gb, 1);
> +    sps->sps_rpl_flag = get_bits(&gb, 1);
> +    sps->sps_pocs_flag = get_bits(&gb, 1);
> +    sps->sps_dquant_flag = get_bits(&gb, 1);
> +    sps->sps_dra_flag = get_bits(&gb, 1);
> +
> +    if (sps->sps_pocs_flag)
> +        sps->log2_max_pic_order_cnt_lsb_minus4 = get_ue_golomb(&gb);
> +
> +    if (!sps->sps_pocs_flag || !sps->sps_rpl_flag) {
> +        sps->log2_sub_gop_length = get_ue_golomb(&gb);
> +        if (sps->log2_sub_gop_length == 0)
> +            sps->log2_ref_pic_gap_length = get_ue_golomb(&gb);
> +    }
> +
> +    if (!sps->sps_rpl_flag)
> +        sps->max_num_tid0_ref_pics = get_ue_golomb(&gb);
> +    else {
> +        sps->sps_max_dec_pic_buffering_minus1 = get_ue_golomb(&gb);
> +        sps->long_term_ref_pic_flag = get_bits(&gb, 1);
> +        sps->rpl1_same_as_rpl0_flag = get_bits(&gb, 1);
> +        sps->num_ref_pic_list_in_sps[0] = get_ue_golomb(&gb);
> +
> +        for (int i = 0; i < sps->num_ref_pic_list_in_sps[0]; ++i)
> +            ref_pic_list_struct(&gb, &sps->rpls[0][i]);
> +
> +        if (!sps->rpl1_same_as_rpl0_flag) {
> +            sps->num_ref_pic_list_in_sps[1] = get_ue_golomb(&gb);
> +            for (int i = 0; i < sps->num_ref_pic_list_in_sps[1]; ++i)
> +                ref_pic_list_struct(&gb, &sps->rpls[1][i]);
> +        }
> +    }
> +
> +    sps->picture_cropping_flag = get_bits(&gb, 1);
> +
> +    if (sps->picture_cropping_flag) {
> +        sps->picture_crop_left_offset = get_ue_golomb(&gb);
> +        sps->picture_crop_right_offset = get_ue_golomb(&gb);
> +        sps->picture_crop_top_offset = get_ue_golomb(&gb);
> +        sps->picture_crop_bottom_offset = get_ue_golomb(&gb);
> +    }
> +
> +    if (sps->chroma_format_idc != 0) {
> +        sps->chroma_qp_table_struct.chroma_qp_table_present_flag =
> get_bits(&gb, 1);
> +
> +        if (sps->chroma_qp_table_struct.chroma_qp_table_present_flag) {
> +            sps->chroma_qp_table_struct.same_qp_table_for_chroma =
> get_bits(&gb, 1);
> +            sps->chroma_qp_table_struct.global_offset_flag =
get_bits(&gb, 1);
> +            for (int i = 0; i < (sps-
> >chroma_qp_table_struct.same_qp_table_for_chroma ? 1 : 2); i++) {
> +
sps->chroma_qp_table_struct.num_points_in_qp_table_minus1[i] =
> get_ue_golomb(&gb);;
> +                for (int j = 0; j <= sps-
> >chroma_qp_table_struct.num_points_in_qp_table_minus1[i]; j++) {
> +
sps->chroma_qp_table_struct.delta_qp_in_val_minus1[i][j] =
> get_bits(&gb, 6);
> +                    sps->chroma_qp_table_struct.delta_qp_out_val[i][j] =
> get_se_golomb(&gb);
> +                }
> +            }
> +        }
> +    }
> +
> +    sps->vui_parameters_present_flag = get_bits(&gb, 1);
> +    if (sps->vui_parameters_present_flag)
> +        vui_parameters(&gb, &(sps->vui_parameters));
> +
> +    // @note
> +    // If necessary, add the missing fields to the EVCParserSPS structure
> +    // and then extend parser implementation
> +
> +    return sps;
> +}
> +
> +// @see ISO_IEC_23094-1 (7.3.2.2 SPS RBSP syntax)
> +//
> +// @note
> +// The current implementation of parse_sps function doesn't handle VUI
> parameters parsing.
> +// If it will be needed, parse_sps function could be extended to handle
VUI
> parameters parsing
> +// to initialize fields of the AVCodecContex i.e. color_primaries,
> color_trc,color_range
> +//
> +EVCParserPPS *ff_evc_parse_pps(EVCParamSets *ps, const uint8_t *bs, int
> bs_size)
> +{
> +    GetBitContext gb;
> +    EVCParserPPS *pps;
> +
> +    int pps_pic_parameter_set_id;
> +
> +    if (init_get_bits8(&gb, bs, bs_size) < 0)
> +        return NULL;
> +
> +    pps_pic_parameter_set_id = get_ue_golomb(&gb);
> +    if (pps_pic_parameter_set_id > EVC_MAX_PPS_COUNT)
> +        return NULL;
> +
> +    if(!ps->pps[pps_pic_parameter_set_id]) {
> +        if ((ps->pps[pps_pic_parameter_set_id] =
av_malloc(sizeof(EVCParserPPS)))
> == NULL)
> +            return NULL;
> +    }
> +
> +    pps = ps->pps[pps_pic_parameter_set_id];
> +    memset(pps, 0, sizeof(*pps));
> +
> +    pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id;
> +
> +    pps->pps_seq_parameter_set_id = get_ue_golomb(&gb);
> +    if (pps->pps_seq_parameter_set_id >= EVC_MAX_SPS_COUNT) {
> +        av_freep(&ps->pps[pps_pic_parameter_set_id]);
> +        return NULL;
> +    }
> +
> +    pps->num_ref_idx_default_active_minus1[0] = get_ue_golomb(&gb);
> +    pps->num_ref_idx_default_active_minus1[1] = get_ue_golomb(&gb);
> +    pps->additional_lt_poc_lsb_len = get_ue_golomb(&gb);
> +    pps->rpl1_idx_present_flag = get_bits(&gb, 1);
> +    pps->single_tile_in_pic_flag = get_bits(&gb, 1);
> +
> +    if (!pps->single_tile_in_pic_flag) {
> +        pps->num_tile_columns_minus1 = get_ue_golomb(&gb);
> +        pps->num_tile_rows_minus1 = get_ue_golomb(&gb);
> +        pps->uniform_tile_spacing_flag = get_bits(&gb, 1);
> +
> +        if (!pps->uniform_tile_spacing_flag) {
> +            for (int i = 0; i < pps->num_tile_columns_minus1; i++)
> +                pps->tile_column_width_minus1[i] = get_ue_golomb(&gb);
> +
> +            for (int i = 0; i < pps->num_tile_rows_minus1; i++)
> +                pps->tile_row_height_minus1[i] = get_ue_golomb(&gb);
> +        }
> +        pps->loop_filter_across_tiles_enabled_flag = get_bits(&gb, 1);
> +        pps->tile_offset_len_minus1 = get_ue_golomb(&gb);
> +    }
> +
> +    pps->tile_id_len_minus1 = get_ue_golomb(&gb);
> +    pps->explicit_tile_id_flag = get_bits(&gb, 1);
> +
> +    if (pps->explicit_tile_id_flag) {
> +        for (int i = 0; i <= pps->num_tile_rows_minus1; i++) {
> +            for (int j = 0; j <= pps->num_tile_columns_minus1; j++)
> +                pps->tile_id_val[i][j] = get_bits(&gb,
pps->tile_id_len_minus1 + 1);
> +        }
> +    }
> +
> +    pps->pic_dra_enabled_flag = 0;
> +    pps->pic_dra_enabled_flag = get_bits(&gb, 1);
> +
> +    if (pps->pic_dra_enabled_flag)
> +        pps->pic_dra_aps_id = get_bits(&gb, 5);
> +
> +    pps->arbitrary_slice_present_flag = get_bits(&gb, 1);
> +    pps->constrained_intra_pred_flag = get_bits(&gb, 1);
> +    pps->cu_qp_delta_enabled_flag = get_bits(&gb, 1);
> +
> +    if (pps->cu_qp_delta_enabled_flag)
> +        pps->log2_cu_qp_delta_area_minus6 = get_ue_golomb(&gb);
> +
> +    return pps;
> +}
> +
> +void ff_evc_ps_free(EVCParamSets *ps) {
> +    for (int i = 0; i < EVC_MAX_SPS_COUNT; i++)
> +        av_freep(&ps->sps[i]);
> +
> +    for (int i = 0; i < EVC_MAX_PPS_COUNT; i++)
> +        av_freep(&ps->pps[i]);
> +}
> diff --git a/libavcodec/evc_ps.h b/libavcodec/evc_ps.h
> new file mode 100644
> index 0000000000..989336079f
> --- /dev/null
> +++ b/libavcodec/evc_ps.h
> @@ -0,0 +1,228 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * EVC decoder/parser shared code
> + */
> +
> +#ifndef AVCODEC_EVC_PS_H
> +#define AVCODEC_EVC_PS_H
> +
> +#include <stdint.h>
> +
> +#include "evc.h"
> +
> +#define EVC_MAX_QP_TABLE_SIZE   58
> +#define NUM_CPB                 32
> +
> +// rpl structure
> +typedef struct RefPicListStruct {
> +    int poc;
> +    int tid;
> +    int ref_pic_num;
> +    int ref_pic_active_num;
> +    int ref_pics[EVC_MAX_NUM_REF_PICS];
> +    char pic_type;
> +
> +} RefPicListStruct;
> +
> +// chromaQP table structure to be signalled in SPS
> +typedef struct ChromaQpTable {
> +    int chroma_qp_table_present_flag;       // u(1)
> +    int same_qp_table_for_chroma;           // u(1)
> +    int global_offset_flag;                 // u(1)
> +    int num_points_in_qp_table_minus1[2];   // ue(v)
> +    int delta_qp_in_val_minus1[2][EVC_MAX_QP_TABLE_SIZE];   // u(6)
> +    int delta_qp_out_val[2][EVC_MAX_QP_TABLE_SIZE];         // se(v)
> +} ChromaQpTable;
> +
> +// Hypothetical Reference Decoder (HRD) parameters, part of VUI
> +typedef struct HRDParameters {
> +    int cpb_cnt_minus1;                             // ue(v)
> +    int bit_rate_scale;                             // u(4)
> +    int cpb_size_scale;                             // u(4)
> +    int bit_rate_value_minus1[NUM_CPB];             // ue(v)
> +    int cpb_size_value_minus1[NUM_CPB];             // ue(v)
> +    int cbr_flag[NUM_CPB];                          // u(1)
> +    int initial_cpb_removal_delay_length_minus1;    // u(5)
> +    int cpb_removal_delay_length_minus1;            // u(5)
> +    int dpb_output_delay_length_minus1;             // u(5)
> +    int time_offset_length;                         // u(5)
> +} HRDParameters;
> +
> +// video usability information (VUI) part of SPS
> +typedef struct VUIParameters {
> +    int aspect_ratio_info_present_flag;             // u(1)
> +    int aspect_ratio_idc;                           // u(8)
> +    int sar_width;                                  // u(16)
> +    int sar_height;                                 // u(16)
> +    int overscan_info_present_flag;                 // u(1)
> +    int overscan_appropriate_flag;                  // u(1)
> +    int video_signal_type_present_flag;             // u(1)
> +    int video_format;                               // u(3)
> +    int video_full_range_flag;                      // u(1)
> +    int colour_description_present_flag;            // u(1)
> +    int colour_primaries;                           // u(8)
> +    int transfer_characteristics;                   // u(8)
> +    int matrix_coefficients;                        // u(8)
> +    int chroma_loc_info_present_flag;               // u(1)
> +    int chroma_sample_loc_type_top_field;           // ue(v)
> +    int chroma_sample_loc_type_bottom_field;        // ue(v)
> +    int neutral_chroma_indication_flag;             // u(1)
> +    int field_seq_flag;                             // u(1)
> +    int timing_info_present_flag;                   // u(1)
> +    int num_units_in_tick;                          // u(32)
> +    int time_scale;                                 // u(32)
> +    int fixed_pic_rate_flag;                        // u(1)
> +    int nal_hrd_parameters_present_flag;            // u(1)
> +    int vcl_hrd_parameters_present_flag;            // u(1)
> +    int low_delay_hrd_flag;                         // u(1)
> +    int pic_struct_present_flag;                    // u(1)
> +    int bitstream_restriction_flag;                 // u(1)
> +    int motion_vectors_over_pic_boundaries_flag;    // u(1)
> +    int max_bytes_per_pic_denom;                    // ue(v)
> +    int max_bits_per_mb_denom;                      // ue(v)
> +    int log2_max_mv_length_horizontal;              // ue(v)
> +    int log2_max_mv_length_vertical;                // ue(v)
> +    int num_reorder_pics;                           // ue(v)
> +    int max_dec_pic_buffering;                      // ue(v)
> +
> +    HRDParameters hrd_parameters;
> +} VUIParameters;
> +
> +// The sturcture reflects SPS RBSP(raw byte sequence payload) layout
> +// @see ISO_IEC_23094-1 section 7.3.2.1
> +//
> +// The following descriptors specify the parsing process of each element
> +// u(n) - unsigned integer using n bits
> +// ue(v) - unsigned integer 0-th order Exp_Golomb-coded syntax element
with
> the left bit first
> +typedef struct EVCParserSPS {
> +    int sps_seq_parameter_set_id;   // ue(v)
> +    int profile_idc;                // u(8)
> +    int level_idc;                  // u(8)
> +    int toolset_idc_h;              // u(32)
> +    int toolset_idc_l;              // u(32)
> +    int chroma_format_idc;          // ue(v)
> +    int pic_width_in_luma_samples;  // ue(v)
> +    int pic_height_in_luma_samples; // ue(v)
> +    int bit_depth_luma_minus8;      // ue(v)
> +    int bit_depth_chroma_minus8;    // ue(v)
> +
> +    int sps_btt_flag;                           // u(1)
> +    int log2_ctu_size_minus5;                   // ue(v)
> +    int log2_min_cb_size_minus2;                // ue(v)
> +    int log2_diff_ctu_max_14_cb_size;           // ue(v)
> +    int log2_diff_ctu_max_tt_cb_size;           // ue(v)
> +    int log2_diff_min_cb_min_tt_cb_size_minus2; // ue(v)
> +
> +    int sps_suco_flag;                       // u(1)
> +    int log2_diff_ctu_size_max_suco_cb_size; // ue(v)
> +    int log2_diff_max_suco_min_suco_cb_size; // ue(v)
> +
> +    int sps_admvp_flag;     // u(1)
> +    int sps_affine_flag;    // u(1)
> +    int sps_amvr_flag;      // u(1)
> +    int sps_dmvr_flag;      // u(1)
> +    int sps_mmvd_flag;      // u(1)
> +    int sps_hmvp_flag;      // u(1)
> +
> +    int sps_eipd_flag;                 // u(1)
> +    int sps_ibc_flag;                  // u(1)
> +    int log2_max_ibc_cand_size_minus2; // ue(v)
> +
> +    int sps_cm_init_flag; // u(1)
> +    int sps_adcc_flag;    // u(1)
> +
> +    int sps_iqt_flag; // u(1)
> +    int sps_ats_flag; // u(1)
> +
> +    int sps_addb_flag;   // u(1)
> +    int sps_alf_flag;    // u(1)
> +    int sps_htdf_flag;   // u(1)
> +    int sps_rpl_flag;    // u(1)
> +    int sps_pocs_flag;   // u(1)
> +    int sps_dquant_flag; // u(1)
> +    int sps_dra_flag;    // u(1)
> +
> +    int log2_max_pic_order_cnt_lsb_minus4; // ue(v)
> +    int log2_sub_gop_length;               // ue(v)
> +    int log2_ref_pic_gap_length;           // ue(v)
> +
> +    int max_num_tid0_ref_pics; // ue(v)
> +
> +    int sps_max_dec_pic_buffering_minus1; // ue(v)
> +    int long_term_ref_pic_flag;           // u(1)
> +    int rpl1_same_as_rpl0_flag;           // u(1)
> +    int num_ref_pic_list_in_sps[2];       // ue(v)
> +    struct RefPicListStruct rpls[2][EVC_MAX_NUM_RPLS];
> +
> +    int picture_cropping_flag;      // u(1)
> +    int picture_crop_left_offset;   // ue(v)
> +    int picture_crop_right_offset;  // ue(v)
> +    int picture_crop_top_offset;    // ue(v)
> +    int picture_crop_bottom_offset; // ue(v)
> +
> +    struct ChromaQpTable chroma_qp_table_struct;
> +
> +    int vui_parameters_present_flag;    // u(1)
> +
> +    struct VUIParameters vui_parameters;
> +
> +} EVCParserSPS;
> +
> +typedef struct EVCParserPPS {
> +    int pps_pic_parameter_set_id;                           // ue(v)
> +    int pps_seq_parameter_set_id;                           // ue(v)
> +    int num_ref_idx_default_active_minus1[2];               // ue(v)
> +    int additional_lt_poc_lsb_len;                          // ue(v)
> +    int rpl1_idx_present_flag;                              // u(1)
> +    int single_tile_in_pic_flag;                            // u(1)
> +    int num_tile_columns_minus1;                            // ue(v)
> +    int num_tile_rows_minus1;                               // ue(v)
> +    int uniform_tile_spacing_flag;                          // u(1)
> +    int tile_column_width_minus1[EVC_MAX_TILE_ROWS];        // ue(v)
> +    int tile_row_height_minus1[EVC_MAX_TILE_COLUMNS];          // ue(v)
> +    int loop_filter_across_tiles_enabled_flag;              // u(1)
> +    int tile_offset_len_minus1;                             // ue(v)
> +    int tile_id_len_minus1;                                 // ue(v)
> +    int explicit_tile_id_flag;                              // u(1)
> +    int tile_id_val[EVC_MAX_TILE_ROWS][EVC_MAX_TILE_COLUMNS];  // u(v)
> +    int pic_dra_enabled_flag;                               // u(1)
> +    int pic_dra_aps_id;                                     // u(5)
> +    int arbitrary_slice_present_flag;                       // u(1)
> +    int constrained_intra_pred_flag;                        // u(1)
> +    int cu_qp_delta_enabled_flag;                           // u(1)
> +    int log2_cu_qp_delta_area_minus6;                       // ue(v)
> +
> +} EVCParserPPS;
> +
> +typedef struct EVCParamSets {
> +    EVCParserSPS *sps[EVC_MAX_SPS_COUNT];
> +    EVCParserPPS *pps[EVC_MAX_PPS_COUNT];
> +} EVCParamSets;
> +
> +// @see ISO_IEC_23094-1 (7.3.2.1 SPS RBSP syntax)
> +EVCParserSPS *ff_evc_parse_sps(EVCParamSets *ps, const uint8_t *bs, int
> bs_size);
> +
> +// @see ISO_IEC_23094-1 (7.3.2.2 SPS RBSP syntax)
> +EVCParserPPS *ff_evc_parse_pps(EVCParamSets *ps, const uint8_t *bs, int
> bs_size);
> +
> +void ff_evc_ps_free(EVCParamSets *ps);
> +
> +#endif /* AVCODEC_EVC_PS_H */
> --
> 2.41.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://protect2.fireeye.com/v1/url?k=8708fc5b-d894d571-87097714-
> 000babe598f7-a29b47b5c273342b&q=1&e=f39a2fa5-9fa0-43a4-8767-
> 4e4532bab712&u=https%3A%2F%2Fffmpeg.org%2Fmailman%2Flistinfo%2Fffmp
> eg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".



More information about the ffmpeg-devel mailing list