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 
32 {
33  FFVulkanContext *s = &ctx->s;
34  FFVulkanFunctions *vk = &s->vkfn;
35 
36  /* Wait on and free execution pool */
37  ff_vk_exec_pool_free(s, &ctx->enc_pool);
38 
39  /* Destroy the session params */
40  if (ctx->session_params)
41  vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
42  ctx->session_params,
43  s->hwctx->alloc);
44 
46 
47  av_buffer_pool_uninit(&ctx->buf_pool);
48 
49  ff_vk_video_common_uninit(s, &ctx->common);
50 
51  ff_vk_uninit(s);
52 }
53 
55 {
56  int err;
58  FFVulkanEncodePicture *vp = pic->priv;
59 
60  AVFrame *f = pic->input_image;
61  AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
62  AVVulkanFramesContext *vkfc = hwfc->hwctx;
63  AVVkFrame *vkf = (AVVkFrame *)f->data[0];
64 
65  if (ctx->codec->picture_priv_data_size > 0) {
66  pic->codec_priv = av_mallocz(ctx->codec->picture_priv_data_size);
67  if (!pic->codec_priv)
68  return AVERROR(ENOMEM);
69  }
70 
71  /* Input image view */
72  err = ff_vk_create_view(&ctx->s, &ctx->common,
73  &vp->in.view, &vp->in.aspect,
74  vkf, vkfc->format[0], 0);
75  if (err < 0)
76  return err;
77 
78  /* Reference view */
79  if (!ctx->common.layered_dpb) {
80  AVFrame *rf = pic->recon_image;
81  AVVkFrame *rvkf = (AVVkFrame *)rf->data[0];
82  err = ff_vk_create_view(&ctx->s, &ctx->common,
83  &vp->dpb.view, &vp->dpb.aspect,
84  rvkf, ctx->pic_format, 1);
85  if (err < 0)
86  return err;
87  } else {
88  vp->dpb.view = ctx->common.layered_view;
89  vp->dpb.aspect = ctx->common.layered_aspect;
90  }
91 
92  return 0;
93 }
94 
96 {
98  FFVulkanFunctions *vk = &ctx->s.vkfn;
99 
100  FFVulkanEncodePicture *vp = pic->priv;
101 
102  if (vp->in.view)
103  vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->in.view,
104  ctx->s.hwctx->alloc);
105 
106  if (!ctx->common.layered_dpb && vp->dpb.view)
107  vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->dpb.view,
108  ctx->s.hwctx->alloc);
109 
110  ctx->slots[vp->dpb_slot.slotIndex] = NULL;
111 
112  return 0;
113 }
114 
116  VkVideoEncodeRateControlInfoKHR *rc_info,
117  VkVideoEncodeRateControlLayerInfoKHR *rc_layer /* Goes in ^ */)
118 {
120 
121  *rc_info = (VkVideoEncodeRateControlInfoKHR) {
122  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR,
123  .rateControlMode = ctx->opts.rc_mode,
124  };
125 
126  if (ctx->opts.rc_mode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
127  *rc_layer = (VkVideoEncodeRateControlLayerInfoKHR) {
128  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR,
129  .averageBitrate = avctx->bit_rate,
130  .maxBitrate = avctx->rc_max_rate ? avctx->rc_max_rate : avctx->bit_rate,
131  .frameRateNumerator = avctx->framerate.num,
132  .frameRateDenominator = avctx->framerate.den,
133  };
134  rc_info->layerCount++;
135  rc_info->pLayers = rc_layer;
136  }
137 
138  return ctx->codec->init_pic_rc(avctx, pic, rc_info, rc_layer);
139 }
140 
142  FFHWBaseEncodePicture *base_pic)
143 {
145  FFVulkanFunctions *vk = &ctx->s.vkfn;
146 
147  const size_t size_align = ctx->caps.minBitstreamBufferSizeAlignment;
148 
149  FFVulkanEncodePicture *vp = base_pic->priv;
150  AVFrame *src = (AVFrame *)base_pic->input_image;
151  AVVkFrame *vkf = (AVVkFrame *)src->data[0];
152 
153  int err, max_pkt_size;
154 
155  FFVkBuffer *sd_buf;
156 
157  int slot_index = -1;
158  FFVkExecContext *exec;
159  VkCommandBuffer cmd_buf;
160  VkImageMemoryBarrier2 img_bar[37];
161  int nb_img_bar = 0;
162 
163  /* Coding start/end */
164  VkVideoBeginCodingInfoKHR encode_start;
165  VkVideoEndCodingInfoKHR encode_end = {
166  .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
167  };
168 
169  VkVideoEncodeRateControlLayerInfoKHR rc_layer;
170  VkVideoEncodeRateControlInfoKHR rc_info;
171  VkVideoEncodeQualityLevelInfoKHR q_info;
172  VkVideoCodingControlInfoKHR encode_ctrl;
173 
174  VkVideoReferenceSlotInfoKHR ref_slot[37];
175  VkVideoEncodeInfoKHR encode_info;
176 
177  /* Create packet data buffer */
178  max_pkt_size = FFALIGN(3 * ctx->base.surface_width * ctx->base.surface_height + (1 << 16),
179  ctx->caps.minBitstreamBufferSizeAlignment);
180 
181  err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &vp->pkt_buf,
182  VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR,
183  &ctx->profile_list, max_pkt_size,
184  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
185  VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
186  if (err < 0)
187  return err;
188 
189  sd_buf = (FFVkBuffer *)vp->pkt_buf->data;
190 
191  /* Setup rate control */
192  err = init_pic_rc(avctx, base_pic, &rc_info, &rc_layer);
193  if (err < 0)
194  return err;
195 
196  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
197  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
198  .pNext = &rc_info,
199  .qualityLevel = ctx->opts.quality,
200  };
201  encode_ctrl = (VkVideoCodingControlInfoKHR) {
202  .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
203  .pNext = &q_info,
204  .flags = VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR |
205  VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR |
206  VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
207  };
208 
209  for (int i = 0; i < ctx->caps.maxDpbSlots; i++) {
210  if (ctx->slots[i] == NULL) {
211  slot_index = i;
212  ctx->slots[i] = base_pic;
213  break;
214  }
215  }
216  av_assert0(slot_index >= 0);
217 
218  /* Current picture's ref slot */
219  vp->dpb_res = (VkVideoPictureResourceInfoKHR) {
220  .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
221  .pNext = NULL,
222  .codedOffset = { 0 },
223  .codedExtent = (VkExtent2D){ avctx->width, avctx->height },
224  .baseArrayLayer = ctx->common.layered_dpb ? slot_index : 0,
225  .imageViewBinding = vp->dpb.view,
226  };
227 
228  vp->dpb_slot = (VkVideoReferenceSlotInfoKHR) {
229  .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
230  .pNext = NULL, // Set later
231  .slotIndex = slot_index,
232  .pPictureResource = &vp->dpb_res,
233  };
234 
235  encode_info = (VkVideoEncodeInfoKHR) {
236  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR,
237  .pNext = NULL, // Set later
238  .flags = 0x0,
239  .srcPictureResource = (VkVideoPictureResourceInfoKHR) {
240  .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
241  .pNext = NULL,
242  .codedOffset = { 0, 0 },
243  .codedExtent = (VkExtent2D){ base_pic->input_image->width,
244  base_pic->input_image->height },
245  .baseArrayLayer = 0,
246  .imageViewBinding = vp->in.view,
247  },
248  .pSetupReferenceSlot = &vp->dpb_slot,
249  .referenceSlotCount = 0,
250  .pReferenceSlots = ref_slot,
251  .dstBuffer = sd_buf->buf,
252  .dstBufferOffset = 0,
253  .dstBufferRange = sd_buf->size,
254  .precedingExternallyEncodedBytes = 0,
255  };
256 
257  for (int i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
258  for (int j = 0; j < base_pic->nb_refs[i]; j++) {
259  FFHWBaseEncodePicture *ref = base_pic->refs[i][j];
260  FFVulkanEncodePicture *rvp = ref->priv;
261  ref_slot[encode_info.referenceSlotCount++] = rvp->dpb_slot;
262  }
263  }
264 
265  /* Calling vkCmdBeginVideoCodingKHR requires to declare all references
266  * being enabled upfront, including the current frame's output ref. */
267  ref_slot[encode_info.referenceSlotCount] = vp->dpb_slot;
268  ref_slot[encode_info.referenceSlotCount].slotIndex = -1;
269 
270  /* Setup picture parameters */
271  err = ctx->codec->init_pic_params(avctx, base_pic,
272  &encode_info);
273  if (err < 0)
274  return err;
275 
276  encode_start = (VkVideoBeginCodingInfoKHR) {
277  .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
278  .pNext = !base_pic->force_idr ? &rc_info : NULL,
279  .videoSession = ctx->common.session,
280  .videoSessionParameters = ctx->session_params,
281  .referenceSlotCount = encode_info.referenceSlotCount + 1,
282  .pReferenceSlots = ref_slot,
283  };
284 
285  /* Write header */
286  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
287  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
288  size_t data_size = encode_info.dstBufferRange;
289  err = ctx->codec->write_sequence_headers(avctx, base_pic, hdr_dst, &data_size);
290  if (err < 0)
291  goto fail;
292  encode_info.dstBufferOffset += data_size;
293  encode_info.dstBufferRange -= data_size;
294  }
295 
296  /* Write extra units */
297  if (ctx->codec->write_extra_headers) {
298  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
299  size_t data_size = encode_info.dstBufferRange;
300  err = ctx->codec->write_extra_headers(avctx, base_pic, hdr_dst, &data_size);
301  if (err < 0)
302  goto fail;
303  encode_info.dstBufferOffset += data_size;
304  encode_info.dstBufferRange -= data_size;
305  }
306 
307  /* Align buffer offset to the required value with filler units */
308  if (ctx->codec->write_filler) {
309  uint8_t *hdr_dst = sd_buf->mapped_mem + encode_info.dstBufferOffset;
310  size_t data_size = encode_info.dstBufferRange;
311 
312  uint32_t offset = encode_info.dstBufferOffset;
313  size_t offset_align = ctx->caps.minBitstreamBufferOffsetAlignment;
314 
315  uint32_t filler_data = FFALIGN(offset, offset_align) - offset;
316 
317  if (filler_data) {
318  while (filler_data < ctx->codec->filler_header_size)
319  filler_data += offset_align;
320 
321  filler_data -= ctx->codec->filler_header_size;
322 
323  err = ctx->codec->write_filler(avctx, filler_data,
324  hdr_dst, &data_size);
325  if (err < 0)
326  goto fail;
327 
328  encode_info.dstBufferOffset += data_size;
329  encode_info.dstBufferRange -= data_size;
330  }
331  }
332 
333  vp->slices_offset = encode_info.dstBufferOffset;
334 
335  /* Align buffer size to the nearest lower alignment requirement. */
336  encode_info.dstBufferRange -= size_align;
337  encode_info.dstBufferRange = FFALIGN(encode_info.dstBufferRange,
338  size_align);
339 
340  /* Start command buffer recording */
341  exec = vp->exec = ff_vk_exec_get(&ctx->s, &ctx->enc_pool);
342  ff_vk_exec_start(&ctx->s, exec);
343  cmd_buf = exec->buf;
344 
345  /* Output packet buffer */
346  err = ff_vk_exec_add_dep_buf(&ctx->s, exec, &vp->pkt_buf, 1, 1);
347  if (err < 0)
348  goto fail;
349 
350  /* Source image */
351  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, src,
352  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
353  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
354  if (err < 0)
355  goto fail;
356 
357  /* Source image layout conversion */
358  img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
359  .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
360  .pNext = NULL,
361  .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
362  .srcAccessMask = vkf->access[0],
363  .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
364  .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR,
365  .oldLayout = vkf->layout[0],
366  .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
367  .srcQueueFamilyIndex = vkf->queue_family[0],
368  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
369  .image = vkf->img[0],
370  .subresourceRange = (VkImageSubresourceRange) {
371  .aspectMask = vp->in.aspect,
372  .layerCount = 1,
373  .levelCount = 1,
374  },
375  };
376  ff_vk_exec_update_frame(&ctx->s, exec, src,
377  &img_bar[nb_img_bar], &nb_img_bar);
378 
379  if (!ctx->common.layered_dpb) {
380  /* Source image's ref slot.
381  * No need to do a layout conversion, since the frames which are allocated
382  * with a DPB usage are automatically converted. */
383  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, base_pic->recon_image,
384  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
385  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
386  if (err < 0)
387  return err;
388 
389  /* All references */
390  for (int i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
391  for (int j = 0; j < base_pic->nb_refs[i]; j++) {
392  FFHWBaseEncodePicture *ref = base_pic->refs[i][j];
393  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ref->recon_image,
394  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
395  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
396  if (err < 0)
397  return err;
398  }
399  }
400  } else {
401  err = ff_vk_exec_add_dep_frame(&ctx->s, exec, ctx->common.layered_frame,
402  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
403  VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
404  if (err < 0)
405  return err;
406  }
407 
408  /* Change image layout */
409  vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
410  .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
411  .pImageMemoryBarriers = img_bar,
412  .imageMemoryBarrierCount = nb_img_bar,
413  });
414 
415  /* Start, use parameters */
416  vk->CmdBeginVideoCodingKHR(cmd_buf, &encode_start);
417 
418  /* Send control data */
419  if (!ctx->session_reset) {
420  vk->CmdControlVideoCodingKHR(cmd_buf, &encode_ctrl);
421  ctx->session_reset++;
422  }
423 
424  /* Encode */
425  vk->CmdBeginQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0, 0);
426  vk->CmdEncodeVideoKHR(cmd_buf, &encode_info);
427  vk->CmdEndQuery(cmd_buf, ctx->enc_pool.query_pool, exec->query_idx + 0);
428 
429  /* End encoding */
430  vk->CmdEndVideoCodingKHR(cmd_buf, &encode_end);
431 
432  /* End recording and submit for execution */
433  err = ff_vk_exec_submit(&ctx->s, vp->exec);
434  if (err < 0)
435  goto fail;
436 
437  /* We don't need to keep the input image any longer, its already ref'd */
438  av_frame_free(&base_pic->input_image);
439 
440  return 0;
441 
442 fail:
443  return err;
444 }
445 
447  FFHWBaseEncodePicture *base_pic)
448 {
450  FFVulkanEncodePicture *vp = base_pic->priv;
451 
452  av_assert0(base_pic->encode_issued);
453 
454  if (base_pic->encode_complete)
455  return;
456 
457  ff_vk_exec_wait(&ctx->s, vp->exec);
458  base_pic->encode_complete = 1;
459 }
460 
462  FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
463 {
464  VkResult ret;
465  FFVulkanEncodePicture *vp = base_pic->priv;
467  FFHWBaseEncodeContext *base_ctx = &ctx->base;
468  AVPacket *pkt_ptr = pkt;
469 
470  FFVkBuffer *sd_buf = (FFVkBuffer *)vp->pkt_buf->data;
471  uint32_t *query_data;
472 
473  vulkan_encode_wait(avctx, base_pic);
474 
475  ret = ff_vk_exec_get_query(&ctx->s, vp->exec, (void **)&query_data, 0);
476  if (ret == VK_NOT_READY) {
477  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
478  ff_vk_ret2str(ret));
479  return AVERROR(EINVAL);
480  }
481 
482  if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
483  av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
484  ff_vk_ret2str(ret));
485  return AVERROR_EXTERNAL;
486  }
487 
488  if (query_data[2] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR) {
489  av_log(avctx, AV_LOG_ERROR, "Unable to encode: %u\n", query_data[2]);
490  return AVERROR_EXTERNAL;
491  }
492 
493  /* Invalidate buffer if needed */
494  if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
495  FFVulkanFunctions *vk = &ctx->s.vkfn;
496  VkMappedMemoryRange invalidate_buf;
497 
498  int offs = vp->slices_offset;
499  /* If the non-coherent alignment is greater than the bitstream buffer
500  * offset's alignment, and the offs value is not aligned already,
501  * align it to the previous alignment point. */
502  if (ctx->s.props.properties.limits.nonCoherentAtomSize >
503  ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
504  (FFALIGN(offs, ctx->s.props.properties.limits.nonCoherentAtomSize) != offs)) {
505  offs -= ctx->s.props.properties.limits.nonCoherentAtomSize;
506  offs = FFALIGN(FFMAX(offs, 0), ctx->s.props.properties.limits.nonCoherentAtomSize);
507  }
508 
509  invalidate_buf = (VkMappedMemoryRange) {
510  .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
511  .memory = sd_buf->mem,
512  .offset = offs,
513  .size = VK_WHOLE_SIZE,
514  };
515 
516  vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &invalidate_buf);
517  }
518 
519  if (vp->non_independent_frame) {
520  av_assert0(!ctx->prev_buf_ref);
521  size_t prev_buf_size = vp->slices_offset + query_data[0] + query_data[1];
522  ctx->prev_buf_ref = vp->pkt_buf;
523  ctx->prev_buf_size = prev_buf_size;
524  vp->pkt_buf = NULL;
525 
526  if (vp->tail_size) {
527  if (base_ctx->tail_pkt->size)
528  return AVERROR_BUG;
529 
530  ret = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, vp->tail_size, 0);
531  if (ret < 0)
532  return ret;
533 
534  memcpy(base_ctx->tail_pkt->data, vp->tail_data, vp->tail_size);
535  pkt_ptr = base_ctx->tail_pkt;
536  }
537  } else {
538  if (ctx->prev_buf_ref) {
539  FFVkBuffer *prev_sd_buf = (FFVkBuffer *)ctx->prev_buf_ref->data;
540  size_t prev_size = ctx->prev_buf_size;
541  size_t size = (vp->slices_offset + query_data[0] + query_data[1]);
542 
543  ret = ff_get_encode_buffer(avctx, pkt, prev_size + size, 0);
544  if (ret < 0)
545  return ret;
546 
547  memcpy(pkt->data, prev_sd_buf->mapped_mem, prev_size);
548  memcpy(pkt->data + prev_size, sd_buf->mapped_mem, size);
549 
550  av_buffer_unref(&ctx->prev_buf_ref);
551  av_buffer_unref(&vp->pkt_buf);
552  } else {
553  pkt->data = sd_buf->mapped_mem;
554  pkt->size = vp->slices_offset + /* base offset */
555  query_data[0] /* secondary offset */ +
556  query_data[1] /* size */;
557 
558  /* Move reference */
559  pkt->buf = vp->pkt_buf;
560  vp->pkt_buf = NULL;
561  }
562  }
563 
564  av_log(avctx, AV_LOG_DEBUG, "Frame %"PRId64"/%"PRId64 " encoded\n",
565  base_pic->display_order, base_pic->encode_order);
566 
567  return ff_hw_base_encode_set_output_property(&ctx->base, avctx,
568  base_pic, pkt_ptr,
569  ctx->codec->flags & VK_ENC_FLAG_NO_DELAY);
570 }
571 
573  .priv_size = sizeof(FFVulkanEncodePicture),
575  .issue = &vulkan_encode_issue,
577  .free = &vulkan_encode_free,
578 };
579 
581 {
583  return ff_hw_base_encode_receive_packet(&ctx->base, avctx, pkt);
584 }
585 
587 {
588  int err;
589  FFHWBaseEncodeContext *base_ctx = &ctx->base;
590  AVVulkanFramesContext *hwfc;
591 
592  enum AVPixelFormat dpb_format;
593  err = ff_hw_base_get_recon_format(base_ctx, NULL, &dpb_format);
594  if (err < 0)
595  return err;
596 
597  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
598  if (!base_ctx->recon_frames_ref)
599  return AVERROR(ENOMEM);
600 
601  base_ctx->recon_frames = (AVHWFramesContext *)base_ctx->recon_frames_ref->data;
602  hwfc = (AVVulkanFramesContext *)base_ctx->recon_frames->hwctx;
603 
605  base_ctx->recon_frames->sw_format = dpb_format;
606  base_ctx->recon_frames->width = avctx->width;
607  base_ctx->recon_frames->height = avctx->height;
608 
609  hwfc->format[0] = ctx->pic_format;
610  hwfc->create_pnext = &ctx->profile_list;
611  hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
612  hwfc->usage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
613 
614  if (ctx->common.layered_dpb)
615  hwfc->nb_layers = ctx->caps.maxDpbSlots;
616 
617  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
618  if (err < 0) {
619  av_log(avctx, AV_LOG_ERROR, "Failed to initialise DPB frame context: %s\n",
620  av_err2str(err));
621  return err;
622  }
623 
624  if (ctx->common.layered_dpb) {
625  ctx->common.layered_frame = av_frame_alloc();
626  if (!ctx->common.layered_frame)
627  return AVERROR(ENOMEM);
628 
629  err = av_hwframe_get_buffer(base_ctx->recon_frames_ref,
630  ctx->common.layered_frame, 0);
631  if (err < 0)
632  return AVERROR(ENOMEM);
633 
634  err = ff_vk_create_view(&ctx->s, &ctx->common,
635  &ctx->common.layered_view,
636  &ctx->common.layered_aspect,
637  (AVVkFrame *)ctx->common.layered_frame->data[0],
638  hwfc->format[0], 1);
639  if (err < 0)
640  return err;
641 
642  av_buffer_unref(&base_ctx->recon_frames_ref);
643  }
644 
645  return 0;
646 }
647 
649 {
650  if (ctx->opts.qp) {
651  ctx->explicit_qp = ctx->opts.qp;
652  } else if (avctx->global_quality > 0) {
653  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
654  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
655  else
656  ctx->explicit_qp = avctx->global_quality;
657  }
658 
659  if (ctx->opts.rc_mode == FF_VK_RC_MODE_AUTO) {
660  if (ctx->explicit_qp >= 0) {
661  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
662  } else if (avctx->global_quality > 0) {
663  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
664  ctx->explicit_qp = avctx->global_quality / FF_QP2LAMBDA;
665  else
666  ctx->explicit_qp = avctx->global_quality;
667  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
668  } else if (avctx->bit_rate) {
669  if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR)
670  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
671  else if (ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR)
672  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
673  else
674  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
675  } else {
676  ctx->explicit_qp = 18;
677  ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
678  av_log(avctx, AV_LOG_WARNING, "No rate control settings specified, using fixed QP = %i\n",
679  ctx->explicit_qp);
680  }
681  } else if (ctx->opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR &&
682  !avctx->bit_rate) {
683  av_log(avctx, AV_LOG_WARNING, "No bitrate specified!\n");
684  return AVERROR(EINVAL);
685  }
686 
687  if (ctx->opts.rc_mode && !(ctx->enc_caps.rateControlModes & ctx->opts.rc_mode)) {
688  static const char *rc_modes[] = {
689  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR] = "default",
690  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR] = "cqp",
691  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR] = "cbr",
692  [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR] = "vbr",
693  };
694  av_log(avctx, AV_LOG_ERROR, "Unsupported rate control mode %s, supported are:\n",
695  rc_modes[FFMIN(FF_ARRAY_ELEMS(rc_modes), ctx->opts.rc_mode)]);
696  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[0]);
697  for (int i = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
698  i <= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR; i <<= 1) {
699  if (!(ctx->enc_caps.rateControlModes & i))
700  continue;
701  av_log(avctx, AV_LOG_ERROR, " %s\n", rc_modes[i]);
702  }
703  return AVERROR(ENOTSUP);
704  }
705 
706  return 0;
707 }
708 
711 {
712  int err;
713 
714  /* Write extradata if needed */
715  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
716  uint8_t data[4096];
717  size_t data_len = sizeof(data);
718 
719  err = ctx->codec->write_sequence_headers(avctx, NULL, data, &data_len);
720  if (err < 0) {
721  av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
722  "for extradata: %d.\n", err);
723  return err;
724  } else {
725  avctx->extradata_size = data_len;
726  avctx->extradata = av_mallocz(avctx->extradata_size +
728  if (!avctx->extradata) {
729  err = AVERROR(ENOMEM);
730  return err;
731  }
732  memcpy(avctx->extradata, data, avctx->extradata_size);
733  }
734  }
735 
736  return 0;
737 }
738 
740  const FFVulkanEncodeDescriptor *vk_desc,
741  const FFVulkanCodec *codec,
742  void *codec_caps, void *quality_pnext)
743 {
744  int i, err;
745  VkResult ret;
746  FFVulkanFunctions *vk = &ctx->s.vkfn;
747  FFVulkanContext *s = &ctx->s;
748  FFHWBaseEncodeContext *base_ctx = &ctx->base;
749 
750  const AVPixFmtDescriptor *desc;
751 
752  VkVideoFormatPropertiesKHR *ret_info;
753  uint32_t nb_out_fmts = 0;
754 
755  VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
756 
757  VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
758 
759  VkVideoSessionCreateInfoKHR session_create = {
760  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
761  };
762  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
763  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
764  .pNext = &ctx->profile_list,
765  };
766 
767  if (!avctx->hw_frames_ctx) {
768  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
769  "required to associate the encoding device.\n");
770  return AVERROR(EINVAL);
771  }
772 
773  ctx->base.op = &vulkan_base_encode_ops;
774  ctx->codec = codec;
775 
776  s->frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
777  s->frames = (AVHWFramesContext *)s->frames_ref->data;
778  s->hwfc = s->frames->hwctx;
779 
780  s->device = (AVHWDeviceContext *)s->frames->device_ref->data;
781  s->hwctx = s->device->hwctx;
782 
784  if (!desc)
785  return AVERROR(EINVAL);
786 
787  s->extensions = ff_vk_extensions_to_mask(s->hwctx->enabled_dev_extensions,
788  s->hwctx->nb_enabled_dev_extensions);
789 
790  if (!(s->extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE)) {
791  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
792  VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
793  return AVERROR(ENOSYS);
794  } else if (!(s->extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1)) {
795  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
796  VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME);
797  return AVERROR(ENOSYS);
798  } else if (!(s->extensions & vk_desc->encode_extension)) {
799  av_log(avctx, AV_LOG_ERROR, "Device does not support encoding %s!\n",
800  avcodec_get_name(avctx->codec_id));
801  return AVERROR(ENOSYS);
802  }
803 
804  /* Load functions */
805  err = ff_vk_load_functions(s->device, vk, s->extensions, 1, 1);
806  if (err < 0)
807  return err;
808 
809  /* Create queue context */
810  ctx->qf_enc = ff_vk_qf_find(s, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, vk_desc->encode_op);
811  if (!ctx->qf_enc) {
812  av_log(avctx, AV_LOG_ERROR, "Encoding of %s is not supported by this device\n",
813  avcodec_get_name(avctx->codec_id));
814  return err;
815  }
816 
817  /* Load all properties */
818  err = ff_vk_load_props(s);
819  if (err < 0)
820  return err;
821 
822  /* Set tuning */
823  ctx->usage_info = (VkVideoEncodeUsageInfoKHR) {
824  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR,
825  .videoUsageHints = ctx->opts.usage,
826  .videoContentHints = ctx->opts.content,
827  .tuningMode = ctx->opts.tune,
828  };
829 
830  /* Load up the profile now, needed for caps and to create a query pool */
831  ctx->profile.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
832  ctx->profile.pNext = &ctx->usage_info;
833  ctx->profile.videoCodecOperation = vk_desc->encode_op;
834  ctx->profile.chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
835  ctx->profile.lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
836  ctx->profile.chromaBitDepth = ctx->profile.lumaBitDepth;
837 
838  /* Setup a profile */
839  err = codec->init_profile(avctx, &ctx->profile, &ctx->usage_info);
840  if (err < 0)
841  return err;
842 
843  ctx->profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
844  ctx->profile_list.profileCount = 1;
845  ctx->profile_list.pProfiles = &ctx->profile;
846 
847  /* Get the capabilities of the encoder for the given profile */
848  ctx->enc_caps.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR;
849  ctx->enc_caps.pNext = codec_caps;
850  ctx->caps.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
851  ctx->caps.pNext = &ctx->enc_caps;
852 
853  ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
854  &ctx->profile,
855  &ctx->caps);
856  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
857  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
858  "%s profile \"%s\" not supported!\n",
859  avcodec_get_name(avctx->codec_id),
860  avcodec_profile_name(avctx->codec_id, avctx->profile));
861  return AVERROR(EINVAL);
862  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
863  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
864  "format (%s) not supported!\n",
866  return AVERROR(EINVAL);
867  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
868  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
869  return AVERROR(EINVAL);
870  } else if (ret != VK_SUCCESS) {
871  return AVERROR_EXTERNAL;
872  }
873 
874  err = init_rc(avctx, ctx);
875  if (err < 0)
876  return err;
877 
878  /* Create command and query pool */
879  query_create = (VkQueryPoolVideoEncodeFeedbackCreateInfoKHR) {
880  .sType = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR,
881  .pNext = &ctx->profile,
882  .encodeFeedbackFlags = ctx->enc_caps.supportedEncodeFeedbackFlags &
883  (~VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR),
884  };
885  err = ff_vk_exec_pool_init(s, ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
886  1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
887  &query_create);
888  if (err < 0)
889  return err;
890 
891  if (ctx->opts.quality > ctx->enc_caps.maxQualityLevels) {
892  av_log(avctx, AV_LOG_ERROR, "Invalid quality level %i: allowed range is "
893  "0 to %i\n",
894  ctx->opts.quality, ctx->enc_caps.maxQualityLevels);
895  return AVERROR(EINVAL);
896  }
897 
898  /* Get quality properties for the profile and quality level */
899  quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
900  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
901  .pVideoProfile = &ctx->profile,
902  .qualityLevel = ctx->opts.quality,
903  };
904  ctx->quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
905  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
906  .pNext = quality_pnext,
907  };
908  ret = vk->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(s->hwctx->phys_dev,
909  &quality_info,
910  &ctx->quality_props);
911  if (ret != VK_SUCCESS)
912  return AVERROR_EXTERNAL;
913 
914  /* Printout informative properties */
915  av_log(avctx, AV_LOG_VERBOSE, "Encoder capabilities for %s profile \"%s\":\n",
916  avcodec_get_name(avctx->codec_id),
917  avcodec_profile_name(avctx->codec_id, avctx->profile));
918  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
919  ctx->caps.minCodedExtent.width, ctx->caps.maxCodedExtent.width);
920  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
921  ctx->caps.minCodedExtent.height, ctx->caps.maxCodedExtent.height);
922  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
923  ctx->caps.pictureAccessGranularity.width);
924  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
925  ctx->caps.pictureAccessGranularity.height);
926  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
927  ctx->caps.minBitstreamBufferOffsetAlignment);
928  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
929  ctx->caps.minBitstreamBufferSizeAlignment);
930  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
931  ctx->caps.maxDpbSlots);
932  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
933  ctx->caps.maxActiveReferencePictures);
934  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
935  CODEC_VER(ctx->caps.stdHeaderVersion.specVersion),
936  CODEC_VER(vk_desc->ext_props.specVersion));
937  av_log(avctx, AV_LOG_VERBOSE, " Encoder max quality: %i\n",
938  ctx->enc_caps.maxQualityLevels);
939  av_log(avctx, AV_LOG_VERBOSE, " Encoder image width alignment: %i\n",
940  ctx->enc_caps.encodeInputPictureGranularity.width);
941  av_log(avctx, AV_LOG_VERBOSE, " Encoder image height alignment: %i\n",
942  ctx->enc_caps.encodeInputPictureGranularity.height);
943  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
944  ctx->caps.flags ? "" :
945  " none",
946  ctx->caps.flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
947  " protected" : "",
948  ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
949  " separate_references" : "");
950 
951  /* Setup width/height alignment */
952  base_ctx->surface_width = avctx->coded_width =
953  FFALIGN(avctx->width, ctx->enc_caps.encodeInputPictureGranularity.width);
954  base_ctx->surface_height = avctx->coded_height =
955  FFALIGN(avctx->height, ctx->enc_caps.encodeInputPictureGranularity.height);
956 
957  /* Setup slice width/height */
958  base_ctx->slice_block_width = ctx->enc_caps.encodeInputPictureGranularity.width;
959  base_ctx->slice_block_height = ctx->enc_caps.encodeInputPictureGranularity.height;
960 
961  /* Check if encoding is possible with the given parameters */
962  if (avctx->coded_width < ctx->caps.minCodedExtent.width ||
963  avctx->coded_height < ctx->caps.minCodedExtent.height ||
964  avctx->coded_width > ctx->caps.maxCodedExtent.width ||
965  avctx->coded_height > ctx->caps.maxCodedExtent.height) {
966  av_log(avctx, AV_LOG_ERROR, "Input of %ix%i too large for encoder limits: %ix%i max\n",
967  avctx->coded_width, avctx->coded_height,
968  ctx->caps.minCodedExtent.width, ctx->caps.minCodedExtent.height);
969  return AVERROR(EINVAL);
970  }
971 
972  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
973 
974  ctx->common.layered_dpb = !(ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
975 
976  /* Get the supported image formats */
977  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
978  &fmt_info,
979  &nb_out_fmts, NULL);
980  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
981  (!nb_out_fmts && ret == VK_SUCCESS)) {
982  return AVERROR(EINVAL);
983  } else if (ret != VK_SUCCESS) {
984  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
985  ff_vk_ret2str(ret));
986  return AVERROR_EXTERNAL;
987  }
988 
989  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
990  if (!ret_info)
991  return AVERROR(ENOMEM);
992 
993  for (int i = 0; i < nb_out_fmts; i++)
994  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
995 
996  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
997  &fmt_info,
998  &nb_out_fmts, ret_info);
999  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1000  (!nb_out_fmts && ret == VK_SUCCESS)) {
1001  av_free(ret_info);
1002  return AVERROR(EINVAL);
1003  } else if (ret != VK_SUCCESS) {
1004  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1005  ff_vk_ret2str(ret));
1006  av_free(ret_info);
1007  return AVERROR_EXTERNAL;
1008  }
1009 
1010  av_log(avctx, AV_LOG_VERBOSE, "Supported input formats:\n");
1011  for (i = 0; i < nb_out_fmts; i++)
1012  av_log(avctx, AV_LOG_VERBOSE, " %i: %i\n", i, ret_info[i].format);
1013 
1014  for (i = 0; i < nb_out_fmts; i++) {
1015  if (ff_vk_pix_fmt_from_vkfmt(ret_info[i].format) == s->frames->sw_format) {
1016  ctx->pic_format = ret_info[i].format;
1017  break;
1018  }
1019  }
1020 
1021  av_free(ret_info);
1022 
1023  if (i == nb_out_fmts) {
1024  av_log(avctx, AV_LOG_ERROR, "Pixel format %s of input frames not supported!\n",
1025  av_get_pix_fmt_name(s->frames->sw_format));
1026  return AVERROR(EINVAL);
1027  }
1028 
1029  /* Create session */
1030  session_create.pVideoProfile = &ctx->profile;
1031  session_create.flags = 0x0;
1032  session_create.queueFamilyIndex = ctx->qf_enc->idx;
1033  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1034  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1035  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1036  session_create.pictureFormat = ctx->pic_format;
1037  session_create.referencePictureFormat = session_create.pictureFormat;
1038  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1039 
1040  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1041  if (err < 0)
1042  return err;
1043 
1044  err = ff_hw_base_encode_init(avctx, &ctx->base);
1045  if (err < 0)
1046  return err;
1047 
1048  err = vulkan_encode_create_dpb(avctx, ctx);
1049  if (err < 0)
1050  return err;
1051 
1052  base_ctx->async_encode = 1;
1053  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
1054  sizeof(FFVulkanEncodePicture *), 0);
1055  if (!base_ctx->encode_fifo)
1056  return AVERROR(ENOMEM);
1057 
1058  return 0;
1059 }
1060 
1062  void *codec_params_pnext)
1063 {
1064  VkResult ret;
1065  FFVulkanFunctions *vk = &ctx->s.vkfn;
1066  FFVulkanContext *s = &ctx->s;
1067 
1068  VkVideoEncodeQualityLevelInfoKHR q_info;
1069  VkVideoSessionParametersCreateInfoKHR session_params_create;
1070 
1071  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
1072  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
1073  .pNext = codec_params_pnext,
1074  .qualityLevel = ctx->opts.quality,
1075  };
1076  session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1077  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1078  .pNext = &q_info,
1079  .videoSession = ctx->common.session,
1080  .videoSessionParametersTemplate = VK_NULL_HANDLE,
1081  };
1082 
1083  /* Create session parameters */
1084  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1085  s->hwctx->alloc, &ctx->session_params);
1086  if (ret != VK_SUCCESS) {
1087  av_log(avctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1088  ff_vk_ret2str(ret));
1089  return AVERROR_EXTERNAL;
1090  }
1091 
1092  return 0;
1093 }
vulkan_loader.h
vulkan_encode_init
static int vulkan_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: vulkan_encode.c:54
ff_vk_load_props
int ff_vk_load_props(FFVulkanContext *s)
Loads props/mprops/driver_props.
Definition: vulkan.c:142
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
FFVulkanEncodePicture::dpb
struct FFVulkanEncodePicture::@328 dpb
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:356
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:519
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:95
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:859
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:427
AVFrame::width
int width
Definition: frame.h:499
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:588
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:239
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:709
data
const char data[16]
Definition: mxf.c:149
ff_vk_create_view
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common, VkImageView *view, VkImageAspectFlags *aspect, AVVkFrame *src, VkFormat vkf, int is_dpb)
Creates image views for video frames.
Definition: vulkan_video.c:291
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:547
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:3002
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:439
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:779
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:88
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:551
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
fail
#define fail()
Definition: checkasm.h:208
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:208
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
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:35
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:607
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
pkt
AVPacket * pkt
Definition: movenc.c:60
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
av_cold
#define av_cold
Definition: attributes.h:106
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:515
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
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:1217
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
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:122
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:552
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:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
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:619
FFVulkanEncodePicture::aspect
VkImageAspectFlags aspect
Definition: vulkan_encode.h:46
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1270
ff_vk_exec_pool_free
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition: vulkan.c:287
FFVkExecContext::query_idx
int query_idx
Definition: vulkan.h:131
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:571
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:335
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:66
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:481
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:269
FFVkBuffer::size
size_t size
Definition: vulkan.h:91
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:228
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:100
FFVulkanContext
Definition: vulkan.h:274
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:977
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:115
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:57
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:550
init_rc
static av_cold int init_rc(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Definition: vulkan_encode.c:648
AVPacket::size
int size
Definition: packet.h:589
AVVkFrame
Definition: hwcontext_vulkan.h:298
FFHWBaseEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: hw_base_encode.h:97
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:90
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
FFVulkanEncodePicture::in
struct FFVulkanEncodePicture::@327 in
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:559
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:514
ff_vulkan_encode_receive_packet
int ff_vulkan_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Encode.
Definition: vulkan_encode.c:580
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:89
FFHWBaseEncodePicture::refs
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: hw_base_encode.h:98
vulkan_encode.h
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
vulkan_encode_issue
static int vulkan_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: vulkan_encode.c:141
vulkan_encode_create_dpb
static int vulkan_encode_create_dpb(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Definition: vulkan_encode.c:586
AVCodecContext::height
int height
Definition: avcodec.h:592
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:1453
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
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:274
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:431
AVFrame::height
int height
Definition: frame.h:499
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:1618
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:739
vulkan_base_encode_ops
static const FFHWEncodePictureOperation vulkan_base_encode_ops
Definition: vulkan_encode.c:572
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:461
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:217
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:607
desc
const char * desc
Definition: libsvtav1.c:78
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:274
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
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:31
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:565
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
FFVkBuffer
Definition: vulkan.h:87
FFVulkanCodec
Definition: vulkan_encode.h:94
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
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:904
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:638
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:277
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:1061
FFVulkanEncodePicture
Definition: vulkan_encode.h:39
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:1285
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:446
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