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 + +#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 */