aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShireesh Kadaramandalgi <shireesh.kadaramandalgi@ittiam.com>2023-02-20 20:13:32 +0530
committerHarish Mahendrakar <harish.mahendrakar@ittiam.com>2023-02-21 12:36:55 -0800
commitb6b12cc5f0d849fc32f7a1604a33ce46ab86d6fc (patch)
tree3cbf88afe1beb23a3250344cb35f799bb1a9287a
parented00dfc32546e06260fdb3d08e2ffd1b79bcbace (diff)
downloadlibavc-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.h7
-rw-r--r--common/ih264_structs.h121
-rw-r--r--decoder/ih264d.h141
-rw-r--r--decoder/ih264d_api.c141
-rw-r--r--decoder/ih264d_error_handler.h4
-rw-r--r--decoder/ih264d_parse_headers.c6
-rw-r--r--decoder/ih264d_parse_slice.c8
-rw-r--r--decoder/ih264d_sei.c231
-rw-r--r--decoder/ih264d_sei.h124
-rw-r--r--decoder/ivd.h6
-rw-r--r--test/decoder/main.c64
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))
{