35 .encode_op = VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR,
37 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME,
38 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION,
86 VkVideoEncodeAV1CapabilitiesKHR
caps;
107 VkVideoEncodeRateControlInfoKHR *rc_info,
108 VkVideoEncodeRateControlLayerInfoKHR *rc_layer)
116 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_GOP_REMAINING_FRAME_INFO_KHR,
117 .useGopRemainingFrames = 0,
118 .gopRemainingIntra = 0,
119 .gopRemainingPredictive = 0,
120 .gopRemainingBipredictive = 0,
123 ap->
vkrc_info = (VkVideoEncodeAV1RateControlInfoKHR) {
124 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_INFO_KHR,
125 .flags = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR |
126 VK_VIDEO_ENCODE_AV1_RATE_CONTROL_REGULAR_GOP_BIT_KHR,
127 .gopFrameCount =
ctx->base.gop_size,
128 .keyFramePeriod =
ctx->base.gop_size,
129 .consecutiveBipredictiveFrameCount =
FFMAX(
ctx->base.b_per_p - 1, 0),
130 .temporalLayerCount = 0,
134 if (rc_info->rateControlMode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
139 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR,
141 .useMinQIndex = avctx->
qmin > 0,
142 .minQIndex.intraQIndex = avctx->
qmin > 0 ? avctx->
qmin : 0,
143 .minQIndex.predictiveQIndex = avctx->
qmin > 0 ? avctx->
qmin : 0,
144 .minQIndex.bipredictiveQIndex = avctx->
qmin > 0 ? avctx->
qmin : 0,
146 .useMaxQIndex = avctx->
qmax > 0,
147 .maxQIndex.intraQIndex = avctx->
qmax > 0 ? avctx->
qmax : 0,
148 .maxQIndex.predictiveQIndex = avctx->
qmax > 0 ? avctx->
qmax : 0,
149 .maxQIndex.bipredictiveQIndex = avctx->
qmax > 0 ? avctx->
qmax : 0,
151 .useMaxFrameSize = 0,
160 static void set_name_slot(
int slot,
int *slot_indices, uint32_t allowed_idx,
int group)
166 if ((slot_indices[
i] == -1) && (allowed_idx & (1 <<
i))) {
167 slot_indices[
i] = slot;
177 VkVideoEncodeInfoKHR *encode_info)
186 VkVideoReferenceSlotInfoKHR *ref_slot;
188 uint32_t ref_name_mask = 0x0;
189 int name_slots[STD_VIDEO_AV1_REFS_PER_FRAME];
191 StdVideoAV1Segmentation *segmentation = &ap->
segmentation;
193 StdVideoAV1Quantization *quantization = &ap->
quantization;
194 StdVideoAV1CDEF *cdef = &ap->
cdef;
198 static const int8_t default_loop_filter_ref_deltas[STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME] =
199 { 1, 0, 0, 0, -1, 0, -1, -1 };
201 VkVideoEncodeAV1PredictionModeKHR pred_mode;
202 VkVideoEncodeAV1RateControlGroupKHR rc_group;
203 int lr_unit_shift = 0;
206 ap->
ext_header = (StdVideoEncodeAV1ExtensionHeader) {
212 .flags = (StdVideoAV1TileInfoFlags) {
217 .context_update_tile_id = 0,
218 .tile_size_bytes_minus_1 = 0,
221 for (
int i = 0;
i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME;
i++) {
222 global_motion->GmType[
i] = 0;
223 for (
int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
224 global_motion->gm_params[
i][j] = 0;
228 for (
int i = 0;
i < STD_VIDEO_AV1_REFS_PER_FRAME;
i++)
231 *loop_restoration = (StdVideoAV1LoopRestoration) {
232 .FrameRestorationType[0] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
233 .FrameRestorationType[1] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
234 .FrameRestorationType[2] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
235 .LoopRestorationSize[0] = 1 + lr_unit_shift,
236 .LoopRestorationSize[1] = 1 + lr_unit_shift - lr_uv_shift,
237 .LoopRestorationSize[2] = 1 + lr_unit_shift - lr_uv_shift,
240 *cdef = (StdVideoAV1CDEF) {
241 .cdef_damping_minus_3 = 0,
245 for (
int i = 0;
i < STD_VIDEO_AV1_MAX_SEGMENTS;
i++) {
246 segmentation->FeatureEnabled[
i] = 0x0;
247 for (
int j = 0; j < STD_VIDEO_AV1_SEG_LVL_MAX; j++) {
248 segmentation->FeatureEnabled[
i] |= 0x0;
249 segmentation->FeatureData[
i][j] = 0;
254 .flags = (StdVideoAV1LoopFilterFlags) {
255 .loop_filter_delta_enabled = 0,
256 .loop_filter_delta_update = 0,
258 .loop_filter_level = { 0 },
259 .loop_filter_sharpness = 0,
260 .update_ref_delta = 0,
261 .loop_filter_ref_deltas = { 0 },
262 .update_mode_delta = 0,
263 .loop_filter_mode_deltas = { 0 },
266 memcpy(
loop_filter->loop_filter_ref_deltas, default_loop_filter_ref_deltas,
267 STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME *
sizeof(int8_t));
269 *quantization = (StdVideoAV1Quantization) {
270 .flags = (StdVideoAV1QuantizationFlags) {
286 ref_slot = (VkVideoReferenceSlotInfoKHR *)encode_info->pSetupReferenceSlot;
288 .flags = (StdVideoEncodeAV1PictureInfoFlags) {
292 .disable_cdf_update = 0,
294 .render_and_frame_size_different = 0,
295 .allow_screen_content_tools = 0,
296 .is_filter_switchable = 0,
297 .force_integer_mv = 0,
298 .frame_size_override_flag = 0,
299 .buffer_removal_time_present_flag = 0,
301 .frame_refs_short_signaling = 0,
302 .allow_high_precision_mv = 0,
303 .is_motion_mode_switchable = 0,
304 .use_ref_frame_mvs = 0,
305 .disable_frame_end_update_cdf = 0,
306 .allow_warped_motion = 0,
308 .skip_mode_present = 0,
309 .delta_q_present = 0,
310 .delta_lf_present = 0,
312 .segmentation_enabled = 0,
313 .segmentation_update_map = 0,
314 .segmentation_temporal_update = 0,
315 .segmentation_update_data = 0,
323 .frame_presentation_time = 0,
324 .current_frame_id = ref_slot->slotIndex,
326 .primary_ref_frame = 0,
327 .refresh_frame_flags = 0x0,
331 .interpolation_filter = 0,
332 .TxMode = STD_VIDEO_AV1_TX_MODE_SELECT,
335 .ref_order_hint = { 0 },
336 .ref_frame_idx = { 0 },
338 .delta_frame_id_minus_1 = { 0 },
341 .pQuantization = quantization,
342 .pSegmentation = segmentation,
345 .pLoopRestoration = loop_restoration,
346 .pGlobalMotion = global_motion,
348 .pBufferRemovalTimes =
NULL,
355 ap->
av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_KEY;
357 quantization->base_q_idx = enc->
q_idx_idr;
360 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_INTRA_ONLY_KHR;
361 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_INTRA_KHR;
365 ap_ref =
ref->codec_priv;
367 ap->
av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_INTER;
368 quantization->base_q_idx = enc->
q_idx_p;
381 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_PREDICTIVE_KHR;
382 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_SINGLE_REFERENCE_KHR;
383 ref_name_mask = enc->
caps.singleReferenceNameMask;
390 ((enc->
caps.maxSingleReferenceCount > 1) ||
391 (enc->
caps.maxUnidirectionalCompoundReferenceCount > 0))) {
392 if (enc->
caps.maxUnidirectionalCompoundReferenceCount) {
393 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_UNIDIRECTIONAL_COMPOUND_KHR;
394 ref_name_mask = enc->
caps.unidirectionalCompoundReferenceNameMask;
397 ap_ref =
ref->codec_priv;
405 ap->
av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_INTER;
406 quantization->base_q_idx = enc->
q_idx_b;
409 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_BIPREDICTIVE_KHR;
410 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_BIDIRECTIONAL_COMPOUND_KHR;
411 ref_name_mask = enc->
caps.bidirectionalCompoundReferenceNameMask;
422 ap_ref =
ref->codec_priv;
431 ap_ref =
ref->codec_priv;
443 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR,
445 .predictionMode = pred_mode,
446 .rateControlGroup = rc_group,
447 .constantQIndex = quantization->base_q_idx,
450 .primaryReferenceCdfOnly = 0,
451 .generateObuExtensionHeader = 0,
458 ref_slot = (VkVideoReferenceSlotInfoKHR *)encode_info->pSetupReferenceSlot;
461 ap->
av1dpb_info = (StdVideoEncodeAV1ReferenceInfo) {
462 .flags = (StdVideoEncodeAV1ReferenceInfoFlags) {
463 .disable_frame_end_update_cdf = 0,
464 .segmentation_enabled = 0,
467 .RefFrameId = ref_slot->slotIndex,
475 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_DPB_SLOT_INFO_KHR,
492 const int chroma_den = 1 << 16;
493 const int max_luma_den = 1 << 8;
494 const int min_luma_den = 1 << 14;
496 memset(obu, 0,
sizeof(*obu));
500 for (
int i = 0;
i < 3;
i++) {
535 memset(obu, 0,
sizeof(*obu));
538 cll->max_cll = cllm->
MaxCLL;
549 VkVideoProfileInfoKHR *
profile,
void *pnext)
558 VkVideoEncodeAV1CapabilitiesKHR av1_caps = {
559 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
561 VkVideoEncodeCapabilitiesKHR enc_caps = {
562 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR,
565 VkVideoCapabilitiesKHR caps = {
566 .sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR,
572 static const int known_profiles[] = {
587 enc->
profile = (VkVideoEncodeAV1ProfileInfoKHR) {
588 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR,
611 "any normal level, using level 7.3 by default.\n");
624 for (
int i = 0;
i < nb_profiles;
i++) {
626 ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(
s->hwctx->phys_dev,
629 if (
ret == VK_SUCCESS) {
632 last_supported = known_profiles[
i];
644 avctx->
profile = last_supported;
663 "must have initial buffer size (%d) <= "
664 "buffer size (%"PRId64
").\n",
673 if (enc->
common.
opts.
rc_mode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
675 enc->
caps.minQIndex, enc->
caps.maxQIndex);
723 .enable_order_hint = 1,
725 .use_128x128_superblock = !!(enc->
caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_128_BIT_KHR),
727 .high_bitdepth =
desc->comp[0].depth > 8,
729 .transfer_characteristics = avctx->
color_trc,
734 .subsampling_x =
desc->log2_chroma_w,
735 .subsampling_y =
desc->log2_chroma_h,
748 .operating_points_cnt_minus_1 = 1 - 1,
771 StdVideoAV1SequenceHeader *seq_hdr = &vk_units->
seq_hdr;
775 StdVideoEncodeAV1OperatingPointInfo *operating_points = vk_units->
operating_points;
778 .flags = (StdVideoAV1TimingInfoFlags) {
787 .flags = (StdVideoAV1ColorConfigFlags) {
801 *seq_hdr = (StdVideoAV1SequenceHeader) {
802 .flags = (StdVideoAV1SequenceHeaderFlags) {
838 operating_points[
i] = (StdVideoEncodeAV1OperatingPointInfo) {
839 .flags = (StdVideoEncodeAV1OperatingPointInfoFlags) {
868 VkVideoEncodeAV1SessionParametersCreateInfoKHR av1_params;
879 if (
ctx->session_params)
880 vk->DestroyVideoSessionParametersKHR(
s->hwctx->act_dev,
884 av1_params = (VkVideoEncodeAV1SessionParametersCreateInfoKHR) {
885 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
886 .pStdSequenceHeader = &vk_units.
seq_hdr,
933 ff_cbs_fragment_free(&obu);
948 VkVideoEncodeSessionParametersGetInfoKHR params_info;
949 VkVideoEncodeSessionParametersFeedbackInfoKHR params_feedback;
952 size_t data_size = 0;
967 params_info = (VkVideoEncodeSessionParametersGetInfoKHR) {
968 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_GET_INFO_KHR,
969 .videoSessionParameters =
ctx->session_params,
971 params_feedback = (VkVideoEncodeSessionParametersFeedbackInfoKHR) {
972 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR,
975 ret = vk->GetEncodedVideoSessionParametersKHR(
s->hwctx->act_dev, ¶ms_info,
978 if (
ret == VK_INCOMPLETE ||
979 (
ret == VK_SUCCESS) && (data_size > 0)) {
989 ret = vk->GetEncodedVideoSessionParametersKHR(
s->hwctx->act_dev, ¶ms_info,
992 if (
ret != VK_SUCCESS) {
998 params_feedback.hasOverrides);
1000 params_feedback.hasOverrides = 1;
1003 if (!params_feedback.hasOverrides)
1021 uint8_t
type,
void *obu_unit)
1025 err = ff_cbs_insert_unit_content(au, -1,
1029 "type = %d.\n",
type);
1037 uint8_t *
data,
size_t *data_len,
1043 ret = ff_cbs_write_fragment_data(enc->
cbs, obu);
1057 uint8_t *
data,
size_t *data_len)
1071 ff_cbs_fragment_reset(obu);
1077 uint8_t *
data,
size_t *data_len)
1110 ff_cbs_fragment_reset(obu);
1115 uint8_t *
data,
size_t *data_len)
1131 .payload_size = padding,
1140 ff_cbs_fragment_reset(obu);
1150 .filler_header_size = 4,
1170 enc->
caps = (VkVideoEncodeAV1CapabilitiesKHR) {
1171 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
1174 enc->
quality_props = (VkVideoEncodeAV1QualityLevelPropertiesKHR) {
1175 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_QUALITY_LEVEL_PROPERTIES_KHR,
1187 !!(enc->
caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_PER_RATE_CONTROL_GROUP_MIN_MAX_Q_INDEX_BIT_KHR));
1189 !!(enc->
caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_GENERATE_OBU_EXTENSION_HEADER_BIT_KHR));
1191 !!(enc->
caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_PRIMARY_REFERENCE_CDF_ONLY_BIT_KHR));
1193 !!(enc->
caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_FRAME_SIZE_OVERRIDE_BIT_KHR));
1195 !!(enc->
caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_MOTION_VECTOR_SCALING_BIT_KHR));
1198 !!(enc->
caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR));
1200 !!(enc->
caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_128_BIT_KHR));
1202 enc->
caps.maxSingleReferenceCount);
1204 enc->
caps.singleReferenceNameMask);
1206 enc->
caps.maxUnidirectionalCompoundReferenceCount);
1208 enc->
caps.maxUnidirectionalCompoundGroup1ReferenceCount);
1210 enc->
caps.unidirectionalCompoundReferenceNameMask);
1212 enc->
caps.maxBidirectionalCompoundReferenceCount);
1214 enc->
caps.maxBidirectionalCompoundGroup1ReferenceCount);
1216 enc->
caps.maxBidirectionalCompoundGroup2ReferenceCount);
1218 enc->
caps.bidirectionalCompoundReferenceNameMask);
1220 enc->
caps.maxTemporalLayerCount);
1222 enc->
caps.maxSpatialLayerCount);
1224 enc->
caps.maxOperatingPoints);
1226 enc->
caps.minQIndex, enc->
caps.maxQIndex);
1228 enc->
caps.prefersGopRemainingFrames);
1230 enc->
caps.requiresGopRemainingFrames);
1232 enc->
caps.maxLevel);
1234 enc->
caps.codedPictureAlignment.width, enc->
caps.codedPictureAlignment.height);
1236 enc->
caps.maxTiles.width, enc->
caps.maxTiles.height);
1238 enc->
caps.minTileSize.width, enc->
caps.minTileSize.height,
1239 enc->
caps.maxTileSize.width, enc->
caps.maxTileSize.height);
1247 ctx->caps.maxDpbSlots,
1248 enc->
caps.maxBidirectionalCompoundReferenceCount,
1268 size_t data_len =
sizeof(
data);
1273 "for extradata: %d.\n", err);
1304 #define OFFSET(x) offsetof(VulkanEncodeAV1Context, x)
1305 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1310 {
"profile",
"Set profile",
1314 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1315 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1321 {
"tier",
"Set tier (seq_tier)",
1326 {
"level",
"Set level (level_idc)",
1330 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1331 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1342 {
LEVEL(
"42", 10) },
1343 {
LEVEL(
"43", 11) },
1344 {
LEVEL(
"50", 12) },
1345 {
LEVEL(
"51", 13) },
1346 {
LEVEL(
"52", 14) },
1347 {
LEVEL(
"53", 15) },
1348 {
LEVEL(
"60", 16) },
1349 {
LEVEL(
"61", 17) },
1350 {
LEVEL(
"62", 18) },
1351 {
LEVEL(
"63", 19) },
1352 {
LEVEL(
"70", 20) },
1353 {
LEVEL(
"71", 21) },
1354 {
LEVEL(
"72", 22) },
1355 {
LEVEL(
"73", 23) },
1381 .
p.
name =
"av1_vulkan",
1402 .p.wrapper_name =
"vulkan",