FFmpeg
Loading...
Searching...
No Matches
vulkan_ffv1.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Lynne <dev@lynne.ee>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "vulkan_decode.h"
22#include "hwaccel_internal.h"
23
24#include "ffv1.h"
25#include "ffv1_vulkan.h"
26#include "libavutil/mem.h"
27
28#define RGB_LINECACHE 2
29
30extern const unsigned char ff_ffv1_dec_setup_comp_spv_data[];
31extern const unsigned int ff_ffv1_dec_setup_comp_spv_len;
32
33extern const unsigned char ff_ffv1_dec_reset_comp_spv_data[];
34extern const unsigned int ff_ffv1_dec_reset_comp_spv_len;
35
36extern const unsigned char ff_ffv1_dec_reset_golomb_comp_spv_data[];
37extern const unsigned int ff_ffv1_dec_reset_golomb_comp_spv_len;
38
39extern const unsigned char ff_ffv1_dec_comp_spv_data[];
40extern const unsigned int ff_ffv1_dec_comp_spv_len;
41
42extern const unsigned char ff_ffv1_dec_rgb_comp_spv_data[];
43extern const unsigned int ff_ffv1_dec_rgb_comp_spv_len;
44
45extern const unsigned char ff_ffv1_dec_golomb_comp_spv_data[];
46extern const unsigned int ff_ffv1_dec_golomb_comp_spv_len;
47
48extern const unsigned char ff_ffv1_dec_rgb_golomb_comp_spv_data[];
49extern const unsigned int ff_ffv1_dec_rgb_golomb_comp_spv_len;
50
51extern const unsigned char ff_ffv1_dec_rgb_float_comp_spv_data[];
52extern const unsigned int ff_ffv1_dec_rgb_float_comp_spv_len;
53
54extern const unsigned char ff_ffv1_dec_rgb_float_golomb_comp_spv_data[];
55extern const unsigned int ff_ffv1_dec_rgb_float_golomb_comp_spv_len;
56
57extern const unsigned char ff_ffv1_dec_bayer_comp_spv_data[];
58extern const unsigned int ff_ffv1_dec_bayer_comp_spv_len;
59
60extern const unsigned char ff_ffv1_dec_bayer_golomb_comp_spv_data[];
61extern const unsigned int ff_ffv1_dec_bayer_golomb_comp_spv_len;
62
64 .codec_id = AV_CODEC_ID_FFV1,
65 .queue_flags = VK_QUEUE_COMPUTE_BIT,
66};
67
70
75
78 uint32_t *slice_offset;
82
83 /* The context-less free callback waits for the decode before reading
84 * back the slice feedback */
85 PFN_vkWaitSemaphores wait_semaphores;
87
101
103 const AVBufferRef *buffer_ref,
104 av_unused const uint8_t *buffer,
105 av_unused uint32_t size)
106{
107 int err;
110 FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
111 FFV1Context *f = avctx->priv_data;
112
113 FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
114 FFVulkanDecodePicture *vp = &fp->vp;
115
117 enum AVPixelFormat sw_format = hwfc->sw_format;
118
119 int max_contexts;
120 int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
121 !(sw_format == AV_PIX_FMT_YA8);
122
123 fp->slice_num = 0;
124
125 max_contexts = 0;
126 for (int i = 0; i < f->quant_table_count; i++)
127 max_contexts = FFMAX(f->context_count[i], max_contexts);
128
129 /* Allocate slice buffer data */
130 if (f->ac == AC_GOLOMB_RICE)
131 fp->plane_state_size = 8;
132 else
134
135 fp->plane_state_size *= max_contexts;
136 fp->slice_state_size = fp->plane_state_size*f->plane_count;
137
138 fp->slice_data_size = 256; /* Overestimation for the SliceContext struct */
141
142 fp->crc_checked = f->ec && (avctx->err_recognition & AV_EF_CRCCHECK);
143
144 /* The context-less free callback needs these device functions, which
145 * prepare_frame_sdr() used to set. vp->sem is kept for the next
146 * non-keyframe's wait and the free callback's CRC readback. */
147 fp->wait_semaphores = ctx->s.vkfn.WaitSemaphores;
148 vp->invalidate_memory_ranges = ctx->s.vkfn.InvalidateMappedMemoryRanges;
149
150 /* Host map the input slices data if supported */
151 if (ctx->s.extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY)
152 ff_vk_host_map_buffer(&ctx->s, &vp->slices_buf, buffer_ref->data,
153 VK_WHOLE_SIZE, buffer_ref,
154 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
155 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
156
157 /* Allocate slice state data */
158 if (f->picture.f->flags & AV_FRAME_FLAG_KEY) {
160 &fp->slice_state,
161 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
162 NULL, f->slice_count*fp->slice_state_size,
163 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
164 if (err < 0)
165 return err;
166 } else {
167 FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
168
169 /* The previous frame's setup may have failed partway */
170 if (!fpl || !fpl->slice_state)
171 return AVERROR_INVALIDDATA;
172
174 }
175
176 /* Allocate slice offsets/status buffer */
179 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
180 NULL, 5*f->slice_count*sizeof(uint32_t),
181 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
182 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
183 if (err < 0)
184 return err;
185
186 /* Allocate slice offsets/status buffer (note, for integer+remap, we don't need it) */
187 if (f->version >=4 && f->micro_version >= 9 &&
190 &fp->slice_fltmap_buf,
191 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
192 NULL, 65536*4*f->slice_count*sizeof(uint32_t),
193 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
194 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
195 /* A megabyte per slice; fall back if there is no BAR space left */
196 if (err < 0)
198 &fp->slice_fltmap_buf,
199 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
200 NULL, 65536*4*f->slice_count*sizeof(uint32_t),
201 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
202 if (err < 0)
203 return err;
204 }
205
206 /* Create a temporaty frame for RGB */
207 if (is_rgb) {
209 if (!vp->dpb_frame)
210 return AVERROR(ENOMEM);
211
213 vp->dpb_frame, 0);
214 if (err < 0)
215 return err;
216 }
217
218 return 0;
219}
220
222 const uint8_t *data,
223 uint32_t size)
224{
225 FFV1Context *f = avctx->priv_data;
226
227 FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
228 FFVulkanDecodePicture *vp = &fp->vp;
229
230 FFVkBuffer *slice_offset = fp->slice_feedback_buf;
231 FFVkBuffer *slices_buf = vp->slices_buf;
232
233 if (fp->slice_num < MAX_SLICES)
234 fp->slice_size[fp->slice_num] = size;
235
236 if (slices_buf && slices_buf->host_ref) {
237 AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 0)*sizeof(uint32_t),
238 data - slices_buf->mapped_mem);
239 AV_WN32(slice_offset->mapped_mem + (2*fp->slice_num + 1)*sizeof(uint32_t),
240 size);
241
242 fp->slice_num++;
243 } else {
244 int err = ff_vk_decode_add_slice(avctx, vp, data, size, 0,
245 &fp->slice_num,
246 (const uint32_t **)&fp->slice_offset);
247 if (err < 0)
248 return err;
249
250 AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 0)*sizeof(uint32_t),
251 fp->slice_offset[fp->slice_num - 1]);
252 AV_WN32(slice_offset->mapped_mem + (2*(fp->slice_num - 1) + 1)*sizeof(uint32_t),
253 size);
254 }
255
256 return 0;
257}
258
259static int cmp_slice_order(const void *a, const void *b)
260{
261 uint64_t x = *(const uint64_t *)a, y = *(const uint64_t *)b;
262 return (x < y) - (x > y);
263}
264
266{
267 int err;
270 FFVulkanFunctions *vk = &ctx->s.vkfn;
271
272 FFV1Context *f = avctx->priv_data;
273 FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
274
276 enum AVPixelFormat sw_format = hwfc->sw_format;
277
278 int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
279 !(sw_format == AV_PIX_FMT_YA8);
280 int color_planes = av_pix_fmt_desc_get(avctx->sw_pix_fmt)->nb_components;
281
282 FFv1VulkanDecodePicture *fp = f->hwaccel_picture_private;
283 FFVulkanDecodePicture *vp = &fp->vp;
284
285 FFVkBuffer *slices_buf = vp->slices_buf;
286 FFVkBuffer *slice_state = fp->slice_state;
287 FFVkBuffer *slice_feedback = fp->slice_feedback_buf;
288 FFVkBuffer *fltmap_buf = NULL;
289 if (fp->slice_fltmap_buf)
290 fltmap_buf = fp->slice_fltmap_buf;
291
292 VkImageView output_views[AV_NUM_DATA_POINTERS];
293 VkImageView rct_image_views[AV_NUM_DATA_POINTERS];
294
295 VkImageMemoryBarrier2 img_bar[37];
296 int nb_img_bar = 0;
297 VkBufferMemoryBarrier2 buf_bar[8];
298 int nb_buf_bar = 0;
299
300 FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
301 err = ff_vk_exec_start(&ctx->s, exec);
302 if (err < 0)
303 return err;
304
305 /* Prepare deps */
306 RET(ff_vk_exec_add_dep_frame(&ctx->s, exec, f->picture.f,
307 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
308 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
309
310 err = ff_vk_exec_mirror_sem_value(&ctx->s, exec, &vp->sem, &vp->sem_value,
311 f->picture.f);
312 if (err < 0)
313 return err;
314
315 /* Exec-owned output views (vp->sem is still mirrored above, for the next
316 * frame's dependency and the free callback's CRC readback). */
317 RET(ff_vk_create_imageviews(&ctx->s, exec, output_views, f->picture.f,
319
320 if (is_rgb) {
321 RET(ff_vk_create_imageviews(&ctx->s, exec, rct_image_views,
324 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
325 VK_PIPELINE_STAGE_2_CLEAR_BIT));
326 }
327
328 if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY)) {
329 FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private;
330 FFVulkanDecodePicture *vpl = &fpl->vp;
331
332 /* Wait on the previous frame, if its decode was ever submitted */
333 if (vpl->sem)
334 ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, vpl->sem_value,
335 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
336 }
337
341
342 if (fp->slice_fltmap_buf)
344
345 AVVkFrame *vkf = (AVVkFrame *)f->picture.f->data[0];
346 for (int i = 0; i < ff_vk_count_images(vkf); i++) {
347 vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
348 vkf->access[i] = VK_ACCESS_2_NONE;
349 }
350
351 /* Setup shader */
353 1, 0, 0,
354 slice_state,
355 0, fp->slice_data_size*f->slice_count,
356 VK_FORMAT_UNDEFINED);
358 1, 1, 0,
359 slice_feedback,
360 0, 2*f->slice_count*sizeof(uint32_t),
361 VK_FORMAT_UNDEFINED);
363 1, 2, 0,
364 slice_feedback,
365 2*f->slice_count*sizeof(uint32_t),
366 VK_WHOLE_SIZE,
367 VK_FORMAT_UNDEFINED);
368 /* The binding is statically used by the shader, so it must always hold
369 * a valid buffer. */
371 1, 3, 0,
372 fltmap_buf ? fltmap_buf : slice_feedback,
373 0,
374 VK_WHOLE_SIZE,
375 VK_FORMAT_UNDEFINED);
376
377 ff_vk_exec_bind_shader(&ctx->s, exec, &fv->setup);
378
379 FFv1ShaderParams pd = {
380 .slice_data = slices_buf->address,
381
382 .img_size[0] = f->picture.f->width,
383 .img_size[1] = f->picture.f->height,
384
385 .plane_state_size = fp->plane_state_size,
386 .key_frame = f->picture.f->flags & AV_FRAME_FLAG_KEY,
387 .crcref = f->crcref,
388 .micro_version = f->micro_version,
389 .remap_allowed = !!fltmap_buf,
390 };
391
392 for (int i = 0; i < f->quant_table_count; i++) {
393 pd.context_count[i] = f->context_count[i];
394 pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
395 f->quant_tables[i][4][127];
396 }
397
398 /* For some reason the C FFv1 encoder/decoder treats these differently */
399 if (sw_format == AV_PIX_FMT_GBRP10 || sw_format == AV_PIX_FMT_GBRP12 ||
400 sw_format == AV_PIX_FMT_GBRP14)
401 memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
402 else
403 ff_vk_set_perm(sw_format, pd.fmt_lut, 0);
404
406 VK_SHADER_STAGE_COMPUTE_BIT,
407 0, sizeof(FFv1ShaderParams), &pd);
408
409 vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
410
411 if (is_rgb) {
412 vkf = (AVVkFrame *)vp->dpb_frame->data[0];
413 for (int i = 0; i < 4; i++) {
414 vkf->layout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
415 vkf->access[i] = VK_ACCESS_2_NONE;
416 }
417
418 ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
419 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
420 VK_PIPELINE_STAGE_2_CLEAR_BIT,
421 VK_ACCESS_2_TRANSFER_WRITE_BIT,
422 VK_IMAGE_LAYOUT_GENERAL,
423 VK_QUEUE_FAMILY_IGNORED);
424
425 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
426 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
427 .pImageMemoryBarriers = img_bar,
428 .imageMemoryBarrierCount = nb_img_bar,
429 .pBufferMemoryBarriers = buf_bar,
430 .bufferMemoryBarrierCount = nb_buf_bar,
431 });
432 nb_img_bar = 0;
433 nb_buf_bar = 0;
434
435 /* The intermediate frame has 4 planes (GBRAP16/32). Clear all of
436 * them since the bayer decoder uses all four. */
437 int n_dec_planes = f->bayer ? 4 : color_planes;
438 for (int i = 0; i < n_dec_planes; i++)
439 vk->CmdClearColorImage(exec->buf, vkf->img[i], VK_IMAGE_LAYOUT_GENERAL,
440 &((VkClearColorValue) { 0 }),
441 1, &((VkImageSubresourceRange) {
442 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
443 .levelCount = 1,
444 .layerCount = 1,
445 }));
446 }
447
448 /* Sync between setup and reset shaders */
449 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
450 COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
451 SHADER_STORAGE_WRITE_BIT,
452 COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT, NONE_KHR,
453 0, fp->slice_data_size*f->slice_count);
454
455 /* Probability data barrier for P-frames */
456 if (!(f->picture.f->flags & AV_FRAME_FLAG_KEY))
457 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
458 COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
459 SHADER_STORAGE_WRITE_BIT,
460 COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
461 fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
462
463 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
464 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
465 .pImageMemoryBarriers = img_bar,
466 .imageMemoryBarrierCount = nb_img_bar,
467 .pBufferMemoryBarriers = buf_bar,
468 .bufferMemoryBarrierCount = nb_buf_bar,
469 });
470 nb_buf_bar = 0;
471 nb_img_bar = 0;
472
473 /* Reset shader */
475 1, 0, 0,
476 slice_state,
477 0, fp->slice_data_size*f->slice_count,
478 VK_FORMAT_UNDEFINED);
480 1, 1, 0,
481 slice_state,
482 f->slice_count*fp->slice_data_size,
483 VK_WHOLE_SIZE,
484 VK_FORMAT_UNDEFINED);
485
486 ff_vk_exec_bind_shader(&ctx->s, exec, &fv->reset);
488 VK_SHADER_STAGE_COMPUTE_BIT,
489 0, sizeof(FFv1ShaderParams), &pd);
490
491 vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices,
492 f->plane_count);
493
494 /* Sync probabilities between reset and decode shaders */
495 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_state,
496 COMPUTE_SHADER_BIT, SHADER_STORAGE_WRITE_BIT, NONE_KHR,
497 COMPUTE_SHADER_BIT, SHADER_STORAGE_READ_BIT,
498 SHADER_STORAGE_WRITE_BIT,
499 fp->slice_data_size*f->slice_count, VK_WHOLE_SIZE);
500
501 /* Input frame barrier */
502 ff_vk_frame_barrier(&ctx->s, exec, f->picture.f, img_bar, &nb_img_bar,
503 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
504 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
505 VK_ACCESS_SHADER_WRITE_BIT |
506 (!is_rgb ? VK_ACCESS_SHADER_READ_BIT : 0),
507 VK_IMAGE_LAYOUT_GENERAL,
508 VK_QUEUE_FAMILY_IGNORED);
509 if (is_rgb)
510 ff_vk_frame_barrier(&ctx->s, exec, vp->dpb_frame, img_bar, &nb_img_bar,
511 VK_PIPELINE_STAGE_2_CLEAR_BIT,
512 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
513 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
514 VK_IMAGE_LAYOUT_GENERAL,
515 VK_QUEUE_FAMILY_IGNORED);
516
517 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
518 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
519 .pImageMemoryBarriers = img_bar,
520 .imageMemoryBarrierCount = nb_img_bar,
521 .pBufferMemoryBarriers = buf_bar,
522 .bufferMemoryBarrierCount = nb_buf_bar,
523 });
524 nb_img_bar = 0;
525 nb_buf_bar = 0;
526
527 /* Decode the largest slices first: they get the oldest waves, which
528 * have issue priority when several waves share a SIMD */
529 uint64_t order[MAX_SLICES];
530 for (int i = 0; i < f->slice_count; i++)
531 order[i] = (uint64_t)(i < fp->slice_num ? fp->slice_size[i] : 0) << 32 | (UINT32_MAX - i);
532 qsort(order, f->slice_count, sizeof(*order), cmp_slice_order);
533 for (int i = 0; i < f->slice_count; i++)
534 AV_WN32(slice_feedback->mapped_mem + (4*f->slice_count + i)*sizeof(uint32_t),
535 UINT32_MAX - (uint32_t)order[i]);
536
537 /* Decode */
539 1, 0, 0,
540 slice_state,
541 0, fp->slice_data_size*f->slice_count,
542 VK_FORMAT_UNDEFINED);
544 1, 1, 0,
545 slice_feedback,
546 4*f->slice_count*sizeof(uint32_t),
547 f->slice_count*sizeof(uint32_t),
548 VK_FORMAT_UNDEFINED);
550 1, 2, 0,
551 slice_feedback,
552 2*f->slice_count*sizeof(uint32_t),
553 VK_WHOLE_SIZE,
554 VK_FORMAT_UNDEFINED);
556 1, 3, 0,
557 slice_state,
558 f->slice_count*fp->slice_data_size,
559 VK_WHOLE_SIZE,
560 VK_FORMAT_UNDEFINED);
561
562 AVFrame *decode_dst = is_rgb ? vp->dpb_frame : f->picture.f;
563 VkImageView *decode_dst_view = is_rgb ? rct_image_views : output_views;
565 decode_dst, decode_dst_view,
566 1, 4,
567 VK_IMAGE_LAYOUT_GENERAL,
568 VK_NULL_HANDLE);
569 if (is_rgb)
571 f->picture.f, output_views,
572 1, 5,
573 VK_IMAGE_LAYOUT_GENERAL,
574 VK_NULL_HANDLE);
575 if (fltmap_buf)
577 1, 6, 0,
578 fltmap_buf,
579 0,
580 VK_WHOLE_SIZE,
581 VK_FORMAT_UNDEFINED);
582
583 ff_vk_exec_bind_shader(&ctx->s, exec, &fv->decode);
585 VK_SHADER_STAGE_COMPUTE_BIT,
586 0, sizeof(FFv1ShaderParams), &pd);
587
588 vk->CmdDispatch(exec->buf, f->num_h_slices, f->num_v_slices, 1);
589
590 err = ff_vk_exec_submit(&ctx->s, exec);
591 if (err < 0)
592 return err;
593
594 /* We don't need the temporary frame after decoding */
596
597 return 0;
598
599fail:
600 ff_vk_exec_discard(&ctx->s, exec);
601 return 0;
602}
603
605 FFVkExecPool *pool, FFVulkanShader *shd,
606 VkSpecializationInfo *sl)
607{
608 int err;
609
610 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
611 (uint32_t []) { 1, 1, 1 }, 0);
612
614 VK_SHADER_STAGE_COMPUTE_BIT);
615
616 const FFVulkanDescriptorSetBinding desc_set_const[] = {
617 { /* rangecoder_buf */
618 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
619 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
620 },
621 { /* crc_ieee_buf */
622 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
623 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
624 },
625 };
626 ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1);
627
628 const FFVulkanDescriptorSetBinding desc_set[] = {
629 { /* slice_data_buf */
630 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
631 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
632 },
633 { /* slice_offsets_buf */
634 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
635 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
636 },
637 { /* slice_status_buf */
638 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
639 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
640 },
641 { /* fltmap_buf */
642 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
643 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
644 },
645 };
646 ff_vk_shader_add_descriptor_set(s, shd, desc_set, 4, 0);
647
651
652 RET(ff_vk_shader_register_exec(s, pool, shd));
653
654fail:
655 return err;
656}
657
659 FFVkExecPool *pool, FFVulkanShader *shd,
660 VkSpecializationInfo *sl, int ac)
661{
662 int err;
663 int wg_dim = FFMIN(s->props.properties.limits.maxComputeWorkGroupSize[0], 1024);
664
665 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
666 (uint32_t []) { wg_dim, 1, 1 }, 0);
667
669 VK_SHADER_STAGE_COMPUTE_BIT);
670
671 const FFVulkanDescriptorSetBinding desc_set_const[] = {
672 { /* rangecoder_buf */
673 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
674 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
675 },
676 };
677 ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 1, 1);
678
679 const FFVulkanDescriptorSetBinding desc_set[] = {
680 { /* slice_data_buf */
681 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
682 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
683 },
684 { /* slice_state_buf */
685 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
686 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
687 },
688 };
689 ff_vk_shader_add_descriptor_set(s, shd, desc_set, 2, 0);
690
691 if (ac == AC_GOLOMB_RICE)
695 else
699
700 RET(ff_vk_shader_register_exec(s, pool, shd));
701
702fail:
703 return err;
704}
705
707 FFVkExecPool *pool, FFVulkanShader *shd,
708 AVHWFramesContext *dec_frames_ctx,
709 AVHWFramesContext *out_frames_ctx,
710 VkSpecializationInfo *sl, int ac, int rgb,
711 int bayer, uint32_t lanes, uint32_t subgroup_size)
712{
713 int err;
714
715 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
716 (uint32_t []) { ac != AC_GOLOMB_RICE ? lanes : 1, 1, 1 },
717 ac != AC_GOLOMB_RICE ? subgroup_size : 0);
718
720 VK_SHADER_STAGE_COMPUTE_BIT);
721
722 const FFVulkanDescriptorSetBinding desc_set_const[] = {
723 { /* rangecoder_buf */
724 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
725 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
726 },
727 { /* quant_buf */
728 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
729 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
730 },
731 };
732 ff_vk_shader_add_descriptor_set(s, shd, desc_set_const, 2, 1);
733
734 const FFVulkanDescriptorSetBinding desc_set[] = {
735 { /* slice_data_buf */
736 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
737 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
738 },
739 { /* slice_offsets_buf */
740 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
741 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
742 },
743 { /* slice_status_buf */
744 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
745 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
746 },
747 { /* slice_state_buf */
748 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
749 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
750 },
751 { /* dec */
752 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
753 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
754 .elems = av_pix_fmt_count_planes(dec_frames_ctx->sw_format),
755 },
756 { /* dst */
757 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
758 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
759 .elems = av_pix_fmt_count_planes(out_frames_ctx->sw_format),
760 },
761 { /* fltmap_buf */
762 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
763 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
764 },
765 };
766 /* Detect a float output from the pixfmt descriptor instead of f->flt:
767 * the encoder side does not (yet) write f->flt to the extradata, so the
768 * parsed value is unreliable for some v4m4+ streams. The descriptor's
769 * FLOAT flag is set by the pixfmt selection logic and is accurate */
770 int is_float = !!(av_pix_fmt_desc_get(out_frames_ctx->sw_format)->flags &
772
773 /* Bindings 5 (dst) and 6 (fltmap_buf) are conditional */
774 ff_vk_shader_add_descriptor_set(s, shd, desc_set,
775 5 + rgb + (is_float && !bayer),
776 0);
777
778 if (bayer) {
779 if (ac == AC_GOLOMB_RICE)
780 ff_vk_shader_link(s, shd,
783 else
784 ff_vk_shader_link(s, shd,
787 } else if (is_float) {
788 if (ac == AC_GOLOMB_RICE)
789 ff_vk_shader_link(s, shd,
792 else
793 ff_vk_shader_link(s, shd,
796 } else if (ac == AC_GOLOMB_RICE) {
797 if (rgb)
798 ff_vk_shader_link(s, shd,
801 else
802 ff_vk_shader_link(s, shd,
805 } else {
806 if (rgb)
807 ff_vk_shader_link(s, shd,
810 else
811 ff_vk_shader_link(s, shd,
814 }
815
816 RET(ff_vk_shader_register_exec(s, pool, shd));
817
818fail:
819 return err;
820}
821
823 AVBufferRef **dst, enum AVPixelFormat sw_format)
824{
825 int err;
826 AVHWFramesContext *frames_ctx;
827 AVVulkanFramesContext *vk_frames;
828 FFV1Context *f = avctx->priv_data;
829
830 *dst = av_hwframe_ctx_alloc(s->device_ref);
831 if (!(*dst))
832 return AVERROR(ENOMEM);
833
834 frames_ctx = (AVHWFramesContext *)((*dst)->data);
835 frames_ctx->format = AV_PIX_FMT_VULKAN;
836 frames_ctx->sw_format = sw_format;
837 frames_ctx->width = s->frames->width;
838 frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
839
840 vk_frames = frames_ctx->hwctx;
841 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
842 vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
843 vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
844 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
845
846 err = av_hwframe_ctx_init(*dst);
847 if (err < 0) {
848 av_log(avctx, AV_LOG_ERROR,
849 "Unable to initialize frame pool with format %s: %s\n",
850 av_get_pix_fmt_name(sw_format), av_err2str(err));
852 return err;
853 }
854
855 return 0;
856}
857
876
878{
879 int err;
880 FFV1Context *f = avctx->priv_data;
884
885 if (f->version < 3)
886 return AVERROR(ENOTSUP);
887
888 /* Streams with a low amount of slices will usually be much slower
889 * to decode, so warn the user. Use the slice structure from the
890 * extradata: slice_count is only set during frame decoding. */
891 if (f->num_h_slices * f->num_v_slices < 16)
892 av_log(avctx, AV_LOG_WARNING, "Stream has a low number of slices (%i), "
893 "decoding may be very slow\n", f->num_h_slices * f->num_v_slices);
894
895 err = ff_vk_decode_init(avctx);
896 if (err < 0)
897 return err;
898 ctx = dec->shared_ctx;
899
900 fv = ctx->sd_ctx = av_mallocz(sizeof(*fv));
901 if (!fv) {
902 err = AVERROR(ENOMEM);
903 goto fail;
904 }
905
906 ctx->sd_ctx_free = &vk_decode_ffv1_uninit;
907
909 AVHWFramesContext *dctx = hwfc;
910 enum AVPixelFormat sw_format = hwfc->sw_format;
911 int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
912 !(sw_format == AV_PIX_FMT_YA8);
913
914 /* Intermediate frame pool for RCT */
915 if (is_rgb) {
919 }
920
921 SPEC_LIST_CREATE(sl, 16, 16*sizeof(uint32_t))
922 ff_ffv1_vk_set_common_sl(avctx, f, sl, sw_format);
923
924 if (RGB_LINECACHE != 2)
925 SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
926
927 if (f->ec && !!(avctx->err_recognition & AV_EF_CRCCHECK))
928 SPEC_LIST_ADD(sl, 1, 32, 1);
929
930 uint32_t subgroup_size;
931 uint32_t lanes = ff_ffv1_vk_rc_lanes(&ctx->s, &subgroup_size);
932
933 /* The ballot quantizers have a threshold for each of CONTEXT_SIZE
934 * invocations */
935 if (f->ac != AC_GOLOMB_RICE && lanes == CONTEXT_SIZE) {
937 if (ff_ffv1_vk_quant_ballot(f, &qb))
938 SPEC_LIST_ADD(sl, 20, 32, 1);
939 }
940
941 /* Setup shader */
942 RET(init_setup_shader(f, &ctx->s, &ctx->exec_pool, &fv->setup, sl));
943
944 /* Reset shader */
945 RET(init_reset_shader(f, &ctx->s, &ctx->exec_pool, &fv->reset, sl, f->ac));
946
947 /* Decode shaders */
948 RET(init_decode_shader(f, &ctx->s, &ctx->exec_pool, &fv->decode,
949 dctx, hwfc, sl, f->ac, is_rgb, f->bayer,
950 lanes, subgroup_size));
951
952 /* Init static data */
954
955 /* Update setup global descriptors */
956 RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
957 &fv->setup, 0, 0, 0,
958 &fv->consts_buf,
959 256*sizeof(uint32_t), 512*sizeof(uint8_t),
960 VK_FORMAT_UNDEFINED));
961 RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
962 &fv->setup, 0, 1, 0,
963 &fv->consts_buf,
964 0, 256*sizeof(uint32_t),
965 VK_FORMAT_UNDEFINED));
966
967 /* Update decode global descriptors */
968 RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
969 &fv->decode, 0, 0, 0,
970 &fv->consts_buf,
971 256*sizeof(uint32_t), 512*sizeof(uint8_t),
972 VK_FORMAT_UNDEFINED));
973 RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
974 &fv->decode, 0, 1, 0,
975 &fv->consts_buf,
976 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
979 sizeof(FFv1QuantBallot),
980 VK_FORMAT_UNDEFINED));
981
982fail:
983 return err;
984}
985
987{
988 AVHWDeviceContext *dev_ctx = _hwctx.nc;
989 AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
990
992 FFVulkanDecodePicture *vp = &fp->vp;
993
994 /* The feedback below is read back on the host: wait for the decode.
995 * The generic free path no longer waits for anything. */
996 if (vp->sem) {
997 VkSemaphoreWaitInfo sem_wait = {
998 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
999 .pSemaphores = &vp->sem,
1000 .pValues = &vp->sem_value,
1001 .semaphoreCount = 1,
1002 };
1003 fp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
1004 }
1005
1006 ff_vk_decode_free_frame(dev_ctx, vp);
1007
1008 /* No feedback to read if setup failed or the decode was never submitted */
1009 if (fp->slice_feedback_buf && vp->sem) {
1010 FFVkBuffer *slice_feedback = fp->slice_feedback_buf;
1011 uint8_t *ssp = slice_feedback->mapped_mem + 2*fp->slice_num*sizeof(uint32_t);
1012
1013 /* Invalidate slice/output data if needed */
1014 if (!(slice_feedback->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
1015 VkMappedMemoryRange invalidate_data = {
1016 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
1017 .memory = slice_feedback->mem,
1018 .offset = 0,
1019 .size = 2*fp->slice_num*sizeof(uint32_t),
1020 };
1022 1, &invalidate_data);
1023 }
1024
1025 int slice_error_cnt = 0;
1026 int crc_mismatch_cnt = 0;
1027 uint32_t max_overread = 0;
1028 for (int i = 0; i < fp->slice_num; i++) {
1029 uint32_t crc_res = 0;
1030 if (fp->crc_checked)
1031 crc_res = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 0);
1032 uint32_t overread = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 4);
1033 max_overread = FFMAX(overread, max_overread);
1034 slice_error_cnt += !!overread;
1035 crc_mismatch_cnt += !!crc_res;
1036 }
1037 if (slice_error_cnt || crc_mismatch_cnt)
1038 av_log(dev_ctx, AV_LOG_ERROR, "Decode status: %i slices overread (%i bytes max), "
1039 "%i CRCs mismatched\n",
1040 slice_error_cnt, max_overread, crc_mismatch_cnt);
1041 }
1042
1045}
1046
1048 .p.name = "ffv1_vulkan",
1049 .p.type = AVMEDIA_TYPE_VIDEO,
1050 .p.id = AV_CODEC_ID_FFV1,
1051 .p.pix_fmt = AV_PIX_FMT_VULKAN,
1052 .start_frame = &vk_ffv1_start_frame,
1053 .decode_slice = &vk_ffv1_decode_slice,
1054 .end_frame = &vk_ffv1_end_frame,
1055 .free_frame_priv = &vk_ffv1_free_frame_priv,
1056 .frame_priv_data_size = sizeof(FFv1VulkanDecodePicture),
1058 .update_thread_context = &ff_vk_update_thread_context,
1060 .frame_params = &ff_vk_frame_params,
1061 .priv_data_size = sizeof(FFVulkanDecodeContext),
1063};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static AVFormatContext * ctx
int32_t
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
#define MAX_SLICES
#define AV_EF_CRCCHECK
Verify checksums embedded in the bitstream (could be of either encoded or decoded data,...
Definition defs.h:48
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
FF Video Codec 1 (a lossless codec)
#define CONTEXT_SIZE
Definition ffv1.h:45
#define MAX_QUANT_TABLE_SIZE
Definition ffv1.h:48
#define AC_GOLOMB_RICE
Definition ffv1.h:52
#define MAX_QUANT_TABLES
Definition ffv1.h:47
#define MAX_CONTEXT_INPUTS
Definition ffv1.h:50
int ff_ffv1_vk_quant_ballot(const FFV1Context *f, FFv1QuantBallot *qb)
Fill in the ballot quantizers of all quant tables.
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
uint32_t ff_ffv1_vk_rc_lanes(const FFVulkanContext *s, uint32_t *required)
Number of invocations that range code a slice together, as a single subgroup.
Definition ffv1_vulkan.c:85
void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, FFV1Context *f, VkSpecializationInfo *sl, enum AVPixelFormat sw_format)
Definition ffv1_vulkan.c:24
static int cmp_slice_order(const void *a, const void *b)
#define RGB_LINECACHE
#define AV_NUM_DATA_POINTERS
Definition frame.h:480
#define fail
Definition test.h:479
@ AV_CODEC_ID_FFV1
Definition codec_id.h:83
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:140
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:694
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int a
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
#define HWACCEL_CAP_THREAD_SAFE
const struct FFHWAccel ff_ffv1_vulkan_hwaccel
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition hwcontext.c:506
#define b
Definition input.c:43
#define AV_WN32(p, v)
#define AV_RN32(p)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define av_unused
Definition attributes.h:164
void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv)
Since storage images may not be swizzled, we have to do this in the shader itself.
Definition vulkan.c:1715
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
Definition vulkan.c:2690
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition vulkan.c:2262
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
Definition vulkan.c:2521
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1631
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition vulkan.c:1418
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition vulkan.c:2216
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:664
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition vulkan.c:2147
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2757
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2555
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition vulkan.c:626
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:987
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2739
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:790
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition vulkan.c:2703
int ff_vk_host_map_buffer(FFVulkanContext *s, FFVkBuffer **dst, uint8_t *src_data, VkDeviceSize size, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
Definition vulkan.c:1540
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition vulkan.c:783
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition vulkan.c:1444
int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore *dst, uint64_t *dst_val, AVFrame *f)
Definition vulkan.c:962
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:767
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition vulkan.c:2425
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:885
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition vulkan.c:2729
void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore sem, uint64_t val, VkPipelineStageFlagBits2 stage)
Definition vulkan.c:829
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
const char data[16]
Definition mxf.c:149
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition pixdesc.h:158
#define AV_PIX_FMT_GBRAP16
Definition pixfmt.h:571
#define AV_PIX_FMT_GBRAP32
Definition pixfmt.h:572
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:564
#define AV_PIX_FMT_GBRP12
Definition pixfmt.h:565
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition pixfmt.h:140
#define AV_PIX_FMT_GBRP14
Definition pixfmt.h:566
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:121
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition refstruct.c:141
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
#define sem_wait(psem)
Definition semaphore.h:27
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1472
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * priv_data
Definition avcodec.h:470
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition avcodec.h:1417
void * hwaccel_priv_data
hwaccel-specific private data
Definition internal.h:130
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:500
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
uint64_t flags
Combination of AV_PIX_FMT_FLAG_... flags.
Definition pixdesc.h:94
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:184
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
VkDevice act_dev
Active device.
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
VkImageTiling tiling
Controls the tiling of allocated frames.
VkImageCreateFlags img_flags
Flags to set during image creation.
VkImageUsageFlagBits usage
Defines extra usage of output frames.
VkDeviceAddress address
Definition vulkan.h:99
VkMemoryPropertyFlagBits flags
Definition vulkan.h:97
AVBufferRef * host_ref
Definition vulkan.h:111
VkDeviceMemory mem
Definition vulkan.h:96
uint8_t * mapped_mem
Definition vulkan.h:103
VkCommandBuffer buf
Definition vulkan.h:142
FFVulkanDecodeShared * shared_ctx
PFN_vkInvalidateMappedMemoryRanges invalidate_memory_ranges
uint16_t context_count[8]
Definition ffv1_vulkan.h:61
uint32_t extend_lookup[8]
Definition ffv1_vulkan.h:60
FFVulkanShader reset
Definition vulkan_ffv1.c:92
AVRefStructPool * slice_fltmap_pool
Definition vulkan_ffv1.c:98
FFVulkanShader setup
Definition vulkan_ffv1.c:91
AVRefStructPool * slice_feedback_pool
Definition vulkan_ffv1.c:99
FFVulkanShader decode
Definition vulkan_ffv1.c:93
AVBufferRef * intermediate_frames_ref
Definition vulkan_ffv1.c:89
AVRefStructPool * slice_state_pool
Definition vulkan_ffv1.c:97
FFVkBuffer * slice_fltmap_buf
Definition vulkan_ffv1.c:76
PFN_vkWaitSemaphores wait_semaphores
Definition vulkan_ffv1.c:85
FFVulkanDecodePicture vp
Definition vulkan_ffv1.c:69
FFVkBuffer * slice_feedback_buf
Definition vulkan_ffv1.c:77
FFVkBuffer * slice_state
Definition vulkan_ffv1.c:71
uint32_t slice_size[MAX_SLICES]
Definition vulkan_ffv1.c:79
Definition rpzaenc.c:60
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static char buffer[20]
Definition seek.c:32
int size
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition refstruct.h:58
#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, d_stage, d_access, d_access2, offs, bsz)
Definition vulkan.h:579
@ FF_VK_REP_NATIVE
Definition vulkan.h:440
#define RET(x)
Definition vulkan.h:37
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition vulkan.h:55
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition vulkan.h:45
static int ff_vk_count_images(AVVkFrame *f)
Definition vulkan.h:357
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Initialize hw_frames_ctx with the parameters needed to decode the stream using the parameters from av...
int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, const uint8_t *data, size_t size, int add_startcode, uint32_t *nb_slices, const uint32_t **offsets)
Add slice data to frame.
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
static int vk_ffv1_end_frame(AVCodecContext *avctx)
const unsigned int ff_ffv1_dec_rgb_golomb_comp_spv_len
static int vk_ffv1_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
static int vk_decode_ffv1_init(AVCodecContext *avctx)
static int cmp_slice_order(const void *a, const void *b)
const unsigned char ff_ffv1_dec_setup_comp_spv_data[]
const unsigned int ff_ffv1_dec_bayer_golomb_comp_spv_len
static int init_decode_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, AVHWFramesContext *dec_frames_ctx, AVHWFramesContext *out_frames_ctx, VkSpecializationInfo *sl, int ac, int rgb, int bayer, uint32_t lanes, uint32_t subgroup_size)
const unsigned char ff_ffv1_dec_comp_spv_data[]
const unsigned char ff_ffv1_dec_golomb_comp_spv_data[]
const unsigned int ff_ffv1_dec_comp_spv_len
static void vk_ffv1_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
const unsigned int ff_ffv1_dec_rgb_float_comp_spv_len
const unsigned int ff_ffv1_dec_reset_golomb_comp_spv_len
const unsigned char ff_ffv1_dec_bayer_golomb_comp_spv_data[]
static int vk_ffv1_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
const unsigned int ff_ffv1_dec_bayer_comp_spv_len
const FFVulkanDecodeDescriptor ff_vk_dec_ffv1_desc
Definition vulkan_ffv1.c:63
const unsigned int ff_ffv1_dec_reset_comp_spv_len
const unsigned int ff_ffv1_dec_setup_comp_spv_len
const unsigned char ff_ffv1_dec_reset_comp_spv_data[]
static void vk_decode_ffv1_uninit(FFVulkanDecodeShared *ctx)
const unsigned int ff_ffv1_dec_golomb_comp_spv_len
static int init_reset_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, VkSpecializationInfo *sl, int ac)
const unsigned char ff_ffv1_dec_bayer_comp_spv_data[]
const unsigned char ff_ffv1_dec_reset_golomb_comp_spv_data[]
const unsigned int ff_ffv1_dec_rgb_float_golomb_comp_spv_len
const unsigned char ff_ffv1_dec_rgb_comp_spv_data[]
const unsigned char ff_ffv1_dec_rgb_float_comp_spv_data[]
const unsigned char ff_ffv1_dec_rgb_float_golomb_comp_spv_data[]
static int init_indirect(AVCodecContext *avctx, FFVulkanContext *s, AVBufferRef **dst, enum AVPixelFormat sw_format)
const unsigned int ff_ffv1_dec_rgb_comp_spv_len
const unsigned char ff_ffv1_dec_rgb_golomb_comp_spv_data[]
static int init_setup_shader(FFV1Context *f, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd, VkSpecializationInfo *sl)
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY