diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c b/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c index e572c06cf3..67c573edea 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c @@ -31,7 +31,46 @@ typedef struct _GstVulkanH265Decoder GstVulkanH265Decoder; typedef struct _GstVulkanH265Picture GstVulkanH265Picture; +typedef struct _VPS VPS; +typedef struct _SPS SPS; +typedef struct _PPS PPS; + +struct _SPS +{ + StdVideoH265SequenceParameterSet sps; + StdVideoH265ScalingLists scaling; + StdVideoH265HrdParameters vui_header; + StdVideoH265SequenceParameterSetVui vui; + StdVideoH265ProfileTierLevel ptl; + StdVideoH265DecPicBufMgr dpbm; + StdVideoH265PredictorPaletteEntries pal; + StdVideoH265SubLayerHrdParameters nal_hrd[GST_H265_MAX_SUB_LAYERS]; + StdVideoH265SubLayerHrdParameters vcl_hrd[GST_H265_MAX_SUB_LAYERS]; + /* 7.4.3.2.1: num_short_term_ref_pic_sets is in [0, 64]. */ + StdVideoH265ShortTermRefPicSet str[64]; + StdVideoH265LongTermRefPicsSps ltr; +}; + +struct _PPS +{ + StdVideoH265PictureParameterSet pps; + StdVideoH265ScalingLists scaling; + StdVideoH265PredictorPaletteEntries pal; +}; + +struct _VPS +{ + StdVideoH265VideoParameterSet vps; + StdVideoH265ProfileTierLevel ptl; + StdVideoH265DecPicBufMgr dpbm; + /* FIXME: a VPS can have multiple header params, each with its own nal and vlc + headers sets. Sadly, that's not currently supported by the GStreamer H265 + parser, which only supports one header params per VPS. */ + StdVideoH265HrdParameters hrd; + StdVideoH265SubLayerHrdParameters nal_hdr[GST_H265_MAX_SUB_LAYERS]; + StdVideoH265SubLayerHrdParameters vcl_hdr[GST_H265_MAX_SUB_LAYERS]; +}; struct _GstVulkanH265Picture { GstVulkanDecoderPicture base; @@ -73,6 +112,9 @@ struct _GstVulkanH265Decoder VkChromaLocation xloc, yloc; GstVideoCodecState *output_state; + VPS std_vps; + SPS std_sps; + PPS std_pps; }; static GstStaticPadTemplate gst_vulkan_h265dec_sink_template = @@ -614,41 +656,7 @@ allocation_failed: } } -struct SPS -{ - StdVideoH265SequenceParameterSet sps; - StdVideoH265ScalingLists scaling; - StdVideoH265HrdParameters vui_header; - StdVideoH265SequenceParameterSetVui vui; - StdVideoH265ProfileTierLevel ptl; - StdVideoH265DecPicBufMgr dpbm; - StdVideoH265PredictorPaletteEntries pal; - StdVideoH265SubLayerHrdParameters nal_hrd[GST_H265_MAX_SUB_LAYERS]; - StdVideoH265SubLayerHrdParameters vcl_hrd[GST_H265_MAX_SUB_LAYERS]; - /* 7.4.3.2.1: num_short_term_ref_pic_sets is in [0, 64]. */ - StdVideoH265ShortTermRefPicSet str[64]; - StdVideoH265LongTermRefPicsSps ltr; -}; -struct PPS -{ - StdVideoH265PictureParameterSet pps; - StdVideoH265ScalingLists scaling; - StdVideoH265PredictorPaletteEntries pal; -}; - -struct VPS -{ - StdVideoH265VideoParameterSet vps; - StdVideoH265ProfileTierLevel ptl; - StdVideoH265DecPicBufMgr dpbm; - /* FIXME: a VPS can have multiple header params, each with its own nal and vlc - headers sets. Sadly, that's not currently supported by the GStreamer H265 - parser, which only supports one header params per VPS. */ - StdVideoH265HrdParameters hrd; - StdVideoH265SubLayerHrdParameters nal_hdr[GST_H265_MAX_SUB_LAYERS]; - StdVideoH265SubLayerHrdParameters vcl_hdr[GST_H265_MAX_SUB_LAYERS]; -}; static void _copy_scaling_list (const GstH265ScalingList * scaling_list, @@ -781,7 +789,7 @@ _copy_profile_tier_level (const GstH265ProfileTierLevel * ptl, } static void -_fill_sps (const GstH265SPS * sps, struct SPS *std_sps) +_fill_sps (const GstH265SPS * sps, SPS * std_sps) { int i; const GstH265VUIParams *vui_params = &sps->vui_params; @@ -1055,7 +1063,7 @@ _fill_sps (const GstH265SPS * sps, struct SPS *std_sps) } static void -_fill_pps (const GstH265PPS * pps, const GstH265SPS * sps, struct PPS *std_pps) +_fill_pps (const GstH265PPS * pps, PPS * std_pps) { int i, j; @@ -1113,7 +1121,7 @@ _fill_pps (const GstH265PPS * pps, const GstH265SPS * sps, struct PPS *std_pps) }, .pps_pic_parameter_set_id = pps->id, .pps_seq_parameter_set_id = pps->sps_id, - .sps_video_parameter_set_id = sps->vps_id, + .sps_video_parameter_set_id = pps->sps->vps_id, .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active_minus1, @@ -1177,7 +1185,7 @@ _fill_pps (const GstH265PPS * pps, const GstH265SPS * sps, struct PPS *std_pps) } static void -_fill_vps (const GstH265VPS * vps, struct VPS * std_vps) +_fill_vps (const GstH265VPS * vps, VPS * std_vps) { const GstH265HRDParams *hrd = &vps->hrd_params; @@ -1261,22 +1269,20 @@ _fill_vps (const GstH265VPS * vps, struct VPS * std_vps) } static GstFlowReturn -_update_parameters (GstVulkanH265Decoder * self, const GstH265PPS * pps) +_update_parameters (GstVulkanH265Decoder * self, const GstH265VPS * vps, + const GstH265SPS * sps, const GstH265PPS * pps) { - GstH265SPS *sps = pps->sps; - GstH265VPS *vps = sps->vps; - struct SPS std_sps; - struct PPS std_pps; - struct VPS std_vps; + + gboolean update = FALSE; VkVideoDecodeH265SessionParametersAddInfoKHR params = { .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR, .stdSPSCount = 1, - .pStdSPSs = &std_sps.sps, + .pStdSPSs = &self->std_sps.sps, .stdPPSCount = 1, - .pStdPPSs = &std_pps.pps, + .pStdPPSs = &self->std_pps.pps, .stdVPSCount = 1, - .pStdVPSs = &std_vps.vps, + .pStdVPSs = &self->std_vps.vps, }; /* *INDENT-OFF* */ GstVulkanDecoderParameters dec_params = { @@ -1291,10 +1297,21 @@ _update_parameters (GstVulkanH265Decoder * self, const GstH265PPS * pps) }; /* *INDENT-ON* */ GError *error = NULL; + if (vps) { + _fill_vps (vps, &self->std_vps); + update = TRUE; + } + if (sps) { + _fill_sps (sps, &self->std_sps); + update = TRUE; + } + if (pps) { + _fill_pps (pps, &self->std_pps); + update = TRUE; + } - _fill_sps (sps, &std_sps); - _fill_pps (pps, sps, &std_pps); - _fill_vps (vps, &std_vps); + if (!update) + return GST_FLOW_OK; if (!gst_vulkan_decoder_update_video_session_parameters (self->decoder, &dec_params, &error)) { @@ -1393,6 +1410,8 @@ gst_vulkan_h265_decoder_start_picture (GstH265Decoder * decoder, { GstVulkanH265Decoder *self = GST_VULKAN_H265_DECODER (decoder); GstH265PPS *pps = slice->header.pps; + GstH265SPS *sps = pps->sps; + GstH265VPS *vps = sps->vps; GstFlowReturn ret; GstVulkanH265Picture *pic; GArray *refs; @@ -1400,10 +1419,14 @@ gst_vulkan_h265_decoder_start_picture (GstH265Decoder * decoder, GST_TRACE_OBJECT (self, "Start picture"); + + ret = + _update_parameters (self, self->need_params_update ? vps : NULL, + self->need_params_update ? sps : NULL, pps); + if (ret != GST_FLOW_OK) + return ret; + if (self->need_params_update) { - ret = _update_parameters (self, pps); - if (ret != GST_FLOW_OK) - return ret; self->need_params_update = FALSE; }