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], VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
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, VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
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  ctx->s.host_cached_flag);
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], VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
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  const uint32_t feedback_flags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
755  VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
756 
757  VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
758 
759  VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
760 
761  VkVideoSessionCreateInfoKHR session_create = {
762  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
763  };
764  VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
765  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
766  .pNext = &ctx->profile_list,
767  };
768 
769  if (!avctx->hw_frames_ctx) {
770  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
771  "required to associate the encoding device.\n");
772  return AVERROR(EINVAL);
773  }
774 
775  if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) !=
776  feedback_flags) {
777  av_log (avctx, AV_LOG_ERROR,
778  "Driver does not support required encode feedback flags "
779  "(BUFFER_OFFSET and BYTES_WRITTEN).\n");
780  return AVERROR(ENOTSUP);
781  }
782 
783  ctx->base.op = &vulkan_base_encode_ops;
784  ctx->codec = codec;
785 
786  s->frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
787  s->frames = (AVHWFramesContext *)s->frames_ref->data;
788  s->hwfc = s->frames->hwctx;
789 
790  s->device = (AVHWDeviceContext *)s->frames->device_ref->data;
791  s->hwctx = s->device->hwctx;
792 
794  if (!desc)
795  return AVERROR(EINVAL);
796 
797  s->extensions = ff_vk_extensions_to_mask(s->hwctx->enabled_dev_extensions,
798  s->hwctx->nb_enabled_dev_extensions);
799 
800  if (!(s->extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE)) {
801  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
802  VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
803  return AVERROR(ENOSYS);
804  } else if (!(s->extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1)) {
805  av_log(avctx, AV_LOG_ERROR, "Device does not support the %s extension!\n",
806  VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME);
807  return AVERROR(ENOSYS);
808  } else if (!(s->extensions & vk_desc->encode_extension)) {
809  av_log(avctx, AV_LOG_ERROR, "Device does not support encoding %s!\n",
810  avcodec_get_name(avctx->codec_id));
811  return AVERROR(ENOSYS);
812  }
813 
814  /* Load functions */
815  err = ff_vk_load_functions(s->device, vk, s->extensions, 1, 1);
816  if (err < 0)
817  return err;
818 
819  /* Create queue context */
820  ctx->qf_enc = ff_vk_qf_find(s, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, vk_desc->encode_op);
821  if (!ctx->qf_enc) {
822  av_log(avctx, AV_LOG_ERROR, "Encoding of %s is not supported by this device\n",
823  avcodec_get_name(avctx->codec_id));
824  return err;
825  }
826 
827  /* Load all properties */
828  err = ff_vk_load_props(s);
829  if (err < 0)
830  return err;
831 
832  /* Set tuning */
833  ctx->usage_info = (VkVideoEncodeUsageInfoKHR) {
834  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR,
835  .videoUsageHints = ctx->opts.usage,
836  .videoContentHints = ctx->opts.content,
837  .tuningMode = ctx->opts.tune,
838  };
839 
840  /* Load up the profile now, needed for caps and to create a query pool */
841  ctx->profile.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
842  ctx->profile.pNext = &ctx->usage_info;
843  ctx->profile.videoCodecOperation = vk_desc->encode_op;
844  ctx->profile.chromaSubsampling = ff_vk_subsampling_from_av_desc(desc);
845  ctx->profile.lumaBitDepth = ff_vk_depth_from_av_depth(desc->comp[0].depth);
846  ctx->profile.chromaBitDepth = ctx->profile.lumaBitDepth;
847 
848  /* Setup a profile */
849  err = codec->init_profile(avctx, &ctx->profile, &ctx->usage_info);
850  if (err < 0)
851  return err;
852 
853  ctx->profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
854  ctx->profile_list.profileCount = 1;
855  ctx->profile_list.pProfiles = &ctx->profile;
856 
857  /* Get the capabilities of the encoder for the given profile */
858  ctx->enc_caps.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR;
859  ctx->enc_caps.pNext = codec_caps;
860  ctx->caps.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
861  ctx->caps.pNext = &ctx->enc_caps;
862 
863  ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
864  &ctx->profile,
865  &ctx->caps);
866  if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
867  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
868  "%s profile \"%s\" not supported!\n",
869  avcodec_get_name(avctx->codec_id),
870  avcodec_profile_name(avctx->codec_id, avctx->profile));
871  return AVERROR(EINVAL);
872  } else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
873  av_log(avctx, AV_LOG_ERROR, "Unable to initialize encoding: "
874  "format (%s) not supported!\n",
876  return AVERROR(EINVAL);
877  } else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
878  ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
879  return AVERROR(EINVAL);
880  } else if (ret != VK_SUCCESS) {
881  return AVERROR_EXTERNAL;
882  }
883 
884  err = init_rc(avctx, ctx);
885  if (err < 0)
886  return err;
887 
888  /* Create command and query pool */
889  query_create = (VkQueryPoolVideoEncodeFeedbackCreateInfoKHR) {
890  .sType = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR,
891  .pNext = &ctx->profile,
892  .encodeFeedbackFlags = feedback_flags,
893  };
894  err = ff_vk_exec_pool_init(s, ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
895  1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
896  &query_create);
897  if (err < 0)
898  return err;
899 
900  if (ctx->opts.quality > ctx->enc_caps.maxQualityLevels) {
901  av_log(avctx, AV_LOG_ERROR, "Invalid quality level %i: allowed range is "
902  "0 to %i\n",
903  ctx->opts.quality, ctx->enc_caps.maxQualityLevels);
904  return AVERROR(EINVAL);
905  }
906 
907  /* Get quality properties for the profile and quality level */
908  quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
909  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
910  .pVideoProfile = &ctx->profile,
911  .qualityLevel = ctx->opts.quality,
912  };
913  ctx->quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
914  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
915  .pNext = quality_pnext,
916  };
917  ret = vk->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(s->hwctx->phys_dev,
918  &quality_info,
919  &ctx->quality_props);
920  if (ret != VK_SUCCESS)
921  return AVERROR_EXTERNAL;
922 
923  /* Printout informative properties */
924  av_log(avctx, AV_LOG_VERBOSE, "Encoder capabilities for %s profile \"%s\":\n",
925  avcodec_get_name(avctx->codec_id),
926  avcodec_profile_name(avctx->codec_id, avctx->profile));
927  av_log(avctx, AV_LOG_VERBOSE, " Width: from %i to %i\n",
928  ctx->caps.minCodedExtent.width, ctx->caps.maxCodedExtent.width);
929  av_log(avctx, AV_LOG_VERBOSE, " Height: from %i to %i\n",
930  ctx->caps.minCodedExtent.height, ctx->caps.maxCodedExtent.height);
931  av_log(avctx, AV_LOG_VERBOSE, " Width alignment: %i\n",
932  ctx->caps.pictureAccessGranularity.width);
933  av_log(avctx, AV_LOG_VERBOSE, " Height alignment: %i\n",
934  ctx->caps.pictureAccessGranularity.height);
935  av_log(avctx, AV_LOG_VERBOSE, " Bitstream offset alignment: %"PRIu64"\n",
936  ctx->caps.minBitstreamBufferOffsetAlignment);
937  av_log(avctx, AV_LOG_VERBOSE, " Bitstream size alignment: %"PRIu64"\n",
938  ctx->caps.minBitstreamBufferSizeAlignment);
939  av_log(avctx, AV_LOG_VERBOSE, " Maximum references: %u\n",
940  ctx->caps.maxDpbSlots);
941  av_log(avctx, AV_LOG_VERBOSE, " Maximum active references: %u\n",
942  ctx->caps.maxActiveReferencePictures);
943  av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
944  CODEC_VER(ctx->caps.stdHeaderVersion.specVersion),
945  CODEC_VER(vk_desc->ext_props.specVersion));
946  av_log(avctx, AV_LOG_VERBOSE, " Encoder max quality: %i\n",
947  ctx->enc_caps.maxQualityLevels);
948  av_log(avctx, AV_LOG_VERBOSE, " Encoder image width alignment: %i\n",
949  ctx->enc_caps.encodeInputPictureGranularity.width);
950  av_log(avctx, AV_LOG_VERBOSE, " Encoder image height alignment: %i\n",
951  ctx->enc_caps.encodeInputPictureGranularity.height);
952  av_log(avctx, AV_LOG_VERBOSE, " Capability flags:%s%s%s\n",
953  ctx->caps.flags ? "" :
954  " none",
955  ctx->caps.flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
956  " protected" : "",
957  ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
958  " separate_references" : "");
959 
960  /* Setup width/height alignment */
961  base_ctx->surface_width = avctx->coded_width =
962  FFALIGN(avctx->width, ctx->enc_caps.encodeInputPictureGranularity.width);
963  base_ctx->surface_height = avctx->coded_height =
964  FFALIGN(avctx->height, ctx->enc_caps.encodeInputPictureGranularity.height);
965 
966  /* Setup slice width/height */
967  base_ctx->slice_block_width = ctx->enc_caps.encodeInputPictureGranularity.width;
968  base_ctx->slice_block_height = ctx->enc_caps.encodeInputPictureGranularity.height;
969 
970  /* Check if encoding is possible with the given parameters */
971  if (avctx->coded_width < ctx->caps.minCodedExtent.width ||
972  avctx->coded_height < ctx->caps.minCodedExtent.height ||
973  avctx->coded_width > ctx->caps.maxCodedExtent.width ||
974  avctx->coded_height > ctx->caps.maxCodedExtent.height) {
975  av_log(avctx, AV_LOG_ERROR, "Input of %ix%i too large for encoder limits: %ix%i max\n",
976  avctx->coded_width, avctx->coded_height,
977  ctx->caps.minCodedExtent.width, ctx->caps.minCodedExtent.height);
978  return AVERROR(EINVAL);
979  }
980 
981  fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
982 
983  ctx->common.layered_dpb = !(ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
984 
985  /* Get the supported image formats */
986  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
987  &fmt_info,
988  &nb_out_fmts, NULL);
989  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
990  (!nb_out_fmts && ret == VK_SUCCESS)) {
991  return AVERROR(EINVAL);
992  } else if (ret != VK_SUCCESS) {
993  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
994  ff_vk_ret2str(ret));
995  return AVERROR_EXTERNAL;
996  }
997 
998  ret_info = av_mallocz(sizeof(*ret_info)*nb_out_fmts);
999  if (!ret_info)
1000  return AVERROR(ENOMEM);
1001 
1002  for (int i = 0; i < nb_out_fmts; i++)
1003  ret_info[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1004 
1005  ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(s->hwctx->phys_dev,
1006  &fmt_info,
1007  &nb_out_fmts, ret_info);
1008  if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1009  (!nb_out_fmts && ret == VK_SUCCESS)) {
1010  av_free(ret_info);
1011  return AVERROR(EINVAL);
1012  } else if (ret != VK_SUCCESS) {
1013  av_log(avctx, AV_LOG_ERROR, "Unable to get Vulkan format properties: %s!\n",
1014  ff_vk_ret2str(ret));
1015  av_free(ret_info);
1016  return AVERROR_EXTERNAL;
1017  }
1018 
1019  av_log(avctx, AV_LOG_VERBOSE, "Supported input formats:\n");
1020  for (i = 0; i < nb_out_fmts; i++)
1021  av_log(avctx, AV_LOG_VERBOSE, " %i: %i\n", i, ret_info[i].format);
1022 
1023  for (i = 0; i < nb_out_fmts; i++) {
1024  if (ff_vk_pix_fmt_from_vkfmt(ret_info[i].format) == s->frames->sw_format) {
1025  ctx->pic_format = ret_info[i].format;
1026  break;
1027  }
1028  }
1029 
1030  av_free(ret_info);
1031 
1032  if (i == nb_out_fmts) {
1033  av_log(avctx, AV_LOG_ERROR, "Pixel format %s of input frames not supported!\n",
1034  av_get_pix_fmt_name(s->frames->sw_format));
1035  return AVERROR(EINVAL);
1036  }
1037 
1038  /* Create session */
1039  session_create.pVideoProfile = &ctx->profile;
1040  session_create.flags = 0x0;
1041  session_create.queueFamilyIndex = ctx->qf_enc->idx;
1042  session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
1043  session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
1044  session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
1045  session_create.pictureFormat = ctx->pic_format;
1046  session_create.referencePictureFormat = session_create.pictureFormat;
1047  session_create.pStdHeaderVersion = &vk_desc->ext_props;
1048 
1049  err = ff_vk_video_common_init(avctx, s, &ctx->common, &session_create);
1050  if (err < 0)
1051  return err;
1052 
1053  err = ff_hw_base_encode_init(avctx, &ctx->base);
1054  if (err < 0)
1055  return err;
1056 
1057  err = vulkan_encode_create_dpb(avctx, ctx);
1058  if (err < 0)
1059  return err;
1060 
1061  base_ctx->async_encode = 1;
1062  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
1063  sizeof(FFVulkanEncodePicture *), 0);
1064  if (!base_ctx->encode_fifo)
1065  return AVERROR(ENOMEM);
1066 
1067  return 0;
1068 }
1069 
1071  void *codec_params_pnext)
1072 {
1073  VkResult ret;
1074  FFVulkanFunctions *vk = &ctx->s.vkfn;
1075  FFVulkanContext *s = &ctx->s;
1076 
1077  VkVideoEncodeQualityLevelInfoKHR q_info;
1078  VkVideoSessionParametersCreateInfoKHR session_params_create;
1079 
1080  q_info = (VkVideoEncodeQualityLevelInfoKHR) {
1081  .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
1082  .pNext = codec_params_pnext,
1083  .qualityLevel = ctx->opts.quality,
1084  };
1085  session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1086  .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1087  .pNext = &q_info,
1088  .videoSession = ctx->common.session,
1089  .videoSessionParametersTemplate = VK_NULL_HANDLE,
1090  };
1091 
1092  /* Create session parameters */
1093  ret = vk->CreateVideoSessionParametersKHR(s->hwctx->act_dev, &session_params_create,
1094  s->hwctx->alloc, &ctx->session_params);
1095  if (ret != VK_SUCCESS) {
1096  av_log(avctx, AV_LOG_ERROR, "Unable to create Vulkan video session parameters: %s!\n",
1097  ff_vk_ret2str(ret));
1098  return AVERROR_EXTERNAL;
1099  }
1100 
1101  return 0;
1102 }
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: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
FFVulkanEncodePicture::in
struct FFVulkanEncodePicture::@341 in
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:520
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:860
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:434
AVFrame::width
int width
Definition: frame.h:506
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:251
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
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:548
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:2836
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:780
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:455
FFVkBuffer::buf
VkBuffer buf
Definition: vulkan.h:126
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:559
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:224
AVVulkanFramesContext
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
Definition: hwcontext_vulkan.h:220
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:496
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:615
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
av_cold
#define av_cold
Definition: attributes.h:111
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:523
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:1229
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1414
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:128
ff_vk_exec_wait
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition: vulkan.c:553
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:620
FFVulkanEncodePicture::aspect
VkImageAspectFlags aspect
Definition: vulkan_encode.h:46
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1282
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:165
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:449
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:337
FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
Definition: vulkan_functions.h:68
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:489
FFVulkanEncodePicture::dpb
struct FFVulkanEncodePicture::@342 dpb
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:281
FFVkBuffer::size
size_t size
Definition: vulkan.h:129
AVVulkanFramesContext::usage
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Definition: hwcontext_vulkan.h:240
FFVkBuffer::mapped_mem
uint8_t * mapped_mem
Definition: vulkan.h:134
FFVulkanContext
Definition: vulkan.h:312
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: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:59
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:310
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:128
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:145
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:406
ff_vk_exec_start
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition: vulkan.c:560
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:522
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:127
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: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:600
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:1465
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:156
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:439
AVFrame::height
int height
Definition: frame.h:506
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:1630
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:229
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:615
desc
const char * desc
Definition: libsvtav1.c:82
AVVulkanFramesContext::nb_layers
int nb_layers
Number of layers each image will have.
Definition: hwcontext_vulkan.h:286
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:466
FFVkBuffer
Definition: vulkan.h:125
FFVulkanCodec
Definition: vulkan_encode.h:94
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:600
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
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:905
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:646
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:274
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:1070
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:1286
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