[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