mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-01-12 00:06:51 +08:00
vulkan_decode: clean up decoder initialization
Now that we don't reset on every seek, we can simplify it.
This commit is contained in:
@@ -372,17 +372,65 @@ int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_vk_decode_flush(AVCodecContext *avctx)
|
||||
static int create_empty_session_parameters(AVCodecContext *avctx,
|
||||
FFVulkanDecodeShared *ctx,
|
||||
VkVideoSessionParametersKHR *empty_session_params)
|
||||
{
|
||||
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
|
||||
FFVulkanDecodeShared *ctx = dec->shared_ctx;
|
||||
if (avctx->codec_id == AV_CODEC_ID_VP9)
|
||||
return 0;
|
||||
|
||||
VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
};
|
||||
VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
};
|
||||
StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
|
||||
VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.pStdSequenceHeader = &av1_empty_seq,
|
||||
};
|
||||
VkVideoSessionParametersCreateInfoKHR session_params_create = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
|
||||
avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
|
||||
avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
|
||||
NULL,
|
||||
.videoSession = ctx->common.session,
|
||||
};
|
||||
|
||||
VkResult ret;
|
||||
FFVulkanContext *s = &ctx->s;
|
||||
FFVulkanFunctions *vk = &s->vkfn;
|
||||
ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
|
||||
s->hwctx->alloc, empty_session_params);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
|
||||
ff_vk_ret2str(ret));
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_reset(AVCodecContext *avctx, FFVulkanDecodeShared *ctx)
|
||||
{
|
||||
int err;
|
||||
FFVulkanContext *s = &ctx->s;
|
||||
FFVulkanFunctions *vk = &s->vkfn;
|
||||
|
||||
FFVulkanFunctions *vk = &ctx->s.vkfn;
|
||||
VkVideoBeginCodingInfoKHR decode_start = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
|
||||
.videoSession = ctx->common.session,
|
||||
.videoSessionParameters = ctx->empty_session_params,
|
||||
};
|
||||
|
||||
if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
|
||||
err = create_empty_session_parameters(avctx, ctx,
|
||||
&decode_start.videoSessionParameters);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
VkVideoCodingControlInfoKHR decode_ctrl = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
|
||||
.flags = VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
|
||||
@@ -391,21 +439,30 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
|
||||
};
|
||||
|
||||
VkCommandBuffer cmd_buf;
|
||||
FFVkExecContext *exec;
|
||||
|
||||
/* Non-video queues do not need to be reset */
|
||||
if (!(get_codecdesc(avctx->codec_id)->decode_op))
|
||||
return;
|
||||
|
||||
exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
|
||||
FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
|
||||
ff_vk_exec_start(&ctx->s, exec);
|
||||
cmd_buf = exec->buf;
|
||||
|
||||
vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
|
||||
vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
|
||||
vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
|
||||
ff_vk_exec_submit(&ctx->s, exec);
|
||||
vk->CmdBeginVideoCodingKHR(exec->buf, &decode_start);
|
||||
vk->CmdControlVideoCodingKHR(exec->buf, &decode_ctrl);
|
||||
vk->CmdEndVideoCodingKHR(exec->buf, &decode_end);
|
||||
|
||||
err = ff_vk_exec_submit(&ctx->s, exec);
|
||||
|
||||
if (decode_start.videoSessionParameters) {
|
||||
/* Wait to complete to delete the temporary session parameters */
|
||||
if (err >= 0)
|
||||
ff_vk_exec_wait(&ctx->s, exec);
|
||||
|
||||
vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
|
||||
decode_start.videoSessionParameters,
|
||||
s->hwctx->alloc);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to reset decoder: %s",
|
||||
ff_vk_ret2str(err));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int ff_vk_decode_frame(AVCodecContext *avctx,
|
||||
@@ -651,7 +708,6 @@ static void free_common(AVRefStructOpaque unused, void *obj)
|
||||
{
|
||||
FFVulkanDecodeShared *ctx = obj;
|
||||
FFVulkanContext *s = &ctx->s;
|
||||
FFVulkanFunctions *vk = &ctx->s.vkfn;
|
||||
|
||||
/* Wait on and free execution pool */
|
||||
ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
|
||||
@@ -659,12 +715,6 @@ static void free_common(AVRefStructOpaque unused, void *obj)
|
||||
/* This also frees all references from this pool */
|
||||
av_frame_free(&ctx->common.layered_frame);
|
||||
|
||||
/* Destroy parameters */
|
||||
if (ctx->empty_session_params)
|
||||
vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
|
||||
ctx->empty_session_params,
|
||||
s->hwctx->alloc);
|
||||
|
||||
av_buffer_pool_uninit(&ctx->buf_pool);
|
||||
|
||||
ff_vk_video_common_uninit(s, &ctx->common);
|
||||
@@ -1237,47 +1287,6 @@ int ff_vk_decode_uninit(AVCodecContext *avctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_empty_session_parameters(AVCodecContext *avctx,
|
||||
FFVulkanDecodeShared *ctx)
|
||||
{
|
||||
VkResult ret;
|
||||
FFVulkanContext *s = &ctx->s;
|
||||
FFVulkanFunctions *vk = &s->vkfn;
|
||||
|
||||
VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
};
|
||||
VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
};
|
||||
StdVideoAV1SequenceHeader av1_empty_seq = { 0 };
|
||||
VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.pStdSequenceHeader = &av1_empty_seq,
|
||||
};
|
||||
VkVideoSessionParametersCreateInfoKHR session_params_create = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
||||
.pNext = avctx->codec_id == AV_CODEC_ID_H264 ? (void *)&h264_params :
|
||||
avctx->codec_id == AV_CODEC_ID_HEVC ? (void *)&h265_params :
|
||||
avctx->codec_id == AV_CODEC_ID_AV1 ? (void *)&av1_params :
|
||||
NULL,
|
||||
.videoSession = ctx->common.session,
|
||||
};
|
||||
|
||||
if (avctx->codec_id == AV_CODEC_ID_VP9)
|
||||
return 0;
|
||||
|
||||
ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
|
||||
s->hwctx->alloc, &ctx->empty_session_params);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to create empty Vulkan video session parameters: %s!\n",
|
||||
ff_vk_ret2str(ret));
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_vk_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
int err;
|
||||
@@ -1287,7 +1296,6 @@ int ff_vk_decode_init(AVCodecContext *avctx)
|
||||
int async_depth;
|
||||
const VkVideoProfileInfoKHR *profile;
|
||||
const FFVulkanDecodeDescriptor *vk_desc;
|
||||
const VkPhysicalDeviceDriverProperties *driver_props;
|
||||
|
||||
VkVideoSessionCreateInfoKHR session_create = {
|
||||
.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
|
||||
@@ -1405,17 +1413,16 @@ int ff_vk_decode_init(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
if (!DECODER_IS_SDR(avctx->codec_id)) {
|
||||
if (!(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
|
||||
err = create_empty_session_parameters(avctx, ctx);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = decode_reset(avctx, ctx);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
/* For SDR decoders, this alignment value will be 0. Since this will make
|
||||
* add_slice() malfunction, set it to a sane default value. */
|
||||
ctx->caps.minBitstreamBufferSizeAlignment = AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceDriverProperties *driver_props;
|
||||
driver_props = &dec->shared_ctx->s.driver_props;
|
||||
if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
|
||||
driver_props->conformanceVersion.major == 1 &&
|
||||
@@ -1424,8 +1431,6 @@ int ff_vk_decode_init(AVCodecContext *avctx)
|
||||
driver_props->conformanceVersion.patch < 3)
|
||||
dec->quirk_av1_offset = 1;
|
||||
|
||||
ff_vk_decode_flush(avctx);
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization successful\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -46,8 +46,6 @@ typedef struct FFVulkanDecodeShared {
|
||||
VkVideoCapabilitiesKHR caps;
|
||||
VkVideoDecodeCapabilitiesKHR dec_caps;
|
||||
|
||||
VkVideoSessionParametersKHR empty_session_params;
|
||||
|
||||
/* Software-defined decoder context */
|
||||
void *sd_ctx;
|
||||
void (*sd_ctx_free)(struct FFVulkanDecodeShared *ctx);
|
||||
@@ -176,11 +174,6 @@ int ff_vk_get_decode_buffer(FFVulkanDecodeContext *ctx, AVBufferRef **buf,
|
||||
int ff_vk_decode_create_params(AVBufferRef **par_ref, void *logctx, FFVulkanDecodeShared *ctx,
|
||||
const VkVideoSessionParametersCreateInfoKHR *session_params_create);
|
||||
|
||||
/**
|
||||
* Flush decoder.
|
||||
*/
|
||||
void ff_vk_decode_flush(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* Free decoder.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user