diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c index 2b259dd9ee..e6485babf0 100644 --- a/gst-libs/gst/codecparsers/gsth265parser.c +++ b/gst-libs/gst/codecparsers/gsth265parser.c @@ -1934,7 +1934,8 @@ gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu, READ_UINT8 (&nr, sps->sps_range_extension_flag, 1); READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1); READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1); - READ_UINT8 (&nr, sps->sps_extension_5bits, 5); + READ_UINT8 (&nr, sps->sps_scc_extension_flag, 1); + READ_UINT8 (&nr, sps->sps_extension_4bits, 4); } if (sps->sps_range_extension_flag) { @@ -1955,6 +1956,64 @@ gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu, sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1); } + if (sps->sps_multilayer_extension_flag) { + GST_WARNING ("do not support multilayer extension, skip all" + " remaining bits"); + goto done; + } + if (sps->sps_3d_extension_flag) { + GST_WARNING ("do not support 3d extension, skip all remaining bits"); + goto done; + } + + if (sps->sps_scc_extension_flag) { + READ_UINT8 (&nr, + sps->sps_scc_extension_params.sps_curr_pic_ref_enabled_flag, 1); + READ_UINT8 (&nr, sps->sps_scc_extension_params.palette_mode_enabled_flag, + 1); + if (sps->sps_scc_extension_params.palette_mode_enabled_flag) { + READ_UE_MAX (&nr, sps->sps_scc_extension_params.palette_max_size, 64); + READ_UE_MAX (&nr, + sps->sps_scc_extension_params.delta_palette_max_predictor_size, + 128 - sps->sps_scc_extension_params.palette_max_size); + + READ_UINT8 (&nr, + sps->sps_scc_extension_params. + sps_palette_predictor_initializers_present_flag, 1); + if (sps->sps_scc_extension_params. + sps_palette_predictor_initializers_present_flag) { + guint comp; + READ_UE_MAX (&nr, + sps->sps_scc_extension_params. + sps_num_palette_predictor_initializer_minus1, + sps->sps_scc_extension_params.palette_max_size + + sps->sps_scc_extension_params.delta_palette_max_predictor_size - 1); + + for (comp = 0; comp < (sps->chroma_format_idc == 0 ? 1 : 3); comp++) { + guint num_bits; + guint num = + sps->sps_scc_extension_params. + sps_num_palette_predictor_initializer_minus1 + 1; + + num_bits = (comp == 0 ? sps->bit_depth_luma_minus8 + 8 : + sps->bit_depth_chroma_minus8 + 8); + for (i = 0; i < num; i++) + READ_UINT32 (&nr, + sps->sps_scc_extension_params.sps_palette_predictor_initializer + [comp] + [i], num_bits); + } + } + } + + READ_UINT8 (&nr, + sps->sps_scc_extension_params.motion_vector_resolution_control_idc, 2); + READ_UINT8 (&nr, + sps->sps_scc_extension_params.intra_boundary_filtering_disabled_flag, + 1); + } + +done: /* calculate ChromaArrayType */ if (!sps->separate_colour_plane_flag) sps->chroma_array_type = sps->chroma_format_idc; @@ -2164,7 +2223,8 @@ gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu, READ_UINT8 (&nr, pps->pps_range_extension_flag, 1); READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1); READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1); - READ_UINT8 (&nr, pps->pps_extension_5bits, 5); + READ_UINT8 (&nr, pps->pps_scc_extension_flag, 1); + READ_UINT8 (&nr, pps->pps_extension_4bits, 4); } if (pps->pps_range_extension_flag) { @@ -2200,6 +2260,87 @@ gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu, pps->pps_extension_params.log2_sao_offset_scale_chroma, 0, MaxBitDepthC); } + + if (pps->pps_multilayer_extension_flag) { + GST_WARNING ("do not support multilayer extension, skip all" + " remaining bits"); + goto done; + } + if (pps->pps_3d_extension_flag) { + GST_WARNING ("do not support 3d extension, skip all remaining bits"); + goto done; + } + + if (pps->pps_scc_extension_flag) { + READ_UINT8 (&nr, + pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag, 1); + READ_UINT8 (&nr, + pps->pps_scc_extension_params. + residual_adaptive_colour_transform_enabled_flag, 1); + if (pps->pps_scc_extension_params. + residual_adaptive_colour_transform_enabled_flag) { + READ_UINT8 (&nr, + pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag, + 1); + READ_SE_ALLOWED (&nr, + pps->pps_scc_extension_params.pps_act_y_qp_offset_plus5, -7, 17); + READ_SE_ALLOWED (&nr, + pps->pps_scc_extension_params.pps_act_cb_qp_offset_plus5, -7, 17); + READ_SE_ALLOWED (&nr, + pps->pps_scc_extension_params.pps_act_cr_qp_offset_plus3, -9, 15); + } + + READ_UINT8 (&nr, + pps->pps_scc_extension_params. + pps_palette_predictor_initializers_present_flag, 1); + if (pps->pps_scc_extension_params. + pps_palette_predictor_initializers_present_flag) { + READ_UE_MAX (&nr, + pps->pps_scc_extension_params.pps_num_palette_predictor_initializer, + sps->sps_scc_extension_params.palette_max_size + + sps->sps_scc_extension_params.delta_palette_max_predictor_size); + if (pps->pps_scc_extension_params.pps_num_palette_predictor_initializer > + 0) { + guint comp; + + READ_UINT8 (&nr, pps->pps_scc_extension_params.monochrome_palette_flag, + 1); + /* It is a requirement of bitstream conformance that the value of + luma_bit_depth_entry_minus8 shall be equal to the value of + bit_depth_luma_minus8 */ + READ_UE_ALLOWED (&nr, + pps->pps_scc_extension_params.luma_bit_depth_entry_minus8, + sps->bit_depth_luma_minus8, sps->bit_depth_luma_minus8); + if (!pps->pps_scc_extension_params.monochrome_palette_flag) { + /* It is a requirement of bitstream conformance that the value + of chroma_bit_depth_entry_minus8 shall be equal to the value + of bit_depth_chroma_minus8. */ + READ_UE_ALLOWED (&nr, + pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8, + sps->bit_depth_chroma_minus8, sps->bit_depth_chroma_minus8); + } + + for (comp = 0; comp < + (pps->pps_scc_extension_params.monochrome_palette_flag ? 1 : 3); + comp++) { + guint num_bits; + guint num = + pps->pps_scc_extension_params. + pps_num_palette_predictor_initializer; + + num_bits = (comp == 0 ? + pps->pps_scc_extension_params.luma_bit_depth_entry_minus8 + 8 : + pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8 + 8); + for (i = 0; i < num; i++) + READ_UINT32 (&nr, + pps->pps_scc_extension_params.pps_palette_predictor_initializer + [comp][i], num_bits); + } + } + } + } + +done: pps->valid = TRUE; return GST_H265_PARSER_OK; @@ -2457,6 +2598,10 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser, if (!gst_h265_slice_parse_pred_weight_table (slice, &nr)) goto error; READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4); + + if (sps->sps_scc_extension_params.motion_vector_resolution_control_idc + == 2) + READ_UINT8 (&nr, slice->use_integer_mv_flag, 1); } READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77); @@ -2465,6 +2610,12 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser, READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12); } + if (pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag) { + READ_SE_ALLOWED (&nr, slice->slice_act_y_qp_offset, -12, 12); + READ_SE_ALLOWED (&nr, slice->slice_act_cb_qp_offset, -12, 12); + READ_SE_ALLOWED (&nr, slice->slice_act_cr_qp_offset, -12, 12); + } + if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1); diff --git a/gst-libs/gst/codecparsers/gsth265parser.h b/gst-libs/gst/codecparsers/gsth265parser.h index e618929a3e..e853031a73 100644 --- a/gst-libs/gst/codecparsers/gsth265parser.h +++ b/gst-libs/gst/codecparsers/gsth265parser.h @@ -434,7 +434,9 @@ typedef struct _GstH265SubLayerHRDParams GstH265SubLayerHRDParams; typedef struct _GstH265HRDParams GstH265HRDParams; typedef struct _GstH265VUIParams GstH265VUIParams; typedef struct _GstH265SPSExtensionParams GstH265SPSExtensionParams; +typedef struct _GstH265SPSSccExtensionParams GstH265SPSSccExtensionParams; typedef struct _GstH265PPSExtensionParams GstH265PPSExtensionParams; +typedef struct _GstH265PPSSccExtensionParams GstH265PPSSccExtensionParams; typedef struct _GstH265ScalingList GstH265ScalingList; typedef struct _GstH265RefPicListModification GstH265RefPicListModification; @@ -950,6 +952,43 @@ struct _GstH265SPSExtensionParams { guint8 cabac_bypass_alignment_enabled_flag; }; +/** + * GstH265SPSSccExtensionParams: + * @sps_curr_pic_ref_enabled_flag: equal to 1 specifies that a picture in the CVS may be + * included in a reference picture list of a slice of the picture itself. + * @palette_mode_enabled_flag: equal to 1 specifies that the decoding process for palette mode + * may be used for intra blocks. Equal to 0 specifies that the decoding process for palette + * mode is not applied. + * @palette_max_size: specifies the maximum allowed palette size. + * @delta_palette_max_predictor_size: specifies the difference between the maximum allowed + * palette predictor size and the maximum allowed palette size. + * @sps_palette_predictor_initializers_present_flag: equal to 1 specifies that the sequence + * palette predictors are initialized using the sps_palette_predictor_initializer specified + * in clause 7.3.2.2.3. + * @sps_num_palette_predictor_initializer_minus1: plus 1 specifies the number of entries in + * the sequence palette predictor initializer. + * @sps_palette_predictor_initializer: specifies the value of the comp-th component of the + * i-th palette entry in the SPS that is used to initialize the array PredictorPaletteEntries. + * @motion_vector_resolution_control_idc: controls the presence and inference of the + * use_integer_mv_flag that specifies the resolution of motion vectors for inter prediction. + * @intra_boundary_filtering_disabled_flag: equal to 1 specifies that the intra boundary + * filtering process is unconditionally disabled for intra prediction. + * Defines the _GstH265SPSSccExtensionParams + * + * Since: 1.18 + */ +struct _GstH265SPSSccExtensionParams { + guint8 sps_curr_pic_ref_enabled_flag; + guint8 palette_mode_enabled_flag; + guint8 palette_max_size; + guint8 delta_palette_max_predictor_size; + guint8 sps_palette_predictor_initializers_present_flag; + guint8 sps_num_palette_predictor_initializer_minus1; + guint32 sps_palette_predictor_initializer[3][128]; + guint8 motion_vector_resolution_control_idc; + guint8 intra_boundary_filtering_disabled_flag; +}; + /** * GstH265PPSExtensionParams: * @log2_max_transform_skip_block_size_minus2: plus 2 specifies the maximum transform block size for which @@ -983,6 +1022,51 @@ struct _GstH265PPSExtensionParams { guint8 log2_sao_offset_scale_chroma; }; +/** + * GstH265PPSSccExtensionParams: + * @pps_curr_pic_ref_enabled_flag: equal to 1 specifies that a picture referring to the PPS may + * be included in a reference picture list of a slice of the picture itself. + * @residual_adaptive_colour_transform_enabled_flag: equal to 1 specifies that an adaptive + * colour transform may be applied to the residual in the decoding process. + * @pps_slice_act_qp_offsets_present_flag: equal to 1 specifies that slice_act_y_qp_offset, + * slice_act_cb_qp_offset, slice_act_cr_qp_offset are present in the slice header. + * @pps_act_y_qp_offset_plus5 @pps_act_cb_qp_offset_plus5 @pps_act_cr_qp_offset_plus3: + * are used to determine the offsets that are applied to the quantization parameter values + * qp derived in clause 8.6.2 for the luma, Cb and Cr components, respectively, when + * tu_residual_act_flag[ xTbY ][ yTbY ] is equal to 1. + * @pps_palette_predictor_initializers_present_flag: equal to 1 specifies that the palette + * predictor initializers used for the pictures referring to the PPS are derived based on + * the palette predictor initializers specified by the PPS. + * @pps_num_palette_predictor_initializer: specifies the number of entries in the picture + * palette predictor initializer. + * @monochrome_palette_flag: equal to 1 specifies that the pictures that refer to this PPS + * are monochrome. Equal to 0 specifies that the pictures that refer to this PPS have + * multiple components. + * @luma_bit_depth_entry_minus8: plus 8 specifies the bit depth of the luma component of the + * entries of the palette predictor initializer. + * @chroma_bit_depth_entry_minus8: plus 8 specifies the bit depth of the chroma components of + * the entries of the palette predictor initializer. + * @pps_palette_predictor_initializer: specifies the value of the comp-th component of the + * i-th palette entry in the PPS that is used to initialize the array PredictorPaletteEntries. + * Defines the _GstH265PPSSccExtensionParams + * + * Since: 1.18 + */ +struct _GstH265PPSSccExtensionParams { + guint8 pps_curr_pic_ref_enabled_flag; + guint8 residual_adaptive_colour_transform_enabled_flag; + guint8 pps_slice_act_qp_offsets_present_flag; + guint8 pps_act_y_qp_offset_plus5; + guint8 pps_act_cb_qp_offset_plus5; + guint8 pps_act_cr_qp_offset_plus3; + guint8 pps_palette_predictor_initializers_present_flag; + guint8 pps_num_palette_predictor_initializer; + guint8 monochrome_palette_flag; + guint8 luma_bit_depth_entry_minus8; + guint32 chroma_bit_depth_entry_minus8; + guint32 pps_palette_predictor_initializer[3][128]; +}; + /** * GstH265ScalingList: * @scaling_list_dc_coef_minus8_16x16: this plus 8 specifies the DC @@ -1091,10 +1175,13 @@ struct _GstH265SPS guint8 sps_range_extension_flag; guint8 sps_multilayer_extension_flag; guint8 sps_3d_extension_flag; - guint8 sps_extension_5bits; + guint8 sps_scc_extension_flag; + guint8 sps_extension_4bits; -/* if sps_range_extension_flag */ + /* if sps_range_extension_flag */ GstH265SPSExtensionParams sps_extnsion_params; + /* if sps_scc_extension_flag */ + GstH265SPSSccExtensionParams sps_scc_extension_params; /* calculated values */ guint8 chroma_array_type; @@ -1167,10 +1254,13 @@ struct _GstH265PPS guint8 pps_range_extension_flag; guint8 pps_multilayer_extension_flag; guint8 pps_3d_extension_flag; - guint8 pps_extension_5bits; + guint8 pps_scc_extension_flag; + guint8 pps_extension_4bits; /* if pps_range_extension_flag*/ - GstH265PPSExtensionParams pps_extension_params; + GstH265PPSExtensionParams pps_extension_params; + /* if pps_scc_extension_flag*/ + GstH265PPSSccExtensionParams pps_scc_extension_params; /* calculated values */ guint32 PicWidthInCtbsY; @@ -1262,9 +1352,17 @@ struct _GstH265PredWeightTable * @pred_weight_table: a #GstH265PredWeightTable * @five_minus_max_num_merge_cand: specifies the maximum number of merging motion vector prediction (MVP) * candidates supported in the slice. + * @use_integer_mv_flag: equal to 1 specifies that the resolution of motion vectors for inter + * prediction in the current slice is integer. (Since: 1.18) * @qp_delta: specifies the inital value of QPy to be used for the coding blocks in the slice. * @cb_qp_offset: a difference to be added to the value of pps_cb_qp_offset. * @cr_qp_offset: a difference to be added to the value of pps_cr_qp_offset. + * @slice_act_y_qp_offset: specify offsets to the quantization parameter values qP derived in + * clause 8.6.2 for luma components. (Since: 1.18) + * @slice_act_cb_qp_offset: specify offsets to the quantization parameter values qP derived in + * clause 8.6.2 for Cb components. (Since: 1.18) + * @slice_act_cr_qp_offset: specify offsets to the quantization parameter values qP derived in + * clause 8.6.2 for Cr components. (Since: 1.18) * @cu_chroma_qp_offset_enabled_flag: equal to 1 if the cu_chroma_qp_offset_flag * may be present in the transform unit syntax. (Since: 1.18) * @deblocking_filter_override_flag: equal to 1 if deblocking paramertes are present in the slice header. @@ -1332,10 +1430,14 @@ struct _GstH265SliceHdr GstH265PredWeightTable pred_weight_table; guint8 five_minus_max_num_merge_cand; + guint8 use_integer_mv_flag; gint8 qp_delta; gint8 cb_qp_offset; gint8 cr_qp_offset; + gint8 slice_act_y_qp_offset; + gint8 slice_act_cb_qp_offset; + gint8 slice_act_cr_qp_offset; guint8 cu_chroma_qp_offset_enabled_flag; diff --git a/tests/check/libs/h265parser.c b/tests/check/libs/h265parser.c index e04ce72c67..819b8cdeb0 100644 --- a/tests/check/libs/h265parser.c +++ b/tests/check/libs/h265parser.c @@ -642,7 +642,7 @@ GST_START_TEST (test_h265_parse_pps) assert_equals_int (pps.pps_range_extension_flag, 1); assert_equals_int (pps.pps_multilayer_extension_flag, 0); assert_equals_int (pps.pps_3d_extension_flag, 0); - assert_equals_int (pps.pps_extension_5bits, 0); + assert_equals_int (pps.pps_extension_4bits, 0); assert_equals_int (pps. pps_extension_params.log2_max_transform_skip_block_size_minus2, 0); assert_equals_int (pps.