@@ -934,6 +934,10 @@ static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
+
+ if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
+ FF_VK_EXT_VIDEO_MAINTENANCE_1))
+ fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
}
/* Get the format of the images necessary */
@@ -1023,6 +1027,7 @@ int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
FFVulkanDecodeProfileData *prof;
+ FFVulkanDecodeShared *ctx;
frames_ctx->sw_format = AV_PIX_FMT_NONE;
@@ -1059,6 +1064,11 @@ int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
if (!dec->dedicated_dpb)
hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
+ ctx = dec->shared_ctx;
+ if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
+ FF_VK_EXT_VIDEO_MAINTENANCE_1))
+ hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+
return err;
}
@@ -36,6 +36,7 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
if (frames_ref) {
int no_storage = 0;
FFVulkanFunctions *vk;
+ VkImageUsageFlagBits usage_req;
const VkFormat *sub = av_vkfmt_from_pixfmt(sw_format);
frames_ctx = (AVHWFramesContext *)frames_ref->data;
@@ -56,13 +57,20 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
if (vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL)
goto skip;
+ s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
+ vk_dev->nb_enabled_dev_extensions);
+
/* Usage mismatch */
- if ((vk_frames->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) !=
- (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT))
+ usage_req = VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_STORAGE_BIT;
+ if (s->extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
+ FF_VK_EXT_VIDEO_MAINTENANCE_1))
+ usage_req |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+
+ if ((vk_frames->usage & usage_req) != usage_req)
goto skip;
- s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
- vk_dev->nb_enabled_dev_extensions);
+ /* More advanced format checks */
err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
if (err < 0)
return err;
@@ -112,13 +120,6 @@ skip:
frames_ctx->width = width;
frames_ctx->height = height;
- vk_frames = frames_ctx->hwctx;
- vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
- vk_frames->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT |
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
- VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-
err = av_hwframe_ctx_init(frames_ref);
if (err < 0) {
av_buffer_unref(&frames_ref);
@@ -2630,6 +2630,11 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT);
+
+ /* Enables encoding of images */
+ if (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
+ FF_VK_EXT_VIDEO_MAINTENANCE_1))
+ hwctx->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
}
/* Image creation flags.
@@ -2648,6 +2653,14 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
}
}
+ /* If image has an encode usage, yet there's no profile attached,
+ * and maintenance1 is supported, enable the profile independent
+ * creation flag. */
+ if ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
+ !(ff_vk_find_struct(hwctx->create_pnext, VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR)) &&
+ p->video_maint_1_features.videoMaintenance1)
+ hwctx->img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
+
if (!hwctx->lock_frame)
hwctx->lock_frame = lock_frame;