History

lavc: add an av1_vulkan encoder

This commit adds a Vulkan AV1 encoder, using the native acceleration API.

Lynne committed 1 year ago

Commit b2928971 parent 2caf23e9 files · +1477 −0Browse files

Unified · Split

9 files
  1. configure +1 −0
  2. libavcodec/Makefile +2 −0
  3. libavcodec/allcodecs.c +1 −0
  4. libavcodec/vulkan_encode_av1.c +1409 −0
  5. libavcodec/vulkan_video.c +41 −0
  6. libavcodec/vulkan_video.h +2 −0
  7. libavutil/hwcontext_vulkan.c +17 −0
  8. libavutil/vulkan_functions.h +1 −0
  9. libavutil/vulkan_loader.h +3 −0
configure+1−0
@@ -3400,6 +3400,7 @@ av1_qsv_encoder_deps="libvpl" · 3399 unmodified lines
3400av1_qsv_encoder_select="qsvenc"3400av1_qsv_encoder_select="qsvenc"
3401av1_vaapi_encoder_deps="VAEncPictureParameterBufferAV1"3401av1_vaapi_encoder_deps="VAEncPictureParameterBufferAV1"
3402av1_vaapi_encoder_select="cbs_av1 vaapi_encode"3402av1_vaapi_encoder_select="cbs_av1 vaapi_encode"
3403av1_vulkan_encoder_select="cbs_av1 vulkan_encode"
3403h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"3404h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
3404h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"3405h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
3405h264_amf_encoder_deps="amf"3406h264_amf_encoder_deps="amf"
libavcodec/Makefile+2−0
@@ -272,6 +272,8 @@ OBJS-$(CONFIG_AV1_MEDIACODEC_ENCODER) += mediacodecenc.o · 271 unmodified lines
272OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o272OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o
273OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o273OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o
274OBJS-$(CONFIG_AV1_VAAPI_ENCODER) += vaapi_encode_av1.o av1_levels.o274OBJS-$(CONFIG_AV1_VAAPI_ENCODER) += vaapi_encode_av1.o av1_levels.o
275OBJS-$(CONFIG_AV1_VULKAN_ENCODER) += vulkan_encode.o vulkan_encode_av1.o \
276 hw_base_encode.o av1_levels.o
275OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o277OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o
276OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o278OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
277OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o279OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
libavcodec/allcodecs.c+1−0
@@ -853,6 +853,7 @@ extern const FFCodec ff_av1_amf_encoder; · 852 unmodified lines
853extern const FFCodec ff_av1_amf_decoder;853extern const FFCodec ff_av1_amf_decoder;
854extern const FFCodec ff_av1_mf_encoder;854extern const FFCodec ff_av1_mf_encoder;
855extern const FFCodec ff_av1_vaapi_encoder;855extern const FFCodec ff_av1_vaapi_encoder;
856extern const FFCodec ff_av1_vulkan_encoder;
856extern const FFCodec ff_libopenh264_encoder;857extern const FFCodec ff_libopenh264_encoder;
857extern const FFCodec ff_libopenh264_decoder;858extern const FFCodec ff_libopenh264_decoder;
858extern const FFCodec ff_h264_amf_encoder;859extern const FFCodec ff_h264_amf_encoder;
libavcodec/vulkan_encode_av1.c+1409−0
@@ -0,0 +1,1409 @@
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/opt.h"
20#include "libavutil/mem.h"
21
22#include "cbs.h"
23#include "cbs_av1.h"
24#include "av1_levels.h"
25#include "libavutil/mastering_display_metadata.h"
26
27#include "codec_internal.h"
28#include "vulkan_encode.h"
29
30#include "libavutil/avassert.h"
31
32const FFVulkanEncodeDescriptor ff_vk_enc_av1_desc = {
33 .codec_id = AV_CODEC_ID_AV1,
34 .encode_extension = FF_VK_EXT_VIDEO_ENCODE_AV1,
35 .encode_op = VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR,
36 .ext_props = {
37 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME,
38 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION,
39 },
40};
41
42enum UnitElems {
43 UNIT_MASTERING_DISPLAY = 1 << 0,
44 UNIT_CONTENT_LIGHT_LEVEL = 1 << 1,
45};
46
47typedef struct VulkanEncodeAV1Picture {
48 int slot;
49 int64_t last_idr_frame;
50
51 enum UnitElems units_needed;
52
53 StdVideoAV1TileInfo tile_info;
54 StdVideoAV1Quantization quantization;
55 StdVideoAV1Segmentation segmentation;
56 StdVideoAV1LoopFilter loop_filter;
57 StdVideoAV1CDEF cdef;
58 StdVideoAV1LoopRestoration loop_restoration;
59 StdVideoAV1GlobalMotion global_motion;
60
61 StdVideoEncodeAV1PictureInfo av1pic_info;
62 VkVideoEncodeAV1PictureInfoKHR vkav1pic_info;
63
64 StdVideoEncodeAV1ExtensionHeader ext_header;
65 StdVideoEncodeAV1ReferenceInfo av1dpb_info;
66 VkVideoEncodeAV1DpbSlotInfoKHR vkav1dpb_info;
67
68 VkVideoEncodeAV1RateControlInfoKHR vkrc_info;
69 VkVideoEncodeAV1RateControlLayerInfoKHR vkrc_layer_info;
70 VkVideoEncodeAV1GopRemainingFrameInfoKHR vkrc_remaining;
71} VulkanEncodeAV1Picture;
72
73typedef struct VulkanEncodeAV1Context {
74 FFVulkanEncodeContext common;
75
76 CodedBitstreamContext *cbs;
77 CodedBitstreamFragment current_access_unit;
78
79 enum UnitElems unit_elems;
80 AV1RawOBU seq_hdr_obu;
81 AV1RawOBU meta_cll_obu;
82 AV1RawOBU meta_mastering_obu;
83
84 VkVideoEncodeAV1ProfileInfoKHR profile;
85
86 VkVideoEncodeAV1CapabilitiesKHR caps;
87 VkVideoEncodeAV1QualityLevelPropertiesKHR quality_props;
88
89 uint64_t hrd_buffer_size;
90 uint64_t initial_buffer_fullness;
91
92 int uniform_tile;
93 int tile_cols;
94 int tile_rows;
95
96 int seq_tier;
97 int seq_level_idx;
98
99 int q_idx_idr;
100 int q_idx_p;
101 int q_idx_b;
102
103 uint8_t *padding_payload;
104} VulkanEncodeAV1Context;
105
106static int init_pic_rc(AVCodecContext *avctx, FFHWBaseEncodePicture *pic,
107 VkVideoEncodeRateControlInfoKHR *rc_info,
108 VkVideoEncodeRateControlLayerInfoKHR *rc_layer)
109{
110 VulkanEncodeAV1Context *enc = avctx->priv_data;
111 FFVulkanEncodeContext *ctx = &enc->common;
112 VulkanEncodeAV1Picture *ap = pic->codec_priv;
113
114 /* This can be easy to calculate */
115 ap->vkrc_remaining = (VkVideoEncodeAV1GopRemainingFrameInfoKHR) {
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,
121 };
122
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,
131 };
132 rc_info->pNext = &ap->vkrc_info;
133
134 if (rc_info->rateControlMode > VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
135 rc_info->virtualBufferSizeInMs = (enc->hrd_buffer_size * 1000LL) / avctx->bit_rate;
136 rc_info->initialVirtualBufferSizeInMs = (enc->initial_buffer_fullness * 1000LL) / avctx->bit_rate;
137
138 ap->vkrc_layer_info = (VkVideoEncodeAV1RateControlLayerInfoKHR) {
139 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR,
140
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,
145
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,
150
151 .useMaxFrameSize = 0,
152 };
153 rc_layer->pNext = &ap->vkrc_layer_info;
154 ap->vkrc_info.temporalLayerCount = 1;
155 }
156
157 return 0;
158}
159
160static void set_name_slot(int slot, int *slot_indices, uint32_t allowed_idx, int group)
161{
162 int from = group ? AV1_REF_FRAME_GOLDEN : 0;
163 int to = group ? AV1_REFS_PER_FRAME : AV1_REF_FRAME_GOLDEN;
164
165 for (int i = from; i < to; i++) {
166 if ((slot_indices[i] == -1) && (allowed_idx & (1 << i))) {
167 slot_indices[i] = slot;
168 return;
169 }
170 }
171
172 av_assert0(0);
173}
174
175
176static int init_pic_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic,
177 VkVideoEncodeInfoKHR *encode_info)
178{
179 VulkanEncodeAV1Context *enc = avctx->priv_data;
180 FFVulkanEncodeContext *ctx = &enc->common;
181 FFHWBaseEncodeContext *base_ctx = &ctx->base;
182
183 FFVulkanEncodePicture *vp = pic->priv;
184 VulkanEncodeAV1Picture *ap = pic->codec_priv;
185 FFHWBaseEncodePicture *ref;
186 VulkanEncodeAV1Picture *ap_ref;
187 VkVideoReferenceSlotInfoKHR *ref_slot;
188
189 AV1RawOBU *seq_obu = &enc->seq_hdr_obu;
190 AV1RawSequenceHeader *seq = &seq_obu->obu.sequence_header;
191
192 uint32_t ref_name_mask = 0x0;
193 int name_slots[STD_VIDEO_AV1_REFS_PER_FRAME];
194
195 StdVideoAV1Segmentation *segmentation = &ap->segmentation;
196 StdVideoAV1LoopFilter *loop_filter = &ap->loop_filter;
197 StdVideoAV1Quantization *quantization = &ap->quantization;
198 StdVideoAV1CDEF *cdef = &ap->cdef;
199 StdVideoAV1LoopRestoration *loop_restoration = &ap->loop_restoration;
200 StdVideoAV1GlobalMotion *global_motion = &ap->global_motion;
201 StdVideoAV1TileInfo *tile_info = &ap->tile_info;
202 static const int8_t default_loop_filter_ref_deltas[STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME] =
203 { 1, 0, 0, 0, -1, 0, -1, -1 };
204
205 VkVideoEncodeAV1PredictionModeKHR pred_mode;
206 VkVideoEncodeAV1RateControlGroupKHR rc_group;
207 int lr_unit_shift = 0;
208 int lr_uv_shift = 0;
209
210 ap->ext_header = (StdVideoEncodeAV1ExtensionHeader) {
211 .temporal_id = 0,
212 .spatial_id = 0,
213 };
214
215 *tile_info = (StdVideoAV1TileInfo) {
216 .flags = (StdVideoAV1TileInfoFlags) {
217 .uniform_tile_spacing_flag = enc->uniform_tile,
218 },
219 .TileCols = enc->tile_cols,
220 .TileRows = enc->tile_rows,
221 .context_update_tile_id = 0,
222 .tile_size_bytes_minus_1 = 0,
223 };
224
225 for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) {
226 global_motion->GmType[i] = 0;
227 for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
228 global_motion->gm_params[i][j] = 0;
229 }
230 }
231
232 for (int i = 0; i < STD_VIDEO_AV1_REFS_PER_FRAME; i++)
233 name_slots[i] = -1;
234
235 *loop_restoration = (StdVideoAV1LoopRestoration) {
236 .FrameRestorationType[0] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
237 .FrameRestorationType[1] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
238 .FrameRestorationType[2] = STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
239 .LoopRestorationSize[0] = 1 + lr_unit_shift,
240 .LoopRestorationSize[1] = 1 + lr_unit_shift - lr_uv_shift,
241 .LoopRestorationSize[2] = 1 + lr_unit_shift - lr_uv_shift,
242 };
243
244 *cdef = (StdVideoAV1CDEF) {
245 .cdef_damping_minus_3 = 0,
246 .cdef_bits = 0,
247 };
248
249 for (int i = 0; i < STD_VIDEO_AV1_MAX_SEGMENTS; i++) {
250 segmentation->FeatureEnabled[i] = 0x0;
251 for (int j = 0; j < STD_VIDEO_AV1_SEG_LVL_MAX; j++) {
252 segmentation->FeatureEnabled[i] |= 0x0;
253 segmentation->FeatureData[i][j] = 0;
254 }
255 }
256
257 *loop_filter = (StdVideoAV1LoopFilter) {
258 .flags = (StdVideoAV1LoopFilterFlags) {
259 .loop_filter_delta_enabled = 0,
260 .loop_filter_delta_update = 0,
261 },
262 .loop_filter_level = { 0 },
263 .loop_filter_sharpness = 0,
264 .update_ref_delta = 0,
265 .loop_filter_ref_deltas = { 0 },
266 .update_mode_delta = 0,
267 .loop_filter_mode_deltas = { 0 },
268 };
269 loop_filter->update_mode_delta = 1;
270 memcpy(loop_filter->loop_filter_ref_deltas, default_loop_filter_ref_deltas,
271 STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME * sizeof(int8_t));
272
273 *quantization = (StdVideoAV1Quantization) {
274 .flags = (StdVideoAV1QuantizationFlags) {
275 .using_qmatrix = 0,
276 .diff_uv_delta = 0,
277 /* Reserved */
278 },
279 .base_q_idx = 0, /* Set later */
280 .DeltaQYDc = 0,
281 .DeltaQUDc = 0,
282 .DeltaQUAc = 0,
283 .DeltaQVDc = 0,
284 .DeltaQVAc = 0,
285 .qm_y = 0,
286 .qm_u = 0,
287 .qm_v = 0,
288 };
289
290 ref_slot = (VkVideoReferenceSlotInfoKHR *)encode_info->pSetupReferenceSlot;
291 ap->av1pic_info = (StdVideoEncodeAV1PictureInfo) {
292 .flags = (StdVideoEncodeAV1PictureInfoFlags) {
293 .error_resilient_mode = (pic->type == FF_HW_PICTURE_TYPE_I ||
294 pic->type == FF_HW_PICTURE_TYPE_IDR) &&
295 (pic->display_order <= pic->encode_order),
296 .disable_cdf_update = 0,
297 .use_superres = 0,
298 .render_and_frame_size_different = 0,
299 .allow_screen_content_tools = 0,
300 .is_filter_switchable = 0,
301 .force_integer_mv = 0,
302 .frame_size_override_flag = 0,
303 .buffer_removal_time_present_flag = 0,
304 .allow_intrabc = 0,
305 .frame_refs_short_signaling = 0,
306 .allow_high_precision_mv = 0,
307 .is_motion_mode_switchable = 0,
308 .use_ref_frame_mvs = 0,
309 .disable_frame_end_update_cdf = 0,
310 .allow_warped_motion = 0,
311 .reduced_tx_set = 0,
312 .skip_mode_present = 0,
313 .delta_q_present = 0,
314 .delta_lf_present = 0,
315 .delta_lf_multi = 0,
316 .segmentation_enabled = 0,
317 .segmentation_update_map = 0,
318 .segmentation_temporal_update = 0,
319 .segmentation_update_data = 0,
320 .UsesLr = 0,
321 .usesChromaLr = 0,
322 .show_frame = pic->display_order <= pic->encode_order,
323 .showable_frame = 0,
324 /* Reserved */
325 },
326 .frame_type = 0, // set later
327 .frame_presentation_time = 0,
328 .current_frame_id = ref_slot->slotIndex,
329 .order_hint = 0, // set later
330 .primary_ref_frame = 0, // set later
331 .refresh_frame_flags = 0x0, // set later
332 .coded_denom = 0,
333 .render_width_minus_1 = base_ctx->surface_width - 1,
334 .render_height_minus_1 = base_ctx->surface_height - 1,
335 .interpolation_filter = 0,
336 .TxMode = STD_VIDEO_AV1_TX_MODE_SELECT,
337 .delta_q_res = 0,
338 .delta_lf_res = 0,
339 .ref_order_hint = { 0 }, // set later
340 .ref_frame_idx = { 0 }, // set later
341 /* Reserved */
342 .delta_frame_id_minus_1 = { 0 },
343
344// .pTileInfo = tile_info, TODO FIX
345 .pQuantization = quantization,
346 .pSegmentation = segmentation,
347 .pLoopFilter = loop_filter,
348 .pCDEF = cdef,
349 .pLoopRestoration = loop_restoration,
350 .pGlobalMotion = global_motion,
351 .pExtensionHeader = &ap->ext_header,
352 .pBufferRemovalTimes = NULL,
353 };
354
355 switch (pic->type) {
356 case FF_HW_PICTURE_TYPE_I:
357 case FF_HW_PICTURE_TYPE_IDR:
358 av_assert0(pic->nb_refs[0] == 0 || pic->nb_refs[1]);
359 ap->av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_KEY;
360 ap->av1pic_info.refresh_frame_flags = 0xFF;
361 quantization->base_q_idx = enc->q_idx_idr;
362 ap->slot = 0;
363 ap->last_idr_frame = pic->display_order;
364 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_INTRA_ONLY_KHR;
365 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_INTRA_KHR;
366 break;
367 case FF_HW_PICTURE_TYPE_P:
368 ref = pic->refs[0][pic->nb_refs[0] - 1];
369 ap_ref = ref->codec_priv;
370
371 ap->av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_INTER;
372 quantization->base_q_idx = enc->q_idx_p;
373
374 ap->last_idr_frame = ap_ref->last_idr_frame;
375 ap->slot = !ap_ref->slot;
376
377 ap->av1pic_info.refresh_frame_flags = 1 << ap->slot;
378
379 /** set the nearest frame in L0 as all reference frame. */
380 for (int i = 0; i < AV1_REFS_PER_FRAME; i++)
381 ap->av1pic_info.ref_frame_idx[i] = ap_ref->slot;
382
383 ap->av1pic_info.primary_ref_frame = ap_ref->slot;
384 ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame;
385 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_PREDICTIVE_KHR;
386 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_SINGLE_REFERENCE_KHR;
387 ref_name_mask = enc->caps.singleReferenceNameMask;
388 set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0);
389
390// vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST;
391
392 /** set the 2nd nearest frame in L0 as Golden frame. */
393 if ((pic->nb_refs[0] > 1) &&
394 ((enc->caps.maxSingleReferenceCount > 1) ||
395 (enc->caps.maxUnidirectionalCompoundReferenceCount > 0))) {
396 if (enc->caps.maxUnidirectionalCompoundReferenceCount) {
397 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_UNIDIRECTIONAL_COMPOUND_KHR;
398 ref_name_mask = enc->caps.unidirectionalCompoundReferenceNameMask;
399 }
400 ref = pic->refs[0][pic->nb_refs[0] - 2];
401 ap_ref = ref->codec_priv;
402 ap->av1pic_info.ref_frame_idx[3] = ap_ref->slot;
403 ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame;
404// vpic->ref_frame_ctrl_l0.fields.search_idx1 = AV1_REF_FRAME_GOLDEN;
405 set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0);
406 }
407 break;
408 case FF_HW_PICTURE_TYPE_B:
409 ap->av1pic_info.frame_type = STD_VIDEO_AV1_FRAME_TYPE_INTER;
410 quantization->base_q_idx = enc->q_idx_b;
411 ap->av1pic_info.refresh_frame_flags = 0x0;
412
413 rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_BIPREDICTIVE_KHR;
414 pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_BIDIRECTIONAL_COMPOUND_KHR;
415 ref_name_mask = enc->caps.bidirectionalCompoundReferenceNameMask;
416
417// fh->reference_select = 1;
418 /** B frame will not be referenced, disable its recon frame. */
419// vpic->picture_flags.bits.disable_frame_recon = 1;
420
421 /** Use LAST_FRAME and BWDREF_FRAME for reference. */
422// vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST;
423// vpic->ref_frame_ctrl_l1.fields.search_idx0 = AV1_REF_FRAME_BWDREF;
424
425 ref = pic->refs[0][pic->nb_refs[0] - 1];
426 ap_ref = ref->codec_priv;
427 ap->last_idr_frame = ap_ref->last_idr_frame;
428 ap->av1pic_info.primary_ref_frame = ap_ref->slot;
429 ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame;
430 for (int i = 0; i < AV1_REF_FRAME_GOLDEN; i++)
431 ap->av1pic_info.ref_frame_idx[i] = ap_ref->slot;
432 set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0);
433
434 ref = pic->refs[1][pic->nb_refs[1] - 1];
435 ap_ref = ref->codec_priv;
436 ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame;
437 for (int i = AV1_REF_FRAME_GOLDEN; i < AV1_REFS_PER_FRAME; i++)
438 ap->av1pic_info.ref_frame_idx[i] = ap_ref->slot;
439 set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 1);
440 break;
441 }
442
443 ap->av1pic_info.flags.showable_frame = ap->av1pic_info.frame_type != STD_VIDEO_AV1_FRAME_TYPE_KEY;
444 ap->av1pic_info.order_hint = pic->display_order - ap->last_idr_frame;
445
446 ap->vkav1pic_info = (VkVideoEncodeAV1PictureInfoKHR) {
447 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR,
448 .pNext = NULL,
449 .predictionMode = pred_mode,
450 .rateControlGroup = rc_group,
451 .constantQIndex = quantization->base_q_idx,
452 .pStdPictureInfo = &ap->av1pic_info,
453 // .referenceNameSlotIndices is set below
454 .primaryReferenceCdfOnly = 0,
455 .generateObuExtensionHeader = 0,
456 };
457 encode_info->pNext = &ap->vkav1pic_info;
458
459 for (int i = 0; i < FF_ARRAY_ELEMS(ap->vkav1pic_info.referenceNameSlotIndices); i++)
460 ap->vkav1pic_info.referenceNameSlotIndices[i] = name_slots[i];
461
462 ref_slot = (VkVideoReferenceSlotInfoKHR *)encode_info->pSetupReferenceSlot;
463 ref_slot->pNext = &ap->vkav1dpb_info;
464
465 ap->av1dpb_info = (StdVideoEncodeAV1ReferenceInfo) {
466 .flags = (StdVideoEncodeAV1ReferenceInfoFlags) {
467 .disable_frame_end_update_cdf = 0,
468 .segmentation_enabled = 0,
469 /* Reserved */
470 },
471 .RefFrameId = ref_slot->slotIndex,
472 .frame_type = ap->av1pic_info.frame_type,
473 .OrderHint = pic->display_order - ap->last_idr_frame,
474 /* Reserved */
475 .pExtensionHeader = &ap->ext_header,
476 };
477
478 ap->vkav1dpb_info = (VkVideoEncodeAV1DpbSlotInfoKHR) {
479 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_DPB_SLOT_INFO_KHR,
480 .pStdReferenceInfo = &ap->av1dpb_info,
481 };
482
483 ap->units_needed = 0;
484 if (pic->type == FF_HW_PICTURE_TYPE_IDR) {
485 AVFrameSideData *sd = NULL;
486 if (enc->unit_elems & UNIT_MASTERING_DISPLAY)
487 sd = av_frame_get_side_data(pic->input_image,
488 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
489 if (sd) {
490 AVMasteringDisplayMetadata *mdm =
491 (AVMasteringDisplayMetadata *)sd->data;
492 if (mdm->has_primaries && mdm->has_luminance) {
493 AV1RawOBU *obu = &enc->meta_mastering_obu;
494 AV1RawMetadata *md = &obu->obu.metadata;
495 AV1RawMetadataHDRMDCV *mdcv = &md->metadata.hdr_mdcv;
496 const int chroma_den = 1 << 16;
497 const int max_luma_den = 1 << 8;
498 const int min_luma_den = 1 << 14;
499
500 memset(obu, 0, sizeof(*obu));
501 obu->header.obu_type = AV1_OBU_METADATA;
502 md->metadata_type = AV1_METADATA_TYPE_HDR_MDCV;
503
504 for (int i = 0; i < 3; i++) {
505 mdcv->primary_chromaticity_x[i] =
506 av_rescale(mdm->display_primaries[i][0].num, chroma_den,
507 mdm->display_primaries[i][0].den);
508 mdcv->primary_chromaticity_y[i] =
509 av_rescale(mdm->display_primaries[i][1].num, chroma_den,
510 mdm->display_primaries[i][1].den);
511 }
512
513 mdcv->white_point_chromaticity_x =
514 av_rescale(mdm->white_point[0].num, chroma_den,
515 mdm->white_point[0].den);
516 mdcv->white_point_chromaticity_y =
517 av_rescale(mdm->white_point[1].num, chroma_den,
518 mdm->white_point[1].den);
519
520 mdcv->luminance_max =
521 av_rescale(mdm->max_luminance.num, max_luma_den,
522 mdm->max_luminance.den);
523 mdcv->luminance_min =
524 av_rescale(mdm->min_luminance.num, min_luma_den,
525 mdm->min_luminance.den);
526 ap->units_needed |= UNIT_MASTERING_DISPLAY;
527 }
528 }
529
530 if (enc->unit_elems & UNIT_CONTENT_LIGHT_LEVEL)
531 sd = av_frame_get_side_data(pic->input_image,
532 AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
533 if (sd) {
534 AVContentLightMetadata *cllm = (AVContentLightMetadata *)sd->data;
535 AV1RawOBU *obu = &enc->meta_cll_obu;
536 AV1RawMetadata *md = &obu->obu.metadata;
537 AV1RawMetadataHDRCLL *cll = &md->metadata.hdr_cll;
538
539 memset(obu, 0, sizeof(*obu));
540 obu->header.obu_type = AV1_OBU_METADATA;
541 md->metadata_type = AV1_METADATA_TYPE_HDR_CLL;
542 cll->max_cll = cllm->MaxCLL;
543 cll->max_fall = cllm->MaxFALL;
544
545 ap->units_needed |= UNIT_CONTENT_LIGHT_LEVEL;
546 }
547 }
548
549 return 0;
550}
551
552static int init_profile(AVCodecContext *avctx,
553 VkVideoProfileInfoKHR *profile, void *pnext)
554{
555 VkResult ret;
556 VulkanEncodeAV1Context *enc = avctx->priv_data;
557 FFVulkanEncodeContext *ctx = &enc->common;
558 FFVulkanContext *s = &ctx->s;
559 FFVulkanFunctions *vk = &ctx->s.vkfn;
560 FFHWBaseEncodeContext *base_ctx = &ctx->base;
561
562 VkVideoEncodeAV1CapabilitiesKHR av1_caps = {
563 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
564 };
565 VkVideoEncodeCapabilitiesKHR enc_caps = {
566 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR,
567 .pNext = &av1_caps,
568 };
569 VkVideoCapabilitiesKHR caps = {
570 .sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR,
571 .pNext = &enc_caps,
572 };
573
574 /* In order of preference */
575 int last_supported = AV_PROFILE_UNKNOWN;
576 static const int known_profiles[] = {
577 AV_PROFILE_AV1_MAIN,
578 AV_PROFILE_AV1_HIGH,
579 AV_PROFILE_AV1_PROFESSIONAL,
580 };
581 int nb_profiles = FF_ARRAY_ELEMS(known_profiles);
582
583 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->frames->sw_format);
584 if (!desc)
585 return AVERROR(EINVAL);
586
587 if (s->frames->sw_format == AV_PIX_FMT_NV12 ||
588 s->frames->sw_format == AV_PIX_FMT_P010)
589 nb_profiles = 1;
590
591 enc->profile = (VkVideoEncodeAV1ProfileInfoKHR) {
592 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR,
593 .pNext = pnext,
594 .stdProfile = ff_vk_av1_profile_to_vk(avctx->profile),
595 };
596 profile->pNext = &enc->profile;
597
598 /* Set level */
599 if (avctx->level == AV_LEVEL_UNKNOWN) {
600 const AV1LevelDescriptor *level;
601 float framerate;
602
603 if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
604 framerate = avctx->framerate.num / avctx->framerate.den;
605 else
606 framerate = 0;
607 level = ff_av1_guess_level(avctx->bit_rate, enc->seq_tier,
608 base_ctx->surface_width, base_ctx->surface_height,
609 enc->tile_rows * enc->tile_cols,
610 enc->tile_cols, framerate);
611 if (level) {
612 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
613 enc->seq_level_idx = ff_vk_av1_level_to_vk(level->level_idx);
614 } else {
615 av_log(avctx, AV_LOG_VERBOSE, "Stream will not conform to "
616 "any normal level, using level 7.3 by default.\n");
617 enc->seq_level_idx = STD_VIDEO_AV1_LEVEL_7_3;
618 enc->seq_tier = 1;
619 }
620 } else {
621 enc->seq_level_idx = ff_vk_av1_level_to_vk(avctx->level);
622 }
623
624 /* User has explicitly specified a profile. */
625 if (avctx->profile != AV_PROFILE_UNKNOWN)
626 return 0;
627
628 av_log(avctx, AV_LOG_DEBUG, "Supported profiles:\n");
629 for (int i = 0; i < nb_profiles; i++) {
630 enc->profile.stdProfile = ff_vk_av1_profile_to_vk(known_profiles[i]);
631 ret = vk->GetPhysicalDeviceVideoCapabilitiesKHR(s->hwctx->phys_dev,
632 profile,
633 &caps);
634 if (ret == VK_SUCCESS) {
635 av_log(avctx, AV_LOG_DEBUG, " %s\n",
636 avcodec_profile_name(avctx->codec_id, known_profiles[i]));
637 last_supported = known_profiles[i];
638 }
639 }
640
641 if (last_supported == AV_PROFILE_UNKNOWN) {
642 av_log(avctx, AV_LOG_ERROR, "No supported profiles for given format\n");
643 return AVERROR(ENOTSUP);
644 }
645
646 enc->profile.stdProfile = ff_vk_av1_profile_to_vk(last_supported);
647 av_log(avctx, AV_LOG_VERBOSE, "Using profile %s\n",
648 avcodec_profile_name(avctx->codec_id, last_supported));
649 avctx->profile = last_supported;
650
651 return 0;
652}
653
654static int init_enc_options(AVCodecContext *avctx)
655{
656 VulkanEncodeAV1Context *enc = avctx->priv_data;
657
658 if (avctx->rc_buffer_size)
659 enc->hrd_buffer_size = avctx->rc_buffer_size;
660 else if (avctx->rc_max_rate > 0)
661 enc->hrd_buffer_size = avctx->rc_max_rate;
662 else
663 enc->hrd_buffer_size = avctx->bit_rate;
664
665 if (avctx->rc_initial_buffer_occupancy) {
666 if (avctx->rc_initial_buffer_occupancy > enc->hrd_buffer_size) {
667 av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
668 "must have initial buffer size (%d) <= "
669 "buffer size (%"PRId64").\n",
670 avctx->rc_initial_buffer_occupancy, enc->hrd_buffer_size);
671 return AVERROR(EINVAL);
672 }
673 enc->initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
674 } else {
675 enc->initial_buffer_fullness = enc->hrd_buffer_size * 3 / 4;
676 }
677
678 if (enc->common.opts.rc_mode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR &&
679 avctx->global_quality) {
680 enc->q_idx_p = av_clip_intp2(avctx->global_quality / FF_QP2LAMBDA, 8);
681 if (fabs(avctx->i_quant_factor) > 0.0)
682 enc->q_idx_idr =
683 av_clip((fabs(avctx->i_quant_factor) * enc->q_idx_p +
684 avctx->i_quant_offset) + 0.5,
685 0, 255);
686 else
687 enc->q_idx_idr = enc->q_idx_p;
688
689 if (fabs(avctx->b_quant_factor) > 0.0)
690 enc->q_idx_b =
691 av_clip((fabs(avctx->b_quant_factor) * enc->q_idx_p +
692 avctx->b_quant_offset) + 0.5,
693 0, 255);
694 else
695 enc->q_idx_b = enc->q_idx_p;
696 } else {
697 /** Arbitrary value */
698 enc->q_idx_idr = enc->q_idx_p = enc->q_idx_b = 128;
699 }
700
701 return 0;
702}
703
704static av_cold int init_sequence_headers(AVCodecContext *avctx)
705{
706 int err;
707 VulkanEncodeAV1Context *enc = avctx->priv_data;
708 FFVulkanEncodeContext *ctx = &enc->common;
709 FFVulkanContext *s = &ctx->s;
710 FFHWBaseEncodeContext *base_ctx = &ctx->base;
711
712 AV1RawOBU *seq_obu = &enc->seq_hdr_obu;
713 AV1RawSequenceHeader *seq = &seq_obu->obu.sequence_header;
714
715 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->frames->sw_format);
716 if (!desc)
717 return AVERROR(EINVAL);
718
719 seq_obu->header.obu_type = AV1_OBU_SEQUENCE_HEADER;
720 *seq = (AV1RawSequenceHeader) {
721 .seq_profile = avctx->profile,
722 .seq_force_integer_mv = seq->seq_force_screen_content_tools ?
723 AV1_SELECT_SCREEN_CONTENT_TOOLS :
724 AV1_SELECT_INTEGER_MV,
725 .frame_width_bits_minus_1 = av_log2(base_ctx->surface_width),
726 .frame_height_bits_minus_1 = av_log2(base_ctx->surface_height),
727 .max_frame_width_minus_1 = base_ctx->surface_width - 1,
728 .max_frame_height_minus_1 = base_ctx->surface_height - 1,
729 .enable_order_hint = 1,
730 .order_hint_bits_minus_1 = av_clip_intp2(av_log2(ctx->base.gop_size), 3),
731 .use_128x128_superblock = !!(enc->caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_128_BIT_KHR),
732 .color_config = (AV1RawColorConfig) {
733 .high_bitdepth = desc->comp[0].depth > 8,
734 .color_primaries = avctx->color_primaries,
735 .transfer_characteristics = avctx->color_trc,
736 .matrix_coefficients = avctx->colorspace,
737 .color_description_present_flag = (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
738 avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
739 avctx->colorspace != AVCOL_SPC_UNSPECIFIED),
740 .subsampling_x = desc->log2_chroma_w,
741 .subsampling_y = desc->log2_chroma_h,
742 .chroma_sample_position = avctx->chroma_sample_location == AVCHROMA_LOC_LEFT ?
743 AV1_CSP_VERTICAL :
744 avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT ?
745 AV1_CSP_COLOCATED :
746 AV1_CSP_UNKNOWN,
747 },
748
749 /* Operating point */
750 .seq_tier = { enc->seq_tier },
751 .seq_level_idx = { enc->seq_level_idx },
752 .decoder_buffer_delay = { base_ctx->decode_delay },
753 .encoder_buffer_delay = { base_ctx->output_delay },
754 .operating_points_cnt_minus_1 = 1 - 1,
755 };
756
757 return 0;
758}
759
760typedef struct VulkanAV1Units {
761 StdVideoAV1SequenceHeader seq_hdr;
762 StdVideoAV1TimingInfo timing_info;
763 StdVideoAV1ColorConfig color_config;
764
765 StdVideoEncodeAV1DecoderModelInfo decoder_model;
766 StdVideoEncodeAV1OperatingPointInfo operating_points[AV1_MAX_OPERATING_POINTS];
767 int nb_operating_points;
768} VulkanAV1Units;
769
770static av_cold int base_unit_to_vk(AVCodecContext *avctx, VulkanAV1Units *vk_units)
771{
772 VulkanEncodeAV1Context *enc = avctx->priv_data;
773
774 AV1RawOBU *seq_obu = &enc->seq_hdr_obu;
775 AV1RawSequenceHeader *seq = &seq_obu->obu.sequence_header;
776
777 StdVideoAV1SequenceHeader *seq_hdr = &vk_units->seq_hdr;
778 StdVideoAV1TimingInfo *timing_info = &vk_units->timing_info;
779 StdVideoAV1ColorConfig *color_config = &vk_units->color_config;
780
781 StdVideoEncodeAV1OperatingPointInfo *operating_points = vk_units->operating_points;
782
783 *timing_info = (StdVideoAV1TimingInfo) {
784 .flags = (StdVideoAV1TimingInfoFlags) {
785 .equal_picture_interval = seq->timing_info.equal_picture_interval,
786 },
787 .num_units_in_display_tick = seq->timing_info.num_units_in_display_tick,
788 .time_scale = seq->timing_info.time_scale,
789 .num_ticks_per_picture_minus_1 = seq->timing_info.num_ticks_per_picture_minus_1,
790 };
791
792 *color_config = (StdVideoAV1ColorConfig) {
793 .flags = (StdVideoAV1ColorConfigFlags) {
794 .mono_chrome = seq->color_config.mono_chrome,
795 .color_range = seq->color_config.color_range,
796 .separate_uv_delta_q = seq->color_config.separate_uv_delta_q,
797 },
798 .BitDepth = seq->color_config.twelve_bit ? 12 :
799 seq->color_config.high_bitdepth ? 10 : 8,
800 .subsampling_x = seq->color_config.subsampling_x,
801 .subsampling_y = seq->color_config.subsampling_y,
802 .color_primaries = seq->color_config.color_primaries,
803 .transfer_characteristics = seq->color_config.transfer_characteristics,
804 .matrix_coefficients = seq->color_config.matrix_coefficients,
805 };
806
807 *seq_hdr = (StdVideoAV1SequenceHeader) {
808 .flags = (StdVideoAV1SequenceHeaderFlags) {
809 .still_picture = seq->still_picture,
810 .reduced_still_picture_header = seq->reduced_still_picture_header,
811 .use_128x128_superblock = seq->use_128x128_superblock,
812 .enable_filter_intra = seq->enable_filter_intra,
813 .enable_intra_edge_filter = seq->enable_intra_edge_filter,
814 .enable_interintra_compound = seq->enable_interintra_compound,
815 .enable_masked_compound = seq->enable_masked_compound,
816 .enable_warped_motion = seq->enable_warped_motion,
817 .enable_dual_filter = seq->enable_dual_filter,
818 .enable_order_hint = seq->enable_order_hint,
819 .enable_jnt_comp = seq->enable_jnt_comp,
820 .enable_ref_frame_mvs = seq->enable_ref_frame_mvs,
821 .frame_id_numbers_present_flag = seq->frame_id_numbers_present_flag,
822 .enable_superres = seq->enable_superres,
823 .enable_cdef = seq->enable_cdef,
824 .enable_restoration = seq->enable_restoration,
825 .film_grain_params_present = seq->film_grain_params_present,
826 .timing_info_present_flag = seq->timing_info_present_flag,
827 .initial_display_delay_present_flag = seq->initial_display_delay_present_flag,
828 },
829 .seq_profile = seq->seq_profile,
830 .frame_width_bits_minus_1 = seq->frame_width_bits_minus_1,
831 .frame_height_bits_minus_1 = seq->frame_height_bits_minus_1,
832 .max_frame_width_minus_1 = seq->max_frame_width_minus_1,
833 .max_frame_height_minus_1 = seq->max_frame_height_minus_1,
834 .delta_frame_id_length_minus_2 = seq->delta_frame_id_length_minus_2,
835 .additional_frame_id_length_minus_1 = seq->additional_frame_id_length_minus_1,
836 .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1,
837 .seq_force_integer_mv = seq->seq_force_integer_mv,
838 .seq_force_screen_content_tools = seq->seq_force_screen_content_tools,
839 .pTimingInfo = timing_info,
840 .pColorConfig = color_config,
841 };
842
843 for (int i = 0; i <= seq->operating_points_cnt_minus_1; i++) {
844 operating_points[i] = (StdVideoEncodeAV1OperatingPointInfo) {
845 .flags = (StdVideoEncodeAV1OperatingPointInfoFlags) {
846 .decoder_model_present_for_this_op = seq->decoder_model_present_for_this_op[i],
847 .low_delay_mode_flag = seq->low_delay_mode_flag[i],
848 .initial_display_delay_present_for_this_op = seq->initial_display_delay_present_for_this_op[i],
849 /* Reserved */
850 },
851 .operating_point_idc = seq->operating_point_idc[i],
852 .seq_level_idx = seq->seq_level_idx[i],
853 .seq_tier = seq->seq_tier[i],
854 .decoder_buffer_delay = seq->decoder_buffer_delay[i],
855 .encoder_buffer_delay = seq->encoder_buffer_delay[i],
856 .initial_display_delay_minus_1 = seq->initial_display_delay_minus_1[i],
857 };
858 }
859 vk_units->nb_operating_points = seq->operating_points_cnt_minus_1 + 1;
860
861 return 0;
862}
863
864static int create_session_params(AVCodecContext *avctx)
865{
866 int err;
867 VulkanEncodeAV1Context *enc = avctx->priv_data;
868 FFVulkanEncodeContext *ctx = &enc->common;
869 FFVulkanContext *s = &ctx->s;
870 FFVulkanFunctions *vk = &ctx->s.vkfn;
871
872 VulkanAV1Units vk_units = { 0 };
873
874 VkVideoEncodeAV1SessionParametersCreateInfoKHR av1_params;
875
876 /* Convert it to Vulkan */
877 err = base_unit_to_vk(avctx, &vk_units);
878 if (err < 0) {
879 av_log(avctx, AV_LOG_ERROR, "Unable to convert sequence header to Vulkan: %s\n",
880 av_err2str(err));
881 return err;
882 }
883
884 /* Destroy the session params */
885 if (ctx->session_params)
886 vk->DestroyVideoSessionParametersKHR(s->hwctx->act_dev,
887 ctx->session_params,
888 s->hwctx->alloc);
889
890 av1_params = (VkVideoEncodeAV1SessionParametersCreateInfoKHR) {
891 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
892 .pStdSequenceHeader = &vk_units.seq_hdr,
893 .pStdDecoderModelInfo = &vk_units.decoder_model,
894 .pStdOperatingPoints = vk_units.operating_points,
895 .stdOperatingPointCount = vk_units.nb_operating_points,
896 };
897
898 return ff_vulkan_encode_create_session_params(avctx, ctx, &av1_params);
899}
900
901static int parse_feedback_units(AVCodecContext *avctx,
902 const uint8_t *data, size_t size)
903{
904 int err;
905 VulkanEncodeAV1Context *enc = avctx->priv_data;
906 AV1RawOBU *seq_obu = &enc->seq_hdr_obu;
907 AV1RawSequenceHeader *seq = &seq_obu->obu.sequence_header;
908
909 CodedBitstreamContext *cbs;
910 CodedBitstreamFragment obu = { 0 };
911
912 err = ff_cbs_init(&cbs, AV_CODEC_ID_AV1, avctx);
913 if (err < 0)
914 return err;
915
916 err = ff_cbs_read(cbs, &obu, NULL, data, size);
917 if (err < 0) {
918 av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n",
919 av_err2str(err));
920 return err;
921 }
922
923 /* If PPS has an override, just copy it entirely. */
924 for (int i = 0; i < obu.nb_units; i++) {
925 if (obu.units[i].type == AV1_OBU_SEQUENCE_HEADER) {
926 AV1RawOBU *f_seq_obu = obu.units[i].content;
927 AV1RawSequenceHeader *f_seq = &f_seq_obu->obu.sequence_header;
928 seq->frame_width_bits_minus_1 = f_seq->frame_width_bits_minus_1;
929 seq->frame_height_bits_minus_1 = f_seq->frame_height_bits_minus_1;
930 seq->max_frame_width_minus_1 = f_seq->max_frame_width_minus_1;
931 seq->max_frame_height_minus_1 = f_seq->max_frame_height_minus_1;
932 seq->seq_choose_screen_content_tools = f_seq->seq_choose_screen_content_tools;
933 seq->seq_force_screen_content_tools = f_seq->seq_force_screen_content_tools;
934 seq->seq_choose_integer_mv = f_seq->seq_choose_integer_mv;
935 seq->seq_force_integer_mv = f_seq->seq_force_integer_mv;
936 }
937 }
938
939 ff_cbs_fragment_free(&obu);
940 ff_cbs_close(&cbs);
941
942 return 0;
943}
944
945static int init_base_units(AVCodecContext *avctx)
946{
947 int err;
948 VkResult ret;
949 VulkanEncodeAV1Context *enc = avctx->priv_data;
950 FFVulkanEncodeContext *ctx = &enc->common;
951 FFVulkanContext *s = &ctx->s;
952 FFVulkanFunctions *vk = &ctx->s.vkfn;
953
954 VkVideoEncodeSessionParametersGetInfoKHR params_info;
955 VkVideoEncodeSessionParametersFeedbackInfoKHR params_feedback;
956
957 void *data = NULL;
958 size_t data_size = 0;
959
960 /* Generate SPS/PPS unit info */
961 err = init_sequence_headers(avctx);
962 if (err < 0) {
963 av_log(avctx, AV_LOG_ERROR, "Unable to initialize sequence header: %s\n",
964 av_err2str(err));
965 return err;
966 }
967
968 /* Create session parameters from them */
969 err = create_session_params(avctx);
970 if (err < 0)
971 return err;
972
973 params_info = (VkVideoEncodeSessionParametersGetInfoKHR) {
974 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_GET_INFO_KHR,
975 .videoSessionParameters = ctx->session_params,
976 };
977 params_feedback = (VkVideoEncodeSessionParametersFeedbackInfoKHR) {
978 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR,
979 };
980
981 ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, &params_info,
982 &params_feedback,
983 &data_size, data);
984 if (ret == VK_INCOMPLETE ||
985 (ret == VK_SUCCESS) && (data_size > 0)) {
986 data = av_mallocz(data_size);
987 if (!data)
988 return AVERROR(ENOMEM);
989 } else {
990 av_log(avctx, AV_LOG_ERROR, "Unable to get feedback for AV1 sequence header = %lu\n",
991 data_size);
992 return err;
993 }
994
995 ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, &params_info,
996 &params_feedback,
997 &data_size, data);
998 if (ret != VK_SUCCESS) {
999 av_log(avctx, AV_LOG_ERROR, "Error writing feedback units\n");
1000 return err;
1001 }
1002
1003 av_log(avctx, AV_LOG_VERBOSE, "Feedback units written, overrides: %i\n",
1004 params_feedback.hasOverrides);
1005
1006 params_feedback.hasOverrides = 1;
1007
1008 /* No need to sync any overrides */
1009 if (!params_feedback.hasOverrides)
1010 return 0;
1011
1012 /* Parse back tne units and override */
1013 err = parse_feedback_units(avctx, data, data_size);
1014 if (err < 0)
1015 return err;
1016
1017 /* Create final session parameters */
1018 err = create_session_params(avctx);
1019 if (err < 0)
1020 return err;
1021
1022 return 0;
1023}
1024
1025static int vulkan_encode_av1_add_obu(AVCodecContext *avctx,
1026 CodedBitstreamFragment *au,
1027 uint8_t type, void *obu_unit)
1028{
1029 int err;
1030
1031 err = ff_cbs_insert_unit_content(au, -1,
1032 type, obu_unit, NULL);
1033 if (err < 0) {
1034 av_log(avctx, AV_LOG_ERROR, "Failed to add OBU unit: "
1035 "type = %d.\n", type);
1036 return err;
1037 }
1038
1039 return err;
1040}
1041
1042static int vulkan_encode_av1_write_obu(AVCodecContext *avctx,
1043 uint8_t *data, size_t *data_len,
1044 CodedBitstreamFragment *obu)
1045{
1046 VulkanEncodeAV1Context *enc = avctx->priv_data;
1047 int ret;
1048
1049 ret = ff_cbs_write_fragment_data(enc->cbs, obu);
1050 if (ret < 0) {
1051 av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n");
1052 return ret;
1053 }
1054
1055 memcpy(data, obu->data, obu->data_size);
1056 *data_len = obu->data_size;
1057
1058 return 0;
1059}
1060
1061static int write_sequence_header(AVCodecContext *avctx,
1062 FFHWBaseEncodePicture *base_pic,
1063 uint8_t *data, size_t *data_len)
1064{
1065 int err;
1066 VulkanEncodeAV1Context *enc = avctx->priv_data;
1067 CodedBitstreamFragment *obu = &enc->current_access_unit;
1068
1069 err = vulkan_encode_av1_add_obu(avctx, obu,
1070 AV1_OBU_SEQUENCE_HEADER, &enc->seq_hdr_obu);
1071 if (err < 0)
1072 goto fail;
1073
1074 err = vulkan_encode_av1_write_obu(avctx, data, data_len, obu);
1075
1076fail:
1077 ff_cbs_fragment_reset(obu);
1078 return err;
1079}
1080
1081static int write_extra_headers(AVCodecContext *avctx,
1082 FFHWBaseEncodePicture *base_pic,
1083 uint8_t *data, size_t *data_len)
1084{
1085 int err;
1086 VulkanEncodeAV1Context *enc = avctx->priv_data;
1087 VulkanEncodeAV1Picture *ap = base_pic->codec_priv;
1088 CodedBitstreamFragment *obu = &enc->current_access_unit;
1089
1090 if (ap->units_needed & AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
1091 err = vulkan_encode_av1_add_obu(avctx, obu,
1092 AV1_OBU_METADATA,
1093 &enc->meta_mastering_obu);
1094 if (err < 0)
1095 goto fail;
1096 }
1097
1098 if (ap->units_needed & UNIT_CONTENT_LIGHT_LEVEL) {
1099 err = vulkan_encode_av1_add_obu(avctx, obu,
1100 AV1_OBU_METADATA,
1101 &enc->meta_cll_obu);
1102 if (err < 0)
1103 goto fail;
1104 }
1105
1106 if (ap->units_needed) {
1107 err = vulkan_encode_av1_write_obu(avctx, data, data_len, obu);
1108 if (err < 0)
1109 goto fail;
1110 } else {
1111 *data_len = 0;
1112 }
1113
1114fail:
1115 ff_cbs_fragment_reset(obu);
1116 return err;
1117}
1118
1119static int write_padding(AVCodecContext *avctx, uint32_t padding,
1120 uint8_t *data, size_t *data_len)
1121{
1122 int err;
1123 VulkanEncodeAV1Context *enc = avctx->priv_data;
1124 CodedBitstreamFragment *obu = &enc->current_access_unit;
1125
1126 AV1RawOBU padding_obu = { 0 };
1127 AV1RawPadding *raw_padding = &padding_obu.obu.padding;
1128
1129 if (!padding)
1130 padding = 16;
1131
1132 /* 2 byte header + 1 byte trailing bits */
1133 padding_obu.header.obu_type = AV1_OBU_PADDING;
1134 *raw_padding = (AV1RawPadding) {
1135 .payload = enc->padding_payload,
1136 .payload_size = padding,
1137 };
1138
1139 err = vulkan_encode_av1_add_obu(avctx, obu, AV1_OBU_PADDING, &padding_obu);
1140 if (err < 0)
1141 goto fail;
1142
1143 err = vulkan_encode_av1_write_obu(avctx, data, data_len, obu);
1144fail:
1145 ff_cbs_fragment_reset(obu);
1146 return err;
1147}
1148
1149static const FFVulkanCodec enc_cb = {
1150 .flags = FF_HW_FLAG_B_PICTURES |
1151 FF_HW_FLAG_B_PICTURE_REFERENCES |
1152 VK_ENC_FLAG_NO_DELAY |
1153 FF_HW_FLAG_SLICE_CONTROL,
1154 .picture_priv_data_size = sizeof(VulkanEncodeAV1Picture),
1155 .filler_header_size = 4,
1156 .init_profile = init_profile,
1157 .init_pic_rc = init_pic_rc,
1158 .init_pic_params = init_pic_params,
1159 .write_sequence_headers = write_sequence_header,
1160 .write_extra_headers = write_extra_headers,
1161 .write_filler = write_padding,
1162};
1163
1164static av_cold int vulkan_encode_av1_init(AVCodecContext *avctx)
1165{
1166 int err;
1167 VulkanEncodeAV1Context *enc = avctx->priv_data;
1168 FFVulkanEncodeContext *ctx = &enc->common;
1169 FFVulkanContext *s = &ctx->s;
1170 FFHWBaseEncodeContext *base_ctx = &ctx->base;
1171 int flags;
1172
1173 if (avctx->profile == AV_PROFILE_UNKNOWN)
1174 avctx->profile = enc->common.opts.profile;
1175
1176 enc->caps = (VkVideoEncodeAV1CapabilitiesKHR) {
1177 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
1178 };
1179
1180 enc->quality_props = (VkVideoEncodeAV1QualityLevelPropertiesKHR) {
1181 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_QUALITY_LEVEL_PROPERTIES_KHR,
1182 };
1183
1184 err = ff_vulkan_encode_init(avctx, &enc->common,
1185 &ff_vk_enc_av1_desc, &enc_cb,
1186 &enc->caps, &enc->quality_props);
1187 if (err < 0)
1188 return err;
1189
1190 av_log(avctx, AV_LOG_VERBOSE, "AV1 encoder capabilities:\n");
1191 av_log(avctx, AV_LOG_VERBOSE, " Standard capability flags:\n");
1192 av_log(avctx, AV_LOG_VERBOSE, " per_rate_control_group_min_max_q_index: %i\n",
1193 !!(enc->caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_PER_RATE_CONTROL_GROUP_MIN_MAX_Q_INDEX_BIT_KHR));
1194 av_log(avctx, AV_LOG_VERBOSE, " generate_obu_extension_header: %i\n",
1195 !!(enc->caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_GENERATE_OBU_EXTENSION_HEADER_BIT_KHR));
1196 av_log(avctx, AV_LOG_VERBOSE, " primary_reference_cdf_only: %i\n",
1197 !!(enc->caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_PRIMARY_REFERENCE_CDF_ONLY_BIT_KHR));
1198 av_log(avctx, AV_LOG_VERBOSE, " frame_size_override: %i\n",
1199 !!(enc->caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_FRAME_SIZE_OVERRIDE_BIT_KHR));
1200 av_log(avctx, AV_LOG_VERBOSE, " motion_vector_scaling: %i\n",
1201 !!(enc->caps.flags & VK_VIDEO_ENCODE_AV1_CAPABILITY_MOTION_VECTOR_SCALING_BIT_KHR));
1202 av_log(avctx, AV_LOG_VERBOSE, " Capabilities:\n");
1203 av_log(avctx, AV_LOG_VERBOSE, " 64x64 superblocks: %i\n",
1204 !!(enc->caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR));
1205 av_log(avctx, AV_LOG_VERBOSE, " 128x128 superblocks: %i\n",
1206 !!(enc->caps.superblockSizes & VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_128_BIT_KHR));
1207 av_log(avctx, AV_LOG_VERBOSE, " maxSingleReferenceCount: %i\n",
1208 enc->caps.maxSingleReferenceCount);
1209 av_log(avctx, AV_LOG_VERBOSE, " singleReferenceNameMask: 0x%x\n",
1210 enc->caps.singleReferenceNameMask);
1211 av_log(avctx, AV_LOG_VERBOSE, " maxUnidirectionalCompoundReferenceCount: %i\n",
1212 enc->caps.maxUnidirectionalCompoundReferenceCount);
1213 av_log(avctx, AV_LOG_VERBOSE, " maxUnidirectionalCompoundGroup1ReferenceCount: %i\n",
1214 enc->caps.maxUnidirectionalCompoundGroup1ReferenceCount);
1215 av_log(avctx, AV_LOG_VERBOSE, " unidirectionalCompoundReferenceNameMask: 0x%x\n",
1216 enc->caps.unidirectionalCompoundReferenceNameMask);
1217 av_log(avctx, AV_LOG_VERBOSE, " maxBidirectionalCompoundReferenceCount: %i\n",
1218 enc->caps.maxBidirectionalCompoundReferenceCount);
1219 av_log(avctx, AV_LOG_VERBOSE, " maxBidirectionalCompoundGroup1ReferenceCount: %i\n",
1220 enc->caps.maxBidirectionalCompoundGroup1ReferenceCount);
1221 av_log(avctx, AV_LOG_VERBOSE, " maxBidirectionalCompoundGroup2ReferenceCount: %i\n",
1222 enc->caps.maxBidirectionalCompoundGroup2ReferenceCount);
1223 av_log(avctx, AV_LOG_VERBOSE, " bidirectionalCompoundReferenceNameMask: 0x%x\n",
1224 enc->caps.bidirectionalCompoundReferenceNameMask);
1225 av_log(avctx, AV_LOG_VERBOSE, " maxTemporalLayerCount: %i\n",
1226 enc->caps.maxTemporalLayerCount);
1227 av_log(avctx, AV_LOG_VERBOSE, " maxSpatialLayerCount: %i\n",
1228 enc->caps.maxSpatialLayerCount);
1229 av_log(avctx, AV_LOG_VERBOSE, " maxOperatingPoints: %i\n",
1230 enc->caps.maxOperatingPoints);
1231 av_log(avctx, AV_LOG_VERBOSE, " min/max Qindex: [%i, %i]\n",
1232 enc->caps.minQIndex, enc->caps.maxQIndex);
1233 av_log(avctx, AV_LOG_VERBOSE, " prefersGopRemainingFrames: %i\n",
1234 enc->caps.prefersGopRemainingFrames);
1235 av_log(avctx, AV_LOG_VERBOSE, " requiresGopRemainingFrames: %i\n",
1236 enc->caps.requiresGopRemainingFrames);
1237 av_log(avctx, AV_LOG_VERBOSE, " maxLevel: %i\n",
1238 enc->caps.maxLevel);
1239 av_log(avctx, AV_LOG_VERBOSE, " codedPictureAlignment: %ix%i\n",
1240 enc->caps.codedPictureAlignment.width, enc->caps.codedPictureAlignment.height);
1241 av_log(avctx, AV_LOG_VERBOSE, " maxTiles: %ix%i\n",
1242 enc->caps.maxTiles.width, enc->caps.maxTiles.height);
1243 av_log(avctx, AV_LOG_VERBOSE, " Tile size: %ix%i to %ix%i\n",
1244 enc->caps.minTileSize.width, enc->caps.minTileSize.height,
1245 enc->caps.maxTileSize.width, enc->caps.maxTileSize.height);
1246
1247 err = init_enc_options(avctx);
1248 if (err < 0)
1249 return err;
1250
1251 flags = ctx->codec->flags;
1252 err = ff_hw_base_init_gop_structure(base_ctx, avctx,
1253 ctx->caps.maxDpbSlots,
1254 enc->caps.maxBidirectionalCompoundReferenceCount,
1255 flags, 0);
1256 if (err < 0)
1257 return err;
1258
1259 base_ctx->output_delay = base_ctx->b_per_p;
1260 base_ctx->decode_delay = base_ctx->max_b_depth;
1261
1262 /* Create units and session parameters */
1263 err = init_base_units(avctx);
1264 if (err < 0)
1265 return err;
1266
1267 /* Init CBS */
1268 err = ff_cbs_init(&enc->cbs, AV_CODEC_ID_AV1, avctx);
1269 if (err < 0)
1270 return err;
1271
1272 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1273 uint8_t data[4096];
1274 size_t data_len = sizeof(data);
1275
1276 err = write_sequence_header(avctx, NULL, data, &data_len);
1277 if (err < 0) {
1278 av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
1279 "for extradata: %d.\n", err);
1280 return err;
1281 } else {
1282 avctx->extradata_size = data_len;
1283 avctx->extradata = av_mallocz(avctx->extradata_size +
1284 AV_INPUT_BUFFER_PADDING_SIZE);
1285 if (!avctx->extradata) {
1286 err = AVERROR(ENOMEM);
1287 return err;
1288 }
1289 memcpy(avctx->extradata, data, avctx->extradata_size);
1290 }
1291 }
1292
1293 enc->padding_payload = av_mallocz(2*ctx->caps.minBitstreamBufferOffsetAlignment);
1294 if (!enc->padding_payload)
1295 return AVERROR(ENOMEM);
1296
1297 memset(enc->padding_payload, 0xaa, 2*ctx->caps.minBitstreamBufferOffsetAlignment);
1298
1299 return 0;
1300}
1301
1302static av_cold int vulkan_encode_av1_close(AVCodecContext *avctx)
1303{
1304 VulkanEncodeAV1Context *enc = avctx->priv_data;
1305 av_free(enc->padding_payload);
1306 ff_vulkan_encode_uninit(&enc->common);
1307 return 0;
1308}
1309
1310#define OFFSET(x) offsetof(VulkanEncodeAV1Context, x)
1311#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1312static const AVOption vulkan_encode_av1_options[] = {
1313 HW_BASE_ENCODE_COMMON_OPTIONS,
1314 VULKAN_ENCODE_COMMON_OPTIONS,
1315
1316 { "profile", "Set profile",
1317 OFFSET(common.opts.profile), AV_OPT_TYPE_INT,
1318 { .i64 = AV_PROFILE_UNKNOWN }, AV_PROFILE_UNKNOWN, 0xffff, FLAGS, .unit = "profile" },
1319
1320#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1321 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1322 { PROFILE("main", AV_PROFILE_AV1_MAIN) },
1323 { PROFILE("high", AV_PROFILE_AV1_HIGH) },
1324 { PROFILE("professional", AV_PROFILE_AV1_PROFESSIONAL) },
1325#undef PROFILE
1326
1327 { "tier", "Set tier (seq_tier)",
1328 OFFSET(common.opts.tier), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "tier" },
1329 { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "tier" },
1330 { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "tier" },
1331
1332 { "level", "Set level (level_idc)",
1333 OFFSET(common.opts.level), AV_OPT_TYPE_INT,
1334 { .i64 = AV_LEVEL_UNKNOWN }, AV_LEVEL_UNKNOWN, 0xff, FLAGS, .unit = "level" },
1335
1336#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1337 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1338 { LEVEL("20", 0) },
1339 { LEVEL("21", 1) },
1340 { LEVEL("22", 2) },
1341 { LEVEL("23", 3) },
1342 { LEVEL("30", 4) },
1343 { LEVEL("31", 5) },
1344 { LEVEL("32", 6) },
1345 { LEVEL("33", 7) },
1346 { LEVEL("40", 8) },
1347 { LEVEL("41", 9) },
1348 { LEVEL("42", 10) },
1349 { LEVEL("43", 11) },
1350 { LEVEL("50", 12) },
1351 { LEVEL("51", 13) },
1352 { LEVEL("52", 14) },
1353 { LEVEL("53", 15) },
1354 { LEVEL("60", 16) },
1355 { LEVEL("61", 17) },
1356 { LEVEL("62", 18) },
1357 { LEVEL("63", 19) },
1358 { LEVEL("70", 20) },
1359 { LEVEL("71", 21) },
1360 { LEVEL("72", 22) },
1361 { LEVEL("73", 23) },
1362#undef LEVEL
1363
1364 { "units", "Set units to include", OFFSET(unit_elems), AV_OPT_TYPE_FLAGS, { .i64 = UNIT_MASTERING_DISPLAY | UNIT_CONTENT_LIGHT_LEVEL }, 0, INT_MAX, FLAGS, "units" },
1365 { "hdr", "Include HDR metadata for mastering display colour volume and content light level information", 0, AV_OPT_TYPE_CONST, { .i64 = UNIT_MASTERING_DISPLAY | UNIT_CONTENT_LIGHT_LEVEL }, INT_MIN, INT_MAX, FLAGS, "units" },
1366
1367 { NULL },
1368};
1369
1370static const FFCodecDefault vulkan_encode_av1_defaults[] = {
1371 { "b", "0" },
1372 { "bf", "2" },
1373 { "g", "300" },
1374 { "qmin", "1" },
1375 { "qmax", "255" },
1376 { NULL },
1377};
1378
1379static const AVClass vulkan_encode_av1_class = {
1380 .class_name = "av1_vulkan",
1381 .item_name = av_default_item_name,
1382 .option = vulkan_encode_av1_options,
1383 .version = LIBAVUTIL_VERSION_INT,
1384};
1385
1386const FFCodec ff_av1_vulkan_encoder = {
1387 .p.name = "av1_vulkan",
1388 CODEC_LONG_NAME("AV1 (Vulkan)"),
1389 .p.type = AVMEDIA_TYPE_VIDEO,
1390 .p.id = AV_CODEC_ID_AV1,
1391 .priv_data_size = sizeof(VulkanEncodeAV1Context),
1392 .init = &vulkan_encode_av1_init,
1393 FF_CODEC_RECEIVE_PACKET_CB(&ff_vulkan_encode_receive_packet),
1394 .close = &vulkan_encode_av1_close,
1395 .p.priv_class = &vulkan_encode_av1_class,
1396 .p.capabilities = AV_CODEC_CAP_DELAY |
1397 AV_CODEC_CAP_HARDWARE |
1398 AV_CODEC_CAP_DR1 |
1399 AV_CODEC_CAP_ENCODER_FLUSH |
1400 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1401 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1402 .defaults = vulkan_encode_av1_defaults,
1403 .p.pix_fmts = (const enum AVPixelFormat[]) {
1404 AV_PIX_FMT_VULKAN,
1405 AV_PIX_FMT_NONE,
1406 },
1407 .hw_configs = ff_vulkan_encode_hw_configs,
1408 .p.wrapper_name = "vulkan",
1409};
libavcodec/vulkan_video.c+41−0
@@ -226,6 +226,37 @@ StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc) · 225 unmodified lines
226 }226 }
227}227}
228 228
229StdVideoAV1Level ff_vk_av1_level_to_vk(int level)
230{
231 switch (level) {
232 case 20: return STD_VIDEO_AV1_LEVEL_2_0;
233 case 21: return STD_VIDEO_AV1_LEVEL_2_1;
234 case 22: return STD_VIDEO_AV1_LEVEL_2_2;
235 case 23: return STD_VIDEO_AV1_LEVEL_2_3;
236 case 30: return STD_VIDEO_AV1_LEVEL_3_0;
237 case 31: return STD_VIDEO_AV1_LEVEL_3_1;
238 case 32: return STD_VIDEO_AV1_LEVEL_3_2;
239 case 33: return STD_VIDEO_AV1_LEVEL_3_3;
240 case 40: return STD_VIDEO_AV1_LEVEL_4_0;
241 case 41: return STD_VIDEO_AV1_LEVEL_4_1;
242 case 42: return STD_VIDEO_AV1_LEVEL_4_2;
243 case 43: return STD_VIDEO_AV1_LEVEL_4_3;
244 case 50: return STD_VIDEO_AV1_LEVEL_5_0;
245 case 51: return STD_VIDEO_AV1_LEVEL_5_1;
246 case 52: return STD_VIDEO_AV1_LEVEL_5_2;
247 case 53: return STD_VIDEO_AV1_LEVEL_5_3;
248 case 60: return STD_VIDEO_AV1_LEVEL_6_0;
249 case 61: return STD_VIDEO_AV1_LEVEL_6_1;
250 case 62: return STD_VIDEO_AV1_LEVEL_6_2;
251 case 63: return STD_VIDEO_AV1_LEVEL_6_3;
252 case 70: return STD_VIDEO_AV1_LEVEL_7_0;
253 case 71: return STD_VIDEO_AV1_LEVEL_7_1;
254 case 72: return STD_VIDEO_AV1_LEVEL_7_2;
255 default:
256 case 73: return STD_VIDEO_AV1_LEVEL_7_3;
257 }
258}
259
229StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)260StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)
230{261{
231 switch (profile) {262 switch (profile) {
@@ -247,6 +278,16 @@ StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile) · 15 unmodified lines
247 }278 }
248}279}
249 280
281StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile)
282{
283 switch (profile) {
284 case AV_PROFILE_AV1_MAIN: return STD_VIDEO_AV1_PROFILE_MAIN;
285 case AV_PROFILE_AV1_HIGH: return STD_VIDEO_AV1_PROFILE_HIGH;
286 case AV_PROFILE_AV1_PROFESSIONAL: return STD_VIDEO_AV1_PROFILE_PROFESSIONAL;
287 default: return STD_VIDEO_AV1_PROFILE_INVALID;
288 }
289}
290
250int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,291int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
251 VkImageView *view, VkImageAspectFlags *aspect,292 VkImageView *view, VkImageAspectFlags *aspect,
252 AVVkFrame *src, VkFormat vkf, int is_dpb)293 AVVkFrame *src, VkFormat vkf, int is_dpb)
libavcodec/vulkan_video.h+2−0
@@ -71,12 +71,14 @@ int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level); · 70 unmodified lines
71 71
72StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc);72StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc);
73StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc);73StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc);
74StdVideoAV1Level ff_vk_av1_level_to_vk(int level);
74 75
75/**76/**
76 * Convert profile from/to AV to Vulkan77 * Convert profile from/to AV to Vulkan
77 */78 */
78StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile);79StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile);
79StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile);80StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile);
81StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile);
80 82
81/**83/**
82 * Creates image views for video frames.84 * Creates image views for video frames.
libavutil/hwcontext_vulkan.c+17−0
@@ -93,6 +93,9 @@ typedef struct VulkanDeviceFeatures { · 92 unmodified lines
93#ifdef VK_KHR_video_decode_vp993#ifdef VK_KHR_video_decode_vp9
94 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;94 VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
95#endif95#endif
96#ifdef VK_KHR_video_encode_av1
97 VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
98#endif
96 99
97 VkPhysicalDeviceShaderObjectFeaturesEXT shader_object;100 VkPhysicalDeviceShaderObjectFeaturesEXT shader_object;
98 VkPhysicalDeviceCooperativeMatrixFeaturesKHR cooperative_matrix;101 VkPhysicalDeviceCooperativeMatrixFeaturesKHR cooperative_matrix;
@@ -237,6 +240,10 @@ static void device_features_init(AVHWDeviceContext *ctx, VulkanDeviceFeatures *f · 138 unmodified lines
237 FF_VK_STRUCT_EXT(s, &feats->device, &feats->vp9_decode, FF_VK_EXT_VIDEO_DECODE_VP9,240 FF_VK_STRUCT_EXT(s, &feats->device, &feats->vp9_decode, FF_VK_EXT_VIDEO_DECODE_VP9,
238 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);241 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
239#endif242#endif
243#ifdef VK_KHR_video_encode_av1
244 FF_VK_STRUCT_EXT(s, &feats->device, &feats->av1_encode, FF_VK_EXT_VIDEO_ENCODE_AV1,
245 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
246#endif
240 247
241 FF_VK_STRUCT_EXT(s, &feats->device, &feats->shader_object, FF_VK_EXT_SHADER_OBJECT,248 FF_VK_STRUCT_EXT(s, &feats->device, &feats->shader_object, FF_VK_EXT_SHADER_OBJECT,
242 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);249 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
@@ -313,6 +320,10 @@ static void device_features_copy_needed(VulkanDeviceFeatures *dst, VulkanDeviceF · 70 unmodified lines
313 COPY_VAL(vp9_decode.videoDecodeVP9);320 COPY_VAL(vp9_decode.videoDecodeVP9);
314#endif321#endif
315 322
323#ifdef VK_KHR_video_encode_av1
324 COPY_VAL(av1_encode.videoEncodeAV1);
325#endif
326
316 COPY_VAL(shader_object.shaderObject);327 COPY_VAL(shader_object.shaderObject);
317 328
318 COPY_VAL(cooperative_matrix.cooperativeMatrix);329 COPY_VAL(cooperative_matrix.cooperativeMatrix);
@@ -660,6 +671,9 @@ static const VulkanOptExtension optional_device_exts[] = { · 341 unmodified lines
660 { VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_H265 },671 { VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_H265 },
661#ifdef VK_KHR_video_decode_vp9672#ifdef VK_KHR_video_decode_vp9
662 { VK_KHR_VIDEO_DECODE_VP9_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_VP9 },673 { VK_KHR_VIDEO_DECODE_VP9_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_VP9 },
674#endif
675#ifdef VK_KHR_video_encode_av1
676 { VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_AV1 },
663#endif677#endif
664 { VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_AV1 },678 { VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_AV1 },
665};679};
@@ -1569,6 +1583,9 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) · 903 unmodified lines
1569 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);1583 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
1570#endif1584#endif
1571 1585
1586#ifdef VK_KHR_video_encode_av1
1587 PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
1588#endif
1572 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);1589 PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
1573 1590
1574 av_free(qf);1591 av_free(qf);
libavutil/vulkan_functions.h+1−0
@@ -65,6 +65,7 @@ typedef uint64_t FFVulkanExtensions; · 64 unmodified lines
65#define FF_VK_EXT_VIDEO_ENCODE_QUEUE (1ULL << 50) /* VK_KHR_video_encode_queue */65#define FF_VK_EXT_VIDEO_ENCODE_QUEUE (1ULL << 50) /* VK_KHR_video_encode_queue */
66#define FF_VK_EXT_VIDEO_ENCODE_H264 (1ULL << 51) /* VK_KHR_video_encode_h264 */66#define FF_VK_EXT_VIDEO_ENCODE_H264 (1ULL << 51) /* VK_KHR_video_encode_h264 */
67#define FF_VK_EXT_VIDEO_ENCODE_H265 (1ULL << 52) /* VK_KHR_video_encode_h265 */67#define FF_VK_EXT_VIDEO_ENCODE_H265 (1ULL << 52) /* VK_KHR_video_encode_h265 */
68#define FF_VK_EXT_VIDEO_ENCODE_AV1 (1ULL << 53) /* VK_KHR_video_encode_av1 */
68 69
69#define FF_VK_EXT_PORTABILITY_SUBSET (1ULL << 62)70#define FF_VK_EXT_PORTABILITY_SUBSET (1ULL << 62)
70#define FF_VK_EXT_NO_FLAG (1ULL << 63)71#define FF_VK_EXT_NO_FLAG (1ULL << 63)
libavutil/vulkan_loader.h+3−0
@@ -83,6 +83,9 @@ static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions, · 82 unmodified lines
83 { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_PUSH_DESCRIPTOR },83 { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_PUSH_DESCRIPTOR },
84#ifdef VK_KHR_shader_expect_assume84#ifdef VK_KHR_shader_expect_assume
85 { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME },85 { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME },
86#endif
87#ifdef VK_KHR_video_encode_av1
88 { VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_AV1 },
86#endif89#endif
87 };90 };
88 91

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t