diff options
author | Shireesh Kadaramandalgi <shireesh.kadaramandalgi@ittiam.com> | 2023-02-20 20:13:32 +0530 |
---|---|---|
committer | Harish Mahendrakar <harish.mahendrakar@ittiam.com> | 2023-02-21 12:36:55 -0800 |
commit | b6b12cc5f0d849fc32f7a1604a33ce46ab86d6fc (patch) | |
tree | 3cbf88afe1beb23a3250344cb35f799bb1a9287a | |
parent | ed00dfc32546e06260fdb3d08e2ffd1b79bcbace (diff) | |
download | libavc-b6b12cc5f0d849fc32f7a1604a33ce46ab86d6fc.tar.gz |
libavc: Add support for FGC SEI message
- Decoder: Added support for FGC SEI parsing and exporting
-rw-r--r-- | common/ih264_defs.h | 7 | ||||
-rw-r--r-- | common/ih264_structs.h | 121 | ||||
-rw-r--r-- | decoder/ih264d.h | 141 | ||||
-rw-r--r-- | decoder/ih264d_api.c | 141 | ||||
-rw-r--r-- | decoder/ih264d_error_handler.h | 4 | ||||
-rw-r--r-- | decoder/ih264d_parse_headers.c | 6 | ||||
-rw-r--r-- | decoder/ih264d_parse_slice.c | 8 | ||||
-rw-r--r-- | decoder/ih264d_sei.c | 231 | ||||
-rw-r--r-- | decoder/ih264d_sei.h | 124 | ||||
-rw-r--r-- | decoder/ivd.h | 6 | ||||
-rw-r--r-- | test/decoder/main.c | 64 |
11 files changed, 851 insertions, 2 deletions
diff --git a/common/ih264_defs.h b/common/ih264_defs.h index 9a564c9..62b2783 100644 --- a/common/ih264_defs.h +++ b/common/ih264_defs.h @@ -785,4 +785,11 @@ typedef enum #define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_HFR 480000 #define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_SFR 240000 +/* + * @brief Below macros related to film grain characteristics SEI + */ +#define SEI_FGC_NUM_COLOUR_COMPONENTS 3 +#define SEI_FGC_MAX_NUM_MODEL_VALUES 6 +#define SEI_FGC_MAX_NUM_INTENSITY_INTERVALS 256 + #endif /* IH264_DEFS_H_ */ diff --git a/common/ih264_structs.h b/common/ih264_structs.h index b8b4564..81ad7fd 100644 --- a/common/ih264_structs.h +++ b/common/ih264_structs.h @@ -1867,6 +1867,117 @@ typedef struct UWORD32 u4_ccv_avg_luminance_value; }sei_ccv_params_t; +/** + * Structure to hold FGC SEI + */ +typedef struct +{ + /** + * Flag to control the presence of FGC SEI params + */ + UWORD8 u1_film_grain_characteristics_cancel_flag; + + /** + * Specifies the pic order count + */ + WORD32 i4_poc; + + /** + * Specifies IDR pic ID + */ + UWORD32 u4_idr_pic_id; + + /** + * Specifies film grain model for simulation + */ + UWORD8 u1_film_grain_model_id; + + /** + * Specifies separate color format for decoded samples and grain + */ + UWORD8 u1_separate_colour_description_present_flag; + + /** + * Specifies the bit depth used for the luma component + */ + UWORD8 u1_film_grain_bit_depth_luma_minus8; + + /** + * Specifies the bit depth used for the Cb and Cr components + */ + UWORD8 u1_film_grain_bit_depth_chroma_minus8; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_full_range_flag; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_colour_primaries; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_transfer_characteristics; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_matrix_coefficients; + + /** + * identifies the blending mode used to blend the simulated film grain with the decoded images + */ + UWORD8 u1_blending_mode_id; + + /** + * Specifies a scale factor used in the film grain characterization equations + */ + UWORD8 u1_log2_scale_factor; + + /** + * Indicates whether film grain is modelled or not on the colour component + */ + UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of intensity intervals for which + * a specific set of model values has been estimated + */ + UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of model values present for each intensity interval in which + * the film grain has been modelled + */ + UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the lower bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + /** + * Specifies the upper bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + /** + * Represents each one of the model values present for + * the colour component and intensity interval + */ + WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS][SEI_FGC_MAX_NUM_MODEL_VALUES]; + + /** + * Specifies the persistence of the film grain characteristics SEI message + */ + UWORD32 u4_film_grain_characteristics_repetition_period; + +}sei_fgc_params_t; /** * Structure to hold shutter interval info SEI @@ -1961,6 +2072,16 @@ typedef struct * CCV parameters */ sei_ccv_params_t s_sei_ccv_params; + + /** + * film grain characteristics info present flag + */ + UWORD8 u1_sei_fgc_params_present_flag; + + /* + * Film grain parameters + */ + sei_fgc_params_t s_sei_fgc_params; /** * shutter interval info present flag diff --git a/decoder/ih264d.h b/decoder/ih264d.h index 5ad2f9a..cbad3dd 100644 --- a/decoder/ih264d.h +++ b/decoder/ih264d.h @@ -293,7 +293,10 @@ typedef enum { IH264D_CMD_CTL_GET_SEI_CCV_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x304, /** Get SEI SII parameters */ - IH264D_CMD_CTL_GET_SEI_SII_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x305 + IH264D_CMD_CTL_GET_SEI_SII_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x305, + + /** Get SEI FGC parameters */ + IH264D_CMD_CTL_GET_SEI_FGC_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x306 }IH264D_CMD_CTL_SUB_CMDS; /*****************************************************************************/ @@ -833,6 +836,24 @@ typedef struct /** * u4_size */ + UWORD32 u4_size; + + /** + * cmd + */ + IVD_API_COMMAND_TYPE_T e_cmd; + + /** + * sub_cmd + */ + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ih264d_ctl_get_sei_fgc_params_ip_t; + +typedef struct +{ + /** + * u4_size + */ UWORD32 u4_size; /** @@ -885,6 +906,124 @@ typedef struct } ih264d_ctl_get_sei_sii_params_op_t; +typedef struct +{ + /** + * u4_size + */ + UWORD32 u4_size; + + /** + * error_code + */ + UWORD32 u4_error_code; + + /** + * Flag to control the presence of FGC SEI params + */ + UWORD8 u1_film_grain_characteristics_cancel_flag; + + /** + * Specifies the pic order count + */ + WORD32 i4_poc; + + /** + * Specifies IDR pic ID + */ + UWORD32 u4_idr_pic_id; + + /** + * Specifies film grain model for simulation + */ + UWORD8 u1_film_grain_model_id; + + /** + * Specifies separate color format for decoded samples and grain + */ + UWORD8 u1_separate_colour_description_present_flag; + + /** + * Specifies the bit depth used for the luma component + */ + UWORD8 u1_film_grain_bit_depth_luma_minus8; + + /** + * Specifies the bit depth used for the Cb and Cr components + */ + UWORD8 u1_film_grain_bit_depth_chroma_minus8; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_full_range_flag; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_colour_primaries; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_transfer_characteristics; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_matrix_coefficients; + + /** + * identifies the blending mode used to blend the simulated film grain with the decoded images + */ + UWORD8 u1_blending_mode_id; + + /** + * Specifies a scale factor used in the film grain characterization equations + */ + UWORD8 u1_log2_scale_factor; + + /** + * Indicates whether film grain is modelled or not on the colour component + */ + UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of intensity intervals for which + * a specific set of model values has been estimated + */ + UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of model values present for each intensity interval in which + * the film grain has been modelled + */ + UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the lower bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + /** + * Specifies the upper bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + /** + * Represents each one of the model values present for + * the colour component and intensity interval + */ + WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS][SEI_FGC_MAX_NUM_MODEL_VALUES]; + + /** + * Specifies the persistence of the film grain characteristics SEI message + */ + UWORD32 u4_film_grain_characteristics_repetition_period; +}ih264d_ctl_get_sei_fgc_params_op_t; + #ifdef __cplusplus } /* closing brace for extern "C" */ #endif diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index cb296c8..17d079d 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -157,6 +157,10 @@ WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl, WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); +WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op); + WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); WORD32 ih264d_deblock_display(dec_struct_t *ps_dec); @@ -195,6 +199,7 @@ void ih264d_export_sei_params(ivd_sei_decode_op_t *ps_sei_decode_op, dec_struct_ i4_status = ih264d_export_sei_ave_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); i4_status = ih264d_export_sei_ccv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); i4_status = ih264d_export_sei_sii_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); + i4_status = ih264d_export_sei_fgc_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); UNUSED(i4_status); } @@ -970,6 +975,33 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, break; } + case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS: + { + ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip; + ih264d_ctl_get_sei_fgc_params_op_t *ps_op; + + ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *)pv_api_op; + + if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_ip_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_op_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + break; + } + case IH264D_CMD_CTL_SET_NUM_CORES: { ih264d_ctl_set_num_cores_ip_t *ps_ip; @@ -3758,6 +3790,12 @@ WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) case IH264D_CMD_CTL_GET_SEI_SII_PARAMS: ret = ih264d_get_sei_sii_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op); break; + + case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS: + ret = ih264d_get_sei_fgc_params(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IH264D_CMD_CTL_SET_PROCESSOR: ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op); @@ -4370,6 +4408,109 @@ WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_ap return IV_SUCCESS; } +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_sei_fgc_params */ +/* */ +/* Description : This function populates SEI FGC message in */ +/* output structure */ +/* Inputs : iv_obj_t decoder handle */ +/* : pv_api_ip pointer to input structure */ +/* : pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : returns 0; 1 with error code when FGC is not present */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip; + ih264d_ctl_get_sei_fgc_params_op_t *ps_op; + dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; + sei_fgc_params_t *ps_sei_fgc; + WORD32 i4_count; + UWORD32 c, i, j; + + ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *)pv_api_op; + UNUSED(ps_ip); + + if(0 == ps_dec->s_sei_export.u1_sei_fgc_params_present_flag) + { + ps_op->u4_error_code = ERROR_SEI_FGC_PARAMS_NOT_FOUND; + return IV_FAIL; + } + + ps_sei_fgc = &ps_dec->s_sei_export.s_sei_fgc_params; + + ps_op->u1_film_grain_characteristics_cancel_flag = + ps_sei_fgc->u1_film_grain_characteristics_cancel_flag; + + if(0 == ps_op->u1_film_grain_characteristics_cancel_flag) + { + + ps_op->i4_poc = ps_sei_fgc->i4_poc; + ps_op->u4_idr_pic_id = ps_sei_fgc->u4_idr_pic_id; + ps_op->u1_film_grain_model_id = ps_sei_fgc->u1_film_grain_model_id; + ps_op->u1_separate_colour_description_present_flag = + ps_sei_fgc->u1_separate_colour_description_present_flag; + + if(ps_op->u1_separate_colour_description_present_flag) + { + ps_op->u1_film_grain_bit_depth_luma_minus8 = + ps_sei_fgc->u1_film_grain_bit_depth_luma_minus8; + ps_op->u1_film_grain_bit_depth_chroma_minus8 = + ps_sei_fgc->u1_film_grain_bit_depth_chroma_minus8 ; + ps_op->u1_film_grain_full_range_flag = + ps_sei_fgc->u1_film_grain_full_range_flag; + ps_op->u1_film_grain_colour_primaries = ps_sei_fgc->u1_film_grain_colour_primaries; + ps_op->u1_film_grain_transfer_characteristics = + ps_sei_fgc->u1_film_grain_transfer_characteristics; + ps_op->u1_film_grain_matrix_coefficients = ps_sei_fgc->u1_film_grain_matrix_coefficients; + } + ps_op->u1_blending_mode_id = ps_sei_fgc->u1_blending_mode_id; + ps_op->u1_log2_scale_factor = ps_sei_fgc->u1_log2_scale_factor; + + for(c = 0 ; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++){ + ps_op->au1_comp_model_present_flag[c] = + ps_sei_fgc->au1_comp_model_present_flag[c]; + } + + for(c = 0 ; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++){ + if(ps_op->au1_comp_model_present_flag[c]){ + ps_op->au1_num_intensity_intervals_minus1[c] = + ps_sei_fgc->au1_num_intensity_intervals_minus1[c]; + + ps_op->au1_num_model_values_minus1[c] = + ps_sei_fgc->au1_num_model_values_minus1[c]; + + for(i = 0 ; i <= ps_op->au1_num_intensity_intervals_minus1[c]; i++){ + ps_op->au1_intensity_interval_lower_bound[c][i] = + ps_sei_fgc->au1_intensity_interval_lower_bound[c][i]; + ps_op->au1_intensity_interval_upper_bound[c][i] = + ps_sei_fgc->au1_intensity_interval_upper_bound[c][i]; + + for(j = 0; j <= ps_op->au1_num_model_values_minus1[c]; j++){ + ps_op->ai4_comp_model_value[c][i][j] = + ps_sei_fgc->ai4_comp_model_value[c][i][j]; + } + } + } + } + ps_op->u4_film_grain_characteristics_repetition_period = + ps_sei_fgc->u4_film_grain_characteristics_repetition_period; + } + return IV_SUCCESS; +} + WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) { ih264d_ctl_set_num_cores_ip_t *ps_ip; diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h index a66fe7b..dfa0b01 100644 --- a/decoder/ih264d_error_handler.h +++ b/decoder/ih264d_error_handler.h @@ -125,7 +125,9 @@ typedef enum ERROR_INV_SEI_CCV_PARAMS = 0x9F, ERROR_INV_FRAME_NUM = 0xA0, ERROR_SEI_SII_PARAMS_NOT_FOUND = 0xA1, - ERROR_INV_SEI_SII_PARAMS = 0xA2 + ERROR_INV_SEI_SII_PARAMS = 0xA2, + ERROR_SEI_FGC_PARAMS_NOT_FOUND = 0xA3, + ERROR_INV_SEI_FGC_PARAMS = 0xA4 } h264_decoder_error_code_t; diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 6cd122e..c6bc494 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -130,6 +130,12 @@ void ih264d_get_pre_sei_params(dec_struct_t *ps_dec, UWORD8 u1_nal_unit_type) ps_dec->ps_sei->s_sei_sii_params = ps_dec->ps_sei_parse->s_sei_sii_params; } + if(NULL != ps_dec->ps_sei){ + ps_dec->ps_sei->u1_sei_fgc_params_present_flag = + ps_dec->ps_sei_parse->u1_sei_fgc_params_present_flag; + ps_dec->ps_sei->s_sei_fgc_params = ps_dec->ps_sei_parse->s_sei_fgc_params; + } + ps_dec->ps_sei_parse->u1_sei_mdcv_params_present_flag = 0; memset(&ps_dec->ps_sei_parse->s_sei_mdcv_params, 0, sizeof(sei_mdcv_params_t)); ps_dec->ps_sei_parse->u1_sei_cll_params_present_flag = 0; diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 353b2a1..e65e4a9 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -459,6 +459,14 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, ps_dec->ps_cur_pic = ps_cur_pic; ps_dec->u1_pic_buf_id = cur_pic_buf_id; ps_cur_pic->u4_ts = ps_dec->u4_ts; + + /*Update POC and inter_pic_id in sei structure, + *later can be used by application for grain synthesis(SMPTE-RDD5)*/ + if(ps_dec->ps_sei->u1_sei_fgc_params_present_flag) + { + ps_dec->ps_sei->s_sei_fgc_params.i4_poc = i4_poc; + ps_dec->ps_sei->s_sei_fgc_params.u4_idr_pic_id = ps_cur_slice->u4_idr_pic_id; + } memcpy(&ps_cur_pic->s_sei_pic, ps_dec->ps_sei, sizeof(sei)); ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id; diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c index 5b4f08c..4d5d421 100644 --- a/decoder/ih264d_sei.c +++ b/decoder/ih264d_sei.c @@ -734,6 +734,188 @@ WORD32 ih264d_parse_sii(dec_bit_stream_t *ps_bitstrm, dec_struct_t *ps_dec, /*****************************************************************************/ /* */ +/* Function Name : ih264d_parse_fgc */ +/* */ +/* Description : This function parses SEI message film grain charcaristics*/ +/* Inputs : ps_bitstrm Bitstream */ +/* ps_dec Poniter decoder context */ +/* ui4_payload_size pay load i4_size */ +/* Globals : None */ +/* Processing : */ +/* Outputs : None */ +/* Return : 0 for successfull parsing, else -1 */ +/* */ +/* Issues : */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_fgc(dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec, + UWORD32 ui4_payload_size) +{ + sei *ps_sei = ps_dec->ps_sei_parse; + dec_err_status_t *ps_err = ps_dec->ps_dec_err_status; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_count; + WORD32 i4_luma_bitdepth, i4_chroma_bitdepth; + UWORD32 c, i, j; + UNUSED(ui4_payload_size); + + if((ps_dec == NULL) || (ps_sei == NULL)) + { + return NOT_OK; + } + + ps_sei->u1_sei_fgc_params_present_flag = 0; + + ps_sei->s_sei_fgc_params.u1_film_grain_characteristics_cancel_flag = (UWORD8)ih264d_get_bit_h264(ps_bitstrm); + + if(0 == ps_sei->s_sei_fgc_params.u1_film_grain_characteristics_cancel_flag) + { + ps_sei->s_sei_fgc_params.u1_film_grain_model_id = (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 2); + if(ps_sei->s_sei_fgc_params.u1_film_grain_model_id > 1) + { + return ERROR_INV_SEI_FGC_PARAMS; + } + ps_sei->s_sei_fgc_params.u1_separate_colour_description_present_flag = + (UWORD8)ih264d_get_bit_h264(ps_bitstrm); + + if(ps_sei->s_sei_fgc_params.u1_separate_colour_description_present_flag){ + ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_luma_minus8 = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 3); + + i4_luma_bitdepth = ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_luma_minus8 + 8; + + ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_chroma_minus8 = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 3); + + i4_chroma_bitdepth = ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_chroma_minus8 + 8; + + ps_sei->s_sei_fgc_params.u1_film_grain_full_range_flag = + (UWORD8)ih264d_get_bit_h264(ps_bitstrm); + + ps_sei->s_sei_fgc_params.u1_film_grain_colour_primaries = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + + ps_sei->s_sei_fgc_params.u1_film_grain_transfer_characteristics = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + + ps_sei->s_sei_fgc_params.u1_film_grain_matrix_coefficients = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + } + else + { + if(ps_dec->ps_cur_sps == NULL) + { + return NOT_OK; + } + i4_luma_bitdepth = ps_dec->ps_cur_sps->i4_bit_depth_luma_minus8 + 8; + i4_chroma_bitdepth = ps_dec->ps_cur_sps->i4_bit_depth_chroma_minus8 + 8; + } + ps_sei->s_sei_fgc_params.u1_blending_mode_id = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 2); + + if(ps_sei->s_sei_fgc_params.u1_blending_mode_id > 1){ + return ERROR_INV_SEI_FGC_PARAMS; + } + + ps_sei->s_sei_fgc_params.u1_log2_scale_factor = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 4); + + for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++){ + + ps_sei->s_sei_fgc_params.au1_comp_model_present_flag[c] = + (UWORD8)ih264d_get_bit_h264(ps_bitstrm); + } + + + for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++){ + if(ps_sei->s_sei_fgc_params.au1_comp_model_present_flag[c]){ + ps_sei->s_sei_fgc_params.au1_num_intensity_intervals_minus1[c] = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + + ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c] = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 3); + + if(ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c] > (SEI_FGC_MAX_NUM_MODEL_VALUES - 1)){ + return ERROR_INV_SEI_FGC_PARAMS; + } + + for(i = 0; i <= ps_sei->s_sei_fgc_params.au1_num_intensity_intervals_minus1[c]; i++){ + + ps_sei->s_sei_fgc_params.au1_intensity_interval_lower_bound[c][i] = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + + ps_sei->s_sei_fgc_params.au1_intensity_interval_upper_bound[c][i] = + (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 8); + + for(j = 0; j <= ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c]; j++){ + + ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] = + (WORD32)ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(0 == ps_sei->s_sei_fgc_params.u1_film_grain_model_id){ + if((1 == j) || (2 == j)){ + if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) || + (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] > 16)) + return ERROR_INV_SEI_FGC_PARAMS; + } + else if((3 == j) || (4 == j)){ + if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) || + (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] > + ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j-2])) + return ERROR_INV_SEI_FGC_PARAMS; + } + else{ + WORD32 max_lim = (c==0)?(1 << i4_luma_bitdepth) - 1: + (1 << i4_chroma_bitdepth) - 1; + + if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) || + (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] > max_lim)){ + return ERROR_INV_SEI_FGC_PARAMS; + } + + } + } + else + { + WORD32 max_lim = (c==0)?(1 << (i4_luma_bitdepth -1)): + (1 << (i4_chroma_bitdepth -1)); + + if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < -max_lim) || + (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] >= max_lim)){ + return ERROR_INV_SEI_FGC_PARAMS; + } + + } + } + + } + } + } + + ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period = + (UWORD32)ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if(ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period < 0 || + ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period > 16384) + { + return ERROR_INV_SEI_FGC_PARAMS; + } + + ps_sei->u1_sei_fgc_params_present_flag = 1; + } + + return (OK); + +} + +/*****************************************************************************/ +/* */ /* Function Name : ih264d_parse_sei_payload */ /* */ /* Description : This function parses SEI pay loads. Currently it's */ @@ -813,6 +995,12 @@ WORD32 ih264d_parse_sei_payload(dec_bit_stream_t *ps_bitstrm, i4_status = ih264d_parse_sii(ps_bitstrm, ps_dec, ui4_payload_size); break; + + case SEI_FILM_GRAIN_CHARACTERISTICS: + i4_status = ih264d_parse_fgc(ps_bitstrm,ps_dec, + ui4_payload_size); + + break; default: i4_status = ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3)); break; @@ -1120,3 +1308,46 @@ WORD32 ih264d_export_sei_sii_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei * } return (OK); } + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_export_sei_fgc_params */ +/* */ +/* Description : This function populates SEI film grain params in */ +/* output structure */ +/* Inputs : ps_sei_fgc_op pointer to sei fgc o\p struct */ +/* : ps_sei pointer to decoded sei params */ +/* Outputs : */ +/* Returns : returns 0 for success; -1 for failure */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_export_sei_fgc_params(ivd_sei_decode_op_t *ps_sei_decode_op, + sei *ps_sei, sei *ps_sei_export) +{ + if((ps_sei_export == NULL) || (ps_sei == NULL)) + { + return NOT_OK; + } + + ps_sei_export->u1_sei_fgc_params_present_flag = ps_sei->u1_sei_fgc_params_present_flag; + ps_sei_decode_op->u1_sei_fgc_params_present_flag = ps_sei->u1_sei_fgc_params_present_flag; + + if(0 == ps_sei_export->u1_sei_fgc_params_present_flag) + { + memset(&ps_sei_export->s_sei_fgc_params, 0, sizeof(sei_fgc_params_t)); + } + else + { + memcpy(&ps_sei_export->s_sei_fgc_params, &ps_sei->s_sei_fgc_params, + sizeof(sei_fgc_params_t)); + } + + return (OK); +} diff --git a/decoder/ih264d_sei.h b/decoder/ih264d_sei.h index c337662..e063a3c 100644 --- a/decoder/ih264d_sei.h +++ b/decoder/ih264d_sei.h @@ -64,6 +64,7 @@ #define SEI_PROG_REF_SEGMENT_START 16 #define SEI_PROG_REF_SEGMENT_END 17 #define SEI_MOT_CON_SLICE_GRP_SET 18 +#define SEI_FILM_GRAIN_CHARACTERISTICS 19 #define SEI_MASTERING_DISP_COL_VOL 137 #define SEI_CONTENT_LIGHT_LEVEL_DATA 144 #define SEI_AMBIENT_VIEWING_ENVIRONMENT 148 @@ -285,6 +286,116 @@ typedef struct } sei_sii_params_t; +typedef struct +{ + /** + * Flag to control the presence of FGC SEI params + */ + UWORD8 u1_film_grain_characteristics_cancel_flag; + + /** + * Specifies the pic order count + */ + WORD32 i4_poc; + + /** + * Specifies IDR pic ID + */ + UWORD32 u4_idr_pic_id; + + /** + * Specifies film grain model for simulation + */ + UWORD8 u1_film_grain_model_id; + + /** + * Specifies separate color format for decoded samples and grain + */ + UWORD8 u1_separate_colour_description_present_flag; + + /** + * Specifies the bit depth used for the luma component + */ + UWORD8 u1_film_grain_bit_depth_luma_minus8; + + /** + * Specifies the bit depth used for the Cb and Cr components + */ + UWORD8 u1_film_grain_bit_depth_chroma_minus8; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_full_range_flag; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_colour_primaries; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_transfer_characteristics; + + /** + * Specifies the colour space of the FGC in SEI + */ + UWORD8 u1_film_grain_matrix_coefficients; + + /** + * identifies the blending mode used to blend the simulated film grain with the decoded images + */ + UWORD8 u1_blending_mode_id; + + /** + * Specifies a scale factor used in the film grain characterization equations + */ + UWORD8 u1_log2_scale_factor; + + /** + * Indicates whether film grain is modelled or not on the colour component + */ + UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of intensity intervals for which + * a specific set of model values has been estimated + */ + UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the number of model values present for each intensity interval in which + * the film grain has been modelled + */ + UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS]; + + /** + * Specifies the lower bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + /** + * Specifies the upper bound of the interval of intensity levels for which + * the set of model values applies + */ + UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]; + + + /** + * Represents each one of the model values present for + * the colour component and intensity interval + */ + WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS][SEI_FGC_MAX_NUM_MODEL_VALUES]; + + /** + * Specifies the persistence of the film grain characteristics SEI message + */ + UWORD32 u4_film_grain_characteristics_repetition_period; + +}sei_fgc_params_t; + struct _sei { UWORD8 u1_seq_param_set_id; @@ -345,6 +456,16 @@ struct _sei * SII parameters */ sei_sii_params_t s_sei_sii_params; + + /** + * film grain params info present flag + */ + UWORD8 u1_sei_fgc_params_present_flag; + + /* + * film grain characteristics parameters + */ + sei_fgc_params_t s_sei_fgc_params; }; typedef struct _sei sei; @@ -363,5 +484,8 @@ WORD32 ih264d_export_sei_ccv_params(ivd_sei_decode_op_t *ps_sei_decode_op, WORD32 ih264d_export_sei_sii_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei *ps_sei, sei *ps_sei_export); +WORD32 ih264d_export_sei_fgc_params(ivd_sei_decode_op_t *ps_sei_decode_op, + sei *ps_sei, sei *ps_sei_export); + #endif /* _IH264D_SEI_H_ */ diff --git a/decoder/ivd.h b/decoder/ivd.h index 586665e..bd1697c 100644 --- a/decoder/ivd.h +++ b/decoder/ivd.h @@ -60,6 +60,10 @@ */ #define SII_MAX_SUB_LAYERS 8 +#define SEI_FGC_NUM_COLOUR_COMPONENTS 3 +#define SEI_FGC_MAX_NUM_MODEL_VALUES 6 +#define SEI_FGC_MAX_NUM_INTENSITY_INTERVALS 256 + /*****************************************************************************/ /* Typedefs */ /*****************************************************************************/ @@ -397,6 +401,8 @@ typedef struct { UWORD8 u1_sei_sii_params_present_flag; + UWORD8 u1_sei_fgc_params_present_flag; + }ivd_sei_decode_op_t; /* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_DECODE */ diff --git a/test/decoder/main.c b/test/decoder/main.c index 38083b1..be3353d 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -1913,6 +1913,38 @@ void flush_output(iv_obj_t *codec_obj, } } +/*************************************************************************/ + /* Get SEI film grain parameters */ + /*************************************************************************/ + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_fgc_params_present_flag) + { + ih264d_ctl_get_sei_fgc_params_ip_t s_ctl_get_sei_fgc_params_ip; + ih264d_ctl_get_sei_fgc_params_op_t s_ctl_get_sei_fgc_params_op; + + memset(&s_ctl_get_sei_fgc_params_ip, 0, + sizeof(ih264d_ctl_get_sei_fgc_params_ip_t)); + memset(&s_ctl_get_sei_fgc_params_op, 0, + sizeof(ih264d_ctl_get_sei_fgc_params_op_t)); + + s_ctl_get_sei_fgc_params_ip.e_cmd = IVD_CMD_VIDEO_CTL; + s_ctl_get_sei_fgc_params_ip.e_sub_cmd = + (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_GET_SEI_FGC_PARAMS; + s_ctl_get_sei_fgc_params_ip.u4_size = + sizeof(ih264d_ctl_get_sei_fgc_params_ip_t); + s_ctl_get_sei_fgc_params_op.u4_size = + sizeof(ih264d_ctl_get_sei_fgc_params_op_t); + + ret = ivd_api_function((iv_obj_t *)codec_obj, + (void *)&s_ctl_get_sei_fgc_params_ip, + (void *)&s_ctl_get_sei_fgc_params_op); + + if(IV_SUCCESS != ret) + { + printf("FGC SEI params not present : Error %x\n", + s_ctl_get_sei_fgc_params_op.u4_error_code); + } + } + if(ps_app_ctx->u4_file_save_flag) { /* Locate the position of extension yuv */ @@ -3432,6 +3464,38 @@ int main(WORD32 argc, CHAR *argv[]) } } + /*************************************************************************/ + /* Get SEI FGC parameters */ + /*************************************************************************/ + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_fgc_params_present_flag) + { + ih264d_ctl_get_sei_fgc_params_ip_t s_ctl_get_sei_fgc_params_ip; + ih264d_ctl_get_sei_fgc_params_op_t s_ctl_get_sei_fgc_params_op; + + memset(&s_ctl_get_sei_fgc_params_ip, 0, + sizeof(ih264d_ctl_get_sei_fgc_params_ip_t)); + memset(&s_ctl_get_sei_fgc_params_op, 0, + sizeof(ih264d_ctl_get_sei_fgc_params_op_t)); + + s_ctl_get_sei_fgc_params_ip.e_cmd = IVD_CMD_VIDEO_CTL; + s_ctl_get_sei_fgc_params_ip.e_sub_cmd = + (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_GET_SEI_FGC_PARAMS; + s_ctl_get_sei_fgc_params_ip.u4_size = + sizeof(ih264d_ctl_get_sei_fgc_params_ip_t); + s_ctl_get_sei_fgc_params_op.u4_size = + sizeof(ih264d_ctl_get_sei_fgc_params_op_t); + + ret = ivd_api_function((iv_obj_t *)codec_obj, + (void *)&s_ctl_get_sei_fgc_params_ip, + (void *)&s_ctl_get_sei_fgc_params_op); + + if(IV_SUCCESS != ret) + { + printf("FGC SEI params not present : Error %x\n", + s_ctl_get_sei_fgc_params_op.u4_error_code); + } + } + if((1 == s_app_ctx.display) && (1 == ps_video_decode_op->u4_output_present)) { |