FFmpeg
Loading...
Searching...
No Matches
vulkan_av1.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "av1dec.h"
20
21#include "vulkan_decode.h"
22
23/* Maximum number of tiles specified by any defined level */
24#define MAX_TILES 256
25
27 .codec_id = AV_CODEC_ID_AV1,
28 .decode_extension = FF_VK_EXT_VIDEO_DECODE_AV1,
29 .queue_flags = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
30 .decode_op = VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR,
31 .ext_props = {
32 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME,
33 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION,
34 },
35};
36
37typedef struct AV1VulkanDecodePicture {
39
40 /* TODO: investigate if this can be removed to make decoding completely
41 * independent. */
43
45
46 /* Current picture */
47 StdVideoDecodeAV1ReferenceInfo std_ref;
48 VkVideoDecodeAV1DpbSlotInfoKHR vkav1_ref;
49 uint16_t width_in_sbs_minus1[64];
51 uint16_t mi_col_starts[64];
52 uint16_t mi_row_starts[64];
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 StdVideoAV1FilmGrain film_grain;
61 StdVideoDecodeAV1PictureInfo std_pic_info;
62 VkVideoDecodeAV1PictureInfoKHR av1_pic_info;
63
64 /* Picture refs */
66 StdVideoDecodeAV1ReferenceInfo std_refs [AV1_NUM_REF_FRAMES];
67 VkVideoDecodeAV1DpbSlotInfoKHR vkav1_refs[AV1_NUM_REF_FRAMES];
68
69 uint8_t frame_id_set;
70 uint8_t frame_id;
73
74static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src,
75 VkVideoReferenceSlotInfoKHR *ref_slot, /* Main structure */
76 VkVideoPictureResourceInfoKHR *ref, /* Goes in ^ */
77 StdVideoDecodeAV1ReferenceInfo *vkav1_std_ref,
78 VkVideoDecodeAV1DpbSlotInfoKHR *vkav1_ref, /* Goes in ^ */
79 const AV1Frame *pic, int is_current, int has_grain,
80 const uint8_t *saved_order_hints)
81{
85 FFVulkanDecodePicture *vkpic = &hp->vp;
86
87 int err = ff_vk_decode_prepare_frame(dec, pic->f, vkpic, is_current,
88 has_grain || dec->dedicated_dpb);
89 if (err < 0)
90 return err;
91
92 *vkav1_std_ref = (StdVideoDecodeAV1ReferenceInfo) {
93 .flags = (StdVideoDecodeAV1ReferenceInfoFlags) {
94 .disable_frame_end_update_cdf = pic->raw_frame_header->disable_frame_end_update_cdf,
95 .segmentation_enabled = pic->raw_frame_header->segmentation_enabled,
96 },
97 .frame_type = pic->raw_frame_header->frame_type,
98 .OrderHint = pic->raw_frame_header->order_hint,
99 .RefFrameSignBias = hp->ref_frame_sign_bias_mask,
100 };
101
102 if (saved_order_hints) {
103 if (dec->quirk_av1_offset)
104 for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
105 vkav1_std_ref->SavedOrderHints[i - 1] = saved_order_hints[i];
106 else
107 for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
108 vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i];
109 }
110
111 *vkav1_ref = (VkVideoDecodeAV1DpbSlotInfoKHR) {
112 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR,
113 .pStdReferenceInfo = vkav1_std_ref,
114 };
115
116 vkav1_std_ref->flags.disable_frame_end_update_cdf = pic->raw_frame_header->disable_frame_end_update_cdf;
117 vkav1_std_ref->flags.segmentation_enabled = pic->raw_frame_header->segmentation_enabled;
118 vkav1_std_ref->frame_type = pic->raw_frame_header->frame_type;
119
120 *ref = (VkVideoPictureResourceInfoKHR) {
121 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
122 .codedOffset = (VkOffset2D){ 0, 0 },
123 .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
124 .baseArrayLayer = ((has_grain || dec->dedicated_dpb) && ctx->common.layered_dpb) ?
125 hp->frame_id : 0,
126 .imageViewBinding = vkpic->view.ref,
127 };
128
129 *ref_slot = (VkVideoReferenceSlotInfoKHR) {
130 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
131 .pNext = vkav1_ref,
132 .slotIndex = hp->frame_id,
133 .pPictureResource = ref,
134 };
135
136 if (ref_src)
137 *ref_src = pic;
138
139 return 0;
140}
141
143 StdVideoAV1TimingInfo *av1_timing_info,
144 StdVideoAV1ColorConfig *av1_color_config,
145 StdVideoAV1SequenceHeader *av1_sequence_header)
146{
147 const AV1DecContext *s = avctx->priv_data;
148 const AV1RawSequenceHeader *seq = s->raw_seq;
149
150 *av1_timing_info = (StdVideoAV1TimingInfo) {
151 .flags = (StdVideoAV1TimingInfoFlags) {
152 .equal_picture_interval = seq->timing_info.equal_picture_interval,
153 },
154 .num_units_in_display_tick = seq->timing_info.num_units_in_display_tick,
155 .time_scale = seq->timing_info.time_scale,
156 .num_ticks_per_picture_minus_1 = seq->timing_info.num_ticks_per_picture_minus_1,
157 };
158
159 *av1_color_config = (StdVideoAV1ColorConfig) {
160 .flags = (StdVideoAV1ColorConfigFlags) {
161 .mono_chrome = seq->color_config.mono_chrome,
162 .color_range = seq->color_config.color_range,
163 .separate_uv_delta_q = seq->color_config.separate_uv_delta_q,
164 },
165 .BitDepth = seq->color_config.twelve_bit ? 12 :
166 seq->color_config.high_bitdepth ? 10 : 8,
167 .subsampling_x = seq->color_config.subsampling_x,
168 .subsampling_y = seq->color_config.subsampling_y,
169 .color_primaries = seq->color_config.color_primaries,
170 .transfer_characteristics = seq->color_config.transfer_characteristics,
171 .matrix_coefficients = seq->color_config.matrix_coefficients,
172 };
173
174 *av1_sequence_header = (StdVideoAV1SequenceHeader) {
175 .flags = (StdVideoAV1SequenceHeaderFlags) {
176 .still_picture = seq->still_picture,
177 .reduced_still_picture_header = seq->reduced_still_picture_header,
178 .use_128x128_superblock = seq->use_128x128_superblock,
179 .enable_filter_intra = seq->enable_filter_intra,
180 .enable_intra_edge_filter = seq->enable_intra_edge_filter,
181 .enable_interintra_compound = seq->enable_interintra_compound,
182 .enable_masked_compound = seq->enable_masked_compound,
183 .enable_warped_motion = seq->enable_warped_motion,
184 .enable_dual_filter = seq->enable_dual_filter,
185 .enable_order_hint = seq->enable_order_hint,
186 .enable_jnt_comp = seq->enable_jnt_comp,
187 .enable_ref_frame_mvs = seq->enable_ref_frame_mvs,
188 .frame_id_numbers_present_flag = seq->frame_id_numbers_present_flag,
189 .enable_superres = seq->enable_superres,
190 .enable_cdef = seq->enable_cdef,
191 .enable_restoration = seq->enable_restoration,
192 .film_grain_params_present = seq->film_grain_params_present,
193 .timing_info_present_flag = seq->timing_info_present_flag,
194 .initial_display_delay_present_flag = seq->initial_display_delay_present_flag,
195 },
196 .seq_profile = seq->seq_profile,
197 .frame_width_bits_minus_1 = seq->frame_width_bits_minus_1,
198 .frame_height_bits_minus_1 = seq->frame_height_bits_minus_1,
199 .max_frame_width_minus_1 = seq->max_frame_width_minus_1,
200 .max_frame_height_minus_1 = seq->max_frame_height_minus_1,
201 .delta_frame_id_length_minus_2 = seq->delta_frame_id_length_minus_2,
202 .additional_frame_id_length_minus_1 = seq->additional_frame_id_length_minus_1,
203 .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1,
204 .seq_force_integer_mv = seq->seq_force_integer_mv,
205 .seq_force_screen_content_tools = seq->seq_force_screen_content_tools,
206 .pTimingInfo = av1_timing_info,
207 .pColorConfig = av1_color_config,
208 };
209}
210
211static int vk_av1_create_params(AVCodecContext *avctx, VkVideoSessionParametersKHR **buf,
213{
214 int err;
217
218 StdVideoAV1SequenceHeader av1_sequence_header;
219 StdVideoAV1TimingInfo av1_timing_info;
220 StdVideoAV1ColorConfig av1_color_config;
221 VkVideoDecodeAV1SessionParametersCreateInfoKHR av1_params;
222 VkVideoSessionParametersCreateInfoKHR session_params_create;
223
224 vk_av1_params_fill(avctx, &av1_timing_info, &av1_color_config,
225 &av1_sequence_header);
226
227 av1_params = (VkVideoDecodeAV1SessionParametersCreateInfoKHR) {
228 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_SESSION_PARAMETERS_CREATE_INFO_KHR,
229 .pStdSequenceHeader = &av1_sequence_header,
230 };
231 session_params_create = (VkVideoSessionParametersCreateInfoKHR) {
232 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
233 .pNext = &av1_params,
234 .videoSession = ctx->common.session,
235 .videoSessionParametersTemplate = VK_NULL_HANDLE,
236 };
237
238 err = ff_vk_decode_create_params(buf, avctx, ctx, &session_params_create);
239 if (err < 0)
240 return err;
241
242 av_log(avctx, AV_LOG_DEBUG, "Created frame parameters\n");
243
244 return 0;
245}
246
248 av_unused const AVBufferRef *buffer_ref,
249 av_unused const uint8_t *buffer,
250 av_unused uint32_t size)
251{
252 int err;
253 int ref_count = 0;
254 AV1DecContext *s = avctx->priv_data;
255 const AV1RawSequenceHeader *seq = s->raw_seq;
256 const AV1Frame *pic = &s->cur_frame;
258 uint32_t frame_id_alloc_mask = 0;
259 uint16_t sb_shift = seq->use_128x128_superblock ? 5 : 4;
260
262 FFVulkanDecodePicture *vp = &ap->vp;
263
264 const AV1RawFrameHeader *frame_header = s->raw_frame_header;
265 const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
266
267 const int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
268 film_grain->apply_grain;
269 StdVideoAV1FrameRestorationType remap_lr_type[4] = { STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
270 STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SWITCHABLE,
271 STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_WIENER,
272 STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SGRPROJ };
273
274 /* Use the current frame_ids in ref[] to decide occupied frame_ids */
275 for (int i = 0; i < STD_VIDEO_AV1_NUM_REF_FRAMES; i++) {
276 const AV1VulkanDecodePicture* rp = s->ref[i].hwaccel_picture_private;
277 if (rp)
278 frame_id_alloc_mask |= 1 << rp->frame_id;
279 }
280
281 if (!ap->frame_id_set) {
282 unsigned slot_idx = 0;
283 for (unsigned i = 0; i < 32; i++) {
284 if (!(frame_id_alloc_mask & (1 << i))) {
285 slot_idx = i;
286 break;
287 }
288 }
289 ap->frame_id = slot_idx;
290 ap->frame_id_set = 1;
291 frame_id_alloc_mask |= (1 << slot_idx);
292 }
293
294 ap->ref_frame_sign_bias_mask = 0x0;
295 for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
297
298 for (int i = 0; i < STD_VIDEO_AV1_REFS_PER_FRAME; i++) {
299 const int idx = pic->raw_frame_header->ref_frame_idx[i];
300 const AV1Frame *ref_frame = &s->ref[idx];
301 AV1VulkanDecodePicture *hp = ref_frame->hwaccel_picture_private;
302 int found = 0;
303
304 if (!ref_frame->f)
305 continue;
306
307 for (int j = 0; j < ref_count; j++) {
308 if (vp->ref_slots[j].slotIndex == hp->frame_id) {
309 found = 1;
310 break;
311 }
312 }
313 if (found)
314 continue;
315
316 err = vk_av1_fill_pict(avctx, &ap->ref_src[ref_count], &vp->ref_slots[ref_count],
317 &vp->refs[ref_count], &ap->std_refs[ref_count], &ap->vkav1_refs[ref_count],
318 ref_frame, 0, 0, ref_frame->order_hints);
319 if (err < 0)
320 return err;
321
322 ref_count++;
323 }
324
325 err = vk_av1_fill_pict(avctx, NULL, &vp->ref_slot, &vp->ref,
326 &ap->std_ref,
327 &ap->vkav1_ref,
328 pic, 1, apply_grain, NULL);
329 if (err < 0)
330 return err;
331
332 ap->av1_pic_info = (VkVideoDecodeAV1PictureInfoKHR) {
333 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PICTURE_INFO_KHR,
334 .pStdPictureInfo = &ap->std_pic_info,
335 .frameHeaderOffset = 0,
336 .tileCount = 0,
337 .pTileOffsets = NULL,
338 .pTileSizes = ap->tile_sizes,
339 };
340
341 for (int i = 0; i < STD_VIDEO_AV1_REFS_PER_FRAME; i++) {
342 const int idx = pic->raw_frame_header->ref_frame_idx[i];
343 const AV1Frame *ref_frame = &s->ref[idx];
344 AV1VulkanDecodePicture *hp = ref_frame->hwaccel_picture_private;
345
346 if (!ref_frame->f)
347 ap->av1_pic_info.referenceNameSlotIndices[i] = AV1_REF_FRAME_NONE;
348 else
349 ap->av1_pic_info.referenceNameSlotIndices[i] = hp->frame_id;
350 }
351
352 vp->decode_info = (VkVideoDecodeInfoKHR) {
353 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR,
354 .pNext = &ap->av1_pic_info,
355 .flags = 0x0,
356 .pSetupReferenceSlot = &vp->ref_slot,
357 .referenceSlotCount = ref_count,
358 .pReferenceSlots = vp->ref_slots,
359 .dstPictureResource = (VkVideoPictureResourceInfoKHR) {
360 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
361 .codedOffset = (VkOffset2D){ 0, 0 },
362 .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
363 .baseArrayLayer = 0,
364 .imageViewBinding = vp->view.out,
365 },
366 };
367
368 ap->tile_info = (StdVideoAV1TileInfo) {
369 .flags = (StdVideoAV1TileInfoFlags) {
370 .uniform_tile_spacing_flag = frame_header->uniform_tile_spacing_flag,
371 },
372 .TileCols = frame_header->tile_cols,
373 .TileRows = frame_header->tile_rows,
374 .context_update_tile_id = frame_header->context_update_tile_id,
375 .tile_size_bytes_minus_1 = frame_header->tile_size_bytes_minus1,
376 .pWidthInSbsMinus1 = ap->width_in_sbs_minus1,
377 .pHeightInSbsMinus1 = ap->height_in_sbs_minus1,
378 .pMiColStarts = ap->mi_col_starts,
379 .pMiRowStarts = ap->mi_row_starts,
380 };
381
382 ap->quantization = (StdVideoAV1Quantization) {
383 .flags.using_qmatrix = frame_header->using_qmatrix,
384 .flags.diff_uv_delta = frame_header->diff_uv_delta,
385 .base_q_idx = frame_header->base_q_idx,
386 .DeltaQYDc = frame_header->delta_q_y_dc,
387 .DeltaQUDc = frame_header->delta_q_u_dc,
388 .DeltaQUAc = frame_header->delta_q_u_ac,
389 .DeltaQVDc = frame_header->delta_q_v_dc,
390 .DeltaQVAc = frame_header->delta_q_v_ac,
391 .qm_y = frame_header->qm_y,
392 .qm_u = frame_header->qm_u,
393 .qm_v = frame_header->qm_v,
394 };
395
396 ap->loop_filter = (StdVideoAV1LoopFilter) {
397 .flags = (StdVideoAV1LoopFilterFlags) {
398 .loop_filter_delta_enabled = frame_header->loop_filter_delta_enabled,
399 .loop_filter_delta_update = frame_header->loop_filter_delta_update,
400 },
401 .loop_filter_sharpness = frame_header->loop_filter_sharpness,
402 };
403
404 for (int i = 0; i < STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS; i++)
405 ap->loop_filter.loop_filter_level[i] = frame_header->loop_filter_level[i];
406 for (int i = 0; i < STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS; i++)
407 ap->loop_filter.loop_filter_mode_deltas[i] = frame_header->loop_filter_mode_deltas[i];
408
409 ap->cdef = (StdVideoAV1CDEF) {
410 .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3,
411 .cdef_bits = frame_header->cdef_bits,
412 };
413
414 ap->loop_restoration = (StdVideoAV1LoopRestoration) {
415 .FrameRestorationType[0] = remap_lr_type[frame_header->lr_type[0]],
416 .FrameRestorationType[1] = remap_lr_type[frame_header->lr_type[1]],
417 .FrameRestorationType[2] = remap_lr_type[frame_header->lr_type[2]],
418 .LoopRestorationSize[0] = 1 + frame_header->lr_unit_shift,
419 .LoopRestorationSize[1] = 1 + frame_header->lr_unit_shift - frame_header->lr_uv_shift,
420 .LoopRestorationSize[2] = 1 + frame_header->lr_unit_shift - frame_header->lr_uv_shift,
421 };
422
423 ap->film_grain = (StdVideoAV1FilmGrain) {
424 .flags = (StdVideoAV1FilmGrainFlags) {
425 .chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma,
426 .overlap_flag = film_grain->overlap_flag,
427 .clip_to_restricted_range = film_grain->clip_to_restricted_range,
428 },
429 .grain_scaling_minus_8 = film_grain->grain_scaling_minus_8,
430 .ar_coeff_lag = film_grain->ar_coeff_lag,
431 .ar_coeff_shift_minus_6 = film_grain->ar_coeff_shift_minus_6,
432 .grain_scale_shift = film_grain->grain_scale_shift,
433 .grain_seed = film_grain->grain_seed,
434 .film_grain_params_ref_idx = film_grain->film_grain_params_ref_idx,
435 .num_y_points = film_grain->num_y_points,
436 .num_cb_points = film_grain->num_cb_points,
437 .num_cr_points = film_grain->num_cr_points,
438 .cb_mult = film_grain->cb_mult,
439 .cb_luma_mult = film_grain->cb_luma_mult,
440 .cb_offset = film_grain->cb_offset,
441 .cr_mult = film_grain->cr_mult,
442 .cr_luma_mult = film_grain->cr_luma_mult,
443 .cr_offset = film_grain->cr_offset,
444 };
445
446 /* Setup frame header */
447 ap->std_pic_info = (StdVideoDecodeAV1PictureInfo) {
448 .flags = (StdVideoDecodeAV1PictureInfoFlags) {
449 .error_resilient_mode = frame_header->error_resilient_mode,
450 .disable_cdf_update = frame_header->disable_cdf_update,
451 .use_superres = frame_header->use_superres,
452 .render_and_frame_size_different = frame_header->render_and_frame_size_different,
453 .allow_screen_content_tools = frame_header->allow_screen_content_tools,
454 .is_filter_switchable = frame_header->is_filter_switchable,
455 .force_integer_mv = pic->force_integer_mv,
456 .frame_size_override_flag = frame_header->frame_size_override_flag,
457 .buffer_removal_time_present_flag = frame_header->buffer_removal_time_present_flag,
458 .allow_intrabc = frame_header->allow_intrabc,
459 .frame_refs_short_signaling = frame_header->frame_refs_short_signaling,
460 .allow_high_precision_mv = frame_header->allow_high_precision_mv,
461 .is_motion_mode_switchable = frame_header->is_motion_mode_switchable,
462 .use_ref_frame_mvs = frame_header->use_ref_frame_mvs,
463 .disable_frame_end_update_cdf = frame_header->disable_frame_end_update_cdf,
464 .allow_warped_motion = frame_header->allow_warped_motion,
465 .reduced_tx_set = frame_header->reduced_tx_set,
466 .reference_select = frame_header->reference_select,
467 .skip_mode_present = frame_header->skip_mode_present,
468 .delta_q_present = frame_header->delta_q_present,
469 .delta_lf_present = frame_header->delta_lf_present,
470 .delta_lf_multi = frame_header->delta_lf_multi,
471 .segmentation_enabled = frame_header->segmentation_enabled,
472 .segmentation_update_map = frame_header->segmentation_update_map,
473 .segmentation_temporal_update = frame_header->segmentation_temporal_update,
474 .segmentation_update_data = frame_header->segmentation_update_data,
475 .UsesLr = frame_header->lr_type[0] || frame_header->lr_type[1] || frame_header->lr_type[2],
476 .apply_grain = apply_grain,
477 },
478 .frame_type = frame_header->frame_type,
479 .current_frame_id = frame_header->current_frame_id,
480 .OrderHint = frame_header->order_hint,
481 .primary_ref_frame = frame_header->primary_ref_frame,
482 .refresh_frame_flags = frame_header->refresh_frame_flags,
483 .interpolation_filter = frame_header->interpolation_filter,
484 .TxMode = frame_header->tx_mode,
485 .delta_q_res = frame_header->delta_q_res,
486 .delta_lf_res = frame_header->delta_lf_res,
487 .SkipModeFrame[0] = s->cur_frame.skip_mode_frame_idx[0],
488 .SkipModeFrame[1] = s->cur_frame.skip_mode_frame_idx[1],
489 .coded_denom = frame_header->coded_denom,
490 .pTileInfo = &ap->tile_info,
491 .pQuantization = &ap->quantization,
492 .pSegmentation = &ap->segmentation,
493 .pLoopFilter = &ap->loop_filter,
494 .pCDEF = &ap->cdef,
495 .pLoopRestoration = &ap->loop_restoration,
496 .pGlobalMotion = &ap->global_motion,
497 .pFilmGrain = apply_grain ? &ap->film_grain : NULL,
498 };
499
500 for (int i = 0; i < 64; i++) {
501 ap->width_in_sbs_minus1[i] = frame_header->width_in_sbs_minus_1[i];
502 ap->height_in_sbs_minus1[i] = frame_header->height_in_sbs_minus_1[i];
503 ap->mi_col_starts[i] = frame_header->tile_start_col_sb[i] << sb_shift;
504 ap->mi_row_starts[i] = frame_header->tile_start_row_sb[i] << sb_shift;
505 }
506
507 for (int i = 0; i < STD_VIDEO_AV1_MAX_SEGMENTS; i++) {
508 ap->segmentation.FeatureEnabled[i] = 0x0;
509 for (int j = 0; j < STD_VIDEO_AV1_SEG_LVL_MAX; j++) {
510 ap->segmentation.FeatureEnabled[i] |= (frame_header->feature_enabled[i][j] << j);
511 ap->segmentation.FeatureData[i][j] = frame_header->feature_value[i][j];
512 }
513 }
514
515 if (dec->quirk_av1_offset)
516 for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
517 ap->std_pic_info.OrderHints[i - 1] = pic->order_hints[i];
518 else
519 for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
520 ap->std_pic_info.OrderHints[i] = pic->order_hints[i];
521
522 for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) {
523 ap->loop_filter.loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i];
524 ap->global_motion.GmType[i] = s->cur_frame.gm_type[i];
525 for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
526 ap->global_motion.gm_params[i][j] = s->cur_frame.gm_params[i][j];
527 }
528 }
529
530 for (int i = 0; i < STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS; i++) {
531 ap->cdef.cdef_y_pri_strength[i] = frame_header->cdef_y_pri_strength[i];
532 ap->cdef.cdef_y_sec_strength[i] = frame_header->cdef_y_sec_strength[i];
533 ap->cdef.cdef_uv_pri_strength[i] = frame_header->cdef_uv_pri_strength[i];
534 ap->cdef.cdef_uv_sec_strength[i] = frame_header->cdef_uv_sec_strength[i];
535 }
536
537 if (apply_grain) {
538 for (int i = 0; i < STD_VIDEO_AV1_MAX_NUM_Y_POINTS; i++) {
539 ap->film_grain.point_y_value[i] = film_grain->point_y_value[i];
540 ap->film_grain.point_y_scaling[i] = film_grain->point_y_scaling[i];
541 }
542
543 for (int i = 0; i < STD_VIDEO_AV1_MAX_NUM_CB_POINTS; i++) {
544 ap->film_grain.point_cb_value[i] = film_grain->point_cb_value[i];
545 ap->film_grain.point_cb_scaling[i] = film_grain->point_cb_scaling[i];
546 ap->film_grain.point_cr_value[i] = film_grain->point_cr_value[i];
547 ap->film_grain.point_cr_scaling[i] = film_grain->point_cr_scaling[i];
548 }
549
550 for (int i = 0; i < STD_VIDEO_AV1_MAX_NUM_POS_LUMA; i++)
551 ap->film_grain.ar_coeffs_y_plus_128[i] = film_grain->ar_coeffs_y_plus_128[i];
552
553 for (int i = 0; i < STD_VIDEO_AV1_MAX_NUM_POS_CHROMA; i++) {
554 ap->film_grain.ar_coeffs_cb_plus_128[i] = film_grain->ar_coeffs_cb_plus_128[i];
555 ap->film_grain.ar_coeffs_cr_plus_128[i] = film_grain->ar_coeffs_cr_plus_128[i];
556 }
557 }
558
559 ap->dec = dec;
560
561 return 0;
562}
563
565 const uint8_t *data,
566 uint32_t size)
567{
568 int err;
569 const AV1DecContext *s = avctx->priv_data;
570 AV1VulkanDecodePicture *ap = s->cur_frame.hwaccel_picture_private;
571 FFVulkanDecodePicture *vp = &ap->vp;
572
573 /* Too many tiles, exceeding all defined levels in the AV1 spec */
574 if (ap->av1_pic_info.tileCount > MAX_TILES)
575 return AVERROR(ENOSYS);
576
577 for (int i = s->tg_start; i <= s->tg_end; i++) {
578 ap->tile_sizes[ap->av1_pic_info.tileCount] = s->tile_group_info[i].tile_size;
579
580 err = ff_vk_decode_add_slice(avctx, vp,
581 data + s->tile_group_info[i].tile_offset,
582 s->tile_group_info[i].tile_size, 0,
583 &ap->av1_pic_info.tileCount,
584 &ap->av1_pic_info.pTileOffsets);
585 if (err < 0)
586 return err;
587 }
588
589 return 0;
590}
591
593{
594 const AV1DecContext *s = avctx->priv_data;
597
598 const AV1Frame *pic = &s->cur_frame;
600 FFVulkanDecodePicture *vp = &ap->vp;
602 AVFrame *rav[AV1_NUM_REF_FRAMES] = { 0 };
603
604#ifdef VK_KHR_video_maintenance2
605 StdVideoAV1SequenceHeader av1_sequence_header;
606 StdVideoAV1TimingInfo av1_timing_info;
607 StdVideoAV1ColorConfig av1_color_config;
608 VkVideoDecodeAV1InlineSessionParametersInfoKHR av1_params;
609
610 if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2) {
611 vk_av1_params_fill(avctx, &av1_timing_info, &av1_color_config,
612 &av1_sequence_header);
613 av1_params = (VkVideoDecodeAV1InlineSessionParametersInfoKHR) {
614 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_INLINE_SESSION_PARAMETERS_INFO_KHR,
615 .pStdSequenceHeader = &av1_sequence_header,
616 };
617 ap->av1_pic_info.pNext = &av1_params;
618 }
619#endif
620
621 if (!ap->av1_pic_info.tileCount)
622 return 0;
623
624 if (!dec->session_params &&
625 !(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
626 int err = vk_av1_create_params(avctx, &dec->session_params, ap);
627 if (err < 0)
628 return err;
629 }
630
631 for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
632 const AV1Frame *rp = ap->ref_src[i];
634
635 rvp[i] = &rhp->vp;
636 rav[i] = ap->ref_src[i]->f;
637 }
638
639 av_log(avctx, AV_LOG_DEBUG, "Decoding frame, %zu bytes, %i tiles\n",
640 vp->slices_size, ap->av1_pic_info.tileCount);
641
642 return ff_vk_decode_frame(avctx, pic->f, vp, rav, rvp);
643}
644
646{
647 AVHWDeviceContext *hwctx = _hwctx.nc;
649
650 /* Free frame resources, this also destroys the session parameters. */
651 ff_vk_decode_free_frame(hwctx, &ap->vp);
652}
653
655 .p.name = "av1_vulkan",
656 .p.type = AVMEDIA_TYPE_VIDEO,
657 .p.id = AV_CODEC_ID_AV1,
658 .p.pix_fmt = AV_PIX_FMT_VULKAN,
659 .start_frame = &vk_av1_start_frame,
660 .decode_slice = &vk_av1_decode_slice,
661 .end_frame = &vk_av1_end_frame,
662 .free_frame_priv = &vk_av1_free_frame_priv,
663 .frame_priv_data_size = sizeof(AV1VulkanDecodePicture),
665 .update_thread_context = &ff_vk_update_thread_context,
666 .decode_params = &ff_vk_params_invalidate,
668 .frame_params = &ff_vk_frame_params,
669 .priv_data_size = sizeof(FFVulkanDecodeContext),
670 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
671};
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
#define MAX_TILES
Definition d3d12va_av1.c:31
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition avcodec.h:404
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
const struct FFHWAccel ff_av1_vulkan_hwaccel
Definition vulkan_av1.c:654
static av_cold void uninit(AVBitStreamFilterContext *ctx)
@ AV1_REF_FRAME_NONE
Definition av1.h:61
@ AV1_NUM_REF_FRAMES
Definition av1.h:84
#define av_unused
Definition attributes.h:164
const char data[16]
Definition mxf.c:149
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
uint8_t ref_frame_sign_bias[AV1_TOTAL_REFS_PER_FRAME]
Definition av1dec.h:66
AV1RawFrameHeader * raw_frame_header
Definition av1dec.h:48
uint8_t force_integer_mv
Definition av1dec.h:75
void * hwaccel_picture_private
RefStruct reference.
Definition av1dec.h:45
struct AVFrame * f
Definition av1dec.h:40
uint8_t order_hints[AV1_TOTAL_REFS_PER_FRAME]
Definition av1dec.h:69
uint8_t twelve_bit
Definition cbs_av1.h:52
uint8_t matrix_coefficients
Definition cbs_av1.h:58
uint8_t subsampling_x
Definition cbs_av1.h:61
uint8_t high_bitdepth
Definition cbs_av1.h:51
uint8_t mono_chrome
Definition cbs_av1.h:53
uint8_t color_range
Definition cbs_av1.h:60
uint8_t transfer_characteristics
Definition cbs_av1.h:57
uint8_t subsampling_y
Definition cbs_av1.h:62
uint8_t separate_uv_delta_q
Definition cbs_av1.h:64
uint8_t color_primaries
Definition cbs_av1.h:56
uint8_t ar_coeffs_y_plus_128[24]
Definition cbs_av1.h:159
uint8_t ar_coeff_shift_minus_6
Definition cbs_av1.h:162
uint8_t point_y_value[14]
Definition cbs_av1.h:148
uint8_t grain_scale_shift
Definition cbs_av1.h:163
uint8_t point_cb_scaling[10]
Definition cbs_av1.h:153
uint8_t film_grain_params_ref_idx
Definition cbs_av1.h:146
uint8_t point_cr_scaling[10]
Definition cbs_av1.h:156
uint8_t ar_coeffs_cr_plus_128[25]
Definition cbs_av1.h:161
uint8_t clip_to_restricted_range
Definition cbs_av1.h:171
uint8_t point_cr_value[10]
Definition cbs_av1.h:155
uint8_t point_cb_value[10]
Definition cbs_av1.h:152
uint8_t chroma_scaling_from_luma
Definition cbs_av1.h:150
uint8_t grain_scaling_minus_8
Definition cbs_av1.h:157
uint8_t point_y_scaling[14]
Definition cbs_av1.h:149
uint8_t ar_coeffs_cb_plus_128[25]
Definition cbs_av1.h:160
uint8_t segmentation_enabled
Definition cbs_av1.h:251
uint8_t frame_type
Definition cbs_av1.h:180
int8_t ref_frame_idx[AV1_REFS_PER_FRAME]
Definition cbs_av1.h:213
uint8_t disable_frame_end_update_cdf
Definition cbs_av1.h:222
uint8_t order_hint
Definition cbs_av1.h:191
uint8_t use_128x128_superblock
Definition cbs_av1.h:114
uint8_t enable_ref_frame_mvs
Definition cbs_av1.h:124
uint8_t frame_id_numbers_present_flag
Definition cbs_av1.h:110
uint8_t enable_dual_filter
Definition cbs_av1.h:120
uint8_t enable_restoration
Definition cbs_av1.h:135
uint8_t reduced_still_picture_header
Definition cbs_av1.h:85
uint8_t enable_intra_edge_filter
Definition cbs_av1.h:116
uint16_t max_frame_height_minus_1
Definition cbs_av1.h:108
uint8_t enable_filter_intra
Definition cbs_av1.h:115
uint8_t timing_info_present_flag
Definition cbs_av1.h:87
uint8_t seq_force_integer_mv
Definition cbs_av1.h:129
uint8_t seq_profile
Definition cbs_av1.h:83
uint8_t film_grain_params_present
Definition cbs_av1.h:139
uint8_t initial_display_delay_present_flag
Definition cbs_av1.h:89
uint8_t enable_jnt_comp
Definition cbs_av1.h:123
uint8_t enable_interintra_compound
Definition cbs_av1.h:117
AV1RawColorConfig color_config
Definition cbs_av1.h:137
uint8_t additional_frame_id_length_minus_1
Definition cbs_av1.h:112
uint8_t enable_masked_compound
Definition cbs_av1.h:118
uint8_t still_picture
Definition cbs_av1.h:84
uint8_t delta_frame_id_length_minus_2
Definition cbs_av1.h:111
uint8_t enable_superres
Definition cbs_av1.h:133
uint8_t frame_height_bits_minus_1
Definition cbs_av1.h:106
uint8_t enable_warped_motion
Definition cbs_av1.h:119
uint8_t order_hint_bits_minus_1
Definition cbs_av1.h:131
uint8_t frame_width_bits_minus_1
Definition cbs_av1.h:105
AV1RawTimingInfo timing_info
Definition cbs_av1.h:92
uint16_t max_frame_width_minus_1
Definition cbs_av1.h:107
uint8_t enable_order_hint
Definition cbs_av1.h:122
uint8_t seq_force_screen_content_tools
Definition cbs_av1.h:127
uint32_t time_scale
Definition cbs_av1.h:69
uint32_t num_units_in_display_tick
Definition cbs_av1.h:68
uint32_t num_ticks_per_picture_minus_1
Definition cbs_av1.h:72
uint8_t equal_picture_interval
Definition cbs_av1.h:71
StdVideoDecodeAV1PictureInfo std_pic_info
Definition vulkan_av1.c:61
FFVulkanDecodePicture vp
Definition vulkan_av1.c:38
StdVideoAV1Quantization quantization
Definition vulkan_av1.c:54
StdVideoAV1CDEF cdef
Definition vulkan_av1.c:57
FFVulkanDecodeContext * dec
Definition vulkan_av1.c:42
StdVideoDecodeAV1ReferenceInfo std_refs[AV1_NUM_REF_FRAMES]
Definition vulkan_av1.c:66
uint16_t mi_row_starts[64]
Definition vulkan_av1.c:52
StdVideoAV1LoopRestoration loop_restoration
Definition vulkan_av1.c:58
StdVideoAV1FilmGrain film_grain
Definition vulkan_av1.c:60
StdVideoAV1Segmentation segmentation
Definition vulkan_av1.c:55
const AV1Frame * ref_src[AV1_NUM_REF_FRAMES]
Definition vulkan_av1.c:65
uint16_t mi_col_starts[64]
Definition vulkan_av1.c:51
uint8_t ref_frame_sign_bias_mask
Definition vulkan_av1.c:71
uint32_t tile_sizes[MAX_TILES]
Definition vulkan_av1.c:44
VkVideoDecodeAV1DpbSlotInfoKHR vkav1_refs[AV1_NUM_REF_FRAMES]
Definition vulkan_av1.c:67
VkVideoDecodeAV1PictureInfoKHR av1_pic_info
Definition vulkan_av1.c:62
StdVideoDecodeAV1ReferenceInfo std_ref
Definition vulkan_av1.c:47
StdVideoAV1GlobalMotion global_motion
Definition vulkan_av1.c:59
StdVideoAV1LoopFilter loop_filter
Definition vulkan_av1.c:56
VkVideoDecodeAV1DpbSlotInfoKHR vkav1_ref
Definition vulkan_av1.c:48
uint16_t height_in_sbs_minus1[64]
Definition vulkan_av1.c:50
StdVideoAV1TileInfo tile_info
Definition vulkan_av1.c:53
uint16_t width_in_sbs_minus1[64]
Definition vulkan_av1.c:49
A reference to a data buffer.
Definition buffer.h:82
main external API structure.
Definition avcodec.h:443
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition avcodec.h:1779
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * priv_data
Definition avcodec.h:470
void * hwaccel_priv_data
hwaccel-specific private data
Definition internal.h:130
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int width
Definition frame.h:544
int height
Definition frame.h:544
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
VkVideoSessionParametersKHR * session_params
FFVulkanDecodeShared * shared_ctx
struct FFVulkanDecodePicture::@321376256110110067000314232201030232256240036361 view
VkVideoReferenceSlotInfoKHR ref_slot
VkVideoPictureResourceInfoKHR refs[36]
VkVideoReferenceSlotInfoKHR ref_slots[36]
VkVideoDecodeInfoKHR decode_info
uint8_t flags
Definition truemotion1.c:98
#define av_log(a,...)
static int ref[MAX_W *MAX_W]
static AVFormatContext * ctx
Definition movenc.c:49
static char buffer[20]
Definition seek.c:32
int size
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition refstruct.h:58
static int vk_av1_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
Definition vulkan_av1.c:564
const FFVulkanDecodeDescriptor ff_vk_dec_av1_desc
Definition vulkan_av1.c:26
#define MAX_TILES
Definition vulkan_av1.c:24
static int vk_av1_end_frame(AVCodecContext *avctx)
Definition vulkan_av1.c:592
static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src, VkVideoReferenceSlotInfoKHR *ref_slot, VkVideoPictureResourceInfoKHR *ref, StdVideoDecodeAV1ReferenceInfo *vkav1_std_ref, VkVideoDecodeAV1DpbSlotInfoKHR *vkav1_ref, const AV1Frame *pic, int is_current, int has_grain, const uint8_t *saved_order_hints)
Definition vulkan_av1.c:74
static void vk_av1_params_fill(AVCodecContext *avctx, StdVideoAV1TimingInfo *av1_timing_info, StdVideoAV1ColorConfig *av1_color_config, StdVideoAV1SequenceHeader *av1_sequence_header)
Definition vulkan_av1.c:142
static void vk_av1_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
Definition vulkan_av1.c:645
static int vk_av1_create_params(AVCodecContext *avctx, VkVideoSessionParametersKHR **buf, AV1VulkanDecodePicture *ap)
Definition vulkan_av1.c:211
static int vk_av1_start_frame(AVCodecContext *avctx, av_unused const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition vulkan_av1.c:247
int ff_vk_decode_frame(AVCodecContext *avctx, AVFrame *pic, FFVulkanDecodePicture *vp, AVFrame *rpic[], FFVulkanDecodePicture *rvkp[])
Decode a frame.
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
int ff_vk_decode_create_params(VkVideoSessionParametersKHR **par_ref, void *logctx, FFVulkanDecodeShared *ctx, const VkVideoSessionParametersCreateInfoKHR *session_params_create)
Create VkVideoSessionParametersKHR wrapped in an AVBufferRef.
int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
Removes current session parameters to recreate them.
int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Initialize hw_frames_ctx with the parameters needed to decode the stream using the parameters from av...
int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, const uint8_t *data, size_t size, int add_startcode, uint32_t *nb_slices, const uint32_t **offsets)
Add slice data to frame.
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic, FFVulkanDecodePicture *vkpic, int is_current, int alloc_dpb)
Prepare a frame, creates the image view, and sets up the dpb fields.
#define FF_VK_EXT_VIDEO_DECODE_AV1
#define FF_VK_EXT_VIDEO_MAINTENANCE_2
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition dec.c:616