You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +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) &&
|
const int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
|
||||||
film_grain->apply_grain;
|
film_grain->apply_grain;
|
||||||
|
|
||||||
if (!dec->session_params || dec->params_changed) {
|
if (!dec->session_params) {
|
||||||
av_buffer_unref(&dec->session_params);
|
|
||||||
err = vk_av1_create_params(avctx, &dec->session_params);
|
err = vk_av1_create_params(avctx, &dec->session_params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
dec->params_changed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ap->frame_id_set) {
|
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)
|
static int vk_av1_end_frame(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
const AV1DecContext *s = avctx->priv_data;
|
const AV1DecContext *s = avctx->priv_data;
|
||||||
|
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
|
||||||
const AV1Frame *pic = &s->cur_frame;
|
const AV1Frame *pic = &s->cur_frame;
|
||||||
AV1VulkanDecodePicture *ap = pic->hwaccel_picture_private;
|
AV1VulkanDecodePicture *ap = pic->hwaccel_picture_private;
|
||||||
FFVulkanDecodePicture *vp = &ap->vp;
|
FFVulkanDecodePicture *vp = &ap->vp;
|
||||||
FFVulkanDecodePicture *rvp[AV1_NUM_REF_FRAMES] = { 0 };
|
FFVulkanDecodePicture *rvp[AV1_NUM_REF_FRAMES] = { 0 };
|
||||||
AVFrame *rav[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++) {
|
for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
|
||||||
const AV1Frame *rp = ap->ref_src[i];
|
const AV1Frame *rp = ap->ref_src[i];
|
||||||
AV1VulkanDecodePicture *rhp = rp->hwaccel_picture_private;
|
AV1VulkanDecodePicture *rhp = rp->hwaccel_picture_private;
|
||||||
@@ -578,7 +583,7 @@ const AVHWAccel ff_av1_vulkan_hwaccel = {
|
|||||||
.frame_priv_data_size = sizeof(AV1VulkanDecodePicture),
|
.frame_priv_data_size = sizeof(AV1VulkanDecodePicture),
|
||||||
.init = &ff_vk_decode_init,
|
.init = &ff_vk_decode_init,
|
||||||
.update_thread_context = &ff_vk_update_thread_context,
|
.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,
|
.flush = &ff_vk_decode_flush,
|
||||||
.uninit = &ff_vk_decode_uninit,
|
.uninit = &ff_vk_decode_uninit,
|
||||||
.frame_params = &ff_vk_frame_params,
|
.frame_params = &ff_vk_frame_params,
|
||||||
|
@@ -66,10 +66,10 @@ int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
|
|||||||
return 0;
|
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;
|
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
|
||||||
dec->params_changed = 1;
|
av_buffer_unref(&dec->session_params);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,7 +65,6 @@ typedef struct FFVulkanDecodeContext {
|
|||||||
/* Thread-local state below */
|
/* Thread-local state below */
|
||||||
AVBufferPool *tmp_pool; /* Pool for temporary data, if needed (HEVC) */
|
AVBufferPool *tmp_pool; /* Pool for temporary data, if needed (HEVC) */
|
||||||
size_t tmp_pool_ele_size;
|
size_t tmp_pool_ele_size;
|
||||||
int params_changed;
|
|
||||||
|
|
||||||
uint32_t *slice_off;
|
uint32_t *slice_off;
|
||||||
unsigned int slice_off_max;
|
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);
|
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.
|
* 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;
|
H264VulkanDecodePicture *hp = pic->hwaccel_picture_private;
|
||||||
FFVulkanDecodePicture *vp = &hp->vp;
|
FFVulkanDecodePicture *vp = &hp->vp;
|
||||||
|
|
||||||
if (!dec->session_params || dec->params_changed) {
|
if (!dec->session_params) {
|
||||||
av_buffer_unref(&dec->session_params);
|
|
||||||
err = vk_h264_create_params(avctx, &dec->session_params);
|
err = vk_h264_create_params(avctx, &dec->session_params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
dec->params_changed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in main slot */
|
/* Fill in main slot */
|
||||||
@@ -519,8 +517,14 @@ static int vk_h264_end_frame(AVCodecContext *avctx)
|
|||||||
FFVulkanDecodePicture *rvp[H264_MAX_PICTURE_COUNT] = { 0 };
|
FFVulkanDecodePicture *rvp[H264_MAX_PICTURE_COUNT] = { 0 };
|
||||||
AVFrame *rav[H264_MAX_PICTURE_COUNT] = { 0 };
|
AVFrame *rav[H264_MAX_PICTURE_COUNT] = { 0 };
|
||||||
|
|
||||||
if (!dec->session_params)
|
if (!dec->session_params) {
|
||||||
return AVERROR(EINVAL);
|
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++) {
|
for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
|
||||||
H264Picture *rp = hp->ref_src[i];
|
H264Picture *rp = hp->ref_src[i];
|
||||||
@@ -560,7 +564,7 @@ const AVHWAccel ff_h264_vulkan_hwaccel = {
|
|||||||
.frame_priv_data_size = sizeof(H264VulkanDecodePicture),
|
.frame_priv_data_size = sizeof(H264VulkanDecodePicture),
|
||||||
.init = &ff_vk_decode_init,
|
.init = &ff_vk_decode_init,
|
||||||
.update_thread_context = &ff_vk_update_thread_context,
|
.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,
|
.flush = &ff_vk_decode_flush,
|
||||||
.uninit = &ff_vk_decode_uninit,
|
.uninit = &ff_vk_decode_uninit,
|
||||||
.frame_params = &ff_vk_frame_params,
|
.frame_params = &ff_vk_frame_params,
|
||||||
|
@@ -767,12 +767,10 @@ static int vk_hevc_start_frame(AVCodecContext *avctx,
|
|||||||
const HEVCPPS *pps = h->ps.pps;
|
const HEVCPPS *pps = h->ps.pps;
|
||||||
int nb_refs = 0;
|
int nb_refs = 0;
|
||||||
|
|
||||||
if (!dec->session_params || dec->params_changed) {
|
if (!dec->session_params) {
|
||||||
av_buffer_unref(&dec->session_params);
|
|
||||||
err = vk_hevc_create_params(avctx, &dec->session_params);
|
err = vk_hevc_create_params(avctx, &dec->session_params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
dec->params_changed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hp->h265pic = (StdVideoDecodeH265PictureInfo) {
|
hp->h265pic = (StdVideoDecodeH265PictureInfo) {
|
||||||
@@ -896,12 +894,26 @@ static int vk_hevc_decode_slice(AVCodecContext *avctx,
|
|||||||
static int vk_hevc_end_frame(AVCodecContext *avctx)
|
static int vk_hevc_end_frame(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
const HEVCContext *h = avctx->priv_data;
|
const HEVCContext *h = avctx->priv_data;
|
||||||
|
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
|
||||||
HEVCFrame *pic = h->ref;
|
HEVCFrame *pic = h->ref;
|
||||||
HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
|
HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
|
||||||
FFVulkanDecodePicture *vp = &hp->vp;
|
FFVulkanDecodePicture *vp = &hp->vp;
|
||||||
FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 };
|
FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 };
|
||||||
AVFrame *rav[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++) {
|
for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
|
||||||
HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private;
|
HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private;
|
||||||
rav[i] = hp->ref_src[i]->frame;
|
rav[i] = hp->ref_src[i]->frame;
|
||||||
@@ -938,7 +950,7 @@ const AVHWAccel ff_hevc_vulkan_hwaccel = {
|
|||||||
.frame_priv_data_size = sizeof(HEVCVulkanDecodePicture),
|
.frame_priv_data_size = sizeof(HEVCVulkanDecodePicture),
|
||||||
.init = &ff_vk_decode_init,
|
.init = &ff_vk_decode_init,
|
||||||
.update_thread_context = &ff_vk_update_thread_context,
|
.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,
|
.flush = &ff_vk_decode_flush,
|
||||||
.uninit = &ff_vk_decode_uninit,
|
.uninit = &ff_vk_decode_uninit,
|
||||||
.frame_params = &ff_vk_frame_params,
|
.frame_params = &ff_vk_frame_params,
|
||||||
|
Reference in New Issue
Block a user