|
|
|
@ -111,7 +111,6 @@ int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dst_ctx->dedicated_dpb = src_ctx->dedicated_dpb; |
|
|
|
|
dst_ctx->layered_dpb = src_ctx->layered_dpb; |
|
|
|
|
dst_ctx->external_fg = src_ctx->external_fg; |
|
|
|
|
dst_ctx->frame_id_alloc_mask = src_ctx->frame_id_alloc_mask; |
|
|
|
|
|
|
|
|
@ -125,51 +124,6 @@ int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int vk_decode_create_view(FFVulkanDecodeContext *dec, VkImageView *dst_view, |
|
|
|
|
VkImageAspectFlags *aspect, AVVkFrame *src, |
|
|
|
|
VkFormat vkf, int is_current) |
|
|
|
|
{ |
|
|
|
|
VkResult ret; |
|
|
|
|
FFVulkanDecodeShared *ctx = dec->shared_ctx; |
|
|
|
|
FFVulkanFunctions *vk = &ctx->s.vkfn; |
|
|
|
|
VkImageAspectFlags aspect_mask = ff_vk_aspect_bits_from_vkfmt(vkf); |
|
|
|
|
|
|
|
|
|
VkSamplerYcbcrConversionInfo yuv_sampler_info = { |
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, |
|
|
|
|
.conversion = ctx->yuv_sampler, |
|
|
|
|
}; |
|
|
|
|
VkImageViewCreateInfo img_view_create_info = { |
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
|
|
|
|
.pNext = &yuv_sampler_info, |
|
|
|
|
.viewType = dec->layered_dpb && !is_current ? |
|
|
|
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, |
|
|
|
|
.format = vkf, |
|
|
|
|
.image = src->img[0], |
|
|
|
|
.components = (VkComponentMapping) { |
|
|
|
|
.r = VK_COMPONENT_SWIZZLE_IDENTITY, |
|
|
|
|
.g = VK_COMPONENT_SWIZZLE_IDENTITY, |
|
|
|
|
.b = VK_COMPONENT_SWIZZLE_IDENTITY, |
|
|
|
|
.a = VK_COMPONENT_SWIZZLE_IDENTITY, |
|
|
|
|
}, |
|
|
|
|
.subresourceRange = (VkImageSubresourceRange) { |
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, |
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
.layerCount = dec->layered_dpb && !is_current ? |
|
|
|
|
VK_REMAINING_ARRAY_LAYERS : 1, |
|
|
|
|
.levelCount = 1, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
ret = vk->CreateImageView(ctx->s.hwctx->act_dev, &img_view_create_info, |
|
|
|
|
ctx->s.hwctx->alloc, dst_view); |
|
|
|
|
if (ret != VK_SUCCESS) |
|
|
|
|
return AVERROR_EXTERNAL; |
|
|
|
|
|
|
|
|
|
*aspect = aspect_mask; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static AVFrame *vk_get_dpb_pool(FFVulkanDecodeShared *ctx) |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
@ -177,7 +131,7 @@ static AVFrame *vk_get_dpb_pool(FFVulkanDecodeShared *ctx) |
|
|
|
|
if (!avf) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
err = av_hwframe_get_buffer(ctx->dpb_hwfc_ref, avf, 0x0); |
|
|
|
|
err = av_hwframe_get_buffer(ctx->common.dpb_hwfc_ref, avf, 0x0); |
|
|
|
|
if (err < 0) |
|
|
|
|
av_frame_free(&avf); |
|
|
|
|
|
|
|
|
@ -207,21 +161,21 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic, |
|
|
|
|
vkpic->destroy_image_view = vk->DestroyImageView; |
|
|
|
|
vkpic->wait_semaphores = vk->WaitSemaphores; |
|
|
|
|
|
|
|
|
|
if (dec->layered_dpb && alloc_dpb) { |
|
|
|
|
vkpic->img_view_ref = ctx->layered_view; |
|
|
|
|
vkpic->img_aspect_ref = ctx->layered_aspect; |
|
|
|
|
if (ctx->common.layered_dpb && alloc_dpb) { |
|
|
|
|
vkpic->img_view_ref = ctx->common.layered_view; |
|
|
|
|
vkpic->img_aspect_ref = ctx->common.layered_aspect; |
|
|
|
|
} else if (alloc_dpb) { |
|
|
|
|
AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->dpb_hwfc_ref->data; |
|
|
|
|
AVHWFramesContext *dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data; |
|
|
|
|
AVVulkanFramesContext *dpb_hwfc = dpb_frames->hwctx; |
|
|
|
|
|
|
|
|
|
vkpic->dpb_frame = vk_get_dpb_pool(ctx); |
|
|
|
|
if (!vkpic->dpb_frame) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
err = vk_decode_create_view(dec, &vkpic->img_view_ref, |
|
|
|
|
&vkpic->img_aspect_ref, |
|
|
|
|
(AVVkFrame *)vkpic->dpb_frame->data[0], |
|
|
|
|
dpb_hwfc->format[0], is_current); |
|
|
|
|
err = ff_vk_create_view(&ctx->s, &ctx->common, |
|
|
|
|
&vkpic->img_view_ref, &vkpic->img_aspect_ref, |
|
|
|
|
(AVVkFrame *)vkpic->dpb_frame->data[0], |
|
|
|
|
dpb_hwfc->format[0], !is_current); |
|
|
|
|
if (err < 0) |
|
|
|
|
return err; |
|
|
|
|
|
|
|
|
@ -232,10 +186,10 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic, |
|
|
|
|
AVHWFramesContext *frames = (AVHWFramesContext *)pic->hw_frames_ctx->data; |
|
|
|
|
AVVulkanFramesContext *hwfc = frames->hwctx; |
|
|
|
|
|
|
|
|
|
err = vk_decode_create_view(dec, &vkpic->img_view_out, |
|
|
|
|
&vkpic->img_aspect, |
|
|
|
|
(AVVkFrame *)pic->data[0], |
|
|
|
|
hwfc->format[0], is_current); |
|
|
|
|
err = ff_vk_create_view(&ctx->s, &ctx->common, |
|
|
|
|
&vkpic->img_view_out, &vkpic->img_aspect, |
|
|
|
|
(AVVkFrame *)pic->data[0], |
|
|
|
|
hwfc->format[0], !is_current); |
|
|
|
|
if (err < 0) |
|
|
|
|
return err; |
|
|
|
|
|
|
|
|
@ -366,7 +320,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx, |
|
|
|
|
AVVkFrame *vkf = (AVVkFrame *)pic->buf[0]->data; |
|
|
|
|
|
|
|
|
|
/* Quirks */ |
|
|
|
|
const int layered_dpb = dec->layered_dpb; |
|
|
|
|
const int layered_dpb = ctx->common.layered_dpb; |
|
|
|
|
|
|
|
|
|
VkVideoSessionParametersKHR *par = (VkVideoSessionParametersKHR *)dec->session_params->data; |
|
|
|
|
VkVideoBeginCodingInfoKHR decode_start = { |
|
|
|
@ -470,7 +424,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx, |
|
|
|
|
.srcAccessMask = VK_ACCESS_2_NONE, |
|
|
|
|
.dstAccessMask = VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR, |
|
|
|
|
.oldLayout = vkf->layout[0], |
|
|
|
|
.newLayout = (dec->layered_dpb || vp->dpb_frame) ? |
|
|
|
|
.newLayout = (layered_dpb || vp->dpb_frame) ? |
|
|
|
|
VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR : |
|
|
|
|
VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, /* Spec, 07252 utter madness */ |
|
|
|
|
.srcQueueFamilyIndex = vkf->queue_family[0], |
|
|
|
@ -545,7 +499,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx, |
|
|
|
|
} else if (vp->decode_info.referenceSlotCount || |
|
|
|
|
vp->img_view_out != vp->img_view_ref) { |
|
|
|
|
/* Single barrier for a single layered ref */ |
|
|
|
|
err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->layered_frame, |
|
|
|
|
err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame, |
|
|
|
|
VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR, |
|
|
|
|
VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR); |
|
|
|
|
if (err < 0) |
|
|
|
@ -616,13 +570,8 @@ static void free_common(FFRefStructOpaque unused, void *obj) |
|
|
|
|
FFVulkanContext *s = &ctx->s; |
|
|
|
|
FFVulkanFunctions *vk = &ctx->s.vkfn; |
|
|
|
|
|
|
|
|
|
/* Destroy layered view */ |
|
|
|
|
if (ctx->layered_view) |
|
|
|
|
vk->DestroyImageView(s->hwctx->act_dev, ctx->layered_view, s->hwctx->alloc); |
|
|
|
|
|
|
|
|
|
/* This also frees all references from this pool */ |
|
|
|
|
av_frame_free(&ctx->layered_frame); |
|
|
|
|
av_buffer_unref(&ctx->dpb_hwfc_ref); |
|
|
|
|
av_frame_free(&ctx->common.layered_frame); |
|
|
|
|
|
|
|
|
|
/* Destroy parameters */ |
|
|
|
|
if (ctx->empty_session_params) |
|
|
|
@ -634,10 +583,6 @@ static void free_common(FFRefStructOpaque unused, void *obj) |
|
|
|
|
|
|
|
|
|
ff_vk_video_common_uninit(s, &ctx->common); |
|
|
|
|
|
|
|
|
|
if (ctx->yuv_sampler) |
|
|
|
|
vk->DestroySamplerYcbcrConversion(s->hwctx->act_dev, ctx->yuv_sampler, |
|
|
|
|
s->hwctx->alloc); |
|
|
|
|
|
|
|
|
|
ff_vk_uninit(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -924,8 +869,8 @@ static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dec->dedicated_dpb = !(dec_caps->flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR); |
|
|
|
|
dec->layered_dpb = !dec->dedicated_dpb ? 0 : |
|
|
|
|
!(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR); |
|
|
|
|
ctx->common.layered_dpb = !dec->dedicated_dpb ? 0 : |
|
|
|
|
!(caps->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR); |
|
|
|
|
|
|
|
|
|
if (dec->dedicated_dpb) { |
|
|
|
|
fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR; |
|
|
|
@ -1128,7 +1073,7 @@ int ff_vk_decode_uninit(AVCodecContext *avctx) |
|
|
|
|
|
|
|
|
|
int ff_vk_decode_init(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
int err, cxpos = 0, cypos = 0, nb_q = 0; |
|
|
|
|
int err, nb_q = 0; |
|
|
|
|
VkResult ret; |
|
|
|
|
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; |
|
|
|
|
FFVulkanDecodeShared *ctx; |
|
|
|
@ -1159,12 +1104,6 @@ int ff_vk_decode_init(AVCodecContext *avctx) |
|
|
|
|
VkVideoSessionCreateInfoKHR session_create = { |
|
|
|
|
.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR, |
|
|
|
|
}; |
|
|
|
|
VkSamplerYcbcrConversionCreateInfo yuv_sampler_info = { |
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, |
|
|
|
|
.components = ff_comp_identity_map, |
|
|
|
|
.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, |
|
|
|
|
.ycbcrRange = avctx->color_range == AVCOL_RANGE_MPEG, /* Ignored */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
err = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VULKAN); |
|
|
|
|
if (err < 0) |
|
|
|
@ -1230,30 +1169,18 @@ int ff_vk_decode_init(AVCodecContext *avctx) |
|
|
|
|
if (err < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
/* Get sampler */ |
|
|
|
|
av_chroma_location_enum_to_pos(&cxpos, &cypos, avctx->chroma_sample_location); |
|
|
|
|
yuv_sampler_info.xChromaOffset = cxpos >> 7; |
|
|
|
|
yuv_sampler_info.yChromaOffset = cypos >> 7; |
|
|
|
|
yuv_sampler_info.format = s->hwfc->format[0]; |
|
|
|
|
ret = vk->CreateSamplerYcbcrConversion(s->hwctx->act_dev, &yuv_sampler_info, |
|
|
|
|
s->hwctx->alloc, &ctx->yuv_sampler); |
|
|
|
|
if (ret != VK_SUCCESS) { |
|
|
|
|
err = AVERROR_EXTERNAL; |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* If doing an out-of-place decoding, create a DPB pool */ |
|
|
|
|
if (dec->dedicated_dpb || avctx->codec_id == AV_CODEC_ID_AV1) { |
|
|
|
|
AVHWFramesContext *dpb_frames; |
|
|
|
|
AVVulkanFramesContext *dpb_hwfc; |
|
|
|
|
|
|
|
|
|
ctx->dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref); |
|
|
|
|
if (!ctx->dpb_hwfc_ref) { |
|
|
|
|
ctx->common.dpb_hwfc_ref = av_hwframe_ctx_alloc(s->frames->device_ref); |
|
|
|
|
if (!ctx->common.dpb_hwfc_ref) { |
|
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dpb_frames = (AVHWFramesContext *)ctx->dpb_hwfc_ref->data; |
|
|
|
|
dpb_frames = (AVHWFramesContext *)ctx->common.dpb_hwfc_ref->data; |
|
|
|
|
dpb_frames->format = s->frames->format; |
|
|
|
|
dpb_frames->sw_format = s->frames->sw_format; |
|
|
|
|
dpb_frames->width = avctx->coded_width; |
|
|
|
@ -1267,23 +1194,25 @@ int ff_vk_decode_init(AVCodecContext *avctx) |
|
|
|
|
dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR | |
|
|
|
|
VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */ |
|
|
|
|
|
|
|
|
|
if (dec->layered_dpb) |
|
|
|
|
if (ctx->common.layered_dpb) |
|
|
|
|
dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots; |
|
|
|
|
|
|
|
|
|
err = av_hwframe_ctx_init(ctx->dpb_hwfc_ref); |
|
|
|
|
err = av_hwframe_ctx_init(ctx->common.dpb_hwfc_ref); |
|
|
|
|
if (err < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
if (dec->layered_dpb) { |
|
|
|
|
ctx->layered_frame = vk_get_dpb_pool(ctx); |
|
|
|
|
if (!ctx->layered_frame) { |
|
|
|
|
if (ctx->common.layered_dpb) { |
|
|
|
|
ctx->common.layered_frame = vk_get_dpb_pool(ctx); |
|
|
|
|
if (!ctx->common.layered_frame) { |
|
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = vk_decode_create_view(dec, &ctx->layered_view, &ctx->layered_aspect, |
|
|
|
|
(AVVkFrame *)ctx->layered_frame->data[0], |
|
|
|
|
s->hwfc->format[0], 0); |
|
|
|
|
err = ff_vk_create_view(&ctx->s, &ctx->common, |
|
|
|
|
&ctx->common.layered_view, |
|
|
|
|
&ctx->common.layered_aspect, |
|
|
|
|
(AVVkFrame *)ctx->common.layered_frame->data[0], |
|
|
|
|
s->hwfc->format[0], 1); |
|
|
|
|
if (err < 0) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|