Compare commits

..

9 Commits

Author SHA1 Message Date
Lynne f39884b3fd
vulkan: fix driver warning for unrecognized structure
VkQueueFamilyQueryResultStatusPropertiesKHR was added with the
VK_KHR_video_queue extension, which NVK does not support yet.
Correctly classify it as part of the video extensions.
2025-11-12 10:36:48 +01:00
Lynne 418235e98a
vulkan_prores: fix buffer leaks on error 2025-11-12 00:37:25 +01:00
Lynne d12bb4a2a5
vulkan_prores: fix pushconst updating
ff_vk_shader_update_push_const executes a command that
updates push data for the currently bound shader.
2025-11-12 00:37:25 +01:00
Lynne dd32bb8855
vulkan: allow arrays of buffers
Could be useful.
2025-11-12 00:37:25 +01:00
Lynne a0d0b5cf73
ffv1enc_vulkan: only use native image representation
This was done for an unknown reason, and for whatever reason,
non-rgb 8+ bit formats were broken by this.
2025-11-12 00:37:24 +01:00
Lynne 9860017495
vulkan/ffv1: use u32vec2 for slice offsets
Simplifies calculations slightly.
2025-11-12 00:37:24 +01:00
Lynne 6080db7d23
ffv1dec: call ff_get_format if width and height change 2025-11-12 00:37:24 +01:00
Lynne 18d7ded29e
prores_raw: call ff_get_format if width and height change 2025-11-12 00:37:24 +01:00
Lynne e93e2a5be1
prores: call ff_get_format if width and height change
The issue is that hardware decoders may have some state they depend on,
which would get broken if the dimensions change.
2025-11-12 00:37:19 +01:00
9 changed files with 34 additions and 33 deletions

View File

@ -139,6 +139,7 @@ typedef struct FFV1Context {
uint32_t crcref;
enum AVPixelFormat pix_fmt;
enum AVPixelFormat configured_pix_fmt;
int configured_width, configured_height;
const AVFrame *cur_enc_frame;
int plane_count;

View File

@ -507,11 +507,15 @@ static int read_header(FFV1Context *f, RangeCoder *c)
if (ret < 0)
return ret;
if (f->configured_pix_fmt != f->pix_fmt) {
if (f->configured_pix_fmt != f->pix_fmt ||
f->configured_width != f->avctx->width ||
f->configured_height != f->avctx->height) {
f->avctx->pix_fmt = get_pixel_format(f);
if (f->avctx->pix_fmt < 0)
return AVERROR(EINVAL);
f->configured_pix_fmt = f->pix_fmt;
f->configured_width = f->avctx->width;
f->configured_height = f->avctx->height;
}
ff_dlog(f->avctx, "%d %d %d\n",

View File

@ -96,9 +96,6 @@ typedef struct VulkanEncodeFFv1Context {
/* Intermediate frame pool */
AVBufferRef *intermediate_frames_ref;
/* Representation mode */
enum FFVkShaderRepFormat rep_fmt;
int num_h_slices;
int num_v_slices;
int force_pcm;
@ -380,7 +377,7 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
fv->rep_fmt));
FF_VK_REP_NATIVE));
ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
@ -402,7 +399,7 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
tmp,
fv->rep_fmt));
FF_VK_REP_NATIVE));
}
/* Setup shader */
@ -1084,7 +1081,7 @@ static int init_rct_search_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.dimensions = 2,
.mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
fv->rep_fmt),
FF_VK_REP_NATIVE),
.elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
.mem_quali = "readonly",
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
@ -1169,7 +1166,7 @@ static int init_setup_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.dimensions = 2,
.mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
fv->rep_fmt),
FF_VK_REP_NATIVE),
.elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
.mem_quali = "readonly",
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
@ -1355,7 +1352,7 @@ static int init_encode_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.dimensions = 2,
.mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
fv->rep_fmt),
FF_VK_REP_NATIVE),
.elems = av_pix_fmt_count_planes(fv->s.frames->sw_format),
.mem_quali = "readonly",
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
@ -1610,12 +1607,6 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
!(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
/* bits_per_raw_sample use regular unsigned representation,
* but in higher bit depths, the data is casted to int16_t */
fv->rep_fmt = FF_VK_REP_UINT;
if (!fv->is_rgb && f->bits_per_raw_sample > 8)
fv->rep_fmt = FF_VK_REP_INT;
/* Init rct search shader */
fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
!fv->force_pcm && fv->optimize_rct;

View File

@ -329,7 +329,7 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame *frame, int *got_frame_ptr,
AVPacket *avpkt)
{
int ret;
int ret, dimensions_changed = 0;
ProResRAWContext *s = avctx->priv_data;
DECLARE_ALIGNED(32, uint8_t, qmat)[64];
memset(qmat, 1, 64);
@ -390,13 +390,14 @@ static int decode_frame(AVCodecContext *avctx,
avctx->width, avctx->height, w, h);
if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
dimensions_changed = 1;
}
avctx->coded_width = FFALIGN(w, 16);
avctx->coded_height = FFALIGN(h, 16);
enum AVPixelFormat pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
if (pix_fmt != s->pix_fmt) {
if (pix_fmt != s->pix_fmt || dimensions_changed) {
s->pix_fmt = pix_fmt;
ret = get_pixel_format(avctx, pix_fmt);

View File

@ -185,7 +185,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
const int data_size, AVCodecContext *avctx)
{
int hdr_size, width, height, flags;
int hdr_size, width, height, flags, dimensions_changed = 0;
int version;
const uint8_t *ptr;
enum AVPixelFormat pix_fmt;
@ -214,6 +214,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
avctx->width, avctx->height, width, height);
if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
return ret;
dimensions_changed = 1;
}
ctx->frame_type = (buf[12] >> 2) & 3;
@ -250,7 +251,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
}
}
if (pix_fmt != ctx->pix_fmt) {
if (pix_fmt != ctx->pix_fmt || dimensions_changed) {
#define HWACCEL_MAX (CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL + CONFIG_PRORES_VULKAN_HWACCEL)
#if HWACCEL_MAX
enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;

View File

@ -114,8 +114,8 @@ void main(void)
{
const uint slice_idx = gl_WorkGroupID.y*gl_NumWorkGroups.x + gl_WorkGroupID.x;
u8buf bs = u8buf(slice_data + slice_offsets[2*slice_idx + 0]);
uint32_t slice_size = slice_offsets[2*slice_idx + 1];
u8buf bs = u8buf(slice_data + slice_offsets[slice_idx].x);
uint32_t slice_size = slice_offsets[slice_idx].y;
rac_init_dec(slice_ctx[slice_idx].c,
bs, slice_size);

View File

@ -697,7 +697,7 @@ static int init_setup_shader(FFV1Context *f, FFVulkanContext *s,
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
.mem_quali = "readonly",
.buf_content = "uint32_t slice_offsets",
.buf_content = "u32vec2 slice_offsets",
.buf_elems = 2*f->max_slice_count,
},
{

View File

@ -212,9 +212,10 @@ static int vk_prores_end_frame(AVCodecContext *avctx)
RET(ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
pr->frame));
RET(ff_vk_exec_add_dep_buf(&ctx->s, exec,
(AVBufferRef *[]){ vp->slices_buf, pp->metadata_buf, },
2, 0));
RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->slices_buf, 1, 0));
vp->slices_buf = NULL;
RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &pp->metadata_buf, 1, 0));
pp->metadata_buf = NULL;
/* Transfer ownership to the exec context */
vp->slices_buf = pp->metadata_buf = NULL;
@ -258,12 +259,11 @@ static int vk_prores_end_frame(AVCodecContext *avctx)
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
ff_vk_exec_bind_shader(&ctx->s, exec, &shaders->reset);
ff_vk_shader_update_push_const(&ctx->s, exec, &shaders->reset,
VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
ff_vk_exec_bind_shader(&ctx->s, exec, &shaders->reset);
vk->CmdDispatch(exec->buf, pr->mb_width << 1, pr->mb_height << 1, 1);
/* Input frame barrier after reset */
@ -300,12 +300,11 @@ static int vk_prores_end_frame(AVCodecContext *avctx)
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
ff_vk_exec_bind_shader(&ctx->s, exec, &shaders->vld);
ff_vk_shader_update_push_const(&ctx->s, exec, &shaders->vld,
VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
ff_vk_exec_bind_shader(&ctx->s, exec, &shaders->vld);
vk->CmdDispatch(exec->buf, AV_CEIL_RSHIFT(pr->slice_count / pr->mb_height, 3), AV_CEIL_RSHIFT(pr->mb_height, 3),
3 + !!pr->alpha_info);
@ -354,7 +353,6 @@ static int vk_prores_end_frame(AVCodecContext *avctx)
VK_NULL_HANDLE);
ff_vk_exec_bind_shader(&ctx->s, exec, &shaders->idct);
ff_vk_shader_update_push_const(&ctx->s, exec, &shaders->idct,
VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
@ -575,8 +573,12 @@ static void vk_prores_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
{
AVHWDeviceContext *dev_ctx = _hwctx.nc;
ProresVulkanDecodePicture *pp = data;
FFVulkanDecodePicture *vp = &pp->vp;
ff_vk_decode_free_frame(dev_ctx, &pp->vp);
av_buffer_unref(&vp->slices_buf);
av_buffer_unref(&pp->metadata_buf);
}
const FFHWAccel ff_prores_vulkan_hwaccel = {

View File

@ -241,7 +241,7 @@ int ff_vk_load_props(FFVulkanContext *s)
.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
};
FF_VK_STRUCT_EXT(s, &s->qf_props[i], &s->query_props[i], FF_VK_EXT_NO_FLAG,
FF_VK_STRUCT_EXT(s, &s->qf_props[i], &s->query_props[i], FF_VK_EXT_VIDEO_QUEUE,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR);
FF_VK_STRUCT_EXT(s, &s->qf_props[i], &s->video_props[i], FF_VK_EXT_VIDEO_QUEUE,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR);
@ -2548,10 +2548,11 @@ print:
GLSLA("%s", desc[i].buf_content);
}
GLSLA("\n}");
} else if (desc[i].elems > 0) {
GLSLA("[%i]", desc[i].elems);
}
if (desc[i].elems > 0)
GLSLA("[%i]", desc[i].elems);
GLSLA(";");
GLSLA("\n");
}