FFmpeg
Loading...
Searching...
No Matches
ffv1enc_vulkan.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 "libavutil/mem.h"
22#include "libavutil/vulkan.h"
23
24#include "avcodec.h"
25#include "internal.h"
26#include "hwconfig.h"
27#include "encode.h"
28#include "libavutil/opt.h"
29#include "codec_internal.h"
30
31#include "ffv1.h"
32#include "ffv1enc.h"
33#include "ffv1_vulkan.h"
34
35/* Parallel Golomb alignment */
36#define LG_ALIGN_W 32
37#define LG_ALIGN_H 32
38
39/* Unlike the decoder, we need 4 lines (but really only 3) */
40#define RGB_LINECACHE 4
41
56
113
114typedef struct SegGatherPushData {
115 VkDeviceAddress sparse;
116 VkDeviceAddress compacted;
117 uint32_t slot_size;
119
120extern const char *ff_source_common_comp;
121extern const char *ff_source_rangecoder_comp;
122extern const char *ff_source_ffv1_vlc_comp;
123extern const char *ff_source_ffv1_common_comp;
124extern const char *ff_source_ffv1_enc_comp;
125
126extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
127extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
128
129extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
130extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
131
132extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
133extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
134
135extern const unsigned char ff_ffv1_enc_comp_spv_data[];
136extern const unsigned int ff_ffv1_enc_comp_spv_len;
137
138extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
139extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
140
141extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
142extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
143
144extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
145extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
146
147extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
148extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
149
150extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
151extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
152
153extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
154extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
155
156extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
157extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
158
159extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
160extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
161
162extern const unsigned char ff_ffv1_enc_bayer_comp_spv_data[];
163extern const unsigned int ff_ffv1_enc_bayer_comp_spv_len;
164
165extern const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[];
166extern const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len;
167
168extern const unsigned char ff_seg_gather_comp_spv_data[];
169extern const unsigned int ff_seg_gather_comp_spv_len;
170
171/* Size output slots with the v4 worst case; v3's ~(2*bits+5) bytes/sample runs
172 * to gigabytes on large frames. The bitstream version is unaffected. */
174{
176 FFV1Context *f = &fv->ctx;
177 int version = f->version;
178 size_t size;
179
180 f->version = 4;
182 f->version = version;
183
184 return size;
185}
186
188 AVFrame *enc_in, VkImageView *enc_in_views,
189 FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
191{
193 FFV1Context *f = &fv->ctx;
194 FFVulkanFunctions *vk = &fv->s.vkfn;
195
196 /* Update descriptors */
198 1, 0, 0,
199 slice_data_buf,
200 0, slice_data_size*f->slice_count,
201 VK_FORMAT_UNDEFINED);
203 enc_in, enc_in_views,
204 1, 1,
205 VK_IMAGE_LAYOUT_GENERAL,
206 VK_NULL_HANDLE);
207
208 ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
210 VK_SHADER_STAGE_COMPUTE_BIT,
211 0, sizeof(FFv1ShaderParams), pd);
212
213 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
214
215 return 0;
216}
217
218static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
219 AVFrame *enc_in, VkImageView *enc_in_views,
220 FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
222{
224 FFV1Context *f = &fv->ctx;
225 FFVulkanFunctions *vk = &fv->s.vkfn;
226
227 /* Update descriptors */
228 ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
229 enc_in, enc_in_views,
230 1, 1,
231 VK_IMAGE_LAYOUT_GENERAL,
232 VK_NULL_HANDLE);
233 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
234 1, 2, 0,
235 fltmap_buf,
236 0, fltmap_size*f->slice_count,
237 VK_FORMAT_UNDEFINED);
238
239 ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
240 ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
241 VK_SHADER_STAGE_COMPUTE_BIT,
242 0, sizeof(FFv1ShaderParams), pd);
243
244 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
245
246 return 0;
247}
248
250 AVFrame *enc_in, VkImageView *enc_in_views,
251 FFVkBuffer *units_buf, uint32_t units_size,
253{
255 FFV1Context *f = &fv->ctx;
256 FFVulkanFunctions *vk = &fv->s.vkfn;
257
258 /* Update descriptors */
259 ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
260 enc_in, enc_in_views,
261 1, 1,
262 VK_IMAGE_LAYOUT_GENERAL,
263 VK_NULL_HANDLE);
265 1, 2, 0,
266 units_buf,
267 0, units_size*f->slice_count,
268 VK_FORMAT_UNDEFINED);
269
270 ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
271 ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
272 VK_SHADER_STAGE_COMPUTE_BIT,
273 0, sizeof(FFv1ShaderParams), pd);
274
275 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
276
277 return 0;
278}
279
281 FFVkExecContext *exec,
282 const AVFrame *pict)
283{
284 int err;
286 FFV1Context *f = &fv->ctx;
287 FFVulkanFunctions *vk = &fv->s.vkfn;
288
290
291 /* Slice data */
292 FFVkBuffer *slice_data_buf;
293 uint32_t plane_state_size;
294 uint32_t slice_state_size;
295 uint32_t slice_data_size;
296
297 /* Remap data */
298 FFVkBuffer *remap_data_buf = NULL;
299 uint32_t remap_data_size = 0;
300
301 /* Output data */
302 size_t maxsize;
303 FFVkBuffer *out_data_buf;
304 FFVkBuffer *gathered_buf = NULL;
305 FFVkBuffer *compacted_buf;
306
307 int has_inter = avctx->gop_size > 1;
308 uint32_t context_count = f->context_count[f->context_model];
309
310 VkImageMemoryBarrier2 img_bar[37];
311 int nb_img_bar = 0;
312 VkBufferMemoryBarrier2 buf_bar[8];
313 int nb_buf_bar = 0;
314
315 /* Frame state */
316 f->cur_enc_frame = pict;
317 if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
319 f->key_frame = fd->key_frame = 1;
320 f->gob_count++;
321 } else {
322 f->key_frame = fd->key_frame = 0;
323 }
324
325 f->slice_count = f->max_slice_count;
326
327 /* Allocate slice buffer data */
328 if (f->ac == AC_GOLOMB_RICE)
329 plane_state_size = 8;
330 else
331 plane_state_size = CONTEXT_SIZE;
332
333 plane_state_size *= context_count;
334 slice_state_size = plane_state_size*f->plane_count;
335
336 slice_data_size = 256; /* Overestimation for the SliceContext struct */
337 slice_state_size += slice_data_size;
338 slice_state_size = FFALIGN(slice_state_size, 8);
339
340 /* Allocate slice data buffer */
341 slice_data_buf = fv->keyframe_slice_data_ref ?
343 if (!slice_data_buf) {
345 &slice_data_buf,
346 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
347 NULL, slice_state_size*f->slice_count,
348 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
349
350 /* Only save it if we're going to use it again */
351 if (has_inter)
352 fv->keyframe_slice_data_ref = av_refstruct_ref(slice_data_buf);
353 }
354
355 if (f->remap_mode) {
356 if (fv->is_float32) {
357 /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
358 remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
359 } else {
361 remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
362 }
363
365 &remap_data_buf,
366 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
367 NULL, remap_data_size*f->slice_count,
368 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
369 }
370
371 /* Output buffer size */
372 maxsize = ffv1_vk_buffer_size(avctx);
373 maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
374
375 /* Sparse per-slice slots: written by encode, read by gather. */
377 &fd->out_data_ref,
378 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
379 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
380 NULL, maxsize,
381 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
382 out_data_buf = fd->out_data_ref;
383
384 /* Device-local gather destination */
386 &gathered_buf,
387 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
388 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
389 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
390 NULL, maxsize,
391 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
392
393 /* Contiguous output, read back by the CPU. */
396 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
397 NULL, maxsize,
398 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
399 fv->s.host_cached_flag));
400 compacted_buf = fd->compacted_data_ref;
401
402 /* Image views */
403 AVFrame *src = (AVFrame *)pict;
404 VkImageView src_views[AV_NUM_DATA_POINTERS];
405
406 AVFrame *tmp = NULL;
407 VkImageView tmp_views[AV_NUM_DATA_POINTERS];
408 if (fv->is_rgb) {
409 /* Create a temporaty frame */
411 if (!(tmp))
412 return AVERROR(ENOMEM);
413
415 tmp, 0));
416 }
417
418 /* With everything allocated, setup push data */
419 FFv1ShaderParams pd = {
420 .slice_data = out_data_buf->address,
421
422 .img_size[0] = fv->s.frames->width,
423 .img_size[1] = fv->s.frames->height,
424
425 .plane_state_size = plane_state_size,
426 .key_frame = f->key_frame,
427 .crcref = f->crcref,
428 .micro_version = f->micro_version,
429
430 .sar[0] = pict->sample_aspect_ratio.num,
431 .sar[1] = pict->sample_aspect_ratio.den,
432 .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
433 !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
434
435 /* 16-byte aligned so the gather can use wide loads */
436 .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
437 .max_pixels_per_slice = fv->max_pixels_per_slice,
438 };
439
440 for (int i = 0; i < f->quant_table_count; i++) {
441 pd.context_count[i] = f->context_count[i];
442 pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
443 f->quant_tables[i][4][127];
444 }
445
446 /* For some reason the C FFv1 encoder/decoder treats these differently */
447 if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
448 avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
450 memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
451 else
452 ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
453
454 /* Start recording */
455 ff_vk_exec_start(&fv->s, exec);
456 fd->idx = exec->idx;
457
458 /* For float pixel formats we want the raw bit pattern, not a value
459 * already passed through fp16/fp32 conversion (which can flush
460 * denormals). Use a UINT view in that case. */
461 RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
462 f->remap_mode ? FF_VK_REP_UINT
464
467
468 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
469 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
470 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
471 if (fv->is_rgb)
472 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
473 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
474 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
475
476 if (fv->optimize_rct || f->remap_mode) {
477 /* Prepare the frame for reading */
478 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
479 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
480 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
481 VK_ACCESS_SHADER_READ_BIT,
482 VK_IMAGE_LAYOUT_GENERAL,
483 VK_QUEUE_FAMILY_IGNORED);
484
485 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
486 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
487 .pImageMemoryBarriers = img_bar,
488 .imageMemoryBarrierCount = nb_img_bar,
489 });
490 nb_img_bar = 0;
491 }
492
493 /* Run RCT search if needed */
494 if (fv->optimize_rct) {
495 RET(run_rct_search(avctx, exec, src, src_views,
496 slice_data_buf, slice_data_size, &pd));
497
498 /* Make sure the writes are visible to the setup shader */
499 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
500 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
501 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
502 0, slice_data_size*f->slice_count);
503 }
504
505 if (f->remap_mode) {
506 if (fv->is_float32) {
507 RET(run_sort32(avctx, exec, src, src_views,
508 remap_data_buf, remap_data_size, &pd));
509 } else {
510 RET(run_remap(avctx, exec, src, src_views,
511 remap_data_buf, remap_data_size, &pd));
512 }
513
514 /* Make sure the writes are visible to the setup shader */
515 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
516 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
517 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
518 0, remap_data_size*f->slice_count);
519 }
520
521 if (fv->optimize_rct || f->remap_mode) {
522 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
523 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
524 .pBufferMemoryBarriers = buf_bar,
525 .bufferMemoryBarrierCount = nb_buf_bar,
526 });
527 nb_buf_bar = 0;
528 }
529
530 /* Setup shader */
531 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
532 1, 0, 0,
533 slice_data_buf,
534 0, slice_data_size*f->slice_count,
535 VK_FORMAT_UNDEFINED);
536 if (f->remap_mode)
538 &fv->setup, 1, 1, 0,
539 remap_data_buf,
540 0, remap_data_size*f->slice_count,
541 VK_FORMAT_UNDEFINED);
542
543 ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
544 ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
545 VK_SHADER_STAGE_COMPUTE_BIT,
546 0, sizeof(FFv1ShaderParams), &pd);
547
548 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
549
550 /* Clean up temporary image if needed */
551 if (fv->is_rgb) {
552 AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
553 vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
554 vkf->access[0] = VK_ACCESS_2_NONE;
555
556 RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
557 tmp,
559
560 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
561 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
562 VK_PIPELINE_STAGE_2_CLEAR_BIT,
563 VK_ACCESS_2_TRANSFER_WRITE_BIT,
564 VK_IMAGE_LAYOUT_GENERAL,
565 VK_QUEUE_FAMILY_IGNORED);
566 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
567 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
568 .pImageMemoryBarriers = img_bar,
569 .imageMemoryBarrierCount = nb_img_bar,
570 });
571 nb_img_bar = 0;
572
573 vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
574 &((VkClearColorValue) { 0 }),
575 1, &((VkImageSubresourceRange) {
576 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
577 .levelCount = 1,
578 .layerCount = 1,
579 }));
580 }
581
582 /* Run reset shader */
583 if (f->key_frame || fv->force_pcm) {
584 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
585 1, 0, 0,
586 slice_data_buf,
587 0, slice_data_size*f->slice_count,
588 VK_FORMAT_UNDEFINED);
589 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
590 1, 1, 0,
591 slice_data_buf,
592 f->slice_count*256,
593 VK_WHOLE_SIZE,
594 VK_FORMAT_UNDEFINED);
595
596 ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
597 ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
598 VK_SHADER_STAGE_COMPUTE_BIT,
599 0, sizeof(FFv1ShaderParams), &pd);
600
601 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
602 f->plane_count);
603 }
604
605 /* Sync between reset and encode shaders */
606 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
607 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
608 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
609 0, slice_data_size*f->slice_count);
610
611 /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
612 * back into the remap buffer; the encode shader reads it. */
613 if (f->remap_mode)
614 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
615 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
616 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
617 0, remap_data_size*f->slice_count);
618 if (f->key_frame || fv->force_pcm)
619 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
620 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
621 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
622 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
623 else
624 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
625 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
626 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
627 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
628
629 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
630 fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
631 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
632 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
633 VK_ACCESS_SHADER_READ_BIT,
634 VK_IMAGE_LAYOUT_GENERAL,
635 VK_QUEUE_FAMILY_IGNORED);
636
637 if (fv->is_rgb)
638 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
639 VK_PIPELINE_STAGE_2_CLEAR_BIT,
640 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
641 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
642 VK_IMAGE_LAYOUT_GENERAL,
643 VK_QUEUE_FAMILY_IGNORED);
644
645 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
646 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
647 .pImageMemoryBarriers = img_bar,
648 .imageMemoryBarrierCount = nb_img_bar,
649 .pBufferMemoryBarriers = buf_bar,
650 .bufferMemoryBarrierCount = nb_buf_bar,
651 });
652 nb_img_bar = 0;
653 nb_buf_bar = 0;
654
655 /* Main encode shader */
656 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
657 1, 0, 0,
658 slice_data_buf,
659 0, slice_data_size*f->slice_count,
660 VK_FORMAT_UNDEFINED);
662 &fv->enc, 1, 1, 0,
663 &fv->results_buf,
664 fd->idx*f->max_slice_count*sizeof(uint32_t),
665 f->slice_count*sizeof(uint32_t),
666 VK_FORMAT_UNDEFINED);
667 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
668 1, 2, 0,
669 slice_data_buf,
670 f->slice_count*256,
671 VK_WHOLE_SIZE,
672 VK_FORMAT_UNDEFINED);
673 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
674 src, src_views,
675 1, 3,
676 VK_IMAGE_LAYOUT_GENERAL,
677 VK_NULL_HANDLE);
678 if (fv->is_rgb)
679 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
680 tmp, tmp_views,
681 1, 4,
682 VK_IMAGE_LAYOUT_GENERAL,
683 VK_NULL_HANDLE);
684 if (f->remap_mode)
686 &fv->enc, 1, 5, 0,
687 remap_data_buf,
688 0, remap_data_size*f->slice_count,
689 VK_FORMAT_UNDEFINED);
690
691 ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
692 ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
693 VK_SHADER_STAGE_COMPUTE_BIT,
694 0, sizeof(FFv1ShaderParams), &pd);
695 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
696
697 /* Gather the per-slice slots into one contiguous buffer, in the same
698 * submission. */
699 FFVkBuffer *results_buf = &fv->results_buf;
700 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
701 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
702 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
703 0, VK_WHOLE_SIZE);
704 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], results_buf,
705 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
706 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
707 0, VK_WHOLE_SIZE);
708 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
709 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
710 .pBufferMemoryBarriers = buf_bar,
711 .bufferMemoryBarrierCount = nb_buf_bar,
712 });
713 nb_buf_bar = 0;
714
715 SegGatherPushData gather_pd = {
716 .sparse = out_data_buf->address,
717 .compacted = gathered_buf->address,
718 .slot_size = (uint32_t)((out_data_buf->size / f->slice_count) & ~(size_t)15),
719 };
720 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->gather, 0, 0, 0,
721 &fv->results_buf,
722 fd->idx*f->max_slice_count*sizeof(uint32_t),
723 f->slice_count*sizeof(uint32_t),
724 VK_FORMAT_UNDEFINED);
725 ff_vk_exec_bind_shader(&fv->s, exec, &fv->gather);
726 ff_vk_shader_update_push_const(&fv->s, exec, &fv->gather,
727 VK_SHADER_STAGE_COMPUTE_BIT,
728 0, sizeof(gather_pd), &gather_pd);
729 vk->CmdDispatch(exec->buf, f->slice_count, 1, 1);
730
731 /* Read the gathered bitstream back with the copy engine. The size is
732 * only known once the encode is done, so the whole buffer is copied;
733 * with the version-4 slot sizing this is close to the payload size. */
734 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], gathered_buf,
735 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
736 TRANSFER_BIT, TRANSFER_READ_BIT, NONE_KHR,
737 0, VK_WHOLE_SIZE);
738 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
739 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
740 .pBufferMemoryBarriers = buf_bar,
741 .bufferMemoryBarrierCount = nb_buf_bar,
742 });
743 nb_buf_bar = 0;
744
745 vk->CmdCopyBuffer(exec->buf, gathered_buf->buf, compacted_buf->buf,
746 1, &(VkBufferCopy) { .size = maxsize });
747
748 /* Submit */
749 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &slice_data_buf);
750 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &gathered_buf);
751 if (remap_data_buf)
752 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &remap_data_buf);
753 err = ff_vk_exec_submit(&fv->s, exec);
754 if (err < 0)
755 goto fail;
756
757 f->picture_number++;
758
760 return 0;
761
762fail:
764 av_refstruct_unref(&slice_data_buf);
765 av_refstruct_unref(&remap_data_buf);
766 av_refstruct_unref(&gathered_buf);
767 ff_vk_exec_discard_deps(&fv->s, exec);
768
769 return err;
770}
771
772/* Return the gathered-output buffer to its pool when the packet is freed. */
773static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
774{
775 av_refstruct_unref(&opaque);
776}
777
779 AVPacket *pkt)
780{
782 FFV1Context *f = &fv->ctx;
783 FFVulkanFunctions *vk = &fv->s.vkfn;
785
786 FFVkBuffer *compacted_buf = fd->compacted_data_ref;
787
788 /* Make sure the encode + gather submission is done */
789 ff_vk_exec_wait(&fv->s, exec);
790
791 /* Invalidate the per-slice sizes if needed */
792 uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
793 if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
794 VkMappedMemoryRange invalidate_data = {
795 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
796 .memory = fv->results_buf.mem,
797 .offset = rb_off,
798 .size = f->slice_count*sizeof(uint32_t),
799 };
800 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
801 1, &invalidate_data);
802 }
803
804 /* The gather packed the slices tight and in order; sum their lengths. */
805 pkt->size = 0;
806 uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
807 for (int i = 0; i < f->slice_count; i++) {
808 uint32_t sl_len = AV_RN32(rb + i*4);
809 av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
810 pkt->size += sl_len;
811 }
812 av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
813
814 /* Invalidate the gathered bitstream if needed */
815 if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
816 VkMappedMemoryRange invalidate_data = {
817 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
818 .memory = compacted_buf->mem,
819 .offset = 0,
820 .size = VK_WHOLE_SIZE,
821 };
822 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
823 1, &invalidate_data);
824 }
825
826 /* Hand the gathered buffer to the packet with no copy: pkt->buf references
827 * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
828 pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
830 if (!pkt->buf) {
833 return AVERROR(ENOMEM);
834 }
835 fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
836 pkt->data = compacted_buf->mapped_mem;
837
838 pkt->pts = fd->pts;
839 pkt->dts = fd->pts;
840 pkt->duration = fd->duration;
841 pkt->flags |= AV_PKT_FLAG_KEY * fd->key_frame;
842
843 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
844 pkt->opaque = fd->frame_opaque;
845 pkt->opaque_ref = fd->frame_opaque_ref;
847 }
848
850
851 return 0;
852}
853
855 AVPacket *pkt)
856{
857 int err;
860 FFVkExecContext *exec;
861 AVFrame *frame;
862
863 while (1) {
864 /* Roll an execution context */
865 exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
866
867 /* If it had a frame, immediately output it */
868 if (exec->had_submission) {
869 exec->had_submission = 0;
870 fv->in_flight--;
871 return get_packet(avctx, exec, pkt);
872 }
873
874 /* Get next frame to encode */
875 frame = fv->frame;
876 err = ff_encode_get_frame(avctx, frame);
877 if (err < 0 && err != AVERROR_EOF) {
878 return err;
879 } else if (err == AVERROR_EOF) {
880 if (!fv->in_flight)
881 return err;
882 continue;
883 }
884
885 /* Encode frame */
886 fd = exec->opaque;
887 fd->pts = frame->pts;
888 fd->duration = frame->duration;
889 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
890 fd->frame_opaque = frame->opaque;
891 fd->frame_opaque_ref = frame->opaque_ref;
892 frame->opaque_ref = NULL;
893 }
894
895 err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
897 if (err < 0)
898 return err;
899
900 fv->in_flight++;
901 if (fv->in_flight < fv->async_depth)
902 return AVERROR(EAGAIN);
903 }
904
905 return 0;
906}
907
908static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
909{
910 int err;
912 FFV1Context *f = &fv->ctx;
913 AVHWFramesContext *frames_ctx;
914 AVVulkanFramesContext *vk_frames;
915
918 return AVERROR(ENOMEM);
919
921 frames_ctx->format = AV_PIX_FMT_VULKAN;
922 frames_ctx->sw_format = sw_format;
923 frames_ctx->width = fv->s.frames->width;
924 frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
925
926 vk_frames = frames_ctx->hwctx;
927 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
928 vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
929 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
930 vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
931
933 if (err < 0) {
934 av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
935 av_get_pix_fmt_name(sw_format), av_err2str(err));
937 return err;
938 }
939
940 return 0;
941}
942
943static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
944{
945 int err;
947 FFVulkanShader *shd = &fv->rct_search;
948
949 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
950 (uint32_t []) { 32, 32, 1 }, 0);
951
953 VK_SHADER_STAGE_COMPUTE_BIT);
954
955 const FFVulkanDescriptorSetBinding desc_set_const[] = {
956 { /* rangecoder_buf */
957 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
958 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
959 },
960 };
961 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
962
963 const FFVulkanDescriptorSetBinding desc_set[] = {
964 { /* slice_data_buf */
965 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
966 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
967 },
968 { /* src */
969 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
970 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
972 },
973 };
974 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
975
976 RET(ff_vk_shader_link(&fv->s, shd,
979
980 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
981
982fail:
983 return err;
984}
985
986static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
987{
988 int err;
990 FFVulkanShader *shd = &fv->sort32;
991
992 uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
993 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
994 (uint32_t []) { wg_x, 1, 1 }, 0);
995
997 VK_SHADER_STAGE_COMPUTE_BIT);
998
999 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1000 { /* rangecoder_buf */
1001 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1002 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1003 },
1004 };
1005 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1006
1007 const FFVulkanDescriptorSetBinding desc_set[] = {
1008 { /* slice_data_buf */
1009 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1010 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1011 },
1012 { /* src */
1013 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1014 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1016 },
1017 { /* units */
1018 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1019 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1020 },
1021 };
1022 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1023
1024 RET(ff_vk_shader_link(&fv->s, shd,
1027
1028 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1029
1030fail:
1031 return err;
1032}
1033
1034static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1035{
1036 int err;
1038 FFVulkanShader *shd = &fv->remap;
1039
1040 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1041 (uint32_t []) { 32, 32, 1 }, 0);
1042
1044 VK_SHADER_STAGE_COMPUTE_BIT);
1045
1046 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1047 { /* rangecoder_buf */
1048 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1049 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1050 },
1051 };
1052 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1053
1054 const FFVulkanDescriptorSetBinding desc_set[] = {
1055 { /* slice_data_buf */
1056 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1057 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1058 },
1059 { /* src */
1060 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1061 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1063 },
1064 { /* fltmap */
1065 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1066 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1067 },
1068 };
1069 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1070
1071 RET(ff_vk_shader_link(&fv->s, shd,
1074
1075 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1076
1077fail:
1078 return err;
1079}
1080
1081static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1082{
1083 int err;
1085 FFVulkanShader *shd = &fv->setup;
1086
1087 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1088 (uint32_t []) { 1, 1, 1 }, 0);
1089
1091 VK_SHADER_STAGE_COMPUTE_BIT);
1092
1093 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1094 { /* rangecoder_buf */
1095 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1096 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1097 },
1098 };
1099 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1100
1101 const FFVulkanDescriptorSetBinding desc_set[] = {
1102 { /* slice_data_buf */
1103 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1104 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1105 },
1106 { /* fltmap */
1107 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1108 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1109 },
1110 };
1111 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1112
1113 RET(ff_vk_shader_link(&fv->s, shd,
1116
1117 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1118
1119fail:
1120 return err;
1121}
1122
1123static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1124{
1125 int err;
1127 FFVulkanShader *shd = &fv->reset;
1128
1129 int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1130
1131 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1132 (uint32_t []) { wg_dim, 1, 1 }, 0);
1133
1135 VK_SHADER_STAGE_COMPUTE_BIT);
1136
1137 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1138 { /* rangecoder_buf */
1139 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1140 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1141 },
1142 };
1143 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1144
1145 const FFVulkanDescriptorSetBinding desc_set[] = {
1146 { /* slice_data_buf */
1147 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1148 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1149 },
1150 { /* slice_state_buf */
1151 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1152 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1153 },
1154 };
1155 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1156
1157 if (fv->ctx.ac == AC_GOLOMB_RICE)
1158 RET(ff_vk_shader_link(&fv->s, shd,
1161 else
1162 RET(ff_vk_shader_link(&fv->s, shd,
1165
1166 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1167
1168fail:
1169 return err;
1170}
1171
1172static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1173{
1174 int err;
1176 FFV1Context *f = &fv->ctx;
1177 FFVulkanShader *shd = &fv->enc;
1178
1179 uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1180 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1181 (uint32_t []) { wg_x, 1, 1 }, 0);
1182
1184 VK_SHADER_STAGE_COMPUTE_BIT);
1185
1186 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1187 { /* rangecoder_buf */
1188 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1189 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1190 },
1191 { /* quant_buf */
1192 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1193 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1194 },
1195 { /* crc_ieee_buf */
1196 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1197 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1198 },
1199 };
1200 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1201
1202 const FFVulkanDescriptorSetBinding desc_set[] = {
1203 { /* slice_data_buf */
1204 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1205 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1206 },
1207 { /* slice_results_buf */
1208 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1209 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1210 },
1211 { /* slice_state_buf */
1212 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1213 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1214 },
1215 { /* src */
1216 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1217 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1219 },
1220 { /* tmp */
1221 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1222 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1223 },
1224 { /* fltmap */
1225 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1226 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1227 },
1228 };
1229 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1230 4 + fv->is_rgb + !!f->remap_mode, 0);
1231
1232 if (f->bayer) {
1233 if (fv->ctx.ac == AC_GOLOMB_RICE)
1234 ff_vk_shader_link(&fv->s, shd,
1237 else
1238 ff_vk_shader_link(&fv->s, shd,
1241 } else if (f->remap_mode) {
1242 if (fv->ctx.ac == AC_GOLOMB_RICE)
1243 ff_vk_shader_link(&fv->s, shd,
1246 else
1247 ff_vk_shader_link(&fv->s, shd,
1250 } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1251 if (fv->is_rgb)
1252 ff_vk_shader_link(&fv->s, shd,
1255 else
1256 ff_vk_shader_link(&fv->s, shd,
1259 } else {
1260 if (fv->is_rgb)
1261 ff_vk_shader_link(&fv->s, shd,
1264 else
1265 ff_vk_shader_link(&fv->s, shd,
1267 ff_ffv1_enc_comp_spv_len, "main");
1268 }
1269
1270 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1271
1272fail:
1273 return err;
1274}
1275
1277{
1278 int err;
1280 FFVulkanShader *shd = &fv->gather;
1281
1282 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
1283 (uint32_t []) { 256, 1, 1 }, 0);
1284
1286 VK_SHADER_STAGE_COMPUTE_BIT);
1287
1288 const FFVulkanDescriptorSetBinding desc_set[] = {
1289 { /* sizes_buf */
1290 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1291 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1292 },
1293 };
1294 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0);
1295
1296 RET(ff_vk_shader_link(&fv->s, shd,
1299
1300 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1301
1302fail:
1303 return err;
1304}
1305
1307{
1308 int err;
1309 size_t maxsize;
1311 FFV1Context *f = &fv->ctx;
1312
1313 if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1314 return err;
1315
1316 if (f->ac == 1)
1317 f->ac = AC_RANGE_CUSTOM_TAB;
1318
1319 err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1320 if (err < 0)
1321 return err;
1322
1323 /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1324 * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1325 f->version = f->bayer ? 4 : 3;
1326
1327 err = ff_ffv1_encode_init(avctx);
1328 if (err < 0)
1329 return err;
1330
1331 /* Rice coding did not support high bit depths */
1332 if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1333 if (f->ac == AC_GOLOMB_RICE) {
1334 av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1335 "forcing range coder\n");
1336 f->ac = AC_RANGE_CUSTOM_TAB;
1337 }
1338 }
1339
1340 if (f->version < 4 && avctx->gop_size > 1) {
1341 av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1342 return AVERROR_INVALIDDATA;
1343 }
1344
1345 if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1346 av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1347 return AVERROR_INVALIDDATA;
1348 }
1349
1350 /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1351 if (f->version == 4)
1352 f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1353
1354 f->num_h_slices = fv->num_h_slices;
1355 f->num_v_slices = fv->num_v_slices;
1356
1357 if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1358 if (avctx->slices) {
1360 if (err < 0)
1361 return err;
1362 } else {
1363 f->num_h_slices = 32;
1364 f->num_v_slices = 32;
1365 }
1366 } else if (f->num_h_slices && f->num_v_slices <= 0) {
1367 f->num_v_slices = MAX_SLICES / f->num_h_slices;
1368 } else if (f->num_v_slices && f->num_h_slices <= 0) {
1369 f->num_h_slices = MAX_SLICES / f->num_v_slices;
1370 }
1371
1372 f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1373 f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1374
1375 if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1376 av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1377 "by the standard is %i\n",
1378 f->num_h_slices * f->num_v_slices, MAX_SLICES);
1379 return AVERROR_PATCHWELCOME;
1380 }
1381
1382 f->max_slice_count = f->num_h_slices * f->num_v_slices;
1383
1384 if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1385 return err;
1386
1387 if (f->version < 4) {
1388 if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1389 ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1390 av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1391 "dimensions is only supported in version 4 (-level 4)\n");
1392 return AVERROR_PATCHWELCOME;
1393 }
1394 }
1395
1396 if (fv->force_pcm) {
1397 if (f->version < 4) {
1398 av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1399 return AVERROR_INVALIDDATA;
1400 } else if (f->ac == AC_GOLOMB_RICE) {
1401 av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1402 return AVERROR_INVALIDDATA;
1403 }
1404 }
1405
1406 /* Init Vulkan */
1407 err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1408 if (err < 0)
1409 return err;
1410
1411 fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1412 if (!fv->qf) {
1413 av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1414 return err;
1415 }
1416
1417 maxsize = ffv1_vk_buffer_size(avctx);
1418 if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1419 av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1420 "than maximum device allocation (%"PRIu64"), clipping\n",
1421 maxsize, fv->s.props_11.maxMemoryAllocationSize);
1422 maxsize = fv->s.props_11.maxMemoryAllocationSize;
1423 }
1424
1425 av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1426 2*maxsize / (1024*1024),
1427 (fv->async_depth * 2*maxsize) / (1024*1024),
1428 fv->async_depth);
1429
1430 err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1431 fv->async_depth,
1432 0, 0, 0, NULL);
1433 if (err < 0)
1434 return err;
1435
1436 /* Detect the special RGB coding mode */
1437 fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1438 !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1439
1440 fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1442
1443 if (fv->is_float32) {
1444 /* Compute the worst-case slice geometry. With version >= 4 the slice
1445 * boundaries are computed via slice_coord() which rounds up, so any
1446 * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1447 * pixels. */
1448 uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1449 uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1450 /* Round up to next pow2 for bitonic sort */
1451 uint32_t n = 1;
1452 uint32_t pn = mw*mh;
1453 while (n < pn)
1454 n <<= 1;
1455 if (n < 2)
1456 n = 2;
1457 fv->max_pixels_per_slice = n;
1458 }
1459
1460 /* Init rct search shader */
1461 fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1462 !fv->force_pcm && fv->optimize_rct && !f->bayer;
1463
1464 /* Init shader specialization consts */
1465 SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1466 SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1467 SPEC_LIST_ADD(sl, 1, 32, f->ec);
1468 ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1469 SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1470 SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1471 SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1472 SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1473
1474 if (fv->optimize_rct) {
1475 err = init_rct_search_shader(avctx, sl);
1476 if (err < 0)
1477 return err;
1478 }
1479
1480 if (f->remap_mode) {
1481 if (fv->is_float32)
1482 err = init_sort32_shader(avctx, sl);
1483 else
1484 err = init_remap_shader(avctx, sl);
1485 if (err < 0)
1486 return err;
1487 }
1488
1489 /* Init setup shader */
1490 err = init_setup_shader(avctx, sl);
1491 if (err < 0)
1492 return err;
1493
1494 /* Init reset shader */
1495 err = init_reset_shader(avctx, sl);
1496 if (err < 0)
1497 return err;
1498
1499 if (fv->is_rgb)
1500 RET(init_indirect(avctx, fv->ctx.use32bit ?
1502
1503 /* Encode shader */
1504 err = init_encode_shader(avctx, sl);
1505 if (err < 0)
1506 return err;
1507
1508 /* Gather shader */
1509 err = init_gather_shader(avctx);
1510 if (err < 0)
1511 return err;
1512
1513 /* Constant data */
1514 err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1515 if (err < 0)
1516 return err;
1517
1518 /* Update setup global descriptors */
1520 &fv->setup, 0, 0, 0,
1521 &fv->consts_buf,
1522 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1523 VK_FORMAT_UNDEFINED));
1524
1525 /* Update encode global descriptors */
1527 &fv->enc, 0, 0, 0,
1528 &fv->consts_buf,
1529 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1530 VK_FORMAT_UNDEFINED));
1532 &fv->enc, 0, 1, 0,
1533 &fv->consts_buf,
1534 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1535 VK_WHOLE_SIZE,
1536 VK_FORMAT_UNDEFINED));
1538 &fv->enc, 0, 2, 0,
1539 &fv->consts_buf,
1540 0, 256*sizeof(uint32_t),
1541 VK_FORMAT_UNDEFINED));
1542
1543 /* Temporary frame */
1544 fv->frame = av_frame_alloc();
1545 if (!fv->frame)
1546 return AVERROR(ENOMEM);
1547
1548 /* Async data pool */
1550 fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1551 if (!fv->exec_ctx_info)
1552 return AVERROR(ENOMEM);
1553 for (int i = 0; i < fv->async_depth; i++)
1555
1556 /* Buffers */
1557 RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1558 fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1559 NULL, NULL,
1560 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1561 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1562 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1563 RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1564
1565fail:
1566 return err;
1567}
1568
1570{
1572
1573 ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1574
1575 ff_vk_shader_free(&fv->s, &fv->enc);
1576 ff_vk_shader_free(&fv->s, &fv->gather);
1577 ff_vk_shader_free(&fv->s, &fv->reset);
1578 ff_vk_shader_free(&fv->s, &fv->setup);
1579 ff_vk_shader_free(&fv->s, &fv->remap);
1580 ff_vk_shader_free(&fv->s, &fv->sort32);
1581 ff_vk_shader_free(&fv->s, &fv->rct_search);
1582
1583 if (fv->exec_ctx_info) {
1584 for (int i = 0; i < fv->async_depth; i++) {
1589 }
1590 }
1592
1594
1598
1602
1603 ff_vk_free_buf(&fv->s, &fv->results_buf);
1604
1605 ff_vk_free_buf(&fv->s, &fv->consts_buf);
1606
1607 av_frame_free(&fv->frame);
1608 ff_vk_uninit(&fv->s);
1609
1610 return 0;
1611}
1612
1613#define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1614#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1616 { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1617 { .i64 = -1 }, -1, 2, VE },
1618 { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1619 { .i64 = 0 }, 0, 1, VE },
1620 { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1621 { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1622 { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1623 { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1624 { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1625 { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1626 { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1627 { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1628 { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1629 { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1630 { "default", NULL, 0, AV_OPT_TYPE_CONST,
1631 { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1632 { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1633 { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1634 { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1635 { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1636
1637 { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1638 { .i64 = -1 }, -1, MAX_SLICES, VE },
1639 { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1640 { .i64 = -1 }, -1, MAX_SLICES, VE },
1641
1642 { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1643 { .i64 = 0 }, 0, 1, VE },
1644
1645 { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1646 { .i64 = 1 }, 0, 1, VE },
1647
1648 { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1649 { .i64 = 1 }, 1, INT_MAX, VE },
1650
1651 { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1652 { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1653 { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1654 { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1655 { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1656 { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1657 { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1658 { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1659 { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1660 { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1661
1662 { NULL }
1663};
1664
1666 { "g", "1" },
1667 { NULL },
1668};
1669
1671 .class_name = "ffv1_vulkan",
1672 .item_name = av_default_item_name,
1674 .version = LIBAVUTIL_VERSION_INT,
1675};
1676
1678 HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1679 NULL,
1680};
1681
1683 .p.name = "ffv1_vulkan",
1684 CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1685 .p.type = AVMEDIA_TYPE_VIDEO,
1686 .p.id = AV_CODEC_ID_FFV1,
1687 .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1690 .close = &vulkan_encode_ffv1_close,
1691 .p.priv_class = &vulkan_encode_ffv1_class,
1692 .p.capabilities = AV_CODEC_CAP_DELAY |
1698 .defaults = vulkan_encode_ffv1_defaults,
1700 .hw_configs = vulkan_encode_ffv1_hw_configs,
1701 .p.wrapper_name = "vulkan",
1702};
const FFCodec ff_ffv1_vulkan_encoder
#define VE
Definition amfenc_av1.c:30
const unsigned char ff_seg_gather_comp_spv_data[]
const unsigned int ff_seg_gather_comp_spv_len
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define FF_CODEC_CAP_EOF_FLUSH
The encoder has AV_CODEC_CAP_DELAY set, but does not actually have delay - it only wants to be flushe...
#define CODEC_PIXFMTS(...)
#define FF_CODEC_RECEIVE_PACKET_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define MAX_SLICES
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition defs.h:62
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition encode.c:218
av_cold int ff_ffv1_common_init(AVCodecContext *avctx, FFV1Context *s)
Definition ffv1.c:36
FF Video Codec 1 (a lossless codec)
#define CONTEXT_SIZE
Definition ffv1.h:45
#define AC_GOLOMB_RICE
Definition ffv1.h:52
#define AC_RANGE_DEFAULT_TAB_FORCE
Definition ffv1.h:55
#define AC_RANGE_CUSTOM_TAB
Definition ffv1.h:54
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
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
int ff_ffv1_encode_determine_slices(AVCodecContext *avctx)
Definition ffv1enc.c:570
av_cold int ff_ffv1_encode_init(AVCodecContext *avctx)
Definition ffv1enc.c:605
size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx)
Definition ffv1enc.c:1863
av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt)
Definition ffv1enc.c:807
av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx)
Definition ffv1enc.c:447
@ QTABLE_DEFAULT
Definition ffv1enc.h:29
@ QTABLE_8BIT
Definition ffv1enc.h:30
@ QTABLE_GT8BIT
Definition ffv1enc.h:31
static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *fltmap_buf, uint32_t fltmap_size, FFv1ShaderParams *pd)
static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, FFVkExecContext *exec, const AVFrame *pict)
const char * ff_source_ffv1_enc_comp
const unsigned char ff_ffv1_enc_reset_comp_spv_data[]
static const FFCodecDefault vulkan_encode_ffv1_defaults[]
const unsigned int ff_ffv1_enc_sort32_comp_spv_len
static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
const char * ff_source_rangecoder_comp
const unsigned int ff_ffv1_enc_bayer_comp_spv_len
static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static const AVOption vulkan_encode_ffv1_options[]
const char * ff_source_ffv1_common_comp
const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[]
const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len
const unsigned char ff_ffv1_enc_bayer_comp_spv_data[]
static int init_gather_shader(AVCodecContext *avctx)
static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *units_buf, uint32_t units_size, FFv1ShaderParams *pd)
const unsigned int ff_ffv1_enc_reset_comp_spv_len
const unsigned int ff_ffv1_enc_rct_search_comp_spv_len
const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[]
const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_remap_comp_spv_len
const char * ff_source_ffv1_vlc_comp
static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[]
static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
const unsigned int ff_ffv1_enc_golomb_comp_spv_len
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
const unsigned int ff_ffv1_enc_setup_comp_spv_len
const unsigned char ff_ffv1_enc_setup_comp_spv_data[]
const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len
const unsigned char ff_ffv1_enc_remap_comp_spv_data[]
const unsigned int ff_ffv1_enc_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_comp_spv_len
#define RGB_LINECACHE
const AVCodecHWConfigInternal *const vulkan_encode_ffv1_hw_configs[]
const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len
const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[]
static int vulkan_encode_ffv1_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
static const AVClass vulkan_encode_ffv1_class
#define OFFSET(x)
const unsigned char ff_ffv1_enc_sort32_comp_spv_data[]
const unsigned char ff_ffv1_enc_rgb_comp_spv_data[]
const unsigned char ff_ffv1_enc_golomb_comp_spv_data[]
const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[]
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len
static int run_rct_search(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *slice_data_buf, uint32_t slice_data_size, FFv1ShaderParams *pd)
const unsigned char ff_ffv1_enc_comp_spv_data[]
const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]
const char * ff_source_common_comp
#define AV_NUM_DATA_POINTERS
Definition frame.h:473
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition codec.h:154
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition codec.h:133
#define AV_CODEC_FLAG_COPY_OPAQUE
Definition avcodec.h:279
@ AV_CODEC_ID_FFV1
Definition codec_id.h:83
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
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:139
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#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_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:695
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:700
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
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_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition hwconfig.h:100
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 AV_RN32(p)
common internal api header.
#define av_cold
Definition attributes.h:117
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:1526
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:2542
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:2070
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:2373
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:310
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Definition vulkan.c:1016
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition vulkan.c:357
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:590
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1443
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2638
int ff_vk_init(FFVulkanContext *s, void *log_parent, AVBufferRef *device_ref, AVBufferRef *frames_ref)
Initializes the AVClass, in case this context is not used as the main user's context.
Definition vulkan.c:2651
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition vulkan.c:1230
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:2027
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:599
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:1958
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2614
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2407
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition vulkan.c:571
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:881
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2591
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:694
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:2555
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:297
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition vulkan.c:687
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:1256
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:636
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:2267
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:777
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:2581
version
Definition libkvazaar.c:313
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
#define FFALIGN(x, a)
Definition macros.h:78
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
const char data[16]
Definition mxf.c:149
AVOptions.
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_GBRPF32
Definition pixfmt.h:584
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:564
#define AV_PIX_FMT_RGBA128
Definition pixfmt.h:636
#define AV_PIX_FMT_RGBA64
Definition pixfmt.h:535
#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
#define AV_PIX_FMT_GBRAPF32
Definition pixfmt.h:585
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:120
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition refstruct.c:140
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
int width
picture width / height.
Definition avcodec.h:604
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition avcodec.h:1375
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1471
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition avcodec.h:1021
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
void * priv_data
Definition avcodec.h:470
int slices
Number of slices.
Definition avcodec.h:1037
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:569
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
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:183
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.
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.
int ac
1=range coder <-> 0=golomb rice
Definition ffv1.h:147
int num_v_slices
Definition ffv1.h:176
int num_h_slices
Definition ffv1.h:177
int use32bit
Definition ffv1.h:160
VkBuffer buf
Definition vulkan.h:95
VkDeviceAddress address
Definition vulkan.h:99
size_t size
Definition vulkan.h:98
VkMemoryPropertyFlagBits flags
Definition vulkan.h:97
VkDeviceMemory mem
Definition vulkan.h:96
uint8_t * mapped_mem
Definition vulkan.h:103
uint32_t idx
Definition vulkan.h:129
void * opaque
Definition vulkan.h:150
int had_submission
Definition vulkan.h:131
VkCommandBuffer buf
Definition vulkan.h:139
FFVkExecContext * contexts
Definition vulkan.h:269
int pool_size
Definition vulkan.h:274
AVHWFramesContext * frames
Definition vulkan.h:333
AVVulkanDeviceContext * hwctx
Definition vulkan.h:329
VkMemoryPropertyFlagBits host_cached_flag
Definition vulkan.h:325
VkPhysicalDeviceVulkan11Properties props_11
Definition vulkan.h:297
FFVulkanFunctions vkfn
Definition vulkan.h:294
VkPhysicalDeviceProperties2 props
Definition vulkan.h:296
AVBufferRef * device_ref
Definition vulkan.h:327
uint16_t context_count[8]
Definition ffv1_vulkan.h:37
uint32_t extend_lookup[8]
Definition ffv1_vulkan.h:36
VkDeviceAddress sparse
VkDeviceAddress compacted
AVRefStructPool * gathered_data_pool
AVRefStructPool * remap_data_pool
FFVkBuffer * keyframe_slice_data_ref
AVRefStructPool * out_data_pool
AVRefStructPool * compacted_data_pool
AVRefStructPool * slice_data_pool
FFVulkanShader rct_search
AVVulkanDeviceQueueFamily * qf
AVBufferRef * intermediate_frames_ref
VulkanEncodeFFv1FrameData * exec_ctx_info
#define av_free(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static AVFormatContext * ctx
Definition movenc.c:49
int size
#define mh
#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, d_stage, d_access, d_access2, offs, bsz)
Definition vulkan.h:562
@ FF_VK_REP_UINT
Definition vulkan.h:435
@ FF_VK_REP_NATIVE
Definition vulkan.h:429
#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_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)
Definition vulkan.h:614