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 /* Start recording */
316 err = ff_vk_exec_start(&fv->s, exec);
317 if (err < 0)
318 return err;
319
320 /* Frame state */
321 f->cur_enc_frame = pict;
322 if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
324 f->key_frame = fd->key_frame = 1;
325 f->gob_count++;
326 } else {
327 f->key_frame = fd->key_frame = 0;
328 }
329
330 f->slice_count = f->max_slice_count;
331
332 /* Allocate slice buffer data */
333 if (f->ac == AC_GOLOMB_RICE)
334 plane_state_size = 8;
335 else
336 plane_state_size = CONTEXT_SIZE;
337
338 plane_state_size *= context_count;
339 slice_state_size = plane_state_size*f->plane_count;
340
341 slice_data_size = 256; /* Overestimation for the SliceContext struct */
342 slice_state_size += slice_data_size;
343 slice_state_size = FFALIGN(slice_state_size, 8);
344
345 /* Allocate slice data buffer */
346 slice_data_buf = fv->keyframe_slice_data_ref ?
348 if (!slice_data_buf) {
350 &slice_data_buf,
351 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
352 NULL, slice_state_size*f->slice_count,
353 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
354
355 /* Only save it if we're going to use it again */
356 if (has_inter)
357 fv->keyframe_slice_data_ref = av_refstruct_ref(slice_data_buf);
358 }
359
360 if (f->remap_mode) {
361 if (fv->is_float32) {
362 /* Per (slice, plane): [units : max_pixels*2 uints] + [bitmap : max_pixels uints]. */
363 remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
364 } else {
366 remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
367 }
368
370 &remap_data_buf,
371 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
372 NULL, remap_data_size*f->slice_count,
373 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
374 }
375
376 /* Output buffer size */
377 maxsize = ffv1_vk_buffer_size(avctx);
378 maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
379
380 /* Sparse per-slice slots: written by encode, read by gather. */
382 &fd->out_data_ref,
383 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
384 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
385 NULL, maxsize,
386 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
387 out_data_buf = fd->out_data_ref;
388
389 /* Device-local gather destination */
391 &gathered_buf,
392 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
393 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
394 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
395 NULL, maxsize,
396 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
397
398 /* Contiguous output, read back by the CPU. */
401 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
402 NULL, maxsize,
403 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
404 fv->s.host_cached_flag));
405 compacted_buf = fd->compacted_data_ref;
406
407 /* Image views */
408 AVFrame *src = (AVFrame *)pict;
409 VkImageView src_views[AV_NUM_DATA_POINTERS];
410
411 AVFrame *tmp = NULL;
412 VkImageView tmp_views[AV_NUM_DATA_POINTERS];
413 if (fv->is_rgb) {
414 /* Create a temporaty frame */
416 if (!(tmp)) {
417 err = AVERROR(ENOMEM);
418 goto fail;
419 }
420
422 tmp, 0));
423 }
424
425 /* With everything allocated, setup push data */
426 FFv1ShaderParams pd = {
427 .slice_data = out_data_buf->address,
428
429 .img_size[0] = fv->s.frames->width,
430 .img_size[1] = fv->s.frames->height,
431
432 .plane_state_size = plane_state_size,
433 .key_frame = f->key_frame,
434 .crcref = f->crcref,
435 .micro_version = f->micro_version,
436
437 .sar[0] = pict->sample_aspect_ratio.num,
438 .sar[1] = pict->sample_aspect_ratio.den,
439 .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
440 !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
441
442 /* 16-byte aligned so the gather can use wide loads */
443 .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
444 .max_pixels_per_slice = fv->max_pixels_per_slice,
445 };
446
447 for (int i = 0; i < f->quant_table_count; i++) {
448 pd.context_count[i] = f->context_count[i];
449 pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
450 f->quant_tables[i][4][127];
451 }
452
453 /* For some reason the C FFv1 encoder/decoder treats these differently */
454 if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
455 avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
457 memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
458 else
459 ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
460
461 /* For float pixel formats we want the raw bit pattern, not a value
462 * already passed through fp16/fp32 conversion (which can flush
463 * denormals). Use a UINT view in that case. */
464 RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
465 f->remap_mode ? FF_VK_REP_UINT
467
470
471 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
472 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
473 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
474 if (fv->is_rgb)
475 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
476 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
477 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
478
479 if (fv->optimize_rct || f->remap_mode) {
480 /* Prepare the frame for reading */
481 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
482 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
483 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
484 VK_ACCESS_SHADER_READ_BIT,
485 VK_IMAGE_LAYOUT_GENERAL,
486 VK_QUEUE_FAMILY_IGNORED);
487
488 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
489 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
490 .pImageMemoryBarriers = img_bar,
491 .imageMemoryBarrierCount = nb_img_bar,
492 });
493 nb_img_bar = 0;
494 }
495
496 /* Run RCT search if needed */
497 if (fv->optimize_rct) {
498 RET(run_rct_search(avctx, exec, src, src_views,
499 slice_data_buf, slice_data_size, &pd));
500
501 /* Make sure the writes are visible to the setup shader */
502 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
503 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
504 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
505 0, slice_data_size*f->slice_count);
506 }
507
508 if (f->remap_mode) {
509 if (fv->is_float32) {
510 RET(run_sort32(avctx, exec, src, src_views,
511 remap_data_buf, remap_data_size, &pd));
512 } else {
513 RET(run_remap(avctx, exec, src, src_views,
514 remap_data_buf, remap_data_size, &pd));
515 }
516
517 /* Make sure the writes are visible to the setup shader */
518 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
519 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
520 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
521 0, remap_data_size*f->slice_count);
522 }
523
524 if (fv->optimize_rct || f->remap_mode) {
525 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
526 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
527 .pBufferMemoryBarriers = buf_bar,
528 .bufferMemoryBarrierCount = nb_buf_bar,
529 });
530 nb_buf_bar = 0;
531 }
532
533 /* Setup shader */
534 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
535 1, 0, 0,
536 slice_data_buf,
537 0, slice_data_size*f->slice_count,
538 VK_FORMAT_UNDEFINED);
539 if (f->remap_mode)
541 &fv->setup, 1, 1, 0,
542 remap_data_buf,
543 0, remap_data_size*f->slice_count,
544 VK_FORMAT_UNDEFINED);
545
546 ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
547 ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
548 VK_SHADER_STAGE_COMPUTE_BIT,
549 0, sizeof(FFv1ShaderParams), &pd);
550
551 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
552
553 /* Clean up temporary image if needed */
554 if (fv->is_rgb) {
555 AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
556 vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
557 vkf->access[0] = VK_ACCESS_2_NONE;
558
559 RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
560 tmp,
562
563 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
564 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
565 VK_PIPELINE_STAGE_2_CLEAR_BIT,
566 VK_ACCESS_2_TRANSFER_WRITE_BIT,
567 VK_IMAGE_LAYOUT_GENERAL,
568 VK_QUEUE_FAMILY_IGNORED);
569 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
570 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
571 .pImageMemoryBarriers = img_bar,
572 .imageMemoryBarrierCount = nb_img_bar,
573 });
574 nb_img_bar = 0;
575
576 vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
577 &((VkClearColorValue) { 0 }),
578 1, &((VkImageSubresourceRange) {
579 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
580 .levelCount = 1,
581 .layerCount = 1,
582 }));
583 }
584
585 /* Run reset shader */
586 if (f->key_frame || fv->force_pcm) {
587 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
588 1, 0, 0,
589 slice_data_buf,
590 0, slice_data_size*f->slice_count,
591 VK_FORMAT_UNDEFINED);
592 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
593 1, 1, 0,
594 slice_data_buf,
595 f->slice_count*256,
596 VK_WHOLE_SIZE,
597 VK_FORMAT_UNDEFINED);
598
599 ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
600 ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
601 VK_SHADER_STAGE_COMPUTE_BIT,
602 0, sizeof(FFv1ShaderParams), &pd);
603
604 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
605 f->plane_count);
606 }
607
608 /* Sync between reset and encode shaders */
609 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
610 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
611 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
612 0, slice_data_size*f->slice_count);
613
614 /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
615 * back into the remap buffer; the encode shader reads it. */
616 if (f->remap_mode)
617 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
618 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
619 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
620 0, remap_data_size*f->slice_count);
621 if (f->key_frame || fv->force_pcm)
622 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
623 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
624 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
625 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
626 else
627 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
628 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
629 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
630 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
631
632 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
633 fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
634 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
635 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
636 VK_ACCESS_SHADER_READ_BIT,
637 VK_IMAGE_LAYOUT_GENERAL,
638 VK_QUEUE_FAMILY_IGNORED);
639
640 if (fv->is_rgb)
641 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
642 VK_PIPELINE_STAGE_2_CLEAR_BIT,
643 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
644 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
645 VK_IMAGE_LAYOUT_GENERAL,
646 VK_QUEUE_FAMILY_IGNORED);
647
648 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
649 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
650 .pImageMemoryBarriers = img_bar,
651 .imageMemoryBarrierCount = nb_img_bar,
652 .pBufferMemoryBarriers = buf_bar,
653 .bufferMemoryBarrierCount = nb_buf_bar,
654 });
655 nb_img_bar = 0;
656 nb_buf_bar = 0;
657
658 /* Main encode shader */
659 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
660 1, 0, 0,
661 slice_data_buf,
662 0, slice_data_size*f->slice_count,
663 VK_FORMAT_UNDEFINED);
665 &fv->enc, 1, 1, 0,
666 &fv->results_buf,
667 fd->idx*f->max_slice_count*sizeof(uint32_t),
668 f->slice_count*sizeof(uint32_t),
669 VK_FORMAT_UNDEFINED);
670 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
671 1, 2, 0,
672 slice_data_buf,
673 f->slice_count*256,
674 VK_WHOLE_SIZE,
675 VK_FORMAT_UNDEFINED);
676 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
677 src, src_views,
678 1, 3,
679 VK_IMAGE_LAYOUT_GENERAL,
680 VK_NULL_HANDLE);
681 if (fv->is_rgb)
682 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
683 tmp, tmp_views,
684 1, 4,
685 VK_IMAGE_LAYOUT_GENERAL,
686 VK_NULL_HANDLE);
687 if (f->remap_mode)
689 &fv->enc, 1, 5, 0,
690 remap_data_buf,
691 0, remap_data_size*f->slice_count,
692 VK_FORMAT_UNDEFINED);
693
694 ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
695 ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
696 VK_SHADER_STAGE_COMPUTE_BIT,
697 0, sizeof(FFv1ShaderParams), &pd);
698 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
699
700 /* Gather the per-slice slots into one contiguous buffer, in the same
701 * submission. */
702 FFVkBuffer *results_buf = &fv->results_buf;
703 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], out_data_buf,
704 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
705 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
706 0, VK_WHOLE_SIZE);
707 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], results_buf,
708 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
709 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
710 0, VK_WHOLE_SIZE);
711 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
712 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
713 .pBufferMemoryBarriers = buf_bar,
714 .bufferMemoryBarrierCount = nb_buf_bar,
715 });
716 nb_buf_bar = 0;
717
718 SegGatherPushData gather_pd = {
719 .sparse = out_data_buf->address,
720 .compacted = gathered_buf->address,
721 .slot_size = (uint32_t)((out_data_buf->size / f->slice_count) & ~(size_t)15),
722 };
723 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->gather, 0, 0, 0,
724 &fv->results_buf,
725 fd->idx*f->max_slice_count*sizeof(uint32_t),
726 f->slice_count*sizeof(uint32_t),
727 VK_FORMAT_UNDEFINED);
728 ff_vk_exec_bind_shader(&fv->s, exec, &fv->gather);
729 ff_vk_shader_update_push_const(&fv->s, exec, &fv->gather,
730 VK_SHADER_STAGE_COMPUTE_BIT,
731 0, sizeof(gather_pd), &gather_pd);
732 vk->CmdDispatch(exec->buf, f->slice_count, 1, 1);
733
734 /* Read the gathered bitstream back with the copy engine. The size is
735 * only known once the encode is done, so the whole buffer is copied;
736 * with the version-4 slot sizing this is close to the payload size. */
737 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], gathered_buf,
738 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
739 TRANSFER_BIT, TRANSFER_READ_BIT, NONE_KHR,
740 0, VK_WHOLE_SIZE);
741 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
742 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
743 .pBufferMemoryBarriers = buf_bar,
744 .bufferMemoryBarrierCount = nb_buf_bar,
745 });
746 nb_buf_bar = 0;
747
748 vk->CmdCopyBuffer(exec->buf, gathered_buf->buf, compacted_buf->buf,
749 1, &(VkBufferCopy) { .size = maxsize });
750
751 /* Submit */
752 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &slice_data_buf);
753 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &gathered_buf);
754 if (remap_data_buf)
755 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &remap_data_buf);
756 err = ff_vk_exec_submit(&fv->s, exec);
757 if (err < 0) {
759 return err;
760 }
761
762 f->picture_number++;
763
765 return 0;
766
767fail:
768 ff_vk_exec_discard(&fv->s, exec);
770 av_refstruct_unref(&slice_data_buf);
771 av_refstruct_unref(&remap_data_buf);
772 av_refstruct_unref(&gathered_buf);
773
774 return err;
775}
776
777/* Return the gathered-output buffer to its pool when the packet is freed. */
778static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
779{
780 av_refstruct_unref(&opaque);
781}
782
784 AVPacket *pkt)
785{
787 FFV1Context *f = &fv->ctx;
788 FFVulkanFunctions *vk = &fv->s.vkfn;
790
791 FFVkBuffer *compacted_buf = fd->compacted_data_ref;
792
793 /* Make sure the encode + gather submission is done */
794 ff_vk_exec_wait(&fv->s, exec);
795
796 /* Invalidate the per-slice sizes if needed */
797 uint32_t rb_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
798 if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
799 VkMappedMemoryRange invalidate_data = {
800 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
801 .memory = fv->results_buf.mem,
802 .offset = rb_off,
803 .size = f->slice_count*sizeof(uint32_t),
804 };
805 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
806 1, &invalidate_data);
807 }
808
809 /* The gather packed the slices tight and in order; sum their lengths. */
810 pkt->size = 0;
811 uint8_t *rb = fv->results_buf.mapped_mem + rb_off;
812 for (int i = 0; i < f->slice_count; i++) {
813 uint32_t sl_len = AV_RN32(rb + i*4);
814 av_log(avctx, AV_LOG_DEBUG, "Slice %i size = %u\n", i, sl_len);
815 pkt->size += sl_len;
816 }
817 av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
818
819 /* Invalidate the gathered bitstream if needed */
820 if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
821 VkMappedMemoryRange invalidate_data = {
822 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
823 .memory = compacted_buf->mem,
824 .offset = 0,
825 .size = VK_WHOLE_SIZE,
826 };
827 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
828 1, &invalidate_data);
829 }
830
831 /* Hand the gathered buffer to the packet with no copy: pkt->buf references
832 * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
833 pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
835 if (!pkt->buf) {
838 return AVERROR(ENOMEM);
839 }
840 fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
841 pkt->data = compacted_buf->mapped_mem;
842
843 pkt->pts = fd->pts;
844 pkt->dts = fd->pts;
845 pkt->duration = fd->duration;
846 pkt->flags |= AV_PKT_FLAG_KEY * fd->key_frame;
847
848 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
849 pkt->opaque = fd->frame_opaque;
850 pkt->opaque_ref = fd->frame_opaque_ref;
852 }
853
855
856 return 0;
857}
858
860 AVPacket *pkt)
861{
862 int err;
865 FFVkExecContext *exec;
866 AVFrame *frame;
867
868 while (1) {
869 /* Roll an execution context */
870 exec = ff_vk_exec_get(&fv->s, &fv->exec_pool);
871
872 /* If it had a frame, immediately output it */
873 if (exec->had_submission) {
874 exec->had_submission = 0;
875 fv->in_flight--;
876 return get_packet(avctx, exec, pkt);
877 }
878
879 /* Get next frame to encode */
880 frame = fv->frame;
881 err = ff_encode_get_frame(avctx, frame);
882 if (err < 0 && err != AVERROR_EOF) {
883 return err;
884 } else if (err == AVERROR_EOF) {
885 if (!fv->in_flight)
886 return err;
887 continue;
888 }
889
890 /* Encode frame */
891 fd = exec->opaque;
892 fd->pts = frame->pts;
893 fd->duration = frame->duration;
894 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
895 fd->frame_opaque = frame->opaque;
896 fd->frame_opaque_ref = frame->opaque_ref;
897 frame->opaque_ref = NULL;
898 }
899
900 err = vulkan_encode_ffv1_submit_frame(avctx, exec, frame);
902 if (err < 0)
903 return err;
904
905 fv->in_flight++;
906 if (fv->in_flight < fv->async_depth)
907 return AVERROR(EAGAIN);
908 }
909
910 return 0;
911}
912
913static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
914{
915 int err;
917 FFV1Context *f = &fv->ctx;
918 AVHWFramesContext *frames_ctx;
919 AVVulkanFramesContext *vk_frames;
920
923 return AVERROR(ENOMEM);
924
926 frames_ctx->format = AV_PIX_FMT_VULKAN;
927 frames_ctx->sw_format = sw_format;
928 frames_ctx->width = fv->s.frames->width;
929 frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
930
931 vk_frames = frames_ctx->hwctx;
932 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
933 vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
934 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
935 vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
936
938 if (err < 0) {
939 av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
940 av_get_pix_fmt_name(sw_format), av_err2str(err));
942 return err;
943 }
944
945 return 0;
946}
947
948static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
949{
950 int err;
952 FFVulkanShader *shd = &fv->rct_search;
953
954 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
955 (uint32_t []) { 32, 32, 1 }, 0);
956
958 VK_SHADER_STAGE_COMPUTE_BIT);
959
960 const FFVulkanDescriptorSetBinding desc_set_const[] = {
961 { /* rangecoder_buf */
962 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
963 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
964 },
965 };
966 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
967
968 const FFVulkanDescriptorSetBinding desc_set[] = {
969 { /* slice_data_buf */
970 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
971 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
972 },
973 { /* src */
974 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
975 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
977 },
978 };
979 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
980
981 RET(ff_vk_shader_link(&fv->s, shd,
984
985 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
986
987fail:
988 return err;
989}
990
991static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
992{
993 int err;
995 FFVulkanShader *shd = &fv->sort32;
996
997 uint32_t wg_x = FFMIN(fv->max_pixels_per_slice, 256);
998 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
999 (uint32_t []) { wg_x, 1, 1 }, 0);
1000
1002 VK_SHADER_STAGE_COMPUTE_BIT);
1003
1004 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1005 { /* rangecoder_buf */
1006 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1007 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1008 },
1009 };
1010 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1011
1012 const FFVulkanDescriptorSetBinding desc_set[] = {
1013 { /* slice_data_buf */
1014 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1015 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1016 },
1017 { /* src */
1018 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1019 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1021 },
1022 { /* units */
1023 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1024 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1025 },
1026 };
1027 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1028
1029 RET(ff_vk_shader_link(&fv->s, shd,
1032
1033 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1034
1035fail:
1036 return err;
1037}
1038
1039static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1040{
1041 int err;
1043 FFVulkanShader *shd = &fv->remap;
1044
1045 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1046 (uint32_t []) { 32, 32, 1 }, 0);
1047
1049 VK_SHADER_STAGE_COMPUTE_BIT);
1050
1051 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1052 { /* rangecoder_buf */
1053 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1054 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1055 },
1056 };
1057 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1058
1059 const FFVulkanDescriptorSetBinding desc_set[] = {
1060 { /* slice_data_buf */
1061 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1062 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1063 },
1064 { /* src */
1065 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1066 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1068 },
1069 { /* fltmap */
1070 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1071 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1072 },
1073 };
1074 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1075
1076 RET(ff_vk_shader_link(&fv->s, shd,
1079
1080 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1081
1082fail:
1083 return err;
1084}
1085
1086static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1087{
1088 int err;
1090 FFVulkanShader *shd = &fv->setup;
1091
1092 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1093 (uint32_t []) { 1, 1, 1 }, 0);
1094
1096 VK_SHADER_STAGE_COMPUTE_BIT);
1097
1098 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1099 { /* rangecoder_buf */
1100 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1101 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1102 },
1103 };
1104 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1105
1106 const FFVulkanDescriptorSetBinding desc_set[] = {
1107 { /* slice_data_buf */
1108 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1109 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1110 },
1111 { /* fltmap */
1112 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1113 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1114 },
1115 };
1116 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1117
1118 RET(ff_vk_shader_link(&fv->s, shd,
1121
1122 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1123
1124fail:
1125 return err;
1126}
1127
1128static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1129{
1130 int err;
1132 FFVulkanShader *shd = &fv->reset;
1133
1134 int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1135
1136 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1137 (uint32_t []) { wg_dim, 1, 1 }, 0);
1138
1140 VK_SHADER_STAGE_COMPUTE_BIT);
1141
1142 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1143 { /* rangecoder_buf */
1144 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1145 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1146 },
1147 };
1148 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1149
1150 const FFVulkanDescriptorSetBinding desc_set[] = {
1151 { /* slice_data_buf */
1152 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1153 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1154 },
1155 { /* slice_state_buf */
1156 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1157 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1158 },
1159 };
1160 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1161
1162 if (fv->ctx.ac == AC_GOLOMB_RICE)
1163 RET(ff_vk_shader_link(&fv->s, shd,
1166 else
1167 RET(ff_vk_shader_link(&fv->s, shd,
1170
1171 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1172
1173fail:
1174 return err;
1175}
1176
1177static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1178{
1179 int err;
1181 FFV1Context *f = &fv->ctx;
1182 FFVulkanShader *shd = &fv->enc;
1183
1184 uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1185 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1186 (uint32_t []) { wg_x, 1, 1 }, 0);
1187
1189 VK_SHADER_STAGE_COMPUTE_BIT);
1190
1191 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1192 { /* rangecoder_buf */
1193 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1194 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1195 },
1196 { /* quant_buf */
1197 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1198 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1199 },
1200 { /* crc_ieee_buf */
1201 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1202 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1203 },
1204 };
1205 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1206
1207 const FFVulkanDescriptorSetBinding desc_set[] = {
1208 { /* slice_data_buf */
1209 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1210 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1211 },
1212 { /* slice_results_buf */
1213 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1214 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1215 },
1216 { /* slice_state_buf */
1217 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1218 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1219 },
1220 { /* src */
1221 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1222 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1224 },
1225 { /* tmp */
1226 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1227 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1228 },
1229 { /* fltmap */
1230 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1231 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1232 },
1233 };
1234 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1235 4 + fv->is_rgb + !!f->remap_mode, 0);
1236
1237 if (f->bayer) {
1238 if (fv->ctx.ac == AC_GOLOMB_RICE)
1239 ff_vk_shader_link(&fv->s, shd,
1242 else
1243 ff_vk_shader_link(&fv->s, shd,
1246 } else if (f->remap_mode) {
1247 if (fv->ctx.ac == AC_GOLOMB_RICE)
1248 ff_vk_shader_link(&fv->s, shd,
1251 else
1252 ff_vk_shader_link(&fv->s, shd,
1255 } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1256 if (fv->is_rgb)
1257 ff_vk_shader_link(&fv->s, shd,
1260 else
1261 ff_vk_shader_link(&fv->s, shd,
1264 } else {
1265 if (fv->is_rgb)
1266 ff_vk_shader_link(&fv->s, shd,
1269 else
1270 ff_vk_shader_link(&fv->s, shd,
1272 ff_ffv1_enc_comp_spv_len, "main");
1273 }
1274
1275 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1276
1277fail:
1278 return err;
1279}
1280
1282{
1283 int err;
1285 FFVulkanShader *shd = &fv->gather;
1286
1287 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
1288 (uint32_t []) { 256, 1, 1 }, 0);
1289
1291 VK_SHADER_STAGE_COMPUTE_BIT);
1292
1293 const FFVulkanDescriptorSetBinding desc_set[] = {
1294 { /* sizes_buf */
1295 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1296 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1297 },
1298 };
1299 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0);
1300
1301 RET(ff_vk_shader_link(&fv->s, shd,
1304
1305 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1306
1307fail:
1308 return err;
1309}
1310
1312{
1313 int err;
1314 size_t maxsize;
1316 FFV1Context *f = &fv->ctx;
1317
1318 if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1319 return err;
1320
1321 if (f->ac == 1)
1322 f->ac = AC_RANGE_CUSTOM_TAB;
1323
1324 err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1325 if (err < 0)
1326 return err;
1327
1328 /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1329 * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1330 f->version = f->bayer ? 4 : 3;
1331
1332 err = ff_ffv1_encode_init(avctx);
1333 if (err < 0)
1334 return err;
1335
1336 /* Rice coding did not support high bit depths */
1337 if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1338 if (f->ac == AC_GOLOMB_RICE) {
1339 av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1340 "forcing range coder\n");
1341 f->ac = AC_RANGE_CUSTOM_TAB;
1342 }
1343 }
1344
1345 if (f->version < 4 && avctx->gop_size > 1) {
1346 av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1347 return AVERROR_INVALIDDATA;
1348 }
1349
1350 if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1351 av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1352 return AVERROR_INVALIDDATA;
1353 }
1354
1355 /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1356 if (f->version == 4)
1357 f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1358
1359 f->num_h_slices = fv->num_h_slices;
1360 f->num_v_slices = fv->num_v_slices;
1361
1362 if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1363 if (avctx->slices) {
1365 if (err < 0)
1366 return err;
1367 } else {
1368 f->num_h_slices = 32;
1369 f->num_v_slices = 32;
1370 }
1371 } else if (f->num_h_slices && f->num_v_slices <= 0) {
1372 f->num_v_slices = MAX_SLICES / f->num_h_slices;
1373 } else if (f->num_v_slices && f->num_h_slices <= 0) {
1374 f->num_h_slices = MAX_SLICES / f->num_v_slices;
1375 }
1376
1377 f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1378 f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1379
1380 if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1381 av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1382 "by the standard is %i\n",
1383 f->num_h_slices * f->num_v_slices, MAX_SLICES);
1384 return AVERROR_PATCHWELCOME;
1385 }
1386
1387 f->max_slice_count = f->num_h_slices * f->num_v_slices;
1388
1389 if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1390 return err;
1391
1392 if (f->version < 4) {
1393 if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1394 ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1395 av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1396 "dimensions is only supported in version 4 (-level 4)\n");
1397 return AVERROR_PATCHWELCOME;
1398 }
1399 }
1400
1401 if (fv->force_pcm) {
1402 if (f->version < 4) {
1403 av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1404 return AVERROR_INVALIDDATA;
1405 } else if (f->ac == AC_GOLOMB_RICE) {
1406 av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1407 return AVERROR_INVALIDDATA;
1408 }
1409 }
1410
1411 /* Init Vulkan */
1412 err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1413 if (err < 0)
1414 return err;
1415
1416 fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1417 if (!fv->qf) {
1418 av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1419 return err;
1420 }
1421
1422 maxsize = ffv1_vk_buffer_size(avctx);
1423 if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1424 av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1425 "than maximum device allocation (%"PRIu64"), clipping\n",
1426 maxsize, fv->s.props_11.maxMemoryAllocationSize);
1427 maxsize = fv->s.props_11.maxMemoryAllocationSize;
1428 }
1429
1430 av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1431 2*maxsize / (1024*1024),
1432 (fv->async_depth * 2*maxsize) / (1024*1024),
1433 fv->async_depth);
1434
1435 err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1436 fv->async_depth,
1437 0, 0, 0, NULL);
1438 if (err < 0)
1439 return err;
1440
1441 /* Detect the special RGB coding mode */
1442 fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1443 !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1444
1445 fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1447
1448 if (fv->is_float32) {
1449 /* Compute the worst-case slice geometry. With version >= 4 the slice
1450 * boundaries are computed via slice_coord() which rounds up, so any
1451 * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1452 * pixels. */
1453 uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1454 uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1455 /* Round up to next pow2 for bitonic sort */
1456 uint32_t n = 1;
1457 uint32_t pn = mw*mh;
1458 while (n < pn)
1459 n <<= 1;
1460 if (n < 2)
1461 n = 2;
1462 fv->max_pixels_per_slice = n;
1463 }
1464
1465 /* Init rct search shader */
1466 fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1467 !fv->force_pcm && fv->optimize_rct && !f->bayer;
1468
1469 /* Init shader specialization consts */
1470 SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1471 SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1472 SPEC_LIST_ADD(sl, 1, 32, f->ec);
1473 ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1474 SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1475 SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1476 SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1477 SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1478
1479 if (fv->optimize_rct) {
1480 err = init_rct_search_shader(avctx, sl);
1481 if (err < 0)
1482 return err;
1483 }
1484
1485 if (f->remap_mode) {
1486 if (fv->is_float32)
1487 err = init_sort32_shader(avctx, sl);
1488 else
1489 err = init_remap_shader(avctx, sl);
1490 if (err < 0)
1491 return err;
1492 }
1493
1494 /* Init setup shader */
1495 err = init_setup_shader(avctx, sl);
1496 if (err < 0)
1497 return err;
1498
1499 /* Init reset shader */
1500 err = init_reset_shader(avctx, sl);
1501 if (err < 0)
1502 return err;
1503
1504 if (fv->is_rgb)
1505 RET(init_indirect(avctx, fv->ctx.use32bit ?
1507
1508 /* Encode shader */
1509 err = init_encode_shader(avctx, sl);
1510 if (err < 0)
1511 return err;
1512
1513 /* Gather shader */
1514 err = init_gather_shader(avctx);
1515 if (err < 0)
1516 return err;
1517
1518 /* Constant data */
1519 err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1520 if (err < 0)
1521 return err;
1522
1523 /* Update setup global descriptors */
1525 &fv->setup, 0, 0, 0,
1526 &fv->consts_buf,
1527 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1528 VK_FORMAT_UNDEFINED));
1529
1530 /* Update encode global descriptors */
1532 &fv->enc, 0, 0, 0,
1533 &fv->consts_buf,
1534 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1535 VK_FORMAT_UNDEFINED));
1537 &fv->enc, 0, 1, 0,
1538 &fv->consts_buf,
1539 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1540 VK_WHOLE_SIZE,
1541 VK_FORMAT_UNDEFINED));
1543 &fv->enc, 0, 2, 0,
1544 &fv->consts_buf,
1545 0, 256*sizeof(uint32_t),
1546 VK_FORMAT_UNDEFINED));
1547
1548 /* Temporary frame */
1549 fv->frame = av_frame_alloc();
1550 if (!fv->frame)
1551 return AVERROR(ENOMEM);
1552
1553 /* Async data pool */
1555 fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1556 if (!fv->exec_ctx_info)
1557 return AVERROR(ENOMEM);
1558 for (int i = 0; i < fv->async_depth; i++) {
1561 }
1562
1563 /* Buffers */
1564 RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1565 fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1566 NULL, NULL,
1567 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1568 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1569 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1570 RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1571
1572fail:
1573 return err;
1574}
1575
1577{
1579
1580 ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1581
1582 ff_vk_shader_free(&fv->s, &fv->enc);
1583 ff_vk_shader_free(&fv->s, &fv->gather);
1584 ff_vk_shader_free(&fv->s, &fv->reset);
1585 ff_vk_shader_free(&fv->s, &fv->setup);
1586 ff_vk_shader_free(&fv->s, &fv->remap);
1587 ff_vk_shader_free(&fv->s, &fv->sort32);
1588 ff_vk_shader_free(&fv->s, &fv->rct_search);
1589
1590 if (fv->exec_ctx_info) {
1591 for (int i = 0; i < fv->async_depth; i++) {
1596 }
1597 }
1599
1601
1605
1609
1610 ff_vk_free_buf(&fv->s, &fv->results_buf);
1611
1612 ff_vk_free_buf(&fv->s, &fv->consts_buf);
1613
1614 av_frame_free(&fv->frame);
1615 ff_vk_uninit(&fv->s);
1616
1617 return 0;
1618}
1619
1620#define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1621#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1623 { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1624 { .i64 = -1 }, -1, 2, VE },
1625 { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1626 { .i64 = 0 }, 0, 1, VE },
1627 { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1628 { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1629 { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1630 { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1631 { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1632 { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1633 { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1634 { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1635 { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1636 { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1637 { "default", NULL, 0, AV_OPT_TYPE_CONST,
1638 { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1639 { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1640 { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1641 { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1642 { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1643
1644 { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1645 { .i64 = -1 }, -1, MAX_SLICES, VE },
1646 { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1647 { .i64 = -1 }, -1, MAX_SLICES, VE },
1648
1649 { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1650 { .i64 = 0 }, 0, 1, VE },
1651
1652 { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1653 { .i64 = 1 }, 0, 1, VE },
1654
1655 { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1656 { .i64 = 1 }, 1, INT_MAX, VE },
1657
1658 { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1659 { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1660 { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1661 { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1662 { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1663 { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1664 { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1665 { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1666 { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1667 { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1668
1669 { NULL }
1670};
1671
1673 { "g", "1" },
1674 { NULL },
1675};
1676
1678 .class_name = "ffv1_vulkan",
1679 .item_name = av_default_item_name,
1681 .version = LIBAVUTIL_VERSION_INT,
1682};
1683
1685 HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1686 NULL,
1687};
1688
1690 .p.name = "ffv1_vulkan",
1691 CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1692 .p.type = AVMEDIA_TYPE_VIDEO,
1693 .p.id = AV_CODEC_ID_FFV1,
1694 .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1697 .close = &vulkan_encode_ffv1_close,
1698 .p.priv_class = &vulkan_encode_ffv1_class,
1699 .p.capabilities = AV_CODEC_CAP_DELAY |
1705 .defaults = vulkan_encode_ffv1_defaults,
1707 .hw_configs = vulkan_encode_ffv1_hw_configs,
1708 .p.wrapper_name = "vulkan",
1709};
const FFCodec ff_ffv1_vulkan_encoder
#define VE
Definition amfenc_av1.c:30
static AVFormatContext * ctx
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:1696
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:2719
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:2240
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:2550
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:331
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Definition vulkan.c:1186
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:395
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:645
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1613
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2815
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:2831
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition vulkan.c:1400
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:2197
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:660
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:2128
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2791
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2584
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition vulkan.c:622
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:969
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2768
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:786
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:2732
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:316
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition vulkan.c:779
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:1426
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:763
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:2444
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:867
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:2758
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:154
int had_submission
Definition vulkan.h:134
VkCommandBuffer buf
Definition vulkan.h:142
FFVkExecContext * contexts
Definition vulkan.h:273
int pool_size
Definition vulkan.h:278
AVHWFramesContext * frames
Definition vulkan.h:343
AVVulkanDeviceContext * hwctx
Definition vulkan.h:339
VkMemoryPropertyFlagBits host_cached_flag
Definition vulkan.h:335
VkPhysicalDeviceVulkan11Properties props_11
Definition vulkan.h:301
FFVulkanFunctions vkfn
Definition vulkan.h:298
VkPhysicalDeviceProperties2 props
Definition vulkan.h:300
AVBufferRef * device_ref
Definition vulkan.h:337
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
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:575
@ FF_VK_REP_UINT
Definition vulkan.h:445
@ FF_VK_REP_NATIVE
Definition vulkan.h:439
#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:642