You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	vulkan_decode: simplify and make session parameter generation more robust
This commit scraps a bool to signal to recreate the session parameters, but instead destroys them, forcing them to be recreated. As this can happen between start_frame and end_frame, do this at both places.
This commit is contained in:
		| @@ -229,12 +229,10 @@ static int vk_av1_start_frame(AVCodecContext          *avctx, | ||||
|     const int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && | ||||
|                             film_grain->apply_grain; | ||||
|  | ||||
|     if (!dec->session_params || dec->params_changed) { | ||||
|         av_buffer_unref(&dec->session_params); | ||||
|     if (!dec->session_params) { | ||||
|         err = vk_av1_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|         dec->params_changed = 0; | ||||
|     } | ||||
|  | ||||
|     if (!ap->frame_id_set) { | ||||
| @@ -530,12 +528,19 @@ static int vk_av1_decode_slice(AVCodecContext *avctx, | ||||
| static int vk_av1_end_frame(AVCodecContext *avctx) | ||||
| { | ||||
|     const AV1DecContext *s = avctx->priv_data; | ||||
|     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; | ||||
|     const AV1Frame *pic = &s->cur_frame; | ||||
|     AV1VulkanDecodePicture *ap = pic->hwaccel_picture_private; | ||||
|     FFVulkanDecodePicture *vp = &ap->vp; | ||||
|     FFVulkanDecodePicture *rvp[AV1_NUM_REF_FRAMES] = { 0 }; | ||||
|     AVFrame *rav[AV1_NUM_REF_FRAMES] = { 0 }; | ||||
|  | ||||
|     if (!dec->session_params) { | ||||
|         int err = vk_av1_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|     } | ||||
|  | ||||
|     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) { | ||||
|         const AV1Frame *rp = ap->ref_src[i]; | ||||
|         AV1VulkanDecodePicture *rhp = rp->hwaccel_picture_private; | ||||
| @@ -578,7 +583,7 @@ const AVHWAccel ff_av1_vulkan_hwaccel = { | ||||
|     .frame_priv_data_size  = sizeof(AV1VulkanDecodePicture), | ||||
|     .init                  = &ff_vk_decode_init, | ||||
|     .update_thread_context = &ff_vk_update_thread_context, | ||||
|     .decode_params         = &ff_vk_params_changed, | ||||
|     .decode_params         = &ff_vk_params_invalidate, | ||||
|     .flush                 = &ff_vk_decode_flush, | ||||
|     .uninit                = &ff_vk_decode_uninit, | ||||
|     .frame_params          = &ff_vk_frame_params, | ||||
|   | ||||
| @@ -66,10 +66,10 @@ int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int ff_vk_params_changed(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s) | ||||
| int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s) | ||||
| { | ||||
|     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; | ||||
|     dec->params_changed = 1; | ||||
|     av_buffer_unref(&dec->session_params); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -65,7 +65,6 @@ typedef struct FFVulkanDecodeContext { | ||||
|     /* Thread-local state below */ | ||||
|     AVBufferPool *tmp_pool; /* Pool for temporary data, if needed (HEVC) */ | ||||
|     size_t tmp_pool_ele_size; | ||||
|     int params_changed; | ||||
|  | ||||
|     uint32_t                       *slice_off; | ||||
|     unsigned int                    slice_off_max; | ||||
| @@ -119,9 +118,9 @@ int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); | ||||
| int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); | ||||
|  | ||||
| /** | ||||
|  * Sets FFVulkanDecodeContext.params_changed to 1. | ||||
|  * Removes current session parameters to recreate them | ||||
|  */ | ||||
| int ff_vk_params_changed(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s); | ||||
| int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s); | ||||
|  | ||||
| /** | ||||
|  * Prepare a frame, creates the image view, and sets up the dpb fields. | ||||
|   | ||||
| @@ -379,12 +379,10 @@ static int vk_h264_start_frame(AVCodecContext          *avctx, | ||||
|     H264VulkanDecodePicture *hp = pic->hwaccel_picture_private; | ||||
|     FFVulkanDecodePicture *vp = &hp->vp; | ||||
|  | ||||
|     if (!dec->session_params || dec->params_changed) { | ||||
|         av_buffer_unref(&dec->session_params); | ||||
|     if (!dec->session_params) { | ||||
|         err = vk_h264_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|         dec->params_changed = 0; | ||||
|     } | ||||
|  | ||||
|     /* Fill in main slot */ | ||||
| @@ -519,8 +517,14 @@ static int vk_h264_end_frame(AVCodecContext *avctx) | ||||
|     FFVulkanDecodePicture *rvp[H264_MAX_PICTURE_COUNT] = { 0 }; | ||||
|     AVFrame *rav[H264_MAX_PICTURE_COUNT] = { 0 }; | ||||
|  | ||||
|     if (!dec->session_params) | ||||
|         return AVERROR(EINVAL); | ||||
|     if (!dec->session_params) { | ||||
|         int err = vk_h264_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|  | ||||
|         hp->h264pic.seq_parameter_set_id = pic->pps->sps_id; | ||||
|         hp->h264pic.pic_parameter_set_id = pic->pps->pps_id; | ||||
|     } | ||||
|  | ||||
|     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) { | ||||
|         H264Picture *rp = hp->ref_src[i]; | ||||
| @@ -560,7 +564,7 @@ const AVHWAccel ff_h264_vulkan_hwaccel = { | ||||
|     .frame_priv_data_size  = sizeof(H264VulkanDecodePicture), | ||||
|     .init                  = &ff_vk_decode_init, | ||||
|     .update_thread_context = &ff_vk_update_thread_context, | ||||
|     .decode_params         = &ff_vk_params_changed, | ||||
|     .decode_params         = &ff_vk_params_invalidate, | ||||
|     .flush                 = &ff_vk_decode_flush, | ||||
|     .uninit                = &ff_vk_decode_uninit, | ||||
|     .frame_params          = &ff_vk_frame_params, | ||||
|   | ||||
| @@ -767,12 +767,10 @@ static int vk_hevc_start_frame(AVCodecContext          *avctx, | ||||
|     const HEVCPPS *pps = h->ps.pps; | ||||
|     int nb_refs = 0; | ||||
|  | ||||
|     if (!dec->session_params || dec->params_changed) { | ||||
|         av_buffer_unref(&dec->session_params); | ||||
|     if (!dec->session_params) { | ||||
|         err = vk_hevc_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|         dec->params_changed = 0; | ||||
|     } | ||||
|  | ||||
|     hp->h265pic = (StdVideoDecodeH265PictureInfo) { | ||||
| @@ -896,12 +894,26 @@ static int vk_hevc_decode_slice(AVCodecContext *avctx, | ||||
| static int vk_hevc_end_frame(AVCodecContext *avctx) | ||||
| { | ||||
|     const HEVCContext *h = avctx->priv_data; | ||||
|     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; | ||||
|     HEVCFrame *pic = h->ref; | ||||
|     HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private; | ||||
|     FFVulkanDecodePicture *vp = &hp->vp; | ||||
|     FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 }; | ||||
|     AVFrame *rav[HEVC_MAX_REFS] = { 0 }; | ||||
|  | ||||
|     if (!dec->session_params) { | ||||
|         const HEVCSPS *sps = h->ps.sps; | ||||
|         const HEVCPPS *pps = h->ps.pps; | ||||
|  | ||||
|         int err = vk_hevc_create_params(avctx, &dec->session_params); | ||||
|         if (err < 0) | ||||
|             return err; | ||||
|  | ||||
|         hp->h265pic.sps_video_parameter_set_id = sps->vps_id; | ||||
|         hp->h265pic.pps_seq_parameter_set_id = pps->sps_id; | ||||
|         hp->h265pic.pps_pic_parameter_set_id = pps->pps_id; | ||||
|     } | ||||
|  | ||||
|     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) { | ||||
|         HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private; | ||||
|         rav[i] = hp->ref_src[i]->frame; | ||||
| @@ -938,7 +950,7 @@ const AVHWAccel ff_hevc_vulkan_hwaccel = { | ||||
|     .frame_priv_data_size  = sizeof(HEVCVulkanDecodePicture), | ||||
|     .init                  = &ff_vk_decode_init, | ||||
|     .update_thread_context = &ff_vk_update_thread_context, | ||||
|     .decode_params         = &ff_vk_params_changed, | ||||
|     .decode_params         = &ff_vk_params_invalidate, | ||||
|     .flush                 = &ff_vk_decode_flush, | ||||
|     .uninit                = &ff_vk_decode_uninit, | ||||
|     .frame_params          = &ff_vk_frame_params, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user