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#include "vulkan_video.h"
35
36/* Parallel Golomb alignment */
37#define LG_ALIGN_W 32
38#define LG_ALIGN_H 32
39
40/* Unlike the decoder, we need 4 lines (but really only 3) */
41#define RGB_LINECACHE 4
42
51
110
111static int cmp_slice_order(const void *a, const void *b)
112{
113 uint64_t x = *(const uint64_t *)a, y = *(const uint64_t *)b;
114 return (x < y) - (x > y);
115}
116
117extern const char *ff_source_common_comp;
118extern const char *ff_source_rangecoder_comp;
119extern const char *ff_source_ffv1_vlc_comp;
120extern const char *ff_source_ffv1_common_comp;
121extern const char *ff_source_ffv1_enc_comp;
122
123extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
124extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
125
126extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
127extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
128
129extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
130extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
131
132extern const unsigned char ff_ffv1_enc_comp_spv_data[];
133extern const unsigned int ff_ffv1_enc_comp_spv_len;
134
135extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
136extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
137
138extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
139extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
140
141extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
142extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
143
144extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
145extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
146
147extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
148extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
149
150extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
151extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
152
153extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
154extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
155
156extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
157extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
158
159extern const unsigned char ff_ffv1_enc_bayer_comp_spv_data[];
160extern const unsigned int ff_ffv1_enc_bayer_comp_spv_len;
161
162extern const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[];
163extern const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len;
164
165/* Size output slots with the v4 worst case; v3's ~(2*bits+5) bytes/sample runs
166 * to gigabytes on large frames. The bitstream version is unaffected. */
168{
170 FFV1Context *f = &fv->ctx;
171 int version = f->version;
172 size_t size;
173
174 f->version = 4;
176 f->version = version;
177
178 return size;
179}
180
182 AVFrame *enc_in, VkImageView *enc_in_views,
183 FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
185{
187 FFV1Context *f = &fv->ctx;
188 FFVulkanFunctions *vk = &fv->s.vkfn;
189
190 /* Update descriptors */
192 1, 0, 0,
193 slice_data_buf,
194 0, slice_data_size*f->slice_count,
195 VK_FORMAT_UNDEFINED);
197 enc_in, enc_in_views,
198 1, 1,
199 VK_IMAGE_LAYOUT_GENERAL,
200 VK_NULL_HANDLE);
201
202 ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
204 VK_SHADER_STAGE_COMPUTE_BIT,
205 0, sizeof(FFv1ShaderParams), pd);
206
207 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
208
209 return 0;
210}
211
212static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
213 AVFrame *enc_in, VkImageView *enc_in_views,
214 FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
216{
218 FFV1Context *f = &fv->ctx;
219 FFVulkanFunctions *vk = &fv->s.vkfn;
220
221 /* Update descriptors */
222 ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
223 enc_in, enc_in_views,
224 1, 1,
225 VK_IMAGE_LAYOUT_GENERAL,
226 VK_NULL_HANDLE);
227 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
228 1, 2, 0,
229 fltmap_buf,
230 0, fltmap_size*f->slice_count,
231 VK_FORMAT_UNDEFINED);
232
233 ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
234 ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
235 VK_SHADER_STAGE_COMPUTE_BIT,
236 0, sizeof(FFv1ShaderParams), pd);
237
238 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
239
240 return 0;
241}
242
244 AVFrame *enc_in, VkImageView *enc_in_views,
245 FFVkBuffer *units_buf, uint32_t units_size,
247{
249 FFV1Context *f = &fv->ctx;
250 FFVulkanFunctions *vk = &fv->s.vkfn;
251
252 /* Update descriptors */
253 ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
254 enc_in, enc_in_views,
255 1, 1,
256 VK_IMAGE_LAYOUT_GENERAL,
257 VK_NULL_HANDLE);
259 1, 2, 0,
260 units_buf,
261 0, units_size*f->slice_count,
262 VK_FORMAT_UNDEFINED);
263
264 ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
265 ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
266 VK_SHADER_STAGE_COMPUTE_BIT,
267 0, sizeof(FFv1ShaderParams), pd);
268
269 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
270
271 return 0;
272}
273
275 FFVkExecContext *exec,
276 AVFrame *pict)
277{
278 int err;
280 FFV1Context *f = &fv->ctx;
281 FFVulkanFunctions *vk = &fv->s.vkfn;
282
284
285 /* Slice data */
286 FFVkBuffer *slice_data_buf;
287 uint32_t plane_state_size;
288 uint32_t slice_state_size;
289 uint32_t slice_data_size;
290
291 /* Remap data */
292 FFVkBuffer *remap_data_buf = NULL;
293 uint32_t remap_data_size = 0;
294
295 /* Output data */
296 size_t maxsize;
297 FFVkBuffer *out_data_buf;
298 FFVkBuffer *compacted_buf;
299
300 int has_inter = avctx->gop_size > 1;
301 uint32_t context_count = f->context_count[f->context_model];
302
303 VkImageMemoryBarrier2 img_bar[37];
304 int nb_img_bar = 0;
305 VkBufferMemoryBarrier2 buf_bar[8];
306 int nb_buf_bar = 0;
307
308 /* Start recording */
309 err = ff_vk_exec_start(&fv->s, exec);
310 if (err < 0)
311 return err;
312
313 /* Frame state */
314 f->cur_enc_frame = pict;
315 if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
317 f->key_frame = fd->key_frame = 1;
318 f->gob_count++;
319 } else {
320 f->key_frame = fd->key_frame = 0;
321 }
322
323 f->slice_count = f->max_slice_count;
324
325 /* Allocate slice buffer data */
326 if (f->ac == AC_GOLOMB_RICE)
327 plane_state_size = 8;
328 else
329 plane_state_size = CONTEXT_SIZE;
330
331 plane_state_size *= context_count;
332 slice_state_size = plane_state_size*f->plane_count;
333
334 slice_data_size = 256; /* Overestimation for the SliceContext struct */
335 slice_state_size += slice_data_size;
336 slice_state_size = FFALIGN(slice_state_size, 8);
337
338 /* Allocate slice data buffer */
339 slice_data_buf = fv->keyframe_slice_data_ref ?
341 if (!slice_data_buf) {
343 &slice_data_buf,
344 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
345 NULL, slice_state_size*f->slice_count,
346 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
347
348 /* Only save it if we're going to use it again */
349 if (has_inter)
350 fv->keyframe_slice_data_ref = av_refstruct_ref(slice_data_buf);
351 }
352
353 if (f->remap_mode) {
354 if (fv->is_float32) {
355 /* Per slice: [units : 4*max_pixels*2 uints] + [bitmaps : 4*max_pixels uints]. */
356 remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
357 } else {
359 remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
360 }
361
363 &remap_data_buf,
364 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
365 NULL, remap_data_size*f->slice_count,
366 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
367 }
368
369 /* Output buffer size */
370 maxsize = ffv1_vk_buffer_size(avctx);
371 maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
372
373 /* Sparse per-slice slots: written by encode, read by gather. */
375 &fd->out_data_ref,
376 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
377 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
378 NULL, maxsize,
379 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
380 out_data_buf = fd->out_data_ref;
381
382 /* Contiguous output, read back by the CPU. */
385 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
387 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
388 fv->s.host_cached_flag));
389 compacted_buf = fd->compacted_data_ref;
390
391 /* Image views */
392 AVFrame *src = pict;
393 VkImageView src_views[AV_NUM_DATA_POINTERS];
394
395 AVFrame *tmp = NULL;
396 VkImageView tmp_views[AV_NUM_DATA_POINTERS];
397 if (fv->is_rgb) {
398 /* Create a temporaty frame */
400 if (!(tmp)) {
401 err = AVERROR(ENOMEM);
402 goto fail;
403 }
404
406 tmp, 0));
407 }
408
409 /* With everything allocated, setup push data */
410 FFv1ShaderParams pd = {
411 .slice_data = out_data_buf->address,
412
413 .img_size[0] = fv->s.frames->width,
414 .img_size[1] = fv->s.frames->height,
415
416 .plane_state_size = plane_state_size,
417 .key_frame = f->key_frame,
418 .crcref = f->crcref,
419 .micro_version = f->micro_version,
420
421 .sar[0] = pict->sample_aspect_ratio.num,
422 .sar[1] = pict->sample_aspect_ratio.den,
423 .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
424 !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
425
426 /* 16-byte aligned so the gather can use wide loads */
427 .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
428 .max_pixels_per_slice = fv->max_pixels_per_slice,
429 };
430
431 for (int i = 0; i < f->quant_table_count; i++) {
432 pd.context_count[i] = f->context_count[i];
433 pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
434 f->quant_tables[i][4][127];
435 }
436
437 /* For some reason the C FFv1 encoder/decoder treats these differently */
438 if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
439 avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
441 memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
442 else
443 ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
444
445 /* For float pixel formats we want the raw bit pattern, not a value
446 * already passed through fp16/fp32 conversion (which can flush
447 * denormals). Use a UINT view in that case. */
448 RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
449 f->remap_mode ? FF_VK_REP_UINT
451
454
455 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
456 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
457 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
458 if (fv->is_rgb)
459 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
460 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
461 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
462
463 /* Inter frames continue the state the previous frame wrote */
464 if (!f->key_frame)
466 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT);
467 fv->prev_sem = exec->sem;
468 fv->prev_sem_val = exec->sem_value;
469
470 if (fv->optimize_rct || f->remap_mode) {
471 /* Prepare the frame for reading */
472 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
473 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
474 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
475 VK_ACCESS_SHADER_READ_BIT,
476 VK_IMAGE_LAYOUT_GENERAL,
477 VK_QUEUE_FAMILY_IGNORED);
478
479 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
480 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
481 .pImageMemoryBarriers = img_bar,
482 .imageMemoryBarrierCount = nb_img_bar,
483 });
484 nb_img_bar = 0;
485 }
486
487 /* Run RCT search if needed */
488 if (fv->optimize_rct) {
489 RET(run_rct_search(avctx, exec, src, src_views,
490 slice_data_buf, slice_data_size, &pd));
491
492 /* Make sure the writes are visible to the setup shader */
493 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
494 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
495 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
496 0, slice_data_size*f->slice_count);
497 }
498
499 if (f->remap_mode) {
500 if (fv->is_float32) {
501 RET(run_sort32(avctx, exec, src, src_views,
502 remap_data_buf, remap_data_size, &pd));
503 } else {
504 RET(run_remap(avctx, exec, src, src_views,
505 remap_data_buf, remap_data_size, &pd));
506 }
507
508 /* Make sure the writes are visible to the setup shader */
509 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
510 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
511 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
512 0, remap_data_size*f->slice_count);
513 }
514
515 if (fv->optimize_rct || f->remap_mode) {
516 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
517 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
518 .pBufferMemoryBarriers = buf_bar,
519 .bufferMemoryBarrierCount = nb_buf_bar,
520 });
521 nb_buf_bar = 0;
522 }
523
524 /* Setup shader */
525 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
526 1, 0, 0,
527 slice_data_buf,
528 0, slice_data_size*f->slice_count,
529 VK_FORMAT_UNDEFINED);
530 /* The remap table is only read in remap mode, but must be a valid buffer */
532 &fv->setup, 1, 1, 0,
533 f->remap_mode ? remap_data_buf : slice_data_buf,
534 0, VK_WHOLE_SIZE,
535 VK_FORMAT_UNDEFINED);
536
537 ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
538 ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
539 VK_SHADER_STAGE_COMPUTE_BIT,
540 0, sizeof(FFv1ShaderParams), &pd);
541
542 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
543
544 /* Clean up temporary image if needed */
545 if (fv->is_rgb) {
546 AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
547 vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
548 vkf->access[0] = VK_ACCESS_2_NONE;
549
550 RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
551 tmp,
553
554 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
555 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
556 VK_PIPELINE_STAGE_2_CLEAR_BIT,
557 VK_ACCESS_2_TRANSFER_WRITE_BIT,
558 VK_IMAGE_LAYOUT_GENERAL,
559 VK_QUEUE_FAMILY_IGNORED);
560 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
561 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
562 .pImageMemoryBarriers = img_bar,
563 .imageMemoryBarrierCount = nb_img_bar,
564 });
565 nb_img_bar = 0;
566
567 vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
568 &((VkClearColorValue) { 0 }),
569 1, &((VkImageSubresourceRange) {
570 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
571 .levelCount = 1,
572 .layerCount = 1,
573 }));
574 }
575
576 /* Run reset shader */
577 if (f->key_frame || fv->force_pcm) {
578 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
579 1, 0, 0,
580 slice_data_buf,
581 0, slice_data_size*f->slice_count,
582 VK_FORMAT_UNDEFINED);
583 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
584 1, 1, 0,
585 slice_data_buf,
586 f->slice_count*256,
587 VK_WHOLE_SIZE,
588 VK_FORMAT_UNDEFINED);
589
590 ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
591 ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
592 VK_SHADER_STAGE_COMPUTE_BIT,
593 0, sizeof(FFv1ShaderParams), &pd);
594
595 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
596 f->plane_count);
597 }
598
599 /* Sync between reset and encode shaders */
600 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
601 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
602 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
603 0, slice_data_size*f->slice_count);
604
605 /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
606 * back into the remap buffer; the encode shader reads it. */
607 if (f->remap_mode)
608 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
609 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
610 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
611 0, remap_data_size*f->slice_count);
612 if (f->key_frame || fv->force_pcm)
613 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
614 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
615 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
616 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
617 else
618 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
619 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
620 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
621 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
622
623 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
624 fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
625 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
626 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
627 VK_ACCESS_SHADER_READ_BIT,
628 VK_IMAGE_LAYOUT_GENERAL,
629 VK_QUEUE_FAMILY_IGNORED);
630
631 if (fv->is_rgb)
632 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
633 VK_PIPELINE_STAGE_2_CLEAR_BIT,
634 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
635 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
636 VK_IMAGE_LAYOUT_GENERAL,
637 VK_QUEUE_FAMILY_IGNORED);
638
639 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
640 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
641 .pImageMemoryBarriers = img_bar,
642 .imageMemoryBarrierCount = nb_img_bar,
643 .pBufferMemoryBarriers = buf_bar,
644 .bufferMemoryBarrierCount = nb_buf_bar,
645 });
646 nb_img_bar = 0;
647 nb_buf_bar = 0;
648
649 /* Main encode shader */
650 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
651 1, 0, 0,
652 slice_data_buf,
653 0, slice_data_size*f->slice_count,
654 VK_FORMAT_UNDEFINED);
656 &fv->enc, 1, 1, 0,
657 &fv->results_buf,
658 fd->idx*(f->max_slice_count + 1)*sizeof(uint32_t),
659 f->slice_count*sizeof(uint32_t),
660 VK_FORMAT_UNDEFINED);
661 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
662 1, 2, 0,
663 slice_data_buf,
664 f->slice_count*256,
665 VK_WHOLE_SIZE,
666 VK_FORMAT_UNDEFINED);
667 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
668 src, src_views,
669 1, 3,
670 VK_IMAGE_LAYOUT_GENERAL,
671 VK_NULL_HANDLE);
672 if (fv->is_rgb)
673 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
674 tmp, tmp_views,
675 1, 4,
676 VK_IMAGE_LAYOUT_GENERAL,
677 VK_NULL_HANDLE);
678 if (f->remap_mode)
680 &fv->enc, 1, 5, 0,
681 remap_data_buf,
682 0, remap_data_size*f->slice_count,
683 VK_FORMAT_UNDEFINED);
684
685 /* Encode the slices that were largest in the previous frame first: they
686 * get the oldest waves, which have issue priority when several waves
687 * share a SIMD */
688 {
689 uint64_t order[MAX_SLICES];
690 size_t order_off = fd->idx*f->max_slice_count*sizeof(uint32_t);
691 uint32_t *dst = (uint32_t *)(fv->order_buf.mapped_mem + order_off);
692 for (int i = 0; i < f->slice_count; i++)
693 order[i] = (uint64_t)(fv->have_prev ? fv->prev_size[i] : 0) << 32 |
694 (UINT32_MAX - i);
695 qsort(order, f->slice_count, sizeof(*order), cmp_slice_order);
696 for (int i = 0; i < f->slice_count; i++)
697 dst[i] = UINT32_MAX - (uint32_t)order[i];
698 if (!(fv->order_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
699 VkMappedMemoryRange flush_data = {
700 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
701 .memory = fv->order_buf.mem,
702 .offset = 0,
703 .size = VK_WHOLE_SIZE,
704 };
705 vk->FlushMappedMemoryRanges(fv->s.hwctx->act_dev, 1, &flush_data);
706 }
707 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
708 1, 6, 0,
709 &fv->order_buf,
710 order_off, f->slice_count*sizeof(uint32_t),
711 VK_FORMAT_UNDEFINED);
712 }
713
714 ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
715 ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
716 VK_SHADER_STAGE_COMPUTE_BIT,
717 0, sizeof(FFv1ShaderParams), &pd);
718 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
719
720 /* Gather the per-slice slots into the packet buffer, in the same
721 * submission. */
722 RET(ff_vk_seg_gather(&fv->s, exec, &fv->gather,
723 &fv->results_buf, fd->idx*(f->max_slice_count + 1)*sizeof(uint32_t),
724 f->slice_count,
725 out_data_buf, (out_data_buf->size / f->slice_count) & ~(size_t)15,
726 compacted_buf, 0, 0));
727
728 /* Submit */
729 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &slice_data_buf);
730 if (remap_data_buf)
731 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &remap_data_buf);
732 err = ff_vk_exec_submit(&fv->s, exec);
733 if (err < 0) {
735 return err;
736 }
737
738 f->picture_number++;
739
741 return 0;
742
743fail:
744 ff_vk_exec_discard(&fv->s, exec);
746 av_refstruct_unref(&slice_data_buf);
747 av_refstruct_unref(&remap_data_buf);
748
749 return err;
750}
751
752/* Return the gathered-output buffer to its pool when the packet is freed. */
753static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
754{
755 av_refstruct_unref(&opaque);
756}
757
759 AVPacket *pkt)
760{
762 FFV1Context *f = &fv->ctx;
763 FFVulkanFunctions *vk = &fv->s.vkfn;
765
766 FFVkBuffer *compacted_buf = fd->compacted_data_ref;
767
768 /* Make sure the encode + gather submission is done */
769 ff_vk_exec_wait(&fv->s, exec);
770
771 /* Invalidate the slice sizes and the packed size if needed */
772 size_t res_off = fd->idx*(f->max_slice_count + 1)*sizeof(uint32_t);
773 size_t total_off = res_off + f->slice_count*sizeof(uint32_t);
774 if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
775 VkMappedMemoryRange invalidate_data = {
776 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
777 .memory = fv->results_buf.mem,
778 .offset = 0,
779 .size = VK_WHOLE_SIZE,
780 };
781 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
782 1, &invalidate_data);
783 }
784
785 /* Keep the slice sizes for the next frame's dispatch order */
786 memcpy(fv->prev_size, fv->results_buf.mapped_mem + res_off,
787 f->slice_count*sizeof(uint32_t));
788 fv->have_prev = 1;
789
790 pkt->size = AV_RN32(fv->results_buf.mapped_mem + total_off);
791 av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
792
793 /* Invalidate the gathered bitstream if needed */
794 if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
795 VkMappedMemoryRange invalidate_data = {
796 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
797 .memory = compacted_buf->mem,
798 .offset = 0,
799 .size = VK_WHOLE_SIZE,
800 };
801 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
802 1, &invalidate_data);
803 }
804
805 memset(compacted_buf->mapped_mem + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
806
807 /* Hand the gathered buffer to the packet with no copy: pkt->buf references
808 * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
809 pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
811 if (!pkt->buf) {
814 return AVERROR(ENOMEM);
815 }
816 fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
817 pkt->data = compacted_buf->mapped_mem;
818 pkt->flags |= AV_PKT_FLAG_KEY * fd->key_frame;
819
821
822 return 0;
823}
824
831
833{
835 ff_vk_encode_loop_flush(avctx, &fv->loop);
836 fv->ctx.picture_number = 0;
837}
838
839static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
840{
841 int err;
843 FFV1Context *f = &fv->ctx;
844 AVHWFramesContext *frames_ctx;
845 AVVulkanFramesContext *vk_frames;
846
849 return AVERROR(ENOMEM);
850
852 frames_ctx->format = AV_PIX_FMT_VULKAN;
853 frames_ctx->sw_format = sw_format;
854 frames_ctx->width = fv->s.frames->width;
855 frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
856
857 vk_frames = frames_ctx->hwctx;
858 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
859 vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
860 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
861 vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
862
864 if (err < 0) {
865 av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
866 av_get_pix_fmt_name(sw_format), av_err2str(err));
868 return err;
869 }
870
871 return 0;
872}
873
874static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
875{
876 int err;
878 FFVulkanShader *shd = &fv->rct_search;
879
880 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
881 (uint32_t []) { 32, 32, 1 }, 0);
882
884 VK_SHADER_STAGE_COMPUTE_BIT);
885
886 const FFVulkanDescriptorSetBinding desc_set_const[] = {
887 { /* rangecoder_buf */
888 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
889 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
890 },
891 };
892 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
893
894 const FFVulkanDescriptorSetBinding desc_set[] = {
895 { /* slice_data_buf */
896 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
897 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
898 },
899 { /* src */
900 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
901 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
903 },
904 };
905 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
906
907 RET(ff_vk_shader_link(&fv->s, shd,
910
911 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
912
913fail:
914 return err;
915}
916
917static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
918{
919 int err;
921 FFVulkanShader *shd = &fv->sort32;
922
923 uint32_t wg_x = FFMIN3(fv->max_pixels_per_slice, 1024,
924 fv->s.props.properties.limits.maxComputeWorkGroupSize[0]);
925 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
926 (uint32_t []) { wg_x, 1, 1 }, 0);
927
929 VK_SHADER_STAGE_COMPUTE_BIT);
930
931 const FFVulkanDescriptorSetBinding desc_set_const[] = {
932 { /* rangecoder_buf */
933 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
934 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
935 },
936 };
937 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
938
939 const FFVulkanDescriptorSetBinding desc_set[] = {
940 { /* slice_data_buf */
941 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
942 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
943 },
944 { /* src */
945 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
946 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
948 },
949 { /* units */
950 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
951 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
952 },
953 };
954 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
955
956 RET(ff_vk_shader_link(&fv->s, shd,
959
960 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
961
962fail:
963 return err;
964}
965
966static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
967{
968 int err;
970 FFVulkanShader *shd = &fv->remap;
971
972 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
973 (uint32_t []) { 32, 32, 1 }, 0);
974
976 VK_SHADER_STAGE_COMPUTE_BIT);
977
978 const FFVulkanDescriptorSetBinding desc_set_const[] = {
979 { /* rangecoder_buf */
980 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
981 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
982 },
983 };
984 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
985
986 const FFVulkanDescriptorSetBinding desc_set[] = {
987 { /* slice_data_buf */
988 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
989 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
990 },
991 { /* src */
992 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
993 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
995 },
996 { /* fltmap */
997 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
998 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
999 },
1000 };
1001 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
1002
1003 RET(ff_vk_shader_link(&fv->s, shd,
1006
1007 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1008
1009fail:
1010 return err;
1011}
1012
1013static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1014{
1015 int err;
1017 FFVulkanShader *shd = &fv->setup;
1018
1019 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1020 (uint32_t []) { 1, 1, 1 }, 0);
1021
1023 VK_SHADER_STAGE_COMPUTE_BIT);
1024
1025 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1026 { /* rangecoder_buf */
1027 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1028 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1029 },
1030 };
1031 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1032
1033 const FFVulkanDescriptorSetBinding desc_set[] = {
1034 { /* slice_data_buf */
1035 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1036 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1037 },
1038 { /* fltmap */
1039 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1040 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1041 },
1042 };
1043 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1044
1045 RET(ff_vk_shader_link(&fv->s, shd,
1048
1049 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1050
1051fail:
1052 return err;
1053}
1054
1055static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1056{
1057 int err;
1059 FFVulkanShader *shd = &fv->reset;
1060
1061 int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1062
1063 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1064 (uint32_t []) { wg_dim, 1, 1 }, 0);
1065
1067 VK_SHADER_STAGE_COMPUTE_BIT);
1068
1069 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1070 { /* rangecoder_buf */
1071 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1072 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1073 },
1074 };
1075 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1076
1077 const FFVulkanDescriptorSetBinding desc_set[] = {
1078 { /* slice_data_buf */
1079 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1080 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1081 },
1082 { /* slice_state_buf */
1083 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1084 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1085 },
1086 };
1087 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1088
1089 if (fv->ctx.ac == AC_GOLOMB_RICE)
1090 RET(ff_vk_shader_link(&fv->s, shd,
1093 else
1094 RET(ff_vk_shader_link(&fv->s, shd,
1097
1098 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1099
1100fail:
1101 return err;
1102}
1103
1104static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1105{
1106 int err;
1108 FFV1Context *f = &fv->ctx;
1109 FFVulkanShader *shd = &fv->enc;
1110
1111 uint32_t subgroup_size;
1112 uint32_t lanes = ff_ffv1_vk_rc_lanes(&fv->s, &subgroup_size);
1113 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1114 (uint32_t []) { fv->ctx.ac != AC_GOLOMB_RICE ? lanes : 1, 1, 1 },
1115 fv->ctx.ac != AC_GOLOMB_RICE ? subgroup_size : 0);
1116
1118 VK_SHADER_STAGE_COMPUTE_BIT);
1119
1120 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1121 { /* rangecoder_buf */
1122 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1123 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1124 },
1125 { /* quant_buf */
1126 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1127 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1128 },
1129 { /* crc_ieee_buf */
1130 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1131 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1132 },
1133 };
1134 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1135
1136 const FFVulkanDescriptorSetBinding desc_set[] = {
1137 { /* slice_data_buf */
1138 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1139 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1140 },
1141 { /* slice_results_buf */
1142 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1143 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1144 },
1145 { /* slice_state_buf */
1146 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1147 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1148 },
1149 { /* src */
1150 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1151 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1153 },
1154 { /* tmp */
1155 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1156 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1157 },
1158 { /* fltmap */
1159 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1160 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1161 },
1162 { /* slice_order */
1163 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1164 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1165 },
1166 };
1167 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 7, 0);
1168
1169 if (f->bayer) {
1170 if (fv->ctx.ac == AC_GOLOMB_RICE)
1171 ff_vk_shader_link(&fv->s, shd,
1174 else
1175 ff_vk_shader_link(&fv->s, shd,
1178 } else if (f->remap_mode) {
1179 if (fv->ctx.ac == AC_GOLOMB_RICE)
1180 ff_vk_shader_link(&fv->s, shd,
1183 else
1184 ff_vk_shader_link(&fv->s, shd,
1187 } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1188 if (fv->is_rgb)
1189 ff_vk_shader_link(&fv->s, shd,
1192 else
1193 ff_vk_shader_link(&fv->s, shd,
1196 } else {
1197 if (fv->is_rgb)
1198 ff_vk_shader_link(&fv->s, shd,
1201 else
1202 ff_vk_shader_link(&fv->s, shd,
1204 ff_ffv1_enc_comp_spv_len, "main");
1205 }
1206
1207 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1208
1209fail:
1210 return err;
1211}
1212
1214{
1215 int err;
1216 size_t maxsize;
1218 FFV1Context *f = &fv->ctx;
1219
1220 if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1221 return err;
1222
1223 if (f->ac == 1)
1224 f->ac = AC_RANGE_CUSTOM_TAB;
1225
1226 err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1227 if (err < 0)
1228 return err;
1229
1230 /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1231 * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1232 f->version = f->bayer ? 4 : 3;
1233
1234 err = ff_ffv1_encode_init(avctx);
1235 if (err < 0)
1236 return err;
1237
1238 /* Rice coding did not support high bit depths */
1239 if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1240 if (f->ac == AC_GOLOMB_RICE) {
1241 av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1242 "forcing range coder\n");
1243 f->ac = AC_RANGE_CUSTOM_TAB;
1244 }
1245 }
1246
1247 if (f->version < 4 && avctx->gop_size > 1) {
1248 av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1249 return AVERROR_INVALIDDATA;
1250 }
1251
1252 if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1253 av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1254 return AVERROR_INVALIDDATA;
1255 }
1256
1257 /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1258 if (f->version == 4)
1259 f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1260
1261 f->num_h_slices = fv->num_h_slices;
1262 f->num_v_slices = fv->num_v_slices;
1263
1264 if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1265 if (avctx->slices) {
1267 if (err < 0)
1268 return err;
1269 } else {
1270 f->num_h_slices = 32;
1271 f->num_v_slices = 32;
1272 }
1273 } else if (f->num_h_slices && f->num_v_slices <= 0) {
1274 f->num_v_slices = MAX_SLICES / f->num_h_slices;
1275 } else if (f->num_v_slices && f->num_h_slices <= 0) {
1276 f->num_h_slices = MAX_SLICES / f->num_v_slices;
1277 }
1278
1279 f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1280 f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1281
1282 if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1283 av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1284 "by the standard is %i\n",
1285 f->num_h_slices * f->num_v_slices, MAX_SLICES);
1286 return AVERROR_PATCHWELCOME;
1287 }
1288
1289 f->max_slice_count = f->num_h_slices * f->num_v_slices;
1290
1291 if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1292 return err;
1293
1294 if (f->version < 4) {
1295 if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1296 ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1297 av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1298 "dimensions is only supported in version 4 (-level 4)\n");
1299 return AVERROR_PATCHWELCOME;
1300 }
1301 }
1302
1303 if (fv->force_pcm) {
1304 if (f->version < 4) {
1305 av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1306 return AVERROR_INVALIDDATA;
1307 } else if (f->ac == AC_GOLOMB_RICE) {
1308 av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1309 return AVERROR_INVALIDDATA;
1310 }
1311 }
1312
1313 /* Init Vulkan */
1314 err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1315 if (err < 0)
1316 return err;
1317
1318 fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1319 if (!fv->qf) {
1320 av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1321 return err;
1322 }
1323
1324 maxsize = ffv1_vk_buffer_size(avctx);
1325 if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1326 av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1327 "than maximum device allocation (%"PRIu64"), clipping\n",
1328 maxsize, fv->s.props_11.maxMemoryAllocationSize);
1329 maxsize = fv->s.props_11.maxMemoryAllocationSize;
1330 }
1331
1332 av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1333 2*maxsize / (1024*1024),
1334 (fv->async_depth * 2*maxsize) / (1024*1024),
1335 fv->async_depth);
1336
1337 err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1338 fv->async_depth,
1339 0, 0, 0, NULL);
1340 if (err < 0)
1341 return err;
1342
1343 /* Detect the special RGB coding mode */
1344 fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1345 !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1346
1347 fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1349
1350 if (fv->is_float32) {
1351 /* Compute the worst-case slice geometry. With version >= 4 the slice
1352 * boundaries are computed via slice_coord() which rounds up, so any
1353 * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1354 * pixels. */
1355 uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1356 uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1357 /* Round up to next pow2 for bitonic sort */
1358 uint32_t n = 1;
1359 uint32_t pn = mw*mh;
1360 while (n < pn)
1361 n <<= 1;
1362 if (n < 2)
1363 n = 2;
1364 fv->max_pixels_per_slice = n;
1365 }
1366
1367 /* Init rct search shader */
1368 fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1369 !fv->force_pcm && fv->optimize_rct && !f->bayer;
1370
1371 /* Init shader specialization consts */
1372 SPEC_LIST_CREATE(sl, 20, 20*sizeof(uint32_t))
1373 SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1374 SPEC_LIST_ADD(sl, 1, 32, f->ec);
1375 ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1376 SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1377 SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1378 SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1379 SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1380
1381 if (f->ac != AC_GOLOMB_RICE) {
1382 const int16_t (*qt)[MAX_QUANT_TABLE_SIZE] = f->quant_tables[f->context_model];
1383 SPEC_LIST_ADD(sl, 19, 32, qt[3][127] || qt[4][127]);
1384 }
1385
1386 if (fv->optimize_rct) {
1387 err = init_rct_search_shader(avctx, sl);
1388 if (err < 0)
1389 return err;
1390 }
1391
1392 if (f->remap_mode) {
1393 if (fv->is_float32)
1394 err = init_sort32_shader(avctx, sl);
1395 else
1396 err = init_remap_shader(avctx, sl);
1397 if (err < 0)
1398 return err;
1399 }
1400
1401 /* Init setup shader */
1402 err = init_setup_shader(avctx, sl);
1403 if (err < 0)
1404 return err;
1405
1406 /* Init reset shader */
1407 err = init_reset_shader(avctx, sl);
1408 if (err < 0)
1409 return err;
1410
1411 if (fv->is_rgb)
1412 RET(init_indirect(avctx, fv->ctx.use32bit ?
1414
1415 /* Encode shader */
1416 err = init_encode_shader(avctx, sl);
1417 if (err < 0)
1418 return err;
1419
1420 /* Gather shader */
1421 err = ff_vk_seg_gather_init(&fv->s, &fv->exec_pool, &fv->gather);
1422 if (err < 0)
1423 return err;
1424
1425 /* Constant data */
1426 err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1427 if (err < 0)
1428 return err;
1429
1430 /* Update setup global descriptors */
1432 &fv->setup, 0, 0, 0,
1433 &fv->consts_buf,
1434 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1435 VK_FORMAT_UNDEFINED));
1436
1437 /* Update encode global descriptors */
1439 &fv->enc, 0, 0, 0,
1440 &fv->consts_buf,
1441 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1442 VK_FORMAT_UNDEFINED));
1444 &fv->enc, 0, 1, 0,
1445 &fv->consts_buf,
1446 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1449 sizeof(FFv1QuantBallot),
1450 VK_FORMAT_UNDEFINED));
1452 &fv->enc, 0, 2, 0,
1453 &fv->consts_buf,
1454 0, 256*sizeof(uint32_t),
1455 VK_FORMAT_UNDEFINED));
1456
1457 RET(ff_vk_encode_loop_init(&fv->s, &fv->exec_pool, &fv->loop,
1459
1460 /* Async data pool */
1462 fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1463 if (!fv->exec_ctx_info)
1464 return AVERROR(ENOMEM);
1465 for (int i = 0; i < fv->async_depth; i++) {
1468 }
1469
1470 /* Buffers */
1471 RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1472 fv->async_depth*(f->max_slice_count + 1)*sizeof(uint32_t),
1473 NULL, NULL,
1474 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1475 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1476 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1477 RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1478
1479 RET(ff_vk_create_buf(&fv->s, &fv->order_buf,
1480 fv->async_depth*f->max_slice_count*sizeof(uint32_t),
1481 NULL, NULL,
1482 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1483 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1484 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1485 RET(ff_vk_map_buffer(&fv->s, &fv->order_buf, NULL, 0));
1486
1487fail:
1488 return err;
1489}
1490
1492{
1494
1495 ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1496
1497 ff_vk_shader_free(&fv->s, &fv->enc);
1498 ff_vk_shader_free(&fv->s, &fv->gather);
1499 ff_vk_shader_free(&fv->s, &fv->reset);
1500 ff_vk_shader_free(&fv->s, &fv->setup);
1501 ff_vk_shader_free(&fv->s, &fv->remap);
1502 ff_vk_shader_free(&fv->s, &fv->sort32);
1503 ff_vk_shader_free(&fv->s, &fv->rct_search);
1504
1505 if (fv->exec_ctx_info) {
1506 for (int i = 0; i < fv->async_depth; i++) {
1510 }
1511 }
1513
1515
1518
1522
1523 ff_vk_free_buf(&fv->s, &fv->results_buf);
1524 ff_vk_free_buf(&fv->s, &fv->order_buf);
1525
1526 ff_vk_free_buf(&fv->s, &fv->consts_buf);
1527
1529 ff_vk_uninit(&fv->s);
1530
1531 return 0;
1532}
1533
1534#define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1535#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1537 { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1538 { .i64 = -1 }, -1, 2, VE },
1539 { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1540 { .i64 = 2 }, 0, 2, VE },
1541 { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1542 { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1543 { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1544 { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1545 { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1546 { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1547 { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1548 { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1549 { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1550 { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1551 { "default", NULL, 0, AV_OPT_TYPE_CONST,
1552 { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1553 { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1554 { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1555 { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1556 { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1557
1558 { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1559 { .i64 = -1 }, -1, MAX_SLICES, VE },
1560 { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1561 { .i64 = -1 }, -1, MAX_SLICES, VE },
1562
1563 { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1564 { .i64 = 0 }, 0, 1, VE },
1565
1566 { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1567 { .i64 = 1 }, 0, 1, VE },
1568
1569 { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1570 { .i64 = 2 }, 1, INT_MAX, VE },
1571
1572 { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1573 { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1574 { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1575 { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1576 { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1577 { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1578 { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1579 { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1580 { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1581 { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1582
1583 { NULL }
1584};
1585
1587 { "g", "1" },
1588 { NULL },
1589};
1590
1592 .class_name = "ffv1_vulkan",
1593 .item_name = av_default_item_name,
1595 .version = LIBAVUTIL_VERSION_INT,
1596};
1597
1599 HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1600 NULL,
1601};
1602
1604 .p.name = "ffv1_vulkan",
1605 CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1606 .p.type = AVMEDIA_TYPE_VIDEO,
1607 .p.id = AV_CODEC_ID_FFV1,
1608 .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1611 .flush = &vulkan_encode_ffv1_flush,
1612 .close = &vulkan_encode_ffv1_close,
1613 .p.priv_class = &vulkan_encode_ffv1_class,
1614 .p.capabilities = AV_CODEC_CAP_DELAY |
1619 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1620 .defaults = vulkan_encode_ffv1_defaults,
1622 .hw_configs = vulkan_encode_ffv1_hw_configs,
1623 .p.wrapper_name = "vulkan",
1624};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const FFCodec ff_ffv1_vulkan_encoder
#define VE
Definition amfenc_av1.c:30
static AVFormatContext * ctx
int32_t
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 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
#define MAX_SLICES
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition defs.h:62
static AVPacket * pkt
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
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 MAX_QUANT_TABLE_SIZE
Definition ffv1.h:48
#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
#define MAX_QUANT_TABLES
Definition ffv1.h:47
#define MAX_CONTEXT_INPUTS
Definition ffv1.h:50
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
uint32_t ff_ffv1_vk_rc_lanes(const FFVulkanContext *s, uint32_t *required)
Number of invocations that range code a slice together, as a single subgroup.
Definition ffv1_vulkan.c:85
void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, FFV1Context *f, VkSpecializationInfo *sl, enum AVPixelFormat sw_format)
Definition ffv1_vulkan.c:24
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:1878
av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt)
Definition ffv1enc.c:822
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, 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 cmp_slice_order(const void *a, const void *b)
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_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
static av_cold void vulkan_encode_ffv1_flush(AVCodecContext *avctx)
#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:480
#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
@ AV_CODEC_ID_FFV1
Definition codec_id.h:83
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#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:140
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:56
#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 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:702
#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:707
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_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
int a
#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 b
Definition input.c:43
#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:1715
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
Definition vulkan.c:2690
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition vulkan.c:2262
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
Definition vulkan.c:2521
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:335
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Definition vulkan.c:1204
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:399
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:649
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1631
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2779
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:2795
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition vulkan.c:1418
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition vulkan.c:2216
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:664
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition vulkan.c:2147
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2757
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2555
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:987
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2739
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:790
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition vulkan.c:2703
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:320
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition vulkan.c:783
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition vulkan.c:1444
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:767
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition vulkan.c:2425
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:885
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition vulkan.c:2729
void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore sem, uint64_t val, VkPipelineStageFlagBits2 stage)
Definition vulkan.c:829
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
#define FFMIN3(a, b, c)
Definition macros.h:50
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
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:121
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition refstruct.c:141
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
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:1376
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1472
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition avcodec.h:1021
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:479
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:723
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:576
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:184
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
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
int64_t picture_number
Definition ffv1.h:135
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
Frame loop for compute encoders.
uint32_t idx
Definition vulkan.h:129
void * opaque
Definition vulkan.h:154
uint64_t sem_value
Definition vulkan.h:147
VkSemaphore sem
Definition vulkan.h:146
VkCommandBuffer buf
Definition vulkan.h:142
FFVkExecContext * contexts
Definition vulkan.h:271
int pool_size
Definition vulkan.h:276
AVHWFramesContext * frames
Definition vulkan.h:344
AVVulkanDeviceContext * hwctx
Definition vulkan.h:340
VkMemoryPropertyFlagBits host_cached_flag
Definition vulkan.h:336
VkPhysicalDeviceVulkan11Properties props_11
Definition vulkan.h:299
FFVulkanFunctions vkfn
Definition vulkan.h:296
VkPhysicalDeviceProperties2 props
Definition vulkan.h:298
AVBufferRef * device_ref
Definition vulkan.h:338
uint16_t context_count[8]
Definition ffv1_vulkan.h:61
uint32_t extend_lookup[8]
Definition ffv1_vulkan.h:60
uint32_t prev_size[MAX_SLICES]
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:579
@ FF_VK_REP_UINT
Definition vulkan.h:446
@ FF_VK_REP_NATIVE
Definition vulkan.h:440
#define RET(x)
Definition vulkan.h:37
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition vulkan.h:55
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition vulkan.h:45
static int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)
Definition vulkan.h:646
int ff_vk_encode_loop_receive_packet(AVCodecContext *avctx, FFVkEncodeLoop *l, AVPacket *pkt)
Call from FFCodec.cb.receive_packet; the packet metadata is carried from the submitted frame to its p...
void ff_vk_encode_loop_uninit(FFVkEncodeLoop *l)
void ff_vk_encode_loop_flush(AVCodecContext *avctx, FFVkEncodeLoop *l)
Waits for and discards every frame in flight.
int ff_vk_encode_loop_init(FFVulkanContext *s, FFVkExecPool *pool, FFVkEncodeLoop *l, int(*submit_frame)(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *frame), int(*get_packet)(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt))
int ff_vk_seg_gather_init(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Packs fixed-stride segment slots back to back into a contiguous buffer.
int ff_vk_seg_gather(FFVulkanContext *s, FFVkExecContext *exec, FFVulkanShader *shd, FFVkBuffer *sizes, size_t sizes_offset, uint32_t nb_segs, FFVkBuffer *sparse, uint32_t slot_size, FFVkBuffer *compacted, size_t compacted_offset, VkDeviceAddress offset_addr)
Gathers nb_segs slots of slot_size bytes from sparse into compacted, with the segment sizes given as ...