FFmpeg
vulkan_encode.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/mem.h"
20 #include "libavutil/avassert.h"
21 #include "vulkan_encode.h"
22 #include "config.h"
23 
25 
27  HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
28  NULL,
29 };
30 
33 {
34  FFVulkanFunctions *vk = &ctx->s.vkfn;
35 
36  FFVulkanEncodePicture *vp = pic->priv;
37 
38  if (vp->in.view)
39  vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->in.view,
40  ctx->s.hwctx->alloc);
41 
42  if (!ctx->common.layered_dpb && vp->dpb.view)
43  vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->dpb.view,
44  ctx->s.hwctx->alloc);
45 
46  vp->in.view = VK_NULL_HANDLE;
47  vp->dpb.view = VK_NULL_HANDLE;
48 
49  ctx->slots[vp->dpb_slot.slotIndex] = NULL;
50 }
51 
53 {
54  FFVulkanContext *s = &ctx->s;
55  FFVulkanFunctions *vk = &s->vkfn;
56 
57  /* Wait on and free execution pool */
58  ff_vk_exec_pool_free(s, &ctx->enc_pool);
59 
60  /* Destroy the session params */
61  if (ctx->session_params)
62  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
63  ctx->session_params,
64  s->hwctx->alloc);
65 
66  /* Destroy the image views of any pictures still in the queue,
67  * as ff_hw_base_encode_close() only frees the picture structs */
68  for (FFHWBaseEncodePicture *pic = ctx->base.pic_start; pic; pic = pic->next)
70 
71  av_refstruct_pool_uninit(&ctx->buf_pool);
72 
74 
75  ff_vk_video_common_uninit(s, &ctx->common);
76 
77  ff_vk_uninit(s);
78 }
79 
81 {
82  int err;
84  FFVulkanEncodePicture *vp = pic->priv;
85 
86  AVFrame *f = pic->input_image;
87  AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
88  AVVulkanFramesContext *vkfc = hwfc->hwctx;
89  AVVkFrame *vkf = (AVVkFrame *)f->data[0];
90 
91  if (ctx->codec->picture_priv_data_size > 0) {
92  pic->codec_priv = av_mallocz(ctx->codec->picture_priv_data_size);
93  if (!pic->codec_priv)
94  return AVERROR(ENOMEM);
95  }
96 
97  /* Input image view */
98  err = ff_vk_create_view(&ctx->s, &ctx->common,
99  &vp->in.view, &vp->in.aspect,
100  vkf, vkfc->format[0], VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
101  if (err < 0)
102  return err;
103 
104  /* Reference view */
105  if (!ctx->common.layered_dpb) {
106  AVFrame *rf = pic->recon_image;
107  AVVkFrame *rvkf = (AVVkFrame *)rf->data[0];
108  err = ff_vk_create_view(&ctx->s, &ctx->common,
109  &vp->dpb.view, &vp->dpb.aspect,
110  rvkf, ctx->pic_format, VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
111  if (err < 0)
112  return err;
113  } else {
114  vp->dpb.view = ctx->common.layered_view;
115  vp->dpb.aspect = ctx->common.layered_aspect;
116  }
117 
118  return 0;
119 }
120 
122 {
124 
126 
127  return 0;
128 }
129 
131  VkVideoEncodeRateControlInfoKHR *rc_info,
132  VkVideoEncodeRateControlLayerInfoKHR *rc_layer /* Goes in ^ */)
133 {
135 
136  *rc_info = (VkVideoEncodeRateControlInfoKHR) {
137  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR,
138  .rateControlMode = ctx->opts.rc_mode,
139  };
140 
141  if (ctx->opts.rc_mode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
142  *rc_layer = (VkVideoEncodeRateControlLayerInfoKHR) {
143  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR,
144  .averageBitrate = avctx->bit_rate,
145  .maxBitrate = avctx->rc_max_rate ? avctx->rc_max_rate : avctx->bit_rate,
146  .frameRateNumerator = avctx->framerate.num,
147  .frameRateDenominator = avctx->framerate.den,
148  };
149  rc_info->layerCount++;
150  rc_info->pLayers = rc_layer;
151  }
152 
153  return ctx->codec->init_pic_rc(avctx, pic, rc_info, rc_layer);
154 }
155 
157  FFHWBaseEncodePicture *base_pic)
158 {
160  FFVulkanFunctions *vk = &ctx->s.vkfn;
161 
162  const size_t size_align = ctx->caps.minBitstreamBufferSizeAlignment;
163 
164  FFVulkanEncodePicture *vp = base_pic->priv;
165  AVFrame *src = (AVFrame *)base_pic->input_image;
166  AVVkFrame *vkf = (AVVkFrame *)src->data[0];
167 
168  int err, max_pkt_size;
169 
170  FFVkBuffer *sd_buf;
171 
172  int slot_index = -1;
173  FFVkExecContext *exec;
174  VkCommandBuffer cmd_buf;
175  VkImageMemoryBarrier2 img_bar[37];
176  int nb_img_bar = 0;
177 
178  /* Coding start/end */
179  VkVideoBeginCodingInfoKHR encode_start;
180  VkVideoEndCodingInfoKHR encode_end = {
181  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
182  };
183 
184  VkVideoEncodeRateControlLayerInfoKHR rc_layer;
185  VkVideoEncodeRateControlInfoKHR rc_info;
186  VkVideoEncodeQualityLevelInfoKHR q_info;
187  VkVideoCodingControlInfoKHR encode_ctrl;
188 
189  VkVideoReferenceSlotInfoKHR ref_slot[37];
190  VkVideoEncodeInfoKHR encode_info;
191 
192  /* Create packet data buffer */
193  max_pkt_size = FFALIGN(3 * ctx->base.surface_width * ctx->base.surface_height + (1 << 16),
194  ctx->caps.minBitstreamBufferSizeAlignment);
195 
196  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &vp->pkt_buf,
197  VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR,
198  &ctx->profile_list, max_pkt_size,
199  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
200  ctx->s.host_cached_flag);
201  if (err < 0)
202  return err;
203 
204  sd_buf = vp->pkt_buf;
205 
206  /* Setup rate control */
207  err = init_pic_rc(avctx, base_pic, &rc_info, &rc_layer);
208  if (err < 0)
209  return err;
210 
211  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
212  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
213  .pNext = &rc_info,
214  .qualityLevel = ctx->opts.quality,
215  };
216  encode_ctrl = (VkVideoCodingControlInfoKHR) {
217  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
218  .pNext = &q_info,
219  .flags = VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR |
220  VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR |
221  VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
222  };
223 
224  for (int i = 0; i < ctx->caps.maxDpbSlots; i++) {
225  if (ctx->slots[i] == NULL) {
226  slot_index = i;
227  ctx->slots[i] = base_pic;
228  break;
229  }
230  }
231  av_assert0(slot_index >= 0);
232 
233  /* Current picture's ref slot */
234  vp->dpb_res = (VkVideoPictureResourceInfoKHR) {
235  .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
236  .pNext = NULL,
237  .codedOffset = { 0 },
238  .codedExtent = (VkExtent2D){ avctx->width, avctx->height },
239  .baseArrayLayer = ctx->common.layered_dpb ? slot_index : 0,
240  .imageViewBinding = vp->dpb.view,
241  };
242 
243  vp->dpb_slot = (VkVideoReferenceSlotInfoKHR) {
244  .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
245  .pNext = NULL, // Set later
246  .slotIndex = slot_index,
247  .pPictureResource = &vp->dpb_res,
248  };
249 
250  encode_info = (VkVideoEncodeInfoKHR) {
251  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR,
252  .pNext = NULL, // Set later
253  .flags = 0x0,
254  .srcPictureResource = (VkVideoPictureResourceInfoKHR) {
255  .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
256  .pNext = NULL,
257  .codedOffset = { 0, 0 },
258  .codedExtent = (VkExtent2D){ base_pic->input_image->width,
259  base_pic->input_image->height },
260  .baseArrayLayer = 0,
261  .imageViewBinding = vp->in.view,
262  },
263  .pSetupReferenceSlot = &vp->dpb_slot,
264  .referenceSlotCount = 0,
265  .pReferenceSlots = ref_slot,
266  .dstBuffer = sd_buf->buf,
267  .dstBufferOffset = 0,
268  .dstBufferRange = sd_buf->size,
269  .precedingExternallyEncodedBytes = 0,
270  };
271 
272  for (int i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
273  for (int j = 0; j < base_pic->nb_refs[i]; j++) {
274  FFHWBaseEncodePicture *ref = base_pic->refs[i][j];
275  FFVulkanEncodePicture *rvp = ref->priv;
276  ref_slot[encode_info.referenceSlotCount++] = rvp->dpb_slot;
277  }
278  }
279 
280  /* Calling vkCmdBeginVideoCodingKHR requires to declare all references
281  * being enabled upfront, including the current frame's output ref. */
282  ref_slot[encode_info.referenceSlotCount] = vp->dpb_slot;
283  ref_slot[encode_info.referenceSlotCount].slotIndex = -1;
284 
285  /* Setup picture parameters */
286  err = ctx->codec->init_pic_params(avctx, base_pic,
287  &encode_info);
288  if (err < 0)
289  return err;
290 
291  encode_start = (VkVideoBeginCodingInfoKHR) {
292  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
293  .pNext = !base_pic->force_idr ? &rc_info : NULL,
294  .videoSession = ctx->common.session,
295  .videoSessionParameters = ctx->session_params,
296  .referenceSlotCount = encode_info.referenceSlotCount + 1,
297  .pReferenceSlots = ref_slot,
298  };
299 
300  /* Write header */
301  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
302  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
303  size_t data_size = encode_info.dstBufferRange;
304  err = ctx->codec->write_sequence_headers(avctx, base_pic, hdr_dst, &data_size);
305  if (err < 0)
306  goto fail;
307  encode_info.dstBufferOffset += data_size;
308  encode_info.dstBufferRange -= data_size;
309  }
310 
311  /* Write extra units */
312  if (ctx->codec->write_extra_headers) {
313  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
314  size_t data_size = encode_info.dstBufferRange;
315  err = ctx->codec->write_extra_headers(avctx, base_pic, hdr_dst, &data_size);
316  if (err < 0)
317  goto fail;
318  encode_info.dstBufferOffset += data_size;
319  encode_info.dstBufferRange -= data_size;
320  }
321 
322  /* Align buffer offset to the required value with filler units */
323  if (ctx->codec->write_filler) {
324  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
325  size_t data_size = encode_info.dstBufferRange;
326 
327  uint32_t offset = encode_info.dstBufferOffset;
328  size_t offset_align = ctx->caps.minBitstreamBufferOffsetAlignment;
329 
330  uint32_t filler_data = FFALIGN(offset, offset_align) - offset;
331 
332  if (filler_data) {
333  while (filler_data < ctx->codec->filler_header_size)
334  filler_data += offset_align;
335 
336  filler_data -= ctx->codec->filler_header_size;
337 
338  err = ctx->codec->write_filler(avctx, filler_data,
339  hdr_dst, &data_size);
340  if (err < 0)
341  goto fail;
342 
343  encode_info.dstBufferOffset += data_size;
344  encode_info.dstBufferRange -= data_size;
345  }
346  }
347 
348  vp->slices_offset = encode_info.dstBufferOffset;
349 
350  /* Align buffer size to the nearest lower alignment requirement. */
351  encode_info.dstBufferRange -= size_align;
352  encode_info.dstBufferRange = FFALIGN(encode_info.dstBufferRange,
353  size_align);
354 
355  /* Start command buffer recording */
356  exec = vp->exec = ff_vk_exec_get(&ctx->s, &ctx->enc_pool);
357  ff_vk_exec_start(&ctx->s, exec);
358  cmd_buf = exec->buf;
359 
360  /* Output packet buffer */
361  ff_vk_exec_add_dep_refstruct(&ctx->s, exec, vp->pkt_buf);
362 
363  /* Source image */
364  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, src,
365  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
366  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
367  if (err < 0)
368  goto fail;
369 
370  /* Source image layout conversion */
371  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
372  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
373  .pNext = NULL,
374  .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
375  .srcAccessMask = vkf->access[0],
376  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
377  .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR,
378  .oldLayout = vkf->layout[0],
379  .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
380  .srcQueueFamilyIndex = vkf->queue_family[0],
381  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
382  .image = vkf->img[0],
383  .subresourceRange = (VkImageSubresourceRange) {
384  .aspectMask = vp->in.aspect,
385  .layerCount = 1,
386  .levelCount = 1,
387  },
388  };
389  ff_vk_exec_update_frame(&ctx->s, exec, src,
390  &img_bar[nb_img_bar], &nb_img_bar);
391 
392  if (!ctx->common.layered_dpb) {
393  /* Source image's ref slot.
394  * No need to do a layout conversion, since the frames which are allocated
395  * with a DPB usage are automatically converted. */
396  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, base_pic->recon_image,
397  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
398  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
399  if (err < 0)
400  return err;
401 
402  /* All references */
403  for (int i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
404  for (int j = 0; j < base_pic->nb_refs[i]; j++) {
405  FFHWBaseEncodePicture *ref = base_pic->refs[i][j];
406  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref->recon_image,
407  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
408  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
409  if (err < 0)
410  return err;
411  }
412  }
413  } else {
414  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
415  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
416  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
417  if (err < 0)
418  return err;
419  }
420 
421  /* Change image layout */
422  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
423  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
424  .pImageMemoryBarriers = img_bar,
425  .imageMemoryBarrierCount = nb_img_bar,
426  });
427 
428  /* Start, use parameters */
429  vk->CmdBeginVideoCodingKHR(cmd_buf, &encode_start);
430 
431  /* Send control data */
432  if (!ctx->session_reset) {
433  vk->CmdControlVideoCodingKHR(cmd_buf, &encode_ctrl);
434  ctx->session_reset++;
435  }
436 
437  /* Encode */
438  vk->CmdBeginQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0, 0);
439  vk->CmdEncodeVideoKHR(cmd_buf, &encode_info);
440  vk->CmdEndQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0);
441 
442  /* End encoding */
443  vk->CmdEndVideoCodingKHR(cmd_buf, &encode_end);
444 
445  /* End recording and submit for execution */
446  err = ff_vk_exec_submit(&ctx->s, vp->exec);
447  if (err < 0)
448  goto fail;
449 
450  /* We don't need to keep the input image any longer, its already ref'd */
451  av_frame_free(&base_pic->input_image);
452 
453  return 0;
454 
455 fail:
456  return err;
457 }
458 
459 static void pkt_buf_free(void *opaque, uint8_t *data)
460 {
461  av_refstruct_unref(&opaque);
462 }
463 
465  FFHWBaseEncodePicture *base_pic)
466 {
468  FFVulkanEncodePicture *vp = base_pic->priv;
469 
470  av_assert0(base_pic->encode_issued);
471 
472  if (base_pic->encode_complete)
473  return;
474 
475  ff_vk_exec_wait(&ctx->s, vp->exec);
476  base_pic->encode_complete = 1;
477 }
478 
480  FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
481 {
482  VkResult ret;
483  FFVulkanEncodePicture *vp = base_pic->priv;
485  FFHWBaseEncodeContext *base_ctx = &ctx->base;
486  AVPacket *pkt_ptr = pkt;
487 
488  FFVkBuffer *sd_buf = vp->pkt_buf;
489  uint32_t *query_data;
490 
491  vulkan_encode_wait(avctx, base_pic);
492 
493  ret = ff_vk_exec_get_query(&ctx->s, vp->exec, (void **)&query_data, 0);
494  if (ret == VK_NOT_READY) {
495  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
496  ff_vk_ret2str(ret));
497  return AVERROR(EINVAL);
498  }
499 
500  if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
501  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
502  ff_vk_ret2str(ret));
503  return AVERROR_EXTERNAL;
504  }
505 
506  if (query_data[2] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR) {
507  av_log(avctx, AV_LOG_ERROR, "Unable to encode: %u\n", query_data[2]);
508  return AVERROR_EXTERNAL;
509  }
510 
511  /* Invalidate buffer if needed */
512  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
513  FFVulkanFunctions *vk = &ctx->s.vkfn;
514  VkMappedMemoryRange invalidate_buf;
515 
516  int offs = vp->slices_offset;
517  /* If the non-coherent alignment is greater than the bitstream buffer
518  * offset's alignment, and the offs value is not aligned already,
519  * align it to the previous alignment point. */
520  if (ctx->s.props.properties.limits.nonCoherentAtomSize >
521  ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
522  (FFALIGN(offs, ctx->s.props.properties.limits.nonCoherentAtomSize) != offs)) {
523  offs -= ctx->s.props.properties.limits.nonCoherentAtomSize;
524  offs = FFALIGN(FFMAX(offs, 0), ctx->s.props.properties.limits.nonCoherentAtomSize);
525  }
526 
527  invalidate_buf = (VkMappedMemoryRange) {
528  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
529  .memory = sd_buf->mem,
530  .offset = offs,
531  .size = VK_WHOLE_SIZE,
532  };
533 
534  vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &invalidate_buf);
535  }
536 
537  if (vp->non_independent_frame) {
538  av_assert0(!ctx->prev_buf_ref);
539  size_t prev_buf_size = vp->slices_offset + query_data[0] + query_data[1];
540  ctx->prev_buf_ref = vp->pkt_buf;
541  ctx->prev_buf_size = prev_buf_size;
542  vp->pkt_buf = NULL;
543 
544  if (vp->tail_size) {
545  if (base_ctx->tail_pkt->size)
546  return AVERROR_BUG;
547 
548  ret = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, vp->tail_size, 0);
549  if (ret < 0)
550  return ret;
551 
552  memcpy(base_ctx->tail_pkt->data, vp->tail_data, vp->tail_size);
553  pkt_ptr = base_ctx->tail_pkt;
554  }
555  } else {
556  if (ctx->prev_buf_ref) {
557  FFVkBuffer *prev_sd_buf = ctx->prev_buf_ref;
558  size_t prev_size = ctx->prev_buf_size;
559  size_t size = (vp->slices_offset + query_data[0] + query_data[1]);
560 
561  ret = ff_get_encode_buffer(avctx, pkt, prev_size + size, 0);
562  if (ret < 0)
563  return ret;
564 
565  memcpy(pkt->data, prev_sd_buf->mapped_mem, prev_size);
566  memcpy(pkt->data + prev_size, sd_buf->mapped_mem, size);
567 
568  av_refstruct_unref(&ctx->prev_buf_ref);
570  } else {
571  pkt->data = sd_buf->mapped_mem;
572  pkt->size = vp->slices_offset + /* base offset */
573  query_data[0] /* secondary offset */ +
574  query_data[1] /* size */;
575 
576  /* Hand the pooled buffer to the packet with no copy */
577  pkt->buf = av_buffer_create(sd_buf->mapped_mem, pkt->size,
578  pkt_buf_free, vp->pkt_buf, 0);
579  if (!pkt->buf)
580  return AVERROR(ENOMEM);
581  vp->pkt_buf = NULL; /* ownership passed to pkt->buf */
582  }
583  }
584 
585  av_log(avctx, AV_LOG_DEBUG, "Frame %"PRId64"/%"PRId64 " encoded\n",
586  base_pic->display_order, base_pic->encode_order);
587 
588  return ff_hw_base_encode_set_output_property(&ctx->base, avctx,
589  base_pic, pkt_ptr,
590  ctx->codec->flags & VK_ENC_FLAG_NO_DELAY);
591 }
592 
594  .priv_size = sizeof(FFVulkanEncodePicture),
596  .issue = &vulkan_encode_issue,
598  .free = &vulkan_encode_free,
599 };
600 
602 {
604  return ff_hw_base_encode_receive_packet(&ctx->base, avctx, pkt);
605 }
606 
608 {
609  int err;
610  FFHWBaseEncodeContext *base_ctx = &ctx->base;
611  AVVulkanFramesContext *hwfc;
612 
613  enum AVPixelFormat dpb_format;
614  err = ff_hw_base_get_recon_format(base_ctx, NULL, &dpb_format);
615  if (err < 0)
616  return err;
617 
618  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
619  if (!base_ctx->recon_frames_ref)
620  return AVERROR(ENOMEM);
621 
622  base_ctx->recon_frames = (AVHWFramesContext *)base_ctx->recon_frames_ref->data;
623  hwfc = (AVVulkanFramesContext *)base_ctx->recon_frames->hwctx;
624 
626  base_ctx->recon_frames->sw_format = dpb_format;
627  base_ctx->recon_frames->width = avctx->width;
628  base_ctx->recon_frames->height = avctx->height;
629 
630  hwfc->format[0] = ctx->pic_format;
631  hwfc->create_pnext = &ctx->profile_list;
632  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
633  hwfc->usage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
634 
635  if (ctx->common.layered_dpb)
636  hwfc->nb_layers = ctx->caps.maxDpbSlots;
637 
638  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
639  if (err < 0) {
640  av_log(avctx, AV_LOG_ERROR, "Failed to initialise DPB frame context: %s\n",
641  av_err2str(err));
642  return err;
643  }
644 
645  if (ctx->common.layered_dpb) {
646  ctx->common.layered_frame = av_frame_alloc();
647  if (!ctx->common.layered_frame)
648  return AVERROR(ENOMEM);
649 
650  err = av_hwframe_get_buffer(base_ctx->recon_frames_ref,
651  ctx->common.layered_frame, 0);
652  if (err < 0)
653  return AVERROR(ENOMEM);
654 
655  err = ff_vk_create_view(&ctx->s, &ctx->common,
656  &ctx->common.layered_view,
657  &ctx->common.layered_aspect,
658  (AVVkFrame *)ctx->common.layered_frame->data[0],
659  hwfc->format[0], VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
660  if (err < 0)
661  return err;
662 
663  av_buffer_unref(&base_ctx->recon_frames_ref);
664  }
665 
666  return 0;
667 }
668 
670 {
671  if (ctx->opts.qp) {
672  ctx->explicit_qp = ctx->opts.qp;
673  } else if (avctx->global_quality > 0) {
674  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
675  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
676  else
677  ctx->explicit_qp = avctx->global_quality;
678  }
679 
680  if (ctx->opts.rc_mode == FF_VK_RC_MODE_AUTO) {
681  if (ctx->explicit_qp >= 0) {
682  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
683  } else if (avctx->global_quality > 0) {
684  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
685  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
686  else
687  ctx->explicit_qp = avctx->global_quality;
688  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
689  } else if (avctx->bit_rate) {
690  if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR)
691  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
692  else if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR)
693  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
694  else
695  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
696  } else {
697  ctx->explicit_qp = 18;
698  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
699  av_log(avctx, AV_LOG_WARNING, "No rate control settings specified, using fixed QP = %i\n",
700  ctx->explicit_qp);
701  }
702  } else if (ctx->opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR &&
703  !avctx->bit_rate) {
704  av_log(avctx, AV_LOG_WARNING, "No bitrate specified!\n");
705  return AVERROR(EINVAL);
706  }
707 
708  if (ctx->opts.rc_mode && !(ctx->enc_caps.rateControlModes & ctx->opts.rc_mode)) {
709  static const char *rc_modes[] = {
710  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR] = "default",
711  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR] = "cqp",
712  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR] = "cbr",
713  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR] = "vbr",
714  };
715  av_log(avctx, AV_LOG_ERROR, "Unsupported rate control mode %s, supported are:\n",
716  rc_modes[FFMIN(FF_ARRAY_ELEMS(rc_modes), ctx->opts.rc_mode)]);
717  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[0]);
718  for (int i = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
719  i <= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR; i <<= 1) {
720  if (!(ctx->enc_caps.rateControlModes & i))
721  continue;
722  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[i]);
723  }
724  return AVERROR(ENOTSUP);
725  }
726 
727  return 0;
728 }
729 
732 {
733  int err;
734 
735  /* Write extradata if needed */
736  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
737  uint8_t data[4096];
738  size_t data_len = sizeof(data);
739 
740  err = ctx->codec->write_sequence_headers(avctx, NULL, data, &data_len);
741  if (err < 0) {
742  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
743  "for extradata: %d.\n", err);
744  return err;
745  } else {
746  avctx->extradata_size = data_len;
747  avctx->extradata = av_mallocz(avctx->extradata_size +
749  if (!avctx->extradata) {
750  err = AVERROR(ENOMEM);
751  return err;
752  }
753  memcpy(avctx->extradata, data, avctx->extradata_size);
754  }
755  }
756 
757  return 0;
758 }
759 
761  const FFVulkanEncodeDescriptor *vk_desc,
762  const FFVulkanCodec *codec,
763  void *codec_caps, void *quality_pnext)
764 {
765  int i, err;
766  VkResult ret;
767  FFVulkanFunctions *vk = &ctx->s.vkfn;
768  FFVulkanContext *s = &ctx->s;
769  FFHWBaseEncodeContext *base_ctx = &ctx->base;
770 
771  const AVPixFmtDescriptor *desc;
772 
773  VkVideoFormatPropertiesKHR *ret_info;
774  uint32_t nb_out_fmts = 0;
775  const uint32_t feedback_flags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
776  VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
777 
778  VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
779 
780  VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
781 
782  VkVideoSessionCreateInfoKHR session_create = {
783  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
784  };
785  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
786  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
787  .pNext = &ctx->profile_list,
788  };
789 
790  if (!avctx->hw_frames_ctx) {
791  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
792  "required to associate the encoding device.\n");
793  return AVERROR(EINVAL);
794  }
795 
796  ctx->base.op = &vulkan_base_encode_ops;
797  ctx->codec = codec;
798 
799  s->frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
800  s->frames = (AVHWFramesContext *)s->frames_ref->data;
801  s->hwfc = s->frames->hwctx;
802 
803  s->device = (AVHWDeviceContext *)s->frames->device_ref->data;
804  s->hwctx = s->device->hwctx;
805 
807  if (!desc)
808  return AVERROR(EINVAL);
809 
810  s->extensions = ff_vk_extensions_to_mask(s->hwctx->enabled_dev_extensions,
811  s->hwctx->nb_enabled_dev_extensions);
812 
813  if (!(s->extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE)) {
814  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
815  VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
816  return AVERROR(ENOSYS);
817  } else if (!(s->extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1)) {
818  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
819  VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME);
820  return AVERROR(ENOSYS);
821  } else if (!(s->extensions & vk_desc->encode_extension)) {
822  av_log(avctx, AV_LOG_ERROR, "Device does not support encoding %s!\n",
823  avcodec_get_name(avctx->codec_id));
824  return AVERROR(ENOSYS);
825  }
826 
827  /* Load functions */
828  err = ff_vk_load_functions(s->device, vk, s->extensions, 1, 1);
829  if (err < 0)
830  return err;
831 
832  /* Create queue context */
833  ctx->qf_enc = ff_vk_qf_find(s, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, vk_desc->encode_op);
834  if (!ctx->qf_enc) {
835  av_log(avctx, AV_LOG_ERROR, "Encoding of %s is not supported by this device\n",
836  avcodec_get_name(avctx->codec_id));
837  return err;
838  }
839 
840  /* Load all properties */
841  err = ff_vk_load_props(s);
842  if (err < 0)
843  return err;
844 
845  /* Set tuning */
846  ctx->usage_info = (VkVideoEncodeUsageInfoKHR) {
847  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR,
848  .videoUsageHints = ctx->opts.usage,
849  .videoContentHints = ctx->opts.content,
850  .tuningMode = ctx->opts.tune,
851  };
852 
853  /* Load up the profile now, needed for caps and to create a query pool */
854  ctx->profile.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
855  ctx->profile.pNext = &ctx->usage_info;
856  ctx->profile.videoCodecOperation = vk_desc->encode_op;
857  ctx->profile.chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
858  ctx->profile.lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
859  ctx->profile.chromaBitDepth = ctx->profile.lumaBitDepth;
860 
861  /* Setup a profile */
862  err = codec->init_profile(avctx, &ctx->profile, &ctx->usage_info);
863  if (err < 0)
864  return err;
865 
866  ctx->profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
867  ctx->profile_list.profileCount = 1;
868  ctx->profile_list.pProfiles = &ctx->profile;
869 
870  /* Get the capabilities of the encoder for the given profile */
871  ctx->enc_caps.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR;
872  ctx->enc_caps.pNext = codec_caps;
873  ctx->caps.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
874  ctx->caps.pNext = &ctx->enc_caps;
875 
876  ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
877  &ctx->profile,
878  &ctx->caps);
879  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
880  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
881  "%s profile \"%s\" not supported!\n",
882  avcodec_get_name(avctx->codec_id),
883  avcodec_profile_name(avctx->codec_id, avctx->profile));
884  return AVERROR(EINVAL);
885  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
886  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
887  "format (%s) not supported!\n",
889  return AVERROR(EINVAL);
890  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
891  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
892  return AVERROR(EINVAL);
893  } else if (ret != VK_SUCCESS) {
894  return AVERROR_EXTERNAL;
895  }
896 
897  if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) !=
898  feedback_flags) {
899  av_log(avctx, AV_LOG_ERROR,
900  "Driver does not support required encode feedback flags "
901  "(BUFFER_OFFSET and BYTES_WRITTEN).\n");
902  return AVERROR(ENOTSUP);
903  }
904 
905  err = init_rc(avctx, ctx);
906  if (err < 0)
907  return err;
908 
909  /* Create command and query pool */
910  query_create = (VkQueryPoolVideoEncodeFeedbackCreateInfoKHR) {
911  .sType = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR,
912  .pNext = &ctx->profile,
913  .encodeFeedbackFlags = feedback_flags,
914  };
915  err = ff_vk_exec_pool_init(s, ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
916  1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
917  &query_create);
918  if (err < 0)
919  return err;
920 
921  if (ctx->opts.quality > ctx->enc_caps.maxQualityLevels) {
922  av_log(avctx, AV_LOG_ERROR, "Invalid quality level %i: allowed range is "
923  "0 to %i\n",
924  ctx->opts.quality, ctx->enc_caps.maxQualityLevels);
925  return AVERROR(EINVAL);
926  }
927 
928  /* Get quality properties for the profile and quality level */
929  quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
930  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
931  .pVideoProfile = &ctx->profile,
932  .qualityLevel = ctx->opts.quality,
933  };
934  ctx->quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
935  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
936  .pNext = quality_pnext,
937  };
938  ret = vk->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(s->hwctx->phys_dev,
939  &quality_info,
940  &ctx->quality_props);
941  if (ret != VK_SUCCESS)
942  return AVERROR_EXTERNAL;
943 
944  /* Printout informative properties */
945  av_log(avctx, AV_LOG_VERBOSE, "Encoder capabilities for %s profile \"%s\":\n",
946  avcodec_get_name(avctx->codec_id),
947  avcodec_profile_name(avctx->codec_id, avctx->profile));
948  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
949  ctx->caps.minCodedExtent.width, ctx->caps.maxCodedExtent.width);
950  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
951  ctx->caps.minCodedExtent.height, ctx->caps.maxCodedExtent.height);
952  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
953  ctx->caps.pictureAccessGranularity.width);
954  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
955  ctx->caps.pictureAccessGranularity.height);
956  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
957  ctx->caps.minBitstreamBufferOffsetAlignment);
958  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
959  ctx->caps.minBitstreamBufferSizeAlignment);
960  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
961  ctx->caps.maxDpbSlots);
962  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
963  ctx->caps.maxActiveReferencePictures);
964  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
965  CODEC_VER(ctx->caps.stdHeaderVersion.specVersion),
966  CODEC_VER(vk_desc->ext_props.specVersion));
967  av_log(avctx, AV_LOG_VERBOSE, " Encoder max quality: %i\n",
968  ctx->enc_caps.maxQualityLevels);
969  av_log(avctx, AV_LOG_VERBOSE, " Encoder image width alignment: %i\n",
970  ctx->enc_caps.encodeInputPictureGranularity.width);
971  av_log(avctx, AV_LOG_VERBOSE, " Encoder image height alignment: %i\n",
972  ctx->enc_caps.encodeInputPictureGranularity.height);
973  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
974  ctx->caps.flags ? "" :
975  " none",
976  ctx->caps.flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
977  " protected" : "",
978  ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
979  " separate_references" : "");
980 
981  /* Setup width/height alignment */
982  base_ctx->surface_width = avctx->coded_width =
983  FFALIGN(avctx->width, ctx->enc_caps.encodeInputPictureGranularity.width);
984  base_ctx->surface_height = avctx->coded_height =
985  FFALIGN(avctx->height, ctx->enc_caps.encodeInputPictureGranularity.height);
986 
987  /* Setup slice width/height */
988  base_ctx->slice_block_width = ctx->enc_caps.encodeInputPictureGranularity.width;
989  base_ctx->slice_block_height = ctx->enc_caps.encodeInputPictureGranularity.height;
990 
991  /* Check if encoding is possible with the given parameters */
992  if (avctx->coded_width < ctx->caps.minCodedExtent.width ||
993  avctx->coded_height < ctx->caps.minCodedExtent.height ||
994  avctx->coded_width > ctx->caps.maxCodedExtent.width ||
995  avctx->coded_height > ctx->caps.maxCodedExtent.height) {
996  av_log(avctx, AV_LOG_ERROR, "Input of %ix%i too large for encoder limits: %ix%i max\n",
997  avctx->coded_width, avctx->coded_height,
998  ctx->caps.minCodedExtent.width, ctx->caps.minCodedExtent.height);
999  return AVERROR(EINVAL);
1000  }
1001 
1002  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
1003 
1004  ctx->common.layered_dpb = !(ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
1005 
1006  /* Get the supported image formats */
1007  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
1008  &fmt_info,
1009  &nb_out_fmts, NULL);
1010  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1011  (!nb_out_fmts && ret == VK_SUCCESS)) {
1012  return AVERROR(EINVAL);
1013  } else if (ret != VK_SUCCESS) {
1014  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1015  ff_vk_ret2str(ret));
1016  return AVERROR_EXTERNAL;
1017  }
1018 
1019  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1020  if (!ret_info)
1021  return AVERROR(ENOMEM);
1022 
1023  for (int i = 0; i < nb_out_fmts; i++)
1024  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1025 
1026  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
1027  &fmt_info,
1028  &nb_out_fmts, ret_info);
1029  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1030  (!nb_out_fmts && ret == VK_SUCCESS)) {
1031  av_free(ret_info);
1032  return AVERROR(EINVAL);
1033  } else if (ret != VK_SUCCESS) {
1034  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1035  ff_vk_ret2str(ret));
1036  av_free(ret_info);
1037  return AVERROR_EXTERNAL;
1038  }
1039 
1040  av_log(avctx, AV_LOG_VERBOSE, "Supported input formats:\n");
1041  for (i = 0; i < nb_out_fmts; i++)
1042  av_log(avctx, AV_LOG_VERBOSE, " %i: %i\n", i, ret_info[i].format);
1043 
1044  for (i = 0; i < nb_out_fmts; i++) {
1045  if (ff_vk_pix_fmt_from_vkfmt(ret_info[i].format) == s->frames->sw_format) {
1046  ctx->pic_format = ret_info[i].format;
1047  break;
1048  }
1049  }
1050 
1051  av_free(ret_info);
1052 
1053  if (i == nb_out_fmts) {
1054  av_log(avctx, AV_LOG_ERROR, "Pixel format %s of input frames not supported!\n",
1055  av_get_pix_fmt_name(s->frames->sw_format));
1056  return AVERROR(EINVAL);
1057  }
1058 
1059  /* Create session */
1060  session_create.pVideoProfile = &ctx->profile;
1061  session_create.flags = 0x0;
1062  session_create.queueFamilyIndex = ctx->qf_enc->idx;
1063  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1064  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1065  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1066  session_create.pictureFormat = ctx->pic_format;
1067  session_create.referencePictureFormat = session_create.pictureFormat;
1068  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1069 
1070  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1071  if (err < 0)
1072  return err;
1073 
1074  err = ff_hw_base_encode_init(avctx, &ctx->base);
1075  if (err < 0)
1076  return err;
1077 
1078  err = vulkan_encode_create_dpb(avctx, ctx);
1079  if (err < 0)
1080  return err;
1081 
1082  base_ctx->async_encode = 1;
1083  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
1084  sizeof(FFVulkanEncodePicture *), 0);
1085  if (!base_ctx->encode_fifo)
1086  return AVERROR(ENOMEM);
1087 
1088  return 0;
1089 }
1090 
1092  void *codec_params_pnext)
1093 {
1094  VkResult ret;
1095  FFVulkanFunctions *vk = &ctx->s.vkfn;
1096  FFVulkanContext *s = &ctx->s;
1097 
1098  VkVideoEncodeQualityLevelInfoKHR q_info;
1099  VkVideoSessionParametersCreateInfoKHR session_params_create;
1100 
1101  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
1102  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
1103  .pNext = codec_params_pnext,
1104  .qualityLevel = ctx->opts.quality,
1105  };
1106  session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1107  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1108  .pNext = &q_info,
1109  .videoSession = ctx->common.session,
1110  .videoSessionParametersTemplate = VK_NULL_HANDLE,
1111  };
1112 
1113  /* Create session parameters */
1114  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1115  s->hwctx->alloc, &ctx->session_params);
1116  if (ret != VK_SUCCESS) {
1117  av_log(avctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1118  ff_vk_ret2str(ret));
1119  return AVERROR_EXTERNAL;
1120  }
1121 
1122  return 0;
1123 }
vulkan_loader.h
vulkan_encode_init
static int vulkan_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vulkan_encode.c:80
ff_vk_load_props
int ff_vk_load_props(FFVulkanContext *s)
Loads props/mprops/driver_props.
Definition: vulkan.c:150
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
FFHWBaseEncodeContext::recon_frames_ref
AVBufferRef * recon_frames_ref
Definition: hw_base_encode.h:156
FFVulkanEncodeDescriptor::encode_op
VkVideoCodecOperationFlagBitsKHR encode_op
Definition: vulkan_encode.h:34
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
FFVulkanEncodeDescriptor::encode_extension
FFVulkanExtensions encode_extension
Definition: vulkan_encode.h:33
FFVulkanEncodePicture::view
VkImageView view
Definition: vulkan_encode.h:45
ff_vulkan_encode_hw_configs
const AVCodecHWConfigInternal *const ff_vulkan_encode_hw_configs[]
Paperwork.
Definition: vulkan_encode.c:26
FFHWBaseEncodePicture::priv
void * priv
Definition: hw_base_encode.h:63
FFHWBaseEncodePicture::codec_priv
void * codec_priv
Definition: hw_base_encode.h:65
ff_vk_exec_add_dep_refstruct
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition: vulkan.c:687
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3460
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ff_vk_exec_pool_init
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition: vulkan.c:357
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
FFVulkanEncodePicture::in
struct FFVulkanEncodePicture::@355 in
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:213
ff_vk_exec_get_query
VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e, void **data, VkQueryResultFlagBits flags)
Performs nb_queries queries and returns their results and statuses.
Definition: vulkan.c:543
av_cold
#define av_cold
Definition: attributes.h:119
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
vulkan_encode_free
static int vulkan_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vulkan_encode.c:121
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
ff_vk_exec_update_frame
void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar)
Definition: vulkan.c:837
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
ff_vk_depth_from_av_depth
VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
Get Vulkan's bit depth from an [8:12] integer.
Definition: vulkan_video.c:128
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
AVFrame::width
int width
Definition: frame.h:544
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
AVPacket::data
uint8_t * data
Definition: packet.h:603
FFVulkanEncodePicture::tail_data
char tail_data[16]
Definition: vulkan_encode.h:62
AVVulkanFramesContext::create_pnext
void * create_pnext
Extension data for image creation.
Definition: hwcontext_vulkan.h:202
ff_hw_base_encode_init
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:781
ff_vulkan_write_global_header
av_cold int ff_vulkan_write_global_header(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Write out the extradata in case its needed.
Definition: vulkan_encode.c:730
data
const char data[16]
Definition: mxf.c:149
FFHWBaseEncodePicture::recon_image
AVFrame * recon_image
Definition: hw_base_encode.h:84
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_vk_exec_get
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
Definition: vulkan.c:571
FFHWBaseEncodeContext::slice_block_width
int slice_block_width
Definition: hw_base_encode.h:144
ff_vk_uninit
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition: vulkan.c:2638
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
avcodec_profile_name
const char * avcodec_profile_name(enum AVCodecID codec_id, int profile)
Return a name for the specified profile, if available.
Definition: utils.c:446
FFVulkanEncodeDescriptor
Definition: vulkan_encode.h:31
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
FFHWBaseEncodeContext::slice_block_height
int slice_block_height
Definition: hw_base_encode.h:145
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
ff_vk_exec_add_dep_frame
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition: vulkan.c:777
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:493
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:95
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:318
FFHWBaseEncodeContext
Definition: hw_base_encode.h:122
ff_vk_subsampling_from_av_desc
VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
Get Vulkan's chroma subsampling from a pixfmt descriptor.
Definition: vulkan_video.c:115
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:563
FFHWBaseEncodePicture::type
int type
Definition: hw_base_encode.h:78
ff_hw_base_encode_close
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:814
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:171
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
FFHWBaseEncodePicture::input_image
AVFrame * input_image
Definition: hw_base_encode.h:83
ff_vk_ret2str
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
Definition: vulkan.c:41
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
avassert.h
ff_hw_base_get_recon_format
int ff_hw_base_get_recon_format(FFHWBaseEncodeContext *ctx, const void *hwconfig, enum AVPixelFormat *fmt)
Definition: hw_base_encode.c:723
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
FFVulkanEncodePicture::non_independent_frame
int non_independent_frame
Definition: vulkan_encode.h:61
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
FFVulkanEncodeDescriptor::ext_props
VkExtensionProperties ext_props
Definition: vulkan_encode.h:36
FFHWBaseEncodeContext::tail_pkt
AVPacket * tail_pkt
Tail data of a pic, now only used for av1 repeat frame header.
Definition: hw_base_encode.h:224
ff_vk_video_common_init
av_cold int ff_vk_video_common_init(AVCodecContext *avctx, FFVulkanContext *s, FFVkVideoCommon *common, VkVideoSessionCreateInfoKHR *session_create)
Initialize video session, allocating and binding necessary memory.
Definition: vulkan_video.c:365
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1235
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1484
ff_vk_load_functions
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
Definition: vulkan_loader.h:134
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:590
FFHWBaseEncodeContext::async_encode
int async_encode
Definition: hw_base_encode.h:216
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
FFVulkanEncodePicture::slices_offset
int slices_offset
Definition: vulkan_encode.h:59
FFVulkanEncodePicture::aspect
VkImageAspectFlags aspect
Definition: vulkan_encode.h:46
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1288
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:310
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
FFVkExecContext::query_idx
int query_idx
Definition: vulkan.h:153
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
ff_vk_get_pooled_buffer
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition: vulkan.c:1256
fail
#define fail
Definition: test.h:478
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:586
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
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
ff_vk_video_common_uninit
av_cold void ff_vk_video_common_uninit(FFVulkanContext *s, FFVkVideoCommon *common)
Free video session and required resources.
Definition: vulkan_video.c:337
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:70
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
FFHWEncodePictureOperation
Definition: hw_base_encode.h:109
AVVulkanFramesContext::format
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
Definition: hwcontext_vulkan.h:232
FFVkBuffer::size
size_t size
Definition: vulkan.h:98
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:191
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:103
FFVulkanContext
Definition: vulkan.h:290
VK_ENC_FLAG_NO_DELAY
#define VK_ENC_FLAG_NO_DELAY
Definition: vulkan_encode.h:101
FFVulkanEncodePicture::tail_size
size_t tail_size
Definition: vulkan_encode.h:63
encode_end
static av_cold int encode_end(AVCodecContext *avctx)
Definition: huffyuvenc.c:978
FFHWBaseEncodePicture::force_idr
int force_idr
Definition: hw_base_encode.h:73
av_buffer_create
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
FFVulkanEncodeContext
Definition: vulkan_encode.h:169
ff_hw_base_encode_set_output_property
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
Definition: hw_base_encode.c:519
init_pic_rc
static int init_pic_rc(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, VkVideoEncodeRateControlInfoKHR *rc_info, VkVideoEncodeRateControlLayerInfoKHR *rc_layer)
Definition: vulkan_encode.c:130
FFHWEncodePictureOperation::priv_size
size_t priv_size
Definition: hw_base_encode.h:111
FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
Definition: vulkan_functions.h:61
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
init_rc
static av_cold int init_rc(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Definition: vulkan_encode.c:669
AVPacket::size
int size
Definition: packet.h:604
AVVkFrame
Definition: hwcontext_vulkan.h:261
FFHWBaseEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: hw_base_encode.h:97
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
size
int size
Definition: twinvq_data.h:10344
ff_hw_base_encode_receive_packet
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
Definition: hw_base_encode.c:558
AVCodecHWConfigInternal
Definition: hwconfig.h:25
FFVkBuffer::flags
VkMemoryPropertyFlagBits flags
Definition: vulkan.h:97
FFHWBaseEncodePicture::encode_order
int64_t encode_order
Definition: hw_base_encode.h:70
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FFVkExecContext
Definition: vulkan.h:128
av_refstruct_unref
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
FFVulkanEncodePicture::pkt_buf
FFVkBuffer * pkt_buf
Definition: vulkan_encode.h:58
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:100
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:421
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:599
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:526
ff_vulkan_encode_receive_packet
int ff_vulkan_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Encode.
Definition: vulkan_encode.c:601
s
uint8_t s
Definition: llvidencdsp.c:39
MAX_REFERENCE_LIST_NUM
#define MAX_REFERENCE_LIST_NUM
Definition: hw_base_encode.h:30
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FFVulkanEncodePicture::exec
FFVkExecContext * exec
Definition: vulkan_encode.h:57
FFVkBuffer::mem
VkDeviceMemory mem
Definition: vulkan.h:96
FFHWBaseEncodePicture::refs
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: hw_base_encode.h:98
vulkan_encode.h
vulkan_encode_issue
static int vulkan_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vulkan_encode.c:156
vulkan_encode_create_dpb
static int vulkan_encode_create_dpb(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Definition: vulkan_encode.c:607
AVCodecContext::height
int height
Definition: avcodec.h:604
vulkan_encode_free_pic
static void vulkan_encode_free_pic(FFVulkanEncodeContext *ctx, FFHWBaseEncodePicture *pic)
Definition: vulkan_encode.c:31
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1471
CODEC_VER
#define CODEC_VER(ver)
Definition: vulkan_video.h:30
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
ret
ret
Definition: filter_design.txt:187
ff_vk_create_view
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common, VkImageView *view, VkImageAspectFlags *aspect, AVVkFrame *src, VkFormat vkf, VkImageUsageFlags usage)
Creates image views for video frames.
Definition: vulkan_video.c:291
FFHWBaseEncodePicture
Definition: hw_base_encode.h:61
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
FFHWBaseEncodeContext::device_ref
AVBufferRef * device_ref
Definition: hw_base_encode.h:148
FFHWBaseEncodeContext::encode_fifo
AVFifo * encode_fifo
Definition: hw_base_encode.h:219
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
ff_vk_qf_find
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition: vulkan.c:297
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:139
pkt_buf_free
static void pkt_buf_free(void *opaque, uint8_t *data)
Definition: vulkan_encode.c:459
FFHWBaseEncodeContext::surface_height
int surface_height
Definition: hw_base_encode.h:141
FFHWBaseEncodeContext::async_depth
int async_depth
Definition: hw_base_encode.h:221
AVCodecContext
main external API structure.
Definition: avcodec.h:443
AVFrame::height
int height
Definition: frame.h:544
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:105
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1636
ff_vulkan_encode_init
av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext *ctx, const FFVulkanEncodeDescriptor *vk_desc, const FFVulkanCodec *codec, void *codec_caps, void *quality_pnext)
Initialize encoder.
Definition: vulkan_encode.c:760
vulkan_base_encode_ops
static const FFHWEncodePictureOperation vulkan_base_encode_ops
Definition: vulkan_encode.c:593
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
FFVulkanEncodePicture::dpb
struct FFVulkanEncodePicture::@356 dpb
vulkan_encode_output
static int vulkan_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
Definition: vulkan_encode.c:479
FFHWBaseEncodeContext::surface_width
int surface_width
Definition: hw_base_encode.h:140
AVVulkanFramesContext::tiling
VkImageTiling tiling
Controls the tiling of allocated frames.
Definition: hwcontext_vulkan.h:180
FF_VK_RC_MODE_AUTO
#define FF_VK_RC_MODE_AUTO
Definition: vulkan_encode.h:166
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
desc
const char * desc
Definition: libsvtav1.c:83
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:237
FFVulkanCodec::init_profile
int(* init_profile)(AVCodecContext *avctx, VkVideoProfileInfoKHR *profile, void *pnext)
Initialize codec-specific structs in a Vulkan profile.
Definition: vulkan_encode.h:116
FFHWBaseEncodePicture::encode_complete
int encode_complete
Definition: hw_base_encode.h:81
mem.h
ff_vulkan_encode_uninit
av_cold void ff_vulkan_encode_uninit(FFVulkanEncodeContext *ctx)
Uninitialize encoder.
Definition: vulkan_encode.c:52
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
FFVkBuffer
Definition: vulkan.h:94
FFVulkanCodec
Definition: vulkan_encode.h:94
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
FFHWBaseEncodeContext::recon_frames
AVHWFramesContext * recon_frames
Definition: hw_base_encode.h:157
ff_vk_exec_submit
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:881
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
ff_vk_extensions_to_mask
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
Definition: vulkan_loader.h:36
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_vk_pix_fmt_from_vkfmt
enum AVPixelFormat ff_vk_pix_fmt_from_vkfmt(VkFormat vkf)
Get pixfmt from a Vulkan format.
Definition: vulkan_video.c:99
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
FFHWBaseEncodePicture::encode_issued
int encode_issued
Definition: hw_base_encode.h:80
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:226
FFHWBaseEncodePicture::display_order
int64_t display_order
Definition: hw_base_encode.h:69
FFVulkanEncodePicture::dpb_slot
VkVideoReferenceSlotInfoKHR dpb_slot
Definition: vulkan_encode.h:42
av_hwframe_get_buffer
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
FFVulkanFunctions
Definition: vulkan_functions.h:276
ff_vulkan_encode_create_session_params
int ff_vulkan_encode_create_session_params(AVCodecContext *avctx, FFVulkanEncodeContext *ctx, void *codec_params_pnext)
Create session parameters.
Definition: vulkan_encode.c:1091
FFVulkanEncodePicture
Definition: vulkan_encode.h:39
FFVulkanEncodePicture::dpb_res
VkVideoPictureResourceInfoKHR dpb_res
Definition: vulkan_encode.h:41
src
#define src
Definition: vp8dsp.c:248
vulkan_encode_wait
static void vulkan_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vulkan_encode.c:464
av_get_pix_fmt_name
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