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_buffer_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 = (FFVkBuffer *)vp->pkt_buf->data;
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  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->pkt_buf, 1, 1);
362  if (err < 0)
363  goto fail;
364 
365  /* Source image */
366  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, src,
367  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
368  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
369  if (err < 0)
370  goto fail;
371 
372  /* Source image layout conversion */
373  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
374  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
375  .pNext = NULL,
376  .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
377  .srcAccessMask = vkf->access[0],
378  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
379  .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR,
380  .oldLayout = vkf->layout[0],
381  .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
382  .srcQueueFamilyIndex = vkf->queue_family[0],
383  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
384  .image = vkf->img[0],
385  .subresourceRange = (VkImageSubresourceRange) {
386  .aspectMask = vp->in.aspect,
387  .layerCount = 1,
388  .levelCount = 1,
389  },
390  };
391  ff_vk_exec_update_frame(&ctx->s, exec, src,
392  &img_bar[nb_img_bar], &nb_img_bar);
393 
394  if (!ctx->common.layered_dpb) {
395  /* Source image's ref slot.
396  * No need to do a layout conversion, since the frames which are allocated
397  * with a DPB usage are automatically converted. */
398  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, base_pic->recon_image,
399  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
400  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
401  if (err < 0)
402  return err;
403 
404  /* All references */
405  for (int i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
406  for (int j = 0; j < base_pic->nb_refs[i]; j++) {
407  FFHWBaseEncodePicture *ref = base_pic->refs[i][j];
408  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref->recon_image,
409  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
410  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
411  if (err < 0)
412  return err;
413  }
414  }
415  } else {
416  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
417  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
418  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
419  if (err < 0)
420  return err;
421  }
422 
423  /* Change image layout */
424  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
425  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
426  .pImageMemoryBarriers = img_bar,
427  .imageMemoryBarrierCount = nb_img_bar,
428  });
429 
430  /* Start, use parameters */
431  vk->CmdBeginVideoCodingKHR(cmd_buf, &encode_start);
432 
433  /* Send control data */
434  if (!ctx->session_reset) {
435  vk->CmdControlVideoCodingKHR(cmd_buf, &encode_ctrl);
436  ctx->session_reset++;
437  }
438 
439  /* Encode */
440  vk->CmdBeginQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0, 0);
441  vk->CmdEncodeVideoKHR(cmd_buf, &encode_info);
442  vk->CmdEndQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0);
443 
444  /* End encoding */
445  vk->CmdEndVideoCodingKHR(cmd_buf, &encode_end);
446 
447  /* End recording and submit for execution */
448  err = ff_vk_exec_submit(&ctx->s, vp->exec);
449  if (err < 0)
450  goto fail;
451 
452  /* We don't need to keep the input image any longer, its already ref'd */
453  av_frame_free(&base_pic->input_image);
454 
455  return 0;
456 
457 fail:
458  return err;
459 }
460 
462  FFHWBaseEncodePicture *base_pic)
463 {
465  FFVulkanEncodePicture *vp = base_pic->priv;
466 
467  av_assert0(base_pic->encode_issued);
468 
469  if (base_pic->encode_complete)
470  return;
471 
472  ff_vk_exec_wait(&ctx->s, vp->exec);
473  base_pic->encode_complete = 1;
474 }
475 
477  FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
478 {
479  VkResult ret;
480  FFVulkanEncodePicture *vp = base_pic->priv;
482  FFHWBaseEncodeContext *base_ctx = &ctx->base;
483  AVPacket *pkt_ptr = pkt;
484 
485  FFVkBuffer *sd_buf = (FFVkBuffer *)vp->pkt_buf->data;
486  uint32_t *query_data;
487 
488  vulkan_encode_wait(avctx, base_pic);
489 
490  ret = ff_vk_exec_get_query(&ctx->s, vp->exec, (void **)&query_data, 0);
491  if (ret == VK_NOT_READY) {
492  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
493  ff_vk_ret2str(ret));
494  return AVERROR(EINVAL);
495  }
496 
497  if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
498  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
499  ff_vk_ret2str(ret));
500  return AVERROR_EXTERNAL;
501  }
502 
503  if (query_data[2] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR) {
504  av_log(avctx, AV_LOG_ERROR, "Unable to encode: %u\n", query_data[2]);
505  return AVERROR_EXTERNAL;
506  }
507 
508  /* Invalidate buffer if needed */
509  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
510  FFVulkanFunctions *vk = &ctx->s.vkfn;
511  VkMappedMemoryRange invalidate_buf;
512 
513  int offs = vp->slices_offset;
514  /* If the non-coherent alignment is greater than the bitstream buffer
515  * offset's alignment, and the offs value is not aligned already,
516  * align it to the previous alignment point. */
517  if (ctx->s.props.properties.limits.nonCoherentAtomSize >
518  ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
519  (FFALIGN(offs, ctx->s.props.properties.limits.nonCoherentAtomSize) != offs)) {
520  offs -= ctx->s.props.properties.limits.nonCoherentAtomSize;
521  offs = FFALIGN(FFMAX(offs, 0), ctx->s.props.properties.limits.nonCoherentAtomSize);
522  }
523 
524  invalidate_buf = (VkMappedMemoryRange) {
525  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
526  .memory = sd_buf->mem,
527  .offset = offs,
528  .size = VK_WHOLE_SIZE,
529  };
530 
531  vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &invalidate_buf);
532  }
533 
534  if (vp->non_independent_frame) {
535  av_assert0(!ctx->prev_buf_ref);
536  size_t prev_buf_size = vp->slices_offset + query_data[0] + query_data[1];
537  ctx->prev_buf_ref = vp->pkt_buf;
538  ctx->prev_buf_size = prev_buf_size;
539  vp->pkt_buf = NULL;
540 
541  if (vp->tail_size) {
542  if (base_ctx->tail_pkt->size)
543  return AVERROR_BUG;
544 
545  ret = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, vp->tail_size, 0);
546  if (ret < 0)
547  return ret;
548 
549  memcpy(base_ctx->tail_pkt->data, vp->tail_data, vp->tail_size);
550  pkt_ptr = base_ctx->tail_pkt;
551  }
552  } else {
553  if (ctx->prev_buf_ref) {
554  FFVkBuffer *prev_sd_buf = (FFVkBuffer *)ctx->prev_buf_ref->data;
555  size_t prev_size = ctx->prev_buf_size;
556  size_t size = (vp->slices_offset + query_data[0] + query_data[1]);
557 
558  ret = ff_get_encode_buffer(avctx, pkt, prev_size + size, 0);
559  if (ret < 0)
560  return ret;
561 
562  memcpy(pkt->data, prev_sd_buf->mapped_mem, prev_size);
563  memcpy(pkt->data + prev_size, sd_buf->mapped_mem, size);
564 
565  av_buffer_unref(&ctx->prev_buf_ref);
566  av_buffer_unref(&vp->pkt_buf);
567  } else {
568  pkt->data = sd_buf->mapped_mem;
569  pkt->size = vp->slices_offset + /* base offset */
570  query_data[0] /* secondary offset */ +
571  query_data[1] /* size */;
572 
573  /* Move reference */
574  pkt->buf = vp->pkt_buf;
575  vp->pkt_buf = NULL;
576  }
577  }
578 
579  av_log(avctx, AV_LOG_DEBUG, "Frame %"PRId64"/%"PRId64 " encoded\n",
580  base_pic->display_order, base_pic->encode_order);
581 
582  return ff_hw_base_encode_set_output_property(&ctx->base, avctx,
583  base_pic, pkt_ptr,
584  ctx->codec->flags & VK_ENC_FLAG_NO_DELAY);
585 }
586 
588  .priv_size = sizeof(FFVulkanEncodePicture),
590  .issue = &vulkan_encode_issue,
592  .free = &vulkan_encode_free,
593 };
594 
596 {
598  return ff_hw_base_encode_receive_packet(&ctx->base, avctx, pkt);
599 }
600 
602 {
603  int err;
604  FFHWBaseEncodeContext *base_ctx = &ctx->base;
605  AVVulkanFramesContext *hwfc;
606 
607  enum AVPixelFormat dpb_format;
608  err = ff_hw_base_get_recon_format(base_ctx, NULL, &dpb_format);
609  if (err < 0)
610  return err;
611 
612  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
613  if (!base_ctx->recon_frames_ref)
614  return AVERROR(ENOMEM);
615 
616  base_ctx->recon_frames = (AVHWFramesContext *)base_ctx->recon_frames_ref->data;
617  hwfc = (AVVulkanFramesContext *)base_ctx->recon_frames->hwctx;
618 
620  base_ctx->recon_frames->sw_format = dpb_format;
621  base_ctx->recon_frames->width = avctx->width;
622  base_ctx->recon_frames->height = avctx->height;
623 
624  hwfc->format[0] = ctx->pic_format;
625  hwfc->create_pnext = &ctx->profile_list;
626  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
627  hwfc->usage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
628 
629  if (ctx->common.layered_dpb)
630  hwfc->nb_layers = ctx->caps.maxDpbSlots;
631 
632  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
633  if (err < 0) {
634  av_log(avctx, AV_LOG_ERROR, "Failed to initialise DPB frame context: %s\n",
635  av_err2str(err));
636  return err;
637  }
638 
639  if (ctx->common.layered_dpb) {
640  ctx->common.layered_frame = av_frame_alloc();
641  if (!ctx->common.layered_frame)
642  return AVERROR(ENOMEM);
643 
644  err = av_hwframe_get_buffer(base_ctx->recon_frames_ref,
645  ctx->common.layered_frame, 0);
646  if (err < 0)
647  return AVERROR(ENOMEM);
648 
649  err = ff_vk_create_view(&ctx->s, &ctx->common,
650  &ctx->common.layered_view,
651  &ctx->common.layered_aspect,
652  (AVVkFrame *)ctx->common.layered_frame->data[0],
653  hwfc->format[0], VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
654  if (err < 0)
655  return err;
656 
657  av_buffer_unref(&base_ctx->recon_frames_ref);
658  }
659 
660  return 0;
661 }
662 
664 {
665  if (ctx->opts.qp) {
666  ctx->explicit_qp = ctx->opts.qp;
667  } else if (avctx->global_quality > 0) {
668  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
669  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
670  else
671  ctx->explicit_qp = avctx->global_quality;
672  }
673 
674  if (ctx->opts.rc_mode == FF_VK_RC_MODE_AUTO) {
675  if (ctx->explicit_qp >= 0) {
676  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
677  } else if (avctx->global_quality > 0) {
678  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
679  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
680  else
681  ctx->explicit_qp = avctx->global_quality;
682  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
683  } else if (avctx->bit_rate) {
684  if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR)
685  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
686  else if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR)
687  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
688  else
689  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
690  } else {
691  ctx->explicit_qp = 18;
692  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
693  av_log(avctx, AV_LOG_WARNING, "No rate control settings specified, using fixed QP = %i\n",
694  ctx->explicit_qp);
695  }
696  } else if (ctx->opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR &&
697  !avctx->bit_rate) {
698  av_log(avctx, AV_LOG_WARNING, "No bitrate specified!\n");
699  return AVERROR(EINVAL);
700  }
701 
702  if (ctx->opts.rc_mode && !(ctx->enc_caps.rateControlModes & ctx->opts.rc_mode)) {
703  static const char *rc_modes[] = {
704  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR] = "default",
705  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR] = "cqp",
706  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR] = "cbr",
707  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR] = "vbr",
708  };
709  av_log(avctx, AV_LOG_ERROR, "Unsupported rate control mode %s, supported are:\n",
710  rc_modes[FFMIN(FF_ARRAY_ELEMS(rc_modes), ctx->opts.rc_mode)]);
711  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[0]);
712  for (int i = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
713  i <= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR; i <<= 1) {
714  if (!(ctx->enc_caps.rateControlModes & i))
715  continue;
716  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[i]);
717  }
718  return AVERROR(ENOTSUP);
719  }
720 
721  return 0;
722 }
723 
726 {
727  int err;
728 
729  /* Write extradata if needed */
730  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
731  uint8_t data[4096];
732  size_t data_len = sizeof(data);
733 
734  err = ctx->codec->write_sequence_headers(avctx, NULL, data, &data_len);
735  if (err < 0) {
736  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
737  "for extradata: %d.\n", err);
738  return err;
739  } else {
740  avctx->extradata_size = data_len;
741  avctx->extradata = av_mallocz(avctx->extradata_size +
743  if (!avctx->extradata) {
744  err = AVERROR(ENOMEM);
745  return err;
746  }
747  memcpy(avctx->extradata, data, avctx->extradata_size);
748  }
749  }
750 
751  return 0;
752 }
753 
755  const FFVulkanEncodeDescriptor *vk_desc,
756  const FFVulkanCodec *codec,
757  void *codec_caps, void *quality_pnext)
758 {
759  int i, err;
760  VkResult ret;
761  FFVulkanFunctions *vk = &ctx->s.vkfn;
762  FFVulkanContext *s = &ctx->s;
763  FFHWBaseEncodeContext *base_ctx = &ctx->base;
764 
765  const AVPixFmtDescriptor *desc;
766 
767  VkVideoFormatPropertiesKHR *ret_info;
768  uint32_t nb_out_fmts = 0;
769  const uint32_t feedback_flags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
770  VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
771 
772  VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
773 
774  VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
775 
776  VkVideoSessionCreateInfoKHR session_create = {
777  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
778  };
779  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
780  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
781  .pNext = &ctx->profile_list,
782  };
783 
784  if (!avctx->hw_frames_ctx) {
785  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
786  "required to associate the encoding device.\n");
787  return AVERROR(EINVAL);
788  }
789 
790  ctx->base.op = &vulkan_base_encode_ops;
791  ctx->codec = codec;
792 
793  s->frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
794  s->frames = (AVHWFramesContext *)s->frames_ref->data;
795  s->hwfc = s->frames->hwctx;
796 
797  s->device = (AVHWDeviceContext *)s->frames->device_ref->data;
798  s->hwctx = s->device->hwctx;
799 
801  if (!desc)
802  return AVERROR(EINVAL);
803 
804  s->extensions = ff_vk_extensions_to_mask(s->hwctx->enabled_dev_extensions,
805  s->hwctx->nb_enabled_dev_extensions);
806 
807  if (!(s->extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE)) {
808  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
809  VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
810  return AVERROR(ENOSYS);
811  } else if (!(s->extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1)) {
812  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
813  VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME);
814  return AVERROR(ENOSYS);
815  } else if (!(s->extensions & vk_desc->encode_extension)) {
816  av_log(avctx, AV_LOG_ERROR, "Device does not support encoding %s!\n",
817  avcodec_get_name(avctx->codec_id));
818  return AVERROR(ENOSYS);
819  }
820 
821  /* Load functions */
822  err = ff_vk_load_functions(s->device, vk, s->extensions, 1, 1);
823  if (err < 0)
824  return err;
825 
826  /* Create queue context */
827  ctx->qf_enc = ff_vk_qf_find(s, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, vk_desc->encode_op);
828  if (!ctx->qf_enc) {
829  av_log(avctx, AV_LOG_ERROR, "Encoding of %s is not supported by this device\n",
830  avcodec_get_name(avctx->codec_id));
831  return err;
832  }
833 
834  /* Load all properties */
835  err = ff_vk_load_props(s);
836  if (err < 0)
837  return err;
838 
839  /* Set tuning */
840  ctx->usage_info = (VkVideoEncodeUsageInfoKHR) {
841  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR,
842  .videoUsageHints = ctx->opts.usage,
843  .videoContentHints = ctx->opts.content,
844  .tuningMode = ctx->opts.tune,
845  };
846 
847  /* Load up the profile now, needed for caps and to create a query pool */
848  ctx->profile.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
849  ctx->profile.pNext = &ctx->usage_info;
850  ctx->profile.videoCodecOperation = vk_desc->encode_op;
851  ctx->profile.chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
852  ctx->profile.lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
853  ctx->profile.chromaBitDepth = ctx->profile.lumaBitDepth;
854 
855  /* Setup a profile */
856  err = codec->init_profile(avctx, &ctx->profile, &ctx->usage_info);
857  if (err < 0)
858  return err;
859 
860  ctx->profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
861  ctx->profile_list.profileCount = 1;
862  ctx->profile_list.pProfiles = &ctx->profile;
863 
864  /* Get the capabilities of the encoder for the given profile */
865  ctx->enc_caps.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR;
866  ctx->enc_caps.pNext = codec_caps;
867  ctx->caps.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
868  ctx->caps.pNext = &ctx->enc_caps;
869 
870  ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
871  &ctx->profile,
872  &ctx->caps);
873  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
874  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
875  "%s profile \"%s\" not supported!\n",
876  avcodec_get_name(avctx->codec_id),
877  avcodec_profile_name(avctx->codec_id, avctx->profile));
878  return AVERROR(EINVAL);
879  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
880  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
881  "format (%s) not supported!\n",
883  return AVERROR(EINVAL);
884  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
885  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
886  return AVERROR(EINVAL);
887  } else if (ret != VK_SUCCESS) {
888  return AVERROR_EXTERNAL;
889  }
890 
891  if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) !=
892  feedback_flags) {
893  av_log(avctx, AV_LOG_ERROR,
894  "Driver does not support required encode feedback flags "
895  "(BUFFER_OFFSET and BYTES_WRITTEN).\n");
896  return AVERROR(ENOTSUP);
897  }
898 
899  err = init_rc(avctx, ctx);
900  if (err < 0)
901  return err;
902 
903  /* Create command and query pool */
904  query_create = (VkQueryPoolVideoEncodeFeedbackCreateInfoKHR) {
905  .sType = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR,
906  .pNext = &ctx->profile,
907  .encodeFeedbackFlags = feedback_flags,
908  };
909  err = ff_vk_exec_pool_init(s, ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
910  1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
911  &query_create);
912  if (err < 0)
913  return err;
914 
915  if (ctx->opts.quality > ctx->enc_caps.maxQualityLevels) {
916  av_log(avctx, AV_LOG_ERROR, "Invalid quality level %i: allowed range is "
917  "0 to %i\n",
918  ctx->opts.quality, ctx->enc_caps.maxQualityLevels);
919  return AVERROR(EINVAL);
920  }
921 
922  /* Get quality properties for the profile and quality level */
923  quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
924  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
925  .pVideoProfile = &ctx->profile,
926  .qualityLevel = ctx->opts.quality,
927  };
928  ctx->quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
929  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
930  .pNext = quality_pnext,
931  };
932  ret = vk->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(s->hwctx->phys_dev,
933  &quality_info,
934  &ctx->quality_props);
935  if (ret != VK_SUCCESS)
936  return AVERROR_EXTERNAL;
937 
938  /* Printout informative properties */
939  av_log(avctx, AV_LOG_VERBOSE, "Encoder capabilities for %s profile \"%s\":\n",
940  avcodec_get_name(avctx->codec_id),
941  avcodec_profile_name(avctx->codec_id, avctx->profile));
942  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
943  ctx->caps.minCodedExtent.width, ctx->caps.maxCodedExtent.width);
944  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
945  ctx->caps.minCodedExtent.height, ctx->caps.maxCodedExtent.height);
946  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
947  ctx->caps.pictureAccessGranularity.width);
948  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
949  ctx->caps.pictureAccessGranularity.height);
950  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
951  ctx->caps.minBitstreamBufferOffsetAlignment);
952  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
953  ctx->caps.minBitstreamBufferSizeAlignment);
954  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
955  ctx->caps.maxDpbSlots);
956  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
957  ctx->caps.maxActiveReferencePictures);
958  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
959  CODEC_VER(ctx->caps.stdHeaderVersion.specVersion),
960  CODEC_VER(vk_desc->ext_props.specVersion));
961  av_log(avctx, AV_LOG_VERBOSE, " Encoder max quality: %i\n",
962  ctx->enc_caps.maxQualityLevels);
963  av_log(avctx, AV_LOG_VERBOSE, " Encoder image width alignment: %i\n",
964  ctx->enc_caps.encodeInputPictureGranularity.width);
965  av_log(avctx, AV_LOG_VERBOSE, " Encoder image height alignment: %i\n",
966  ctx->enc_caps.encodeInputPictureGranularity.height);
967  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
968  ctx->caps.flags ? "" :
969  " none",
970  ctx->caps.flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
971  " protected" : "",
972  ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
973  " separate_references" : "");
974 
975  /* Setup width/height alignment */
976  base_ctx->surface_width = avctx->coded_width =
977  FFALIGN(avctx->width, ctx->enc_caps.encodeInputPictureGranularity.width);
978  base_ctx->surface_height = avctx->coded_height =
979  FFALIGN(avctx->height, ctx->enc_caps.encodeInputPictureGranularity.height);
980 
981  /* Setup slice width/height */
982  base_ctx->slice_block_width = ctx->enc_caps.encodeInputPictureGranularity.width;
983  base_ctx->slice_block_height = ctx->enc_caps.encodeInputPictureGranularity.height;
984 
985  /* Check if encoding is possible with the given parameters */
986  if (avctx->coded_width < ctx->caps.minCodedExtent.width ||
987  avctx->coded_height < ctx->caps.minCodedExtent.height ||
988  avctx->coded_width > ctx->caps.maxCodedExtent.width ||
989  avctx->coded_height > ctx->caps.maxCodedExtent.height) {
990  av_log(avctx, AV_LOG_ERROR, "Input of %ix%i too large for encoder limits: %ix%i max\n",
991  avctx->coded_width, avctx->coded_height,
992  ctx->caps.minCodedExtent.width, ctx->caps.minCodedExtent.height);
993  return AVERROR(EINVAL);
994  }
995 
996  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
997 
998  ctx->common.layered_dpb = !(ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
999 
1000  /* Get the supported image formats */
1001  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
1002  &fmt_info,
1003  &nb_out_fmts, NULL);
1004  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1005  (!nb_out_fmts && ret == VK_SUCCESS)) {
1006  return AVERROR(EINVAL);
1007  } else if (ret != VK_SUCCESS) {
1008  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1009  ff_vk_ret2str(ret));
1010  return AVERROR_EXTERNAL;
1011  }
1012 
1013  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
1014  if (!ret_info)
1015  return AVERROR(ENOMEM);
1016 
1017  for (int i = 0; i < nb_out_fmts; i++)
1018  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1019 
1020  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
1021  &fmt_info,
1022  &nb_out_fmts, ret_info);
1023  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1024  (!nb_out_fmts && ret == VK_SUCCESS)) {
1025  av_free(ret_info);
1026  return AVERROR(EINVAL);
1027  } else if (ret != VK_SUCCESS) {
1028  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1029  ff_vk_ret2str(ret));
1030  av_free(ret_info);
1031  return AVERROR_EXTERNAL;
1032  }
1033 
1034  av_log(avctx, AV_LOG_VERBOSE, "Supported input formats:\n");
1035  for (i = 0; i < nb_out_fmts; i++)
1036  av_log(avctx, AV_LOG_VERBOSE, " %i: %i\n", i, ret_info[i].format);
1037 
1038  for (i = 0; i < nb_out_fmts; i++) {
1039  if (ff_vk_pix_fmt_from_vkfmt(ret_info[i].format) == s->frames->sw_format) {
1040  ctx->pic_format = ret_info[i].format;
1041  break;
1042  }
1043  }
1044 
1045  av_free(ret_info);
1046 
1047  if (i == nb_out_fmts) {
1048  av_log(avctx, AV_LOG_ERROR, "Pixel format %s of input frames not supported!\n",
1049  av_get_pix_fmt_name(s->frames->sw_format));
1050  return AVERROR(EINVAL);
1051  }
1052 
1053  /* Create session */
1054  session_create.pVideoProfile = &ctx->profile;
1055  session_create.flags = 0x0;
1056  session_create.queueFamilyIndex = ctx->qf_enc->idx;
1057  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1058  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1059  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1060  session_create.pictureFormat = ctx->pic_format;
1061  session_create.referencePictureFormat = session_create.pictureFormat;
1062  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1063 
1064  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1065  if (err < 0)
1066  return err;
1067 
1068  err = ff_hw_base_encode_init(avctx, &ctx->base);
1069  if (err < 0)
1070  return err;
1071 
1072  err = vulkan_encode_create_dpb(avctx, ctx);
1073  if (err < 0)
1074  return err;
1075 
1076  base_ctx->async_encode = 1;
1077  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
1078  sizeof(FFVulkanEncodePicture *), 0);
1079  if (!base_ctx->encode_fifo)
1080  return AVERROR(ENOMEM);
1081 
1082  return 0;
1083 }
1084 
1086  void *codec_params_pnext)
1087 {
1088  VkResult ret;
1089  FFVulkanFunctions *vk = &ctx->s.vkfn;
1090  FFVulkanContext *s = &ctx->s;
1091 
1092  VkVideoEncodeQualityLevelInfoKHR q_info;
1093  VkVideoSessionParametersCreateInfoKHR session_params_create;
1094 
1095  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
1096  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
1097  .pNext = codec_params_pnext,
1098  .qualityLevel = ctx->opts.quality,
1099  };
1100  session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1101  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1102  .pNext = &q_info,
1103  .videoSession = ctx->common.session,
1104  .videoSessionParametersTemplate = VK_NULL_HANDLE,
1105  };
1106 
1107  /* Create session parameters */
1108  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1109  s->hwctx->alloc, &ctx->session_params);
1110  if (ret != VK_SUCCESS) {
1111  av_log(avctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1112  ff_vk_ret2str(ret));
1113  return AVERROR_EXTERNAL;
1114  }
1115 
1116  return 0;
1117 }
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:147
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
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
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
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:540
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:880
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:724
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:568
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:2704
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:800
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:92
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
FFVulkanEncodePicture::dpb
struct FFVulkanEncodePicture::@355 dpb
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:40
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:1465
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:131
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:573
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
ff_vk_exec_add_dep_buf
int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e, AVBufferRef **deps, int nb_deps, int ref)
Execution dependency management.
Definition: vulkan.c:640
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:299
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
FFVkExecContext::query_idx
int query_idx
Definition: vulkan.h:131
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
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:69
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
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:95
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:100
FFVulkanContext
Definition: vulkan.h:275
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
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:60
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:663
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:94
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:111
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
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:580
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:595
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:93
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:601
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:286
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
FFVkExecContext::buf
VkCommandBuffer buf
Definition: vulkan.h:122
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:754
vulkan_base_encode_ops
static const FFHWEncodePictureOperation vulkan_base_encode_ops
Definition: vulkan_encode.c:587
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
vulkan_encode_output
static int vulkan_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
Definition: vulkan_encode.c:476
FFVulkanEncodePicture::pkt_buf
AVBufferRef * pkt_buf
Definition: vulkan_encode.h:58
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
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:91
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:925
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:275
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:1085
FFVulkanEncodePicture
Definition: vulkan_encode.h:39
FFVulkanEncodePicture::in
struct FFVulkanEncodePicture::@354 in
ff_vk_get_pooled_buffer
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool, AVBufferRef **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition: vulkan.c:1306
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:461
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:3376