1 /*
2 * DXVA2 AV1 HW acceleration.
3 *
4 * copyright (c) 2020 Hendrik Leppkes
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "config_components.h"
24
27
30
32
35
38 };
39
41 DXVA_PicParams_AV1
pp;
46 };
47
49 {
53 return 10;
54 else
55 return 8;
56 }
57
59 DXVA_PicParams_AV1 *pp)
60 {
65
68
69 memset(pp, 0, sizeof(*pp));
70
71 pp->width = avctx->
width;
72 pp->height = avctx->
height;
73
76
81
82 /* Tiling info */
85 pp->tiles.context_update_id =
frame_header->context_update_tile_id;
86
87 for (
i = 0;
i < pp->tiles.cols;
i++)
89
90 for (
i = 0;
i < pp->tiles.rows;
i++)
92
93 /* Coding tools */
98 pp->coding.warped_motion =
frame_header->allow_warped_motion;
101 pp->coding.screen_content_tools =
frame_header->allow_screen_content_tools;
107 pp->coding.high_precision_mv =
frame_header->allow_high_precision_mv;
108 pp->coding.switchable_motion_mode =
frame_header->is_motion_mode_switchable;
110 pp->coding.disable_frame_end_update_cdf =
frame_header->disable_frame_end_update_cdf;
111 pp->coding.disable_cdf_update =
frame_header->disable_cdf_update;
112 pp->coding.reference_mode =
frame_header->reference_select;
114 pp->coding.reduced_tx_set =
frame_header->reduced_tx_set;
117 pp->coding.use_ref_frame_mvs =
frame_header->use_ref_frame_mvs;
119 pp->coding.reference_frame_update = 1; // 0 for show_existing_frame with key frames, but those are not passed to the hwaccel
120
121 /* Format & Picture Info flags */
124 pp->format.showable_frame =
frame_header->showable_frame;
128
129 /* References */
130 pp->primary_ref_frame =
frame_header->primary_ref_frame;
133
134 memset(pp->RefFrameMapTextureIndex, 0xFF, sizeof(pp->RefFrameMapTextureIndex));
137 AVFrame *ref_frame =
h->ref[ref_idx].f;
138
139 pp->frame_refs[
i].width = ref_frame->
width;
140 pp->frame_refs[
i].height = ref_frame->
height;
141 pp->frame_refs[
i].Index = ref_frame->
buf[0] ? ref_idx : 0xFF;
142
143 /* Global Motion */
146 for (j = 0; j < 6; ++j) {
148 }
149 }
152 if (ref_frame->
buf[0])
154 }
155
156 /* Loop filter parameters */
157 pp->loop_filter.filter_level[0] =
frame_header->loop_filter_level[0];
158 pp->loop_filter.filter_level[1] =
frame_header->loop_filter_level[1];
159 pp->loop_filter.filter_level_u =
frame_header->loop_filter_level[2];
160 pp->loop_filter.filter_level_v =
frame_header->loop_filter_level[3];
161 pp->loop_filter.sharpness_level =
frame_header->loop_filter_sharpness;
162 pp->loop_filter.mode_ref_delta_enabled =
frame_header->loop_filter_delta_enabled;
163 pp->loop_filter.mode_ref_delta_update =
frame_header->loop_filter_delta_update;
164 pp->loop_filter.delta_lf_multi =
frame_header->delta_lf_multi;
165 pp->loop_filter.delta_lf_present =
frame_header->delta_lf_present;
166 pp->loop_filter.delta_lf_res =
frame_header->delta_lf_res;
167
169 pp->loop_filter.ref_deltas[
i] =
frame_header->loop_filter_ref_deltas[
i];
170 }
171
172 pp->loop_filter.mode_deltas[0] =
frame_header->loop_filter_mode_deltas[0];
173 pp->loop_filter.mode_deltas[1] =
frame_header->loop_filter_mode_deltas[1];
174 pp->loop_filter.frame_restoration_type[0] = remap_lr_type[
frame_header->lr_type[0]];
175 pp->loop_filter.frame_restoration_type[1] = remap_lr_type[
frame_header->lr_type[1]];
176 pp->loop_filter.frame_restoration_type[2] = remap_lr_type[
frame_header->lr_type[2]];
178 pp->loop_filter.log2_restoration_unit_size[0] = uses_lr ? (6 +
frame_header->lr_unit_shift) : 8;
179 pp->loop_filter.log2_restoration_unit_size[1] = uses_lr ? (6 +
frame_header->lr_unit_shift -
frame_header->lr_uv_shift) : 8;
180 pp->loop_filter.log2_restoration_unit_size[2] = uses_lr ? (6 +
frame_header->lr_unit_shift -
frame_header->lr_uv_shift) : 8;
181
182 /* Quantization */
183 pp->quantization.delta_q_present =
frame_header->delta_q_present;
184 pp->quantization.delta_q_res =
frame_header->delta_q_res;
185 pp->quantization.base_qindex =
frame_header->base_q_idx;
186 pp->quantization.y_dc_delta_q =
frame_header->delta_q_y_dc;
187 pp->quantization.u_dc_delta_q =
frame_header->delta_q_u_dc;
188 pp->quantization.v_dc_delta_q =
frame_header->delta_q_v_dc;
189 pp->quantization.u_ac_delta_q =
frame_header->delta_q_u_ac;
190 pp->quantization.v_ac_delta_q =
frame_header->delta_q_v_ac;
194
195 /* Cdef parameters */
198 for (
i = 0;
i < 8;
i++) {
199 pp->cdef.y_strengths[
i].primary =
frame_header->cdef_y_pri_strength[
i];
200 pp->cdef.y_strengths[
i].secondary =
frame_header->cdef_y_sec_strength[
i];
201 pp->cdef.uv_strengths[
i].primary =
frame_header->cdef_uv_pri_strength[
i];
202 pp->cdef.uv_strengths[
i].secondary =
frame_header->cdef_uv_sec_strength[
i];
203 }
204
205 /* Misc flags */
207
208 /* Segmentation */
209 pp->segmentation.enabled =
frame_header->segmentation_enabled;
210 pp->segmentation.update_map =
frame_header->segmentation_update_map;
211 pp->segmentation.update_data =
frame_header->segmentation_update_data;
212 pp->segmentation.temporal_update =
frame_header->segmentation_temporal_update;
215 pp->segmentation.feature_mask[
i].mask |=
frame_header->feature_enabled[
i][j] << j;
216 pp->segmentation.feature_data[
i][j] =
frame_header->feature_value[
i][j];
217 }
218 }
219
220 /* Film grain */
221 if (apply_grain) {
222 pp->film_grain.apply_grain = 1;
231
232 pp->film_grain.grain_seed = film_grain->
grain_seed;
237 }
242 }
247 }
248 for (
i = 0;
i < 24;
i++) {
250 }
251 for (
i = 0;
i < 25;
i++) {
254 }
255 pp->film_grain.cb_mult = film_grain->
cb_mult;
257 pp->film_grain.cr_mult = film_grain->
cr_mult;
259 pp->film_grain.cb_offset = film_grain->
cb_offset;
260 pp->film_grain.cr_offset = film_grain->
cr_offset;
261 pp->film_grain.cr_offset = film_grain->
cr_offset;
262 }
263
264 // XXX: Setting the StatusReportFeedbackNumber breaks decoding on some drivers (tested on NVIDIA 457.09)
265 // Status Reporting is not used by FFmpeg, hence not providing a number does not cause any issues
266 //pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
267 return 0;
268 }
269
273 {
277
278 if (!DXVA_CONTEXT_VALID(avctx,
ctx))
279 return -1;
281
282 /* Fill up DXVA_PicParams_AV1 */
284 return -1;
285
288 return 0;
289 }
290
294 {
300
302
303 /* too many tiles, exceeding all defined levels in the AV1 spec */
306
307 /* Shortcut if all tiles are in the same buffer */
308 if (ctx_pic->
tile_count ==
h->tg_end -
h->tg_start + 1) {
311
312 for (uint32_t tile_num = 0; tile_num < ctx_pic->
tile_count; tile_num++) {
313 ctx_pic->
tiles[tile_num].DataOffset =
h->tile_group_info[tile_num].tile_offset;
314 ctx_pic->
tiles[tile_num].DataSize =
h->tile_group_info[tile_num].tile_size;
315 ctx_pic->
tiles[tile_num].row =
h->tile_group_info[tile_num].tile_row;
316 ctx_pic->
tiles[tile_num].column =
h->tile_group_info[tile_num].tile_column;
317 ctx_pic->
tiles[tile_num].anchor_frame = 0xFF;
318 }
319
320 return 0;
321 }
322
323 /* allocate an internal buffer */
328 }
330
332
333 for (uint32_t tile_num =
h->tg_start; tile_num <= h->tg_end; tile_num++) {
334 ctx_pic->
tiles[tile_num].DataOffset = ctx_pic->
bitstream_size +
h->tile_group_info[tile_num].tile_offset;
335 ctx_pic->
tiles[tile_num].DataSize =
h->tile_group_info[tile_num].tile_size;
336 ctx_pic->
tiles[tile_num].row =
h->tile_group_info[tile_num].tile_row;
337 ctx_pic->
tiles[tile_num].column =
h->tile_group_info[tile_num].tile_column;
338 ctx_pic->
tiles[tile_num].anchor_frame = 0xFF;
339 }
340
342
343 return 0;
344 }
345
349 {
353 void *dxva_data_ptr;
354 uint8_t *dxva_data;
355 unsigned dxva_size;
356 unsigned padding;
358
359 #if CONFIG_D3D11VA
361 type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
365 &dxva_size, &dxva_data_ptr)))
366 return -1;
367 }
368 #endif
369 #if CONFIG_DXVA2
371 type = DXVA2_BitStreamDateBufferType;
374 &dxva_data_ptr, &dxva_size)))
375 return -1;
376 }
377 #endif
378
379 dxva_data = dxva_data_ptr;
380
383 return -1;
384 }
385
387
389 if (padding > 0) {
392 }
393
394 #if CONFIG_D3D11VA
397 return -1;
398 #endif
399 #if CONFIG_DXVA2
402 return -1;
403 #endif
404
405 #if CONFIG_D3D11VA
407 D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
408 memset(dsc11, 0, sizeof(*dsc11));
409 dsc11->BufferType =
type;
411 dsc11->NumMBsInBuffer = 0;
412
413 type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
414 }
415 #endif
416 #if CONFIG_DXVA2
418 DXVA2_DecodeBufferDesc *dsc2 = bs;
419 memset(dsc2, 0, sizeof(*dsc2));
420 dsc2->CompressedBufferType =
type;
422 dsc2->NumMBsInBuffer = 0;
423
424 type = DXVA2_SliceControlBufferType;
425 }
426 #endif
427
430 }
431
433 {
437
439 return -1;
440
442 &ctx_pic->
pp,
sizeof(ctx_pic->
pp),
445
447 }
448
450 {
452
454 ctx->bitstream_allocated = 0;
455
457 }
458
459 #if CONFIG_AV1_DXVA2_HWACCEL
473 };
474 #endif
475
476 #if CONFIG_AV1_D3D11VA_HWACCEL
478 .
name =
"av1_d3d11va",
490 };
491 #endif
492
493 #if CONFIG_AV1_D3D11VA2_HWACCEL
495 .
name =
"av1_d3d11va2",
507 };
508 #endif