39 vk->DestroyImageView(
ctx->s.hwctx->act_dev, vp->
in.
view,
42 vp->
in.
view = VK_NULL_HANDLE;
56 if (
ctx->session_params)
57 vk->DestroyVideoSessionParametersKHR(
s->hwctx->act_dev,
86 if (
ctx->codec->picture_priv_data_size > 0) {
96 VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, 0);
101 if (!
ctx->common.layered_dpb) {
123 VkVideoEncodeRateControlInfoKHR *rc_info,
124 VkVideoEncodeRateControlLayerInfoKHR *rc_layer )
128 *rc_info = (VkVideoEncodeRateControlInfoKHR) {
129 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR,
130 .rateControlMode =
ctx->opts.rc_mode,
133 if (
ctx->opts.rc_mode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
134 *rc_layer = (VkVideoEncodeRateControlLayerInfoKHR) {
135 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR,
141 rc_info->layerCount++;
142 rc_info->pLayers = rc_layer;
145 return ctx->codec->init_pic_rc(avctx, pic, rc_info, rc_layer);
154 const size_t size_align =
ctx->caps.minBitstreamBufferSizeAlignment;
160 int err, max_pkt_size;
166 VkCommandBuffer cmd_buf;
167 VkImageMemoryBarrier2 img_bar[37];
171 VkVideoBeginCodingInfoKHR encode_start;
173 .sType = VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR,
176 VkVideoEncodeRateControlLayerInfoKHR rc_layer;
177 VkVideoEncodeRateControlInfoKHR rc_info;
178 VkVideoEncodeQualityLevelInfoKHR q_info;
179 VkVideoCodingControlInfoKHR encode_ctrl;
181 VkVideoReferenceSlotInfoKHR ref_slot[37];
182 VkVideoEncodeInfoKHR encode_info;
185 max_pkt_size =
FFALIGN(3 *
ctx->base.surface_width *
ctx->base.surface_height + (1 << 16),
186 ctx->caps.minBitstreamBufferSizeAlignment);
189 VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR,
190 &
ctx->profile_list, max_pkt_size,
191 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
192 ctx->s.host_cached_flag);
199 err =
init_pic_rc(avctx, base_pic, &rc_info, &rc_layer);
203 q_info = (VkVideoEncodeQualityLevelInfoKHR) {
204 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
206 .qualityLevel =
ctx->opts.quality,
208 encode_ctrl = (VkVideoCodingControlInfoKHR) {
209 .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR,
211 .flags = VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR |
212 VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR |
213 VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR,
216 for (
int i = 0;
i <
ctx->caps.maxDpbSlots;
i++) {
219 ctx->slots[
i] = base_pic;
226 vp->
dpb_res = (VkVideoPictureResourceInfoKHR) {
227 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
229 .codedOffset = { 0 },
230 .codedExtent = (VkExtent2D){ avctx->
width, avctx->
height },
231 .baseArrayLayer =
ctx->common.layered_dpb ? slot_index : 0,
232 .imageViewBinding = vp->
dpb.
view,
235 vp->
dpb_slot = (VkVideoReferenceSlotInfoKHR) {
236 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
238 .slotIndex = slot_index,
239 .pPictureResource = &vp->
dpb_res,
242 encode_info = (VkVideoEncodeInfoKHR) {
243 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR,
246 .srcPictureResource = (VkVideoPictureResourceInfoKHR) {
247 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
249 .codedOffset = { 0, 0 },
253 .imageViewBinding = vp->
in.
view,
255 .pSetupReferenceSlot = &vp->
dpb_slot,
256 .referenceSlotCount = 0,
257 .pReferenceSlots = ref_slot,
258 .dstBuffer = sd_buf->
buf,
259 .dstBufferOffset = 0,
260 .dstBufferRange = sd_buf->
size,
261 .precedingExternallyEncodedBytes = 0,
265 for (
int j = 0; j < base_pic->
nb_refs[
i]; j++) {
268 ref_slot[encode_info.referenceSlotCount++] = rvp->
dpb_slot;
274 ref_slot[encode_info.referenceSlotCount] = vp->
dpb_slot;
275 ref_slot[encode_info.referenceSlotCount].slotIndex = -1;
278 err =
ctx->codec->init_pic_params(avctx, base_pic,
283 encode_start = (VkVideoBeginCodingInfoKHR) {
284 .sType = VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR,
286 .videoSession =
ctx->common.session,
287 .videoSessionParameters =
ctx->session_params,
288 .referenceSlotCount = encode_info.referenceSlotCount + 1,
289 .pReferenceSlots = ref_slot,
294 uint8_t *hdr_dst = sd_buf->
mapped_mem + encode_info.dstBufferOffset;
295 size_t data_size = encode_info.dstBufferRange;
296 err =
ctx->codec->write_sequence_headers(avctx, base_pic, hdr_dst, &data_size);
299 encode_info.dstBufferOffset += data_size;
300 encode_info.dstBufferRange -= data_size;
304 if (
ctx->codec->write_extra_headers) {
305 uint8_t *hdr_dst = sd_buf->
mapped_mem + encode_info.dstBufferOffset;
306 size_t data_size = encode_info.dstBufferRange;
307 err =
ctx->codec->write_extra_headers(avctx, base_pic, hdr_dst, &data_size);
310 encode_info.dstBufferOffset += data_size;
311 encode_info.dstBufferRange -= data_size;
315 if (
ctx->codec->write_filler) {
316 uint8_t *hdr_dst = sd_buf->
mapped_mem + encode_info.dstBufferOffset;
317 size_t data_size = encode_info.dstBufferRange;
319 uint32_t
offset = encode_info.dstBufferOffset;
320 size_t offset_align =
ctx->caps.minBitstreamBufferOffsetAlignment;
325 while (filler_data < ctx->codec->filler_header_size)
326 filler_data += offset_align;
328 filler_data -=
ctx->codec->filler_header_size;
330 err =
ctx->codec->write_filler(avctx, filler_data,
331 hdr_dst, &data_size);
335 encode_info.dstBufferOffset += data_size;
336 encode_info.dstBufferRange -= data_size;
343 encode_info.dstBufferRange -= size_align;
344 encode_info.dstBufferRange =
FFALIGN(encode_info.dstBufferRange,
359 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
360 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR);
370 img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
371 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
373 .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
374 .srcAccessMask = VK_ACCESS_2_NONE,
375 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
376 .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR,
377 .oldLayout = vkf->
layout[0],
378 .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
380 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
381 .image = vkf->
img[0],
382 .subresourceRange = (VkImageSubresourceRange) {
389 &img_bar[nb_img_bar], &nb_img_bar);
393 if (!
ctx->common.layered_dpb) {
396 if (di->
layout != VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR) {
397 img_bar[nb_img_bar] = (VkImageMemoryBarrier2) {
398 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
399 .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
400 .srcAccessMask = VK_ACCESS_2_NONE,
401 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
402 .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR |
403 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR,
405 .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR,
406 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
407 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
409 .subresourceRange = (VkImageSubresourceRange) {
410 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
416 di->
layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
422 VkMemoryBarrier2 mem_bar = {
423 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
424 .srcStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
425 .srcAccessMask = VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR,
426 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
427 .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR |
428 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR,
432 vk->CmdPipelineBarrier2(cmd_buf, &(VkDependencyInfo) {
433 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
434 .pMemoryBarriers = &mem_bar,
435 .memoryBarrierCount = 1,
436 .pImageMemoryBarriers = img_bar,
437 .imageMemoryBarrierCount = nb_img_bar,
441 vk->CmdBeginVideoCodingKHR(cmd_buf, &encode_start);
444 if (!
ctx->session_reset) {
445 vk->CmdControlVideoCodingKHR(cmd_buf, &encode_ctrl);
446 ctx->session_reset++;
450 vk->CmdBeginQuery(cmd_buf,
ctx->enc_pool.query_pool, exec->
query_idx + 0, 0);
451 vk->CmdEncodeVideoKHR(cmd_buf, &encode_info);
452 vk->CmdEndQuery(cmd_buf,
ctx->enc_pool.query_pool, exec->
query_idx + 0);
455 vk->CmdEndVideoCodingKHR(cmd_buf, &
encode_end);
501 uint32_t *query_data;
506 if (ret == VK_NOT_READY) {
512 if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
518 if (query_data[2] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR) {
524 if (!(sd_buf->
flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
526 VkMappedMemoryRange invalidate_buf;
532 if (
ctx->s.props.properties.limits.nonCoherentAtomSize >
533 ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
534 (
FFALIGN(offs,
ctx->s.props.properties.limits.nonCoherentAtomSize) != offs)) {
535 offs -=
ctx->s.props.properties.limits.nonCoherentAtomSize;
536 offs =
FFALIGN(
FFMAX(offs, 0),
ctx->s.props.properties.limits.nonCoherentAtomSize);
539 invalidate_buf = (VkMappedMemoryRange) {
540 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
541 .memory = sd_buf->
mem,
543 .size = VK_WHOLE_SIZE,
546 vk->FlushMappedMemoryRanges(
ctx->s.hwctx->act_dev, 1, &invalidate_buf);
551 size_t prev_buf_size = vp->
slices_offset + query_data[0] + query_data[1];
553 ctx->prev_buf_size = prev_buf_size;
568 if (
ctx->prev_buf_ref) {
570 size_t prev_size =
ctx->prev_buf_size;
638 if (!
frame->buf[0]) {
642 frame->data[0] = (uint8_t *)di;
654 VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR,
655 VK_IMAGE_TILING_OPTIMAL, &
ctx->profile_list,
657 ctx->common.layered_dpb ?
658 ctx->caps.maxDpbSlots : 1);
665 if (
ctx->common.layered_dpb) {
668 VkImageMemoryBarrier2 img_bar;
671 if (!
ctx->common.layered_img)
674 ctx->common.layered_view =
ctx->common.layered_img->view;
675 ctx->common.layered_aspect =
ctx->common.layered_img->aspect;
683 img_bar = (VkImageMemoryBarrier2) {
684 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
685 .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
686 .srcAccessMask = VK_ACCESS_2_NONE,
687 .dstStageMask = VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR,
688 .dstAccessMask = VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR |
689 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR,
690 .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
691 .newLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR,
692 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
693 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
694 .image =
ctx->common.layered_img->img,
695 .subresourceRange = (VkImageSubresourceRange) {
696 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
697 .layerCount = VK_REMAINING_ARRAY_LAYERS,
701 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
702 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
703 .pImageMemoryBarriers = &img_bar,
704 .imageMemoryBarrierCount = 1,
711 ctx->common.layered_img->layout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR;
722 ctx->explicit_qp =
ctx->opts.qp;
731 if (
ctx->explicit_qp >= 0) {
732 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
738 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
740 if (
ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR)
741 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
742 else if (
ctx->enc_caps.rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR)
743 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
745 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
747 ctx->explicit_qp = 18;
748 ctx->opts.rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
752 }
else if (
ctx->opts.rc_mode != VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR &&
758 if (
ctx->opts.rc_mode && !(
ctx->enc_caps.rateControlModes &
ctx->opts.rc_mode)) {
759 static const char *rc_modes[] = {
760 [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR] =
"default",
761 [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR] =
"cqp",
762 [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR] =
"cbr",
763 [VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR] =
"vbr",
768 for (
int i = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
769 i <= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
i <<= 1) {
770 if (!(
ctx->enc_caps.rateControlModes &
i))
788 size_t data_len =
sizeof(
data);
790 err =
ctx->codec->write_sequence_headers(avctx,
NULL,
data, &data_len);
793 "for extradata: %d.\n", err);
813 void *codec_caps,
void *quality_pnext)
823 VkVideoFormatPropertiesKHR *ret_info;
824 uint32_t nb_out_fmts = 0;
825 const uint32_t feedback_flags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
826 VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
828 VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR quality_info;
830 VkQueryPoolVideoEncodeFeedbackCreateInfoKHR query_create;
832 VkVideoSessionCreateInfoKHR session_create = {
833 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR,
835 VkPhysicalDeviceVideoFormatInfoKHR fmt_info = {
836 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR,
837 .pNext = &
ctx->profile_list,
842 "required to associate the encoding device.\n");
851 s->hwfc =
s->frames->hwctx;
854 s->hwctx =
s->device->hwctx;
861 s->hwctx->nb_enabled_dev_extensions);
865 VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
869 VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME);
896 ctx->usage_info = (VkVideoEncodeUsageInfoKHR) {
897 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR,
898 .videoUsageHints =
ctx->opts.usage,
899 .videoContentHints =
ctx->opts.content,
900 .tuningMode =
ctx->opts.tune,
904 ctx->profile.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR;
905 ctx->profile.pNext = &
ctx->usage_info;
909 ctx->profile.chromaBitDepth =
ctx->profile.lumaBitDepth;
916 ctx->profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
917 ctx->profile_list.profileCount = 1;
918 ctx->profile_list.pProfiles = &
ctx->profile;
921 ctx->enc_caps.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR;
922 ctx->enc_caps.pNext = codec_caps;
923 ctx->caps.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR;
924 ctx->caps.pNext = &
ctx->enc_caps;
926 ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(
s->hwctx->phys_dev,
929 if (ret == VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR) {
931 "%s profile \"%s\" not supported!\n",
935 }
else if (ret == VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR) {
937 "format (%s) not supported!\n",
940 }
else if (ret == VK_ERROR_FEATURE_NOT_PRESENT ||
941 ret == VK_ERROR_FORMAT_NOT_SUPPORTED) {
943 }
else if (ret != VK_SUCCESS) {
947 if ((
ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) !=
950 "Driver does not support required encode feedback flags "
951 "(BUFFER_OFFSET and BYTES_WRITTEN).\n");
960 query_create = (VkQueryPoolVideoEncodeFeedbackCreateInfoKHR) {
961 .sType = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR,
962 .pNext = &
ctx->profile,
963 .encodeFeedbackFlags = feedback_flags,
966 1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
971 if (
ctx->opts.quality >
ctx->enc_caps.maxQualityLevels) {
974 ctx->opts.quality,
ctx->enc_caps.maxQualityLevels);
979 quality_info = (VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR) {
980 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
981 .pVideoProfile = &
ctx->profile,
982 .qualityLevel =
ctx->opts.quality,
984 ctx->quality_props = (VkVideoEncodeQualityLevelPropertiesKHR) {
985 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR,
986 .pNext = quality_pnext,
988 ret = vk->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(
s->hwctx->phys_dev,
990 &
ctx->quality_props);
991 if (ret != VK_SUCCESS)
999 ctx->caps.minCodedExtent.width,
ctx->caps.maxCodedExtent.width);
1001 ctx->caps.minCodedExtent.height,
ctx->caps.maxCodedExtent.height);
1003 ctx->caps.pictureAccessGranularity.width);
1005 ctx->caps.pictureAccessGranularity.height);
1007 ctx->caps.minBitstreamBufferOffsetAlignment);
1009 ctx->caps.minBitstreamBufferSizeAlignment);
1011 ctx->caps.maxDpbSlots);
1013 ctx->caps.maxActiveReferencePictures);
1014 av_log(avctx,
AV_LOG_VERBOSE,
" Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
1018 ctx->enc_caps.maxQualityLevels);
1020 ctx->enc_caps.encodeInputPictureGranularity.width);
1022 ctx->enc_caps.encodeInputPictureGranularity.height);
1024 ctx->caps.flags ?
"" :
1026 ctx->caps.flags & VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR ?
1028 ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR ?
1029 " separate_references" :
"");
1033 FFALIGN(avctx->
width,
ctx->enc_caps.encodeInputPictureGranularity.width);
1035 FFALIGN(avctx->
height,
ctx->enc_caps.encodeInputPictureGranularity.height);
1046 av_log(avctx,
AV_LOG_ERROR,
"Input of %ix%i too large for encoder limits: %ix%i max\n",
1048 ctx->caps.minCodedExtent.width,
ctx->caps.minCodedExtent.height);
1052 fmt_info.imageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
1054 ctx->common.layered_dpb = !(
ctx->caps.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR);
1057 ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(
s->hwctx->phys_dev,
1059 &nb_out_fmts,
NULL);
1060 if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1061 (!nb_out_fmts && ret == VK_SUCCESS)) {
1063 }
else if (ret != VK_SUCCESS) {
1069 ret_info =
av_mallocz(
sizeof(*ret_info)*nb_out_fmts);
1073 for (
int i = 0;
i < nb_out_fmts;
i++)
1074 ret_info[
i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1076 ret = vk->GetPhysicalDeviceVideoFormatPropertiesKHR(
s->hwctx->phys_dev,
1078 &nb_out_fmts, ret_info);
1079 if (ret == VK_ERROR_FORMAT_NOT_SUPPORTED ||
1080 (!nb_out_fmts && ret == VK_SUCCESS)) {
1083 }
else if (ret != VK_SUCCESS) {
1091 for (
i = 0;
i < nb_out_fmts;
i++)
1094 for (
i = 0;
i < nb_out_fmts;
i++) {
1096 ctx->pic_format = ret_info[
i].format;
1103 if (
i == nb_out_fmts) {
1110 session_create.pVideoProfile = &
ctx->profile;
1111 session_create.flags = VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_PARAMETER_OPTIMIZATIONS_BIT_KHR;
1112 session_create.queueFamilyIndex =
ctx->qf_enc->idx;
1113 session_create.maxCodedExtent =
ctx->caps.maxCodedExtent;
1114 session_create.maxDpbSlots =
ctx->caps.maxDpbSlots;
1115 session_create.maxActiveReferencePictures =
ctx->caps.maxActiveReferencePictures;
1116 session_create.pictureFormat =
ctx->pic_format;
1117 session_create.referencePictureFormat = session_create.pictureFormat;
1118 session_create.pStdHeaderVersion = &vk_desc->
ext_props;
1142 void *codec_params_pnext)
1148 VkVideoEncodeQualityLevelInfoKHR q_info;
1149 VkVideoSessionParametersCreateInfoKHR session_params_create;
1151 q_info = (VkVideoEncodeQualityLevelInfoKHR) {
1152 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR,
1153 .pNext = codec_params_pnext,
1154 .qualityLevel =
ctx->opts.quality,
1156 session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
1157 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
1159 .videoSession =
ctx->common.session,
1160 .videoSessionParametersTemplate = VK_NULL_HANDLE,
1164 ret = vk->CreateVideoSessionParametersKHR(
s->hwctx->act_dev, &session_params_create,
1165 s->hwctx->alloc, &
ctx->session_params);
1166 if (ret != VK_SUCCESS) {
1167 av_log(avctx,
AV_LOG_ERROR,
"Unable to create Vulkan video session parameters: %s!\n",
static const char *const format[]
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define i(width, name, range_min, range_max)
int(* init)(AVBSFContext *ctx)
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
const char * avcodec_profile_name(enum AVCodecID codec_id, int profile)
Return a name for the specified profile, if available.
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
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.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_cold int encode_end(AVCodecContext *avctx)
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
#define MAX_REFERENCE_LIST_NUM
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
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.
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
int ff_vk_load_props(FFVulkanContext *s)
Loads props/mprops/driver_props.
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e, void **data, VkQueryResultFlagBits flags)
Performs nb_queries queries and returns their results and statuses.
void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar)
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Memory handling functions.
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.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
void * av_refstruct_pool_get(AVRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
#define FF_ARRAY_ELEMS(a)
main external API structure.
int width
picture width / height.
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
int global_quality
Global quality for codecs which cannot change it per frame.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
int64_t bit_rate
the average bitrate
int64_t rc_max_rate
maximum bitrate
int flags
AV_CODEC_FLAG_*.
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
int coded_width
Bitstream width / height, may be different from width/height e.g.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
This struct describes a set or pool of "hardware" frames (i.e.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
This structure stores compressed data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
VkImageLayout layout[AV_NUM_DATA_POINTERS]
uint32_t queue_family[AV_NUM_DATA_POINTERS]
Queue family of the images.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
VkFormat format[AV_NUM_DATA_POINTERS]
Vulkan format for each image.
int(* get_recon_frame)(AVCodecContext *avctx, AVFrame *frame)
AVPacket * tail_pkt
Tail data of a pic, now only used for av1 repeat frame header.
int nb_refs[MAX_REFERENCE_LIST_NUM]
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
VkMemoryPropertyFlagBits flags
VkImageAspectFlags aspect
int(* init_profile)(AVCodecContext *avctx, VkVideoProfileInfoKHR *profile, void *pnext)
Initialize codec-specific structs in a Vulkan profile.
VkVideoCodecOperationFlagBitsKHR encode_op
VkExtensionProperties ext_props
FFVulkanExtensions encode_extension
struct FFVulkanEncodePicture::@241153336102273375156314120123002360217156257341 in
VkVideoPictureResourceInfoKHR dpb_res
int non_independent_frame
VkImageAspectFlags aspect
struct FFVulkanEncodePicture::@211005011031223012316203343327310203116057373135 dpb
VkVideoReferenceSlotInfoKHR dpb_slot
static int ref[MAX_W *MAX_W]
static int vulkan_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
static int vulkan_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
const AVCodecHWConfigInternal *const ff_vulkan_encode_hw_configs[]
Paperwork.
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.
static void vulkan_encode_free_pic(FFVulkanEncodeContext *ctx, FFHWBaseEncodePicture *pic)
static int vulkan_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
static int vulkan_encode_create_dpb(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
static int vulkan_encode_get_recon_frame(AVCodecContext *avctx, AVFrame *frame)
static void vulkan_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
static int vulkan_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
static const FFHWEncodePictureOperation vulkan_base_encode_ops
av_cold void ff_vulkan_encode_uninit(FFVulkanEncodeContext *ctx)
Uninitialize encoder.
static void vulkan_encode_recon_free(void *opaque, uint8_t *data)
static int init_pic_rc(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, VkVideoEncodeRateControlInfoKHR *rc_info, VkVideoEncodeRateControlLayerInfoKHR *rc_layer)
int ff_vulkan_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Encode.
av_cold int ff_vulkan_write_global_header(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
Write out the extradata in case its needed.
static av_cold int init_rc(AVCodecContext *avctx, FFVulkanEncodeContext *ctx)
static void pkt_buf_free(void *opaque, uint8_t *data)
int ff_vulkan_encode_create_session_params(AVCodecContext *avctx, FFVulkanEncodeContext *ctx, void *codec_params_pnext)
Create session parameters.
#define FF_VK_RC_MODE_AUTO
#define VK_ENC_FLAG_NO_DELAY
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth)
Get Vulkan's bit depth from an [8:12] integer.
VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFmtDescriptor *desc)
Get Vulkan's chroma subsampling from a pixfmt descriptor.
int ff_vk_create_view(FFVulkanContext *s, VkImageView *view, VkImageAspectFlags *aspect, VkImage img, VkFormat vkf, VkImageUsageFlags usage, int layered)
Creates image views for video frames.
av_cold void ff_vk_video_common_uninit(FFVulkanContext *s, FFVkVideoCommon *common)
Free video session and required resources.
av_cold int ff_vk_video_dpb_init(FFVulkanContext *s, FFVkVideoCommon *common, VkFormat format, VkImageUsageFlags usage, VkImageTiling tiling, void *create_pnext, int width, int height, int nb_layers)
Initialize the internal DPB image pool.
enum AVPixelFormat ff_vk_pix_fmt_from_vkfmt(VkFormat vkf)
Get pixfmt from a Vulkan format.
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.