FFmpeg
Loading...
Searching...
No Matches
d3d12va_encode_av1.c
Go to the documentation of this file.
1/*
2 * Direct3D 12 HW acceleration video encoder
3 *
4 * Copyright (c) 2024 Intel Corporation
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 "libavutil/opt.h"
24#include "libavutil/common.h"
25#include "libavutil/mem.h"
26#include "libavutil/pixdesc.h"
28
29#include "config_components.h"
30#include "avcodec.h"
31#include "cbs.h"
32#include "cbs_av1.h"
33#include "av1_levels.h"
34#include "codec_internal.h"
35#include "d3d12va_encode.h"
36#include "encode.h"
37#include "hw_base_encode.h"
38
39#include <d3d12.h>
40#include <d3d12video.h>
41
42/* Added in Windows SDK 10.0.26100.0; define fallbacks for older SDKs. */
43#ifndef D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION
44#define D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION \
45 ((D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE)5)
46#endif
47#ifndef D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION
48#define D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION \
49 ((D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE)6)
50#endif
51
52#ifndef D3D12_VIDEO_ENCODER_AV1_INVALID_DPB_RESOURCE_INDEX
53#define D3D12_VIDEO_ENCODER_AV1_INVALID_DPB_RESOURCE_INDEX ( 0xff )
54#endif
55
61
63 int tier; // 0: Main tier, 1: High tier
64 int level; // AV1 level (2.0-7.3 map to 0-23)
65
66 int enable_cdef; // Constrained Directional Enhancement Filter
67 int enable_restoration; // loop restoration
68 int enable_superres; // super-resolution
70
73
79
83
87
89 uint8_t temporal_id;
90 uint8_t spatial_id;
91 uint8_t show_frame;
92 uint8_t frame_type;
94 uint8_t slot;
96
127
128typedef struct D3D12VAEncodeAV1Level {
129 uint8_t level;
130 D3D12_VIDEO_ENCODER_AV1_LEVELS d3d12_level;
132
134 { 0, D3D12_VIDEO_ENCODER_AV1_LEVELS_2_0 },
135 { 1, D3D12_VIDEO_ENCODER_AV1_LEVELS_2_1 },
136 { 2, D3D12_VIDEO_ENCODER_AV1_LEVELS_2_2 },
137 { 3, D3D12_VIDEO_ENCODER_AV1_LEVELS_2_3 },
138 { 4, D3D12_VIDEO_ENCODER_AV1_LEVELS_3_0 },
139 { 5, D3D12_VIDEO_ENCODER_AV1_LEVELS_3_1 },
140 { 6, D3D12_VIDEO_ENCODER_AV1_LEVELS_3_2 },
141 { 7, D3D12_VIDEO_ENCODER_AV1_LEVELS_3_3 },
142 { 8, D3D12_VIDEO_ENCODER_AV1_LEVELS_4_0 },
143 { 9, D3D12_VIDEO_ENCODER_AV1_LEVELS_4_1 },
144 { 10, D3D12_VIDEO_ENCODER_AV1_LEVELS_4_2 },
145 { 11, D3D12_VIDEO_ENCODER_AV1_LEVELS_4_3 },
146 { 12, D3D12_VIDEO_ENCODER_AV1_LEVELS_5_0 },
147 { 13, D3D12_VIDEO_ENCODER_AV1_LEVELS_5_1 },
148 { 14, D3D12_VIDEO_ENCODER_AV1_LEVELS_5_2 },
149 { 15, D3D12_VIDEO_ENCODER_AV1_LEVELS_5_3 },
150 { 16, D3D12_VIDEO_ENCODER_AV1_LEVELS_6_0 },
151 { 17, D3D12_VIDEO_ENCODER_AV1_LEVELS_6_1 },
152 { 18, D3D12_VIDEO_ENCODER_AV1_LEVELS_6_2 },
153 { 19, D3D12_VIDEO_ENCODER_AV1_LEVELS_6_3 },
154 { 20, D3D12_VIDEO_ENCODER_AV1_LEVELS_7_0 },
155 { 21, D3D12_VIDEO_ENCODER_AV1_LEVELS_7_1 },
156 { 22, D3D12_VIDEO_ENCODER_AV1_LEVELS_7_2 },
157 { 23, D3D12_VIDEO_ENCODER_AV1_LEVELS_7_3 },
158};
159
161 uint64_t full;
162 uint64_t prefix;
163 uint64_t data;
165
166static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_main = D3D12_VIDEO_ENCODER_AV1_PROFILE_MAIN;
167static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_high = D3D12_VIDEO_ENCODER_AV1_PROFILE_HIGH;
168static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_professional = D3D12_VIDEO_ENCODER_AV1_PROFILE_PROFESSIONAL;
169
170#define D3D_PROFILE_DESC(name) \
171 { sizeof(D3D12_VIDEO_ENCODER_AV1_PROFILE), { .pAV1Profile = (D3D12_VIDEO_ENCODER_AV1_PROFILE *)&profile_ ## name } }
173 { AV_PROFILE_AV1_MAIN, 8, 3, 1, 1, D3D_PROFILE_DESC(main) },
174 { AV_PROFILE_AV1_MAIN, 10, 3, 1, 1, D3D_PROFILE_DESC(main) },
175 { AV_PROFILE_AV1_HIGH, 10, 3, 1, 1, D3D_PROFILE_DESC(high) },
176 { AV_PROFILE_AV1_PROFESSIONAL, 8, 3, 1, 1, D3D_PROFILE_DESC(professional) },
177 { AV_PROFILE_AV1_PROFESSIONAL, 10, 3, 1, 1, D3D_PROFILE_DESC(professional) },
178 { AV_PROFILE_AV1_PROFESSIONAL, 12, 3, 1, 1, D3D_PROFILE_DESC(professional) },
180};
181
183 char *data, size_t *data_len,
185{
186 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
187 int err = 0;
188
189 err = ff_cbs_write_fragment_data(priv->cbc, obu);
190 if (err < 0) {
191 av_log(avctx, AV_LOG_ERROR, "Failed to write packed OBU data.\n");
192 return err;
193 }
194
195 memcpy(data, obu->data, obu->data_size);
196 *data_len = (8 * obu->data_size) - obu->data_bit_padding;
197
198 return 0;
199}
200
203 CodedBitstreamUnitType obu_type,
204 void* obu_unit)
205{
206 int err = 0;
207
208 err = ff_cbs_insert_unit_content(au, -1, obu_type, obu_unit, NULL);
209 if (err < 0) {
210 av_log(avctx, AV_LOG_ERROR, "Failed to add OBU unit: "
211 "type = %d.\n", obu_type);
212 return err;
213 }
214 return 0;
215}
216
218 char *data, size_t *data_len)
219{
220 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
222 int err = 0;
223
226 if (err < 0)
227 goto fail;
228
229 err = d3d12va_encode_av1_write_obu(avctx, data, data_len, obu);
230
231fail:
232 ff_cbs_fragment_reset(obu);
233 return err;
234}
235
238 AV1RawOBU *frameheader_obu)
239{
240 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
241 AV1RawFrameHeader *fh = &frameheader_obu->obu.frame_header;
242 uint8_t *data = NULL;
243 HRESULT hr = S_OK;
244 int err = 0;
245 D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES *post_encode_values = NULL;
246
247 // Update the frame header according to the picture post_encode_values
248 hr = ID3D12Resource_Map(pic->resolved_metadata, 0, NULL, (void **)&data);
249 if (FAILED(hr)) {
250 err = AVERROR_UNKNOWN;
251 return err;
252 }
253 uint64_t nb_subregions = FFMAX(((D3D12_VIDEO_ENCODER_OUTPUT_METADATA *)data)->WrittenSubregionsCount, 1);
254 D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES *tile_partition =
255 (D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES *) (data +
256 sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) +
257 sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA) * nb_subregions);
258
259 post_encode_values = (D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES *) (data +
260 sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) +
261 sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA) * nb_subregions +
262 sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES));
263
264 if (nb_subregions > 1)
265 fh->context_update_tile_id = tile_partition->ContextUpdateTileId;
266
267 if (priv->post_encode_values_flag & D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_QUANTIZATION) {
268 fh->base_q_idx = post_encode_values->Quantization.BaseQIndex;
269 fh->delta_q_y_dc = post_encode_values->Quantization.YDCDeltaQ;
270 fh->delta_q_u_dc = post_encode_values->Quantization.UDCDeltaQ;
271 fh->delta_q_u_ac = post_encode_values->Quantization.UACDeltaQ;
272 fh->delta_q_v_dc = post_encode_values->Quantization.VDCDeltaQ;
273 fh->delta_q_v_ac = post_encode_values->Quantization.VACDeltaQ;
274 fh->using_qmatrix = post_encode_values->Quantization.UsingQMatrix;
275 fh->qm_y = post_encode_values->Quantization.QMY;
276 fh->qm_u = post_encode_values->Quantization.QMU;
277 fh->qm_v = post_encode_values->Quantization.QMV;
278 }
279
280 if (priv->post_encode_values_flag & D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_LOOP_FILTER) {
281 fh->loop_filter_level[0] = post_encode_values->LoopFilter.LoopFilterLevel[0];
282 fh->loop_filter_level[1] = post_encode_values->LoopFilter.LoopFilterLevel[1];
283 fh->loop_filter_level[2] = post_encode_values->LoopFilter.LoopFilterLevelU;
284 fh->loop_filter_level[3] = post_encode_values->LoopFilter.LoopFilterLevelV;
285 fh->loop_filter_sharpness = post_encode_values->LoopFilter.LoopFilterSharpnessLevel;
286 fh->loop_filter_delta_enabled = post_encode_values->LoopFilter.LoopFilterDeltaEnabled;
288 for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) {
289 fh->loop_filter_ref_deltas[i] = post_encode_values->LoopFilter.RefDeltas[i];
290 fh->update_ref_delta[i] = post_encode_values->LoopFilter.RefDeltas[i];
291 }
292 for (int i = 0; i < 2; i++) {
293 fh->loop_filter_mode_deltas[i] = post_encode_values->LoopFilter.ModeDeltas[i];
294 fh->update_mode_delta[i] = post_encode_values->LoopFilter.ModeDeltas[i];
295 }
296 }
297 }
298 if (priv->post_encode_values_flag & D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_CDEF_DATA) {
299 fh->cdef_damping_minus_3 = post_encode_values->CDEF.CdefDampingMinus3;
300 fh->cdef_bits = post_encode_values->CDEF.CdefBits;
301 for (int i = 0; i < 8; i++) {
302 fh->cdef_y_pri_strength[i] = post_encode_values->CDEF.CdefYPriStrength[i];
303 fh->cdef_y_sec_strength[i] = post_encode_values->CDEF.CdefYSecStrength[i];
304 fh->cdef_uv_pri_strength[i] = post_encode_values->CDEF.CdefUVPriStrength[i];
305 fh->cdef_uv_sec_strength[i] = post_encode_values->CDEF.CdefUVSecStrength[i];
306 }
307 }
308 if (priv->post_encode_values_flag & D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_QUANTIZATION_DELTA) {
309 fh->delta_q_present = post_encode_values->QuantizationDelta.DeltaQPresent;
310 fh->delta_q_res = post_encode_values->QuantizationDelta.DeltaQRes;
311 }
312
313 if (priv->post_encode_values_flag & D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_REFERENCE_INDICES) {
314 for (int i = 0; i < AV1_REFS_PER_FRAME; i++) {
315 fh->ref_frame_idx[i] = post_encode_values->ReferenceIndices[i];
316 }
317 }
318
319 ID3D12Resource_Unmap(pic->resolved_metadata, 0, NULL);
320 return 0;
321}
322
325 char *data, size_t *data_len)
326{
327 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
329 AV1RawOBU *frameheader_obu = av_mallocz(sizeof(AV1RawOBU));
330 int err = 0;
331
332 av_fifo_read(priv->picture_header_list, frameheader_obu, 1);
333 err = d3d12va_encode_av1_update_current_frame_picture_header(avctx, pic,frameheader_obu);
334 if (err < 0) {
335 av_log(avctx, AV_LOG_ERROR, "Failed to update current frame picture header: %d.\n", err);
336 return err;
337 }
338
339 // Add the frame header OBU
340 frameheader_obu->header.obu_has_size_field = 1;
341
342 err = d3d12va_encode_av1_add_obu(avctx, obu, AV1_OBU_FRAME_HEADER, frameheader_obu);
343 if (err < 0)
344 goto fail;
345 err = d3d12va_encode_av1_write_obu(avctx, data, data_len, obu);
346
347fail:
348 ff_cbs_fragment_reset(obu);
349 av_freep(&frameheader_obu);
350 return err;
351}
352
354 uint8_t* tile_group,
355 uint32_t tile_group_size,
356 char *data, size_t *data_len)
357{
358 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
361 AV1RawTileGroup *tg = &tile_group_obu->obu.tile_group;
362 int err = 0;
363
365 tg->tg_start = 0;
366 tg->tg_end = priv->tile_cols * priv->tile_rows - 1;
367
368 tg->tile_data.data = tile_group;
369 tg->tile_data.data_ref = NULL;
370 tg->tile_data.data_size = tile_group_size;
371 tile_group_obu->header.obu_has_size_field = 1;
372 tile_group_obu->header.obu_type = AV1_OBU_TILE_GROUP;
373
375 if (err < 0)
376 goto fail;
377 err = d3d12va_encode_av1_write_obu(avctx, data, data_len, obu);
378
379fail:
380 ff_cbs_fragment_reset(obu);
381 return err;
382}
383
386 uint64_t tile_size_bytes,
387 uint64_t *nb_subregions_out,
388 D3D12VAEncodeAV1TileInfo **tiles_out,
389 size_t *tile_payload_size_out)
390{
391 uint8_t *meta_data = NULL;
392 HRESULT hr = S_OK;
393 int err = 0;
394
395 D3D12_VIDEO_ENCODER_OUTPUT_METADATA *out;
396 D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA *subregions;
398 uint64_t nb_subregions;
399 size_t tile_payload_size = 0;
400
401 hr = ID3D12Resource_Map(pic->resolved_metadata, 0, NULL, (void **)&meta_data);
402 if (FAILED(hr))
403 return AVERROR_EXTERNAL;
404
405 out = (D3D12_VIDEO_ENCODER_OUTPUT_METADATA *)meta_data;
406 subregions = (D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA *) (meta_data +
407 sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA));
408
409 if (out->EncodeErrorFlags != D3D12_VIDEO_ENCODER_ENCODE_ERROR_FLAG_NO_ERROR) {
410 av_log(avctx, AV_LOG_ERROR, "AV1 encode failed: error flags %#"PRIx64".\n",
411 (uint64_t)out->EncodeErrorFlags);
412 err = AVERROR_EXTERNAL;
413 goto unmap;
414 }
415
416 nb_subregions = out->WrittenSubregionsCount;
417 if (nb_subregions == 0 || subregions[0].bSize == 0) {
418 av_log(avctx, AV_LOG_ERROR, "No subregion metadata found\n");
419 err = AVERROR(EINVAL);
420 goto unmap;
421 }
422
423 tiles = av_malloc_array(nb_subregions, sizeof(*tiles));
424 if (!tiles) {
425 err = AVERROR(ENOMEM);
426 goto unmap;
427 }
428
429 for (uint64_t i = 0; i < nb_subregions; i++) {
430 tiles[i].full = subregions[i].bSize;
431 tiles[i].prefix = subregions[i].bStartOffset;
432 tiles[i].data = subregions[i].bSize - subregions[i].bStartOffset;
433 tile_payload_size += tiles[i].data;
434 }
435 /* Every tile except the last is prefixed with a tile_size_minus_1 field. */
436 if (nb_subregions > 1)
437 tile_payload_size += (nb_subregions - 1) * tile_size_bytes;
438
439 *nb_subregions_out = nb_subregions;
440 *tiles_out = tiles;
441 *tile_payload_size_out = tile_payload_size;
442
443unmap:
444 ID3D12Resource_Unmap(pic->resolved_metadata, 0, NULL);
445 return err;
446}
447
450{
451 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
452 int err = 0;
453 uint8_t *ptr = NULL;
454 uint8_t *mapped_data = NULL;
455 uint8_t *tile_group_buf = NULL;
456 char *obu_buf = NULL;
457 HRESULT hr = S_OK;
458 size_t av1_pic_hd_size = 0;
459 size_t bit_len = 0;
460 size_t obu_size = 0;
461 size_t tile_payload_size = 0;
462 size_t total_size = 0;
463 uint64_t nb_subregions = 0;
464 int output_buffer_mapped = 0;
465
467 char pic_hd_data[MAX_PARAM_BUFFER_SIZE] = { 0 };
468
470 &nb_subregions, &tiles,
471 &tile_payload_size);
472 if (err < 0)
473 goto end;
474
475 hr = ID3D12Resource_Map(pic->output_buffer, 0, NULL, (void **)&mapped_data);
476 if (FAILED(hr)) {
477 err = AVERROR_UNKNOWN;
478 goto end;
479 }
480 output_buffer_mapped = 1;
481
482 tile_group_buf = av_malloc(tile_payload_size);
483 if (!tile_group_buf) {
484 err = AVERROR(ENOMEM);
485 goto end;
486 }
487
488 uint8_t *dst = tile_group_buf;
489 uint8_t *tiles_base = mapped_data + pic->aligned_header_size;
490 uint64_t src_off = 0;
491 for (uint64_t i = 0; i < nb_subregions; i++) {
492 /* Tiles are laid out contiguously by their full size; the actual
493 * tile data starts bStartOffset bytes into each subregion. */
494 uint64_t src_pos = src_off + tiles[i].prefix;
495 src_off += tiles[i].full;
496
497 if (i != nb_subregions - 1) {
498 /* Write tile_size_minus_1 as a little-endian integer */
499 uint64_t v = tiles[i].data - 1;
500 for (uint64_t b = 0; b < priv->tile_size_bytes; b++)
501 *dst++ = (v >> (8 * b)) & 0xff;
502 }
503 memcpy(dst, tiles_base + src_pos, tiles[i].data);
504 dst += tiles[i].data;
505 }
506
507 err = d3d12va_encode_av1_write_picture_header(avctx, pic, pic_hd_data, &bit_len);
508 if (err < 0) {
509 av_log(avctx, AV_LOG_ERROR, "Failed to write picture header: %d.\n", err);
510 goto end;
511 }
512 av1_pic_hd_size = bit_len / 8;
513
514 obu_buf = av_malloc(tile_payload_size + MAX_PARAM_BUFFER_SIZE);
515 if (!obu_buf) {
516 err = AVERROR(ENOMEM);
517 goto end;
518 }
519 err = d3d12va_encode_av1_write_tile_group(avctx, tile_group_buf,
520 tile_payload_size, obu_buf, &bit_len);
521 if (err < 0) {
522 av_log(avctx, AV_LOG_ERROR, "Failed to write tile group: %d.\n", err);
523 goto end;
524 }
525 obu_size = bit_len / 8;
526
527 total_size = pic->header_size + av1_pic_hd_size + obu_size;
528 err = ff_get_encode_buffer(avctx, pkt, total_size, 0);
529 if (err < 0)
530 goto end;
531 ptr = pkt->data;
532
533 memcpy(ptr, mapped_data, pic->header_size);
534 ptr += pic->header_size;
535
536 memcpy(ptr, pic_hd_data, av1_pic_hd_size);
537 ptr += av1_pic_hd_size;
538
539 memcpy(ptr, obu_buf, obu_size);
540
541 av_log(avctx, AV_LOG_DEBUG, "AV1 packet: %"PRIu64" tiles, header %d, "
542 "pic header %zu, tile group %zu, total %zu bytes.\n",
543 nb_subregions, pic->header_size, av1_pic_hd_size, obu_size, total_size);
544
545end:
546 if (output_buffer_mapped)
547 ID3D12Resource_Unmap(pic->output_buffer, 0, NULL);
548 av_freep(&tiles);
549 av_freep(&tile_group_buf);
550 av_freep(&obu_buf);
552 pic->output_buffer = NULL;
553 return err;
554}
555
557 AVCodecContext *avctx,
560{
561 AV1RawOBU *seqheader_obu = &common->raw_sequence_header;
562 AV1RawSequenceHeader *seq = &seqheader_obu->obu.sequence_header;
564
565 seq->seq_profile = avctx->profile;
568 seq->seq_tier[0] = opts->tier;
569
572 .high_bitdepth = desc->comp[0].depth == 8 ? 0 : 1,
573 .color_primaries = avctx->color_primaries,
574 .transfer_characteristics = avctx->color_trc,
575 .matrix_coefficients = avctx->colorspace,
576 .color_description_present_flag = (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
580 .subsampling_x = desc->log2_chroma_w,
581 .subsampling_y = desc->log2_chroma_h,
582 };
583
584 switch (avctx->chroma_sample_location) {
587 break;
590 break;
591 default:
593 break;
594 }
595
596 if (avctx->level != AV_LEVEL_UNKNOWN) {
597 seq->seq_level_idx[0] = avctx->level;
598 }
599 else {
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
608 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
609 int tile_cols = priv->tile_cols > 0 ? priv->tile_cols : 1;
610 int tile_rows = priv->tile_rows > 0 ? priv->tile_rows : 1;
611
612 level = ff_av1_guess_level(avctx->bit_rate, opts->tier,
613 base_ctx->surface_width, base_ctx->surface_height,
615 if (level) {
616 av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
617 seq->seq_level_idx[0] = level->level_idx;
618 }
619 else {
620 av_log(avctx, AV_LOG_VERBOSE, "Stream will not conform to "
621 "any normal level, using maximum parameters level by default.\n");
622 seq->seq_level_idx[0] = 31;
623 seq->seq_tier[0] = 1;
624 }
625 }
626
627 // Still picture mode
628 seq->still_picture = (base_ctx->gop_size == 1);
630
631 // Feature flags
632 seq->use_128x128_superblock = opts->enable_128x128_superblock;
633 seq->enable_filter_intra = opts->enable_filter_intra;
634 seq->enable_intra_edge_filter = opts->enable_intra_edge_filter;
635 seq->enable_interintra_compound = opts->enable_interintra_compound;
636 seq->enable_masked_compound = opts->enable_masked_compound;
637 seq->enable_warped_motion = opts->enable_warped_motion;
638 seq->enable_dual_filter = opts->enable_dual_filter;
639 seq->enable_order_hint = !seq->still_picture;
640 if (seq->enable_order_hint) {
642 }
643 seq->enable_jnt_comp = opts->enable_jnt_comp && seq->enable_order_hint;
644 seq->enable_ref_frame_mvs = opts->enable_ref_frame_mvs && seq->enable_order_hint;
645 seq->enable_superres = opts->enable_superres;
646 seq->enable_cdef = opts->enable_cdef;
647 seq->enable_restoration = opts->enable_restoration;
648
649 return 0;
650
651}
652
654{
655 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
657 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
658 AVD3D12VAFramesContext *hwctx = base_ctx->input_frames->hwctx;
659 AV1RawOBU *seqheader_obu = &priv->units.raw_sequence_header;
661
662 D3D12_VIDEO_ENCODER_AV1_PROFILE profile = D3D12_VIDEO_ENCODER_AV1_PROFILE_MAIN;
663 D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS level = { 0 };
664 HRESULT hr;
665 int err;
666
667 D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 support = {
668 .NodeIndex = 0,
669 .Codec = D3D12_VIDEO_ENCODER_CODEC_AV1,
670 .InputFormat = hwctx->format,
671 .RateControl = ctx->rc,
672 .IntraRefresh = ctx->intra_refresh.Mode,
673 .SubregionFrameEncoding = ctx->subregion_mode,
674 .ResolutionsListCount = 1,
675 .pResolutionList = &ctx->resolution,
676 .CodecGopSequence = ctx->gop,
677 .MaxReferenceFramesInDPB = AV1_NUM_REF_FRAMES,
678 .CodecConfiguration = ctx->codec_conf,
679 .SuggestedProfile.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_PROFILE),
680 .SuggestedProfile.pAV1Profile = &profile,
681 .SuggestedLevel.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS),
682 .SuggestedLevel.pAV1LevelSetting = &level,
683 .pResolutionDependentSupport = &ctx->res_limits,
684 .SubregionFrameEncodingData.pTilesPartition_AV1 = ctx->subregions_layout.pTilesPartition_AV1,
685 };
686
687 hr = ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT1,
688 &support, sizeof(support));
689
690 if (FAILED(hr)) {
691 av_log(avctx, AV_LOG_ERROR, "Failed to check encoder support(%lx).\n", (long)hr);
692 return AVERROR(EINVAL);
693 }
694
695 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK)) {
696 av_log(avctx, AV_LOG_ERROR, "Driver does not support requested features. ValidationFlags: %#x\n",
697 support.ValidationFlags);
698 ff_d3d12va_encode_check_encoder_feature_flags(avctx, support.ValidationFlags);
699 return AVERROR(EINVAL);
700 }
701
702 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) {
703 ctx->is_texture_array = 1;
704 av_log(avctx, AV_LOG_DEBUG, "D3D12 video encode on this device uses texture array mode.\n");
705 }
706
707 // Check if the configuration with DELTA_QP is supported
708 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_DELTA_QP_AVAILABLE) {
709 base_ctx->roi_allowed = 1;
710 // Store the QP map region size from resolution limits
711 ctx->qp_map_region_size = ctx->res_limits.QPMapRegionPixelsSize;
712 av_log(avctx, AV_LOG_DEBUG, "ROI encoding is supported via delta QP "
713 "(QP map region size: %d pixels).\n", ctx->qp_map_region_size);
714 } else {
715 base_ctx->roi_allowed = 0;
716 av_log(avctx, AV_LOG_DEBUG, "ROI encoding not supported by hardware for current rate control mode \n");
717 }
718
719 // Check motion estimation precision mode support
720 if (ctx->me_precision != D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM) {
721 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE)) {
722 av_log(avctx, AV_LOG_ERROR, "Hardware does not support motion estimation "
723 "precision mode limits.\n");
724 return AVERROR(ENOTSUP);
725 }
726 av_log(avctx, AV_LOG_VERBOSE, "Hardware supports motion estimation "
727 "precision mode limits.\n");
728 }
729
730 memset(seqheader_obu, 0, sizeof(*seqheader_obu));
731 seq->seq_profile = profile;
732 seq->seq_level_idx[0] = level.Level;
733 seq->seq_tier[0] = level.Tier;
734
735 seq->max_frame_width_minus_1 = ctx->resolution.Width - 1;
736 seq->max_frame_height_minus_1 = ctx->resolution.Height - 1;
737 seq->frame_width_bits_minus_1 = av_log2(ctx->resolution.Width);
738 seq->frame_height_bits_minus_1 = av_log2(ctx->resolution.Height);
739
740 seqheader_obu->header.obu_type = AV1_OBU_SEQUENCE_HEADER;
741
742 err = d3d12va_hw_base_encode_init_params_av1(base_ctx, avctx,
743 &priv->units, &priv->unit_opts);
744 if (err < 0)
745 return err;
746
747 if (avctx->level == AV_LEVEL_UNKNOWN)
748 avctx->level = level.Level;
749
750 return 0;
751}
752
753static av_always_inline int d3d12va_encode_av1_tile_log2(int blksize, int target)
754{
755 int k;
756 for (k = 0; (blksize << k) < target; k++);
757 return k;
758}
759
761{
763 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
764 D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES *tiles_layout;
765
766 ctx->subregions_layout.DataSize =
767 sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES);
768 tiles_layout = av_mallocz(ctx->subregions_layout.DataSize);
769 if (!tiles_layout)
770 return AVERROR(ENOMEM);
771 ctx->subregions_layout.pTilesPartition_AV1 = tiles_layout;
772
773 int use_128 = priv->unit_opts.enable_128x128_superblock;
774 int width = ctx->resolution.Width;
775 int height = ctx->resolution.Height;
776
777 int mi_cols = 2 * ((width + 7) >> 3);
778 int mi_rows = 2 * ((height + 7) >> 3);
779 int sb_cols = use_128 ? ((mi_cols + 31) >> 5) : ((mi_cols + 15) >> 4);
780 int sb_rows = use_128 ? ((mi_rows + 31) >> 5) : ((mi_rows + 15) >> 4);
781 int sb_shift = use_128 ? 5 : 4;
782 int sb_size = sb_shift + 2;
783
784 int max_tile_width_sb = AV1_MAX_TILE_WIDTH >> sb_size;
785 int max_tile_area_sb = AV1_MAX_TILE_AREA >> (2 * sb_size);
786
787 int min_log2_tile_cols = d3d12va_encode_av1_tile_log2(max_tile_width_sb, sb_cols);
788 int min_log2_tiles = FFMAX(min_log2_tile_cols,
789 d3d12va_encode_av1_tile_log2(max_tile_area_sb, sb_rows * sb_cols));
790 int max_tile_area_sb_varied;
791 int tile_width_sb, tile_height_sb, widest_tile_sb;
792 int tile_cols, tile_rows;
793 int min_tile_cols = (sb_cols + max_tile_width_sb - 1) / max_tile_width_sb;
794 int i;
795
796 if (priv->tile_cols > AV1_MAX_TILE_COLS ||
798 av_log(avctx, AV_LOG_ERROR, "Invalid tile number %dx%d, should be at "
799 "most %dx%d.\n", priv->tile_cols, priv->tile_rows,
801 return AVERROR(EINVAL);
802 }
803
804 /* Calculate tile columns. When the user did not set tile explicitly
805 * (tile_cols == 0) this fallback to the minimum valid number */
806 tile_cols = av_clip(priv->tile_cols, min_tile_cols, sb_cols);
807 if (!priv->tile_cols)
808 priv->tile_cols = tile_cols;
809 else if (priv->tile_cols != tile_cols) {
810 av_log(avctx, AV_LOG_ERROR, "Invalid tile cols %d, should be in range "
811 "of %d~%d.\n", priv->tile_cols, min_tile_cols, sb_cols);
812 return AVERROR(EINVAL);
813 }
814
816 tile_width_sb = (sb_cols + (1 << priv->tile_cols_log2) - 1) >> priv->tile_cols_log2;
817
818 if (priv->tile_rows > sb_rows) {
819 av_log(avctx, AV_LOG_ERROR, "Invalid tile rows %d, should be less than "
820 "%d.\n", priv->tile_rows, sb_rows);
821 return AVERROR(EINVAL);
822 }
823
824 tile_rows = priv->tile_rows ? priv->tile_rows : 1;
825 for (; tile_rows <= sb_rows && tile_rows <= AV1_MAX_TILE_ROWS; tile_rows++) {
826 /* try uniformed tile first. */
828
829 if ((sb_cols + tile_width_sb - 1) / tile_width_sb == priv->tile_cols) {
830 for (i = 0; i < priv->tile_cols - 1; i++)
831 priv->width_in_sbs_minus_1[i] = tile_width_sb - 1;
832 priv->width_in_sbs_minus_1[i] = sb_cols - (priv->tile_cols - 1) * tile_width_sb - 1;
833
834 tile_height_sb = (sb_rows + (1 << priv->tile_rows_log2) - 1) >>
835 priv->tile_rows_log2;
836
837 if ((sb_rows + tile_height_sb - 1) / tile_height_sb == tile_rows &&
838 tile_height_sb <= max_tile_area_sb / tile_width_sb) {
839 for (i = 0; i < tile_rows - 1; i++)
840 priv->height_in_sbs_minus_1[i] = tile_height_sb - 1;
841 priv->height_in_sbs_minus_1[i] = sb_rows - (tile_rows - 1) * tile_height_sb - 1;
842
843 priv->uniform_tile_spacing = 1;
844 break;
845 }
846 }
847
848 /* Try non-uniform fallback: distribute columns/rows as evenly as possible */
849 widest_tile_sb = 0;
850 for (i = 0; i < priv->tile_cols; i++) {
851 priv->width_in_sbs_minus_1[i] =
852 (i + 1) * sb_cols / priv->tile_cols - i * sb_cols / priv->tile_cols - 1;
853 widest_tile_sb = FFMAX(widest_tile_sb, priv->width_in_sbs_minus_1[i] + 1);
854 }
855
856 if (min_log2_tiles)
857 max_tile_area_sb_varied = (sb_rows * sb_cols) >> (min_log2_tiles + 1);
858 else
859 max_tile_area_sb_varied = sb_rows * sb_cols;
860 tile_height_sb = FFMAX(1, max_tile_area_sb_varied / widest_tile_sb);
861
863 (sb_rows + tile_height_sb - 1) / tile_height_sb,
864 sb_rows)) {
865 for (i = 0; i < tile_rows; i++)
866 priv->height_in_sbs_minus_1[i] =
867 (i + 1) * sb_rows / tile_rows - i * sb_rows / tile_rows - 1;
868
869 priv->uniform_tile_spacing = 0;
870 break;
871 }
872
873 if (priv->tile_rows) {
874 av_log(avctx, AV_LOG_ERROR, "Invalid tile rows %d.\n", priv->tile_rows);
875 return AVERROR(EINVAL);
876 }
877 }
878
879 priv->tile_rows = tile_rows;
880 av_log(avctx, AV_LOG_DEBUG, "Setting tile cols/rows to %d/%d.\n",
881 priv->tile_cols, priv->tile_rows);
882
884 av_log(avctx, AV_LOG_ERROR, "Resolution %dx%d requires %dx%d tiles which "
885 "exceeds the AV1 maximum of %dx%d.\n", width, height,
887 return AVERROR(EINVAL);
888 }
889
890 priv->context_update_tile_id = priv->tile_cols * priv->tile_rows - 1;
891 priv->tile_size_bytes = 4;
892
893 tiles_layout->RowCount = priv->tile_rows;
894 tiles_layout->ColCount = priv->tile_cols;
895 for (i = 0; i < priv->tile_cols; i++)
896 tiles_layout->ColWidths[i] = priv->width_in_sbs_minus_1[i] + 1;
897 for (i = 0; i < priv->tile_rows; i++)
898 tiles_layout->RowHeights[i] = priv->height_in_sbs_minus_1[i] + 1;
899 tiles_layout->ContextUpdateTileId = priv->context_update_tile_id;
900
901 ctx->num_subregions = priv->tile_cols * priv->tile_rows;
902
903 if (ctx->num_subregions <= 1)
904 ctx->subregion_mode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME;
905 else if (priv->uniform_tile_spacing)
907 else
909
910 av_log(avctx, AV_LOG_VERBOSE, "AV1 tile partition: %d cols x %d rows "
911 "(%s superblocks, %s).\n", priv->tile_cols, priv->tile_rows,
912 use_128 ? "128x128" : "64x64",
913 ctx->num_subregions <= 1 ? "full frame" :
914 priv->uniform_tile_spacing ? "uniform grid" : "configurable grid");
915
916 return 0;
917}
918
920{
921 HRESULT hr = S_OK;
922 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
924 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
925
926 D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION *config;
927 D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION_SUPPORT av1_caps;
928
929 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codec_caps = {
930 .NodeIndex = 0,
931 .Codec = D3D12_VIDEO_ENCODER_CODEC_AV1,
932 .Profile = ctx->profile->d3d12_profile,
933 .CodecSupportLimits.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION_SUPPORT),
934 };
935
936 codec_caps.CodecSupportLimits.pAV1Support = &av1_caps;
937
938 hr = ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT,
939 &codec_caps, sizeof(codec_caps));
940 if (!(SUCCEEDED(hr) && codec_caps.IsSupported))
941 return AVERROR(EINVAL);
942
943 ctx->codec_conf.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION);
944 ctx->codec_conf.pAV1Config = av_mallocz(ctx->codec_conf.DataSize);
945 if (!ctx->codec_conf.pAV1Config)
946 return AVERROR(ENOMEM);
947
948 priv->post_encode_values_flag = av1_caps.PostEncodeValuesFlags;
949 config = ctx->codec_conf.pAV1Config;
950
951 config->FeatureFlags = D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_NONE;
952 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_128x128_SUPERBLOCK) {
953 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_128x128_SUPERBLOCK;
955 }
956
957 base_ctx->surface_width = FFALIGN(avctx->width, priv->unit_opts.enable_128x128_superblock ? 128 : 64);
958 base_ctx->surface_height = FFALIGN(avctx->height, priv->unit_opts.enable_128x128_superblock ? 128 : 64);
959
960 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_RESTORATION_FILTER) {
961 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_RESTORATION_FILTER;
963 }
964
965 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_PALETTE_ENCODING) {
966 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_PALETTE_ENCODING;
967 priv->unit_opts.enable_palette = 1;
968 }
969
970 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTRA_BLOCK_COPY) {
971 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTRA_BLOCK_COPY;
973 }
974
975 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_FILTER_DELTAS) {
976 // Loop filter deltas
977 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_FILTER_DELTAS;
979 }
980
981 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_CDEF_FILTERING) {
982 // CDEF (Constrained Directional Enhancement Filter)
983 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_CDEF_FILTERING;
984 priv->unit_opts.enable_cdef = 1;
985 }
986
987 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_DUAL_FILTER) {
988 // Dual filter
989 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_DUAL_FILTER;
991 }
992
993 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_JNT_COMP) {
994 // Joint compound prediction
995 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_JNT_COMP;
996 priv->unit_opts.enable_jnt_comp = 1;
997 }
998
999 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_FRAME_REFERENCE_MOTION_VECTORS) {
1000 // Frame reference motion vectors
1001 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_FRAME_REFERENCE_MOTION_VECTORS;
1003 }
1004
1005 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_SUPER_RESOLUTION) {
1006 // Super-resolution
1007 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_SUPER_RESOLUTION;
1008 priv->unit_opts.enable_superres = 1;
1009 }
1010
1011 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_WARPED_MOTION) {
1012 // Warped motion
1013 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_WARPED_MOTION;
1015 }
1016
1017 if (av1_caps.SupportedFeatureFlags & D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTERINTRA_COMPOUND) {
1018 // Inter-intra compound prediction
1019 config->FeatureFlags |= D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTERINTRA_COMPOUND;
1021 }
1022
1023 return 0;
1024}
1025
1027{
1028 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1030 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
1031 int err = 0;
1032 int fixed_qp_key, fixed_qp_inter;
1033
1034 err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_AV1, avctx);
1035 if (err < 0)
1036 return err;
1037
1038 if (ctx->rc.Mode == D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP) {
1039 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP *cqp_ctl;
1040 fixed_qp_inter = av_clip_uintp2(ctx->rc_quality, 8);
1041
1042 if (avctx->i_quant_factor > 0.0)
1043 fixed_qp_key = av_clip_uintp2((avctx->i_quant_factor * fixed_qp_inter +
1044 avctx->i_quant_offset) + 0.5, 8);
1045 else
1046 fixed_qp_key = fixed_qp_inter;
1047
1048 av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
1049 "%d / %d for Key / Inter frames.\n",
1050 fixed_qp_key, fixed_qp_inter);
1051
1052 ctx->rc.ConfigParams.DataSize = sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP);
1053 cqp_ctl = av_mallocz(ctx->rc.ConfigParams.DataSize);
1054 if (!cqp_ctl)
1055 return AVERROR(ENOMEM);
1056
1057 cqp_ctl->ConstantQP_FullIntracodedFrame = fixed_qp_key;
1058 cqp_ctl->ConstantQP_InterPredictedFrame_PrevRefOnly = fixed_qp_inter;
1059 cqp_ctl->ConstantQP_InterPredictedFrame_BiDirectionalRef = fixed_qp_inter;
1060
1061 ctx->rc.ConfigParams.pConfiguration_CQP = cqp_ctl;
1062
1063 priv->q_idx_idr = fixed_qp_key;
1064 priv->q_idx_p = fixed_qp_inter;
1065
1066 }
1067
1068 // GOP configuration for AV1
1069 ctx->gop.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_SEQUENCE_STRUCTURE);
1070 ctx->gop.pAV1SequenceStructure = av_mallocz(ctx->gop.DataSize);
1071 if (!ctx->gop.pAV1SequenceStructure)
1072 return AVERROR(ENOMEM);
1073
1074 ctx->gop.pAV1SequenceStructure->IntraDistance = base_ctx->gop_size;
1075 ctx->gop.pAV1SequenceStructure->InterFramePeriod = base_ctx->b_per_p + 1;
1076
1077 return 0;
1078}
1079
1081{
1083 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
1084 int i = 0;
1085
1086 ctx->level.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS);
1087 ctx->level.pAV1LevelSetting = av_mallocz(ctx->level.DataSize);
1088 if (!ctx->level.pAV1LevelSetting)
1089 return AVERROR(ENOMEM);
1090
1091 if (avctx->level != AV_LEVEL_UNKNOWN) {
1092 for (i = 0; i < FF_ARRAY_ELEMS(av1_levels); i++) {
1093 if (avctx->level == av1_levels[i].level) {
1094 ctx->level.pAV1LevelSetting->Level = av1_levels[i].d3d12_level;
1095 break;
1096 }
1097 }
1098
1099 if (i == FF_ARRAY_ELEMS(av1_levels) ) {
1100 av_log(avctx, AV_LOG_ERROR, "Invalid AV1 level %d.\n", avctx->level);
1101 return AVERROR(EINVAL);
1102 }
1103 } else {
1104 ctx->level.pAV1LevelSetting->Level = D3D12_VIDEO_ENCODER_AV1_LEVELS_5_2;
1105 avctx->level = D3D12_VIDEO_ENCODER_AV1_LEVELS_5_2;
1106 av_log(avctx, AV_LOG_DEBUG, "Using default AV1 level 5.2\n");
1107 }
1108
1109 if (priv->tier == 1 || avctx->bit_rate > 30000000) {
1110 ctx->level.pAV1LevelSetting->Tier = D3D12_VIDEO_ENCODER_AV1_TIER_HIGH;
1111 av_log(avctx, AV_LOG_DEBUG, "Using AV1 High tier\n");
1112 } else {
1113 ctx->level.pAV1LevelSetting->Tier = D3D12_VIDEO_ENCODER_AV1_TIER_MAIN;
1114 av_log(avctx, AV_LOG_DEBUG, "Using AV1 Main tier\n");
1115 }
1116
1117 if (priv->tier >= 0) {
1118 ctx->level.pAV1LevelSetting->Tier = priv->tier == 0 ?
1119 D3D12_VIDEO_ENCODER_AV1_TIER_MAIN :
1120 D3D12_VIDEO_ENCODER_AV1_TIER_HIGH;
1121 }
1122
1123 av_log(avctx, AV_LOG_DEBUG, "AV1 level set to %d, tier: %s\n",
1124 ctx->level.pAV1LevelSetting->Level,
1125 ctx->level.pAV1LevelSetting->Tier == D3D12_VIDEO_ENCODER_AV1_TIER_MAIN ? "Main" : "High");
1126
1127 return 0;
1128}
1129
1131{
1132 if (!pic->pic_ctl.pAV1PicData)
1133 return;
1134
1135 av_freep(&pic->pic_ctl.pAV1PicData);
1136}
1137
1140{
1141 FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1142 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
1144 D3D12VAEncodePicture *d3d12va_pic = pic->priv;
1146 CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data;
1147 AV1RawOBU *frameheader_obu = &priv->units.raw_frame_header;
1148 AV1RawFrameHeader *fh = &frameheader_obu->obu.frame_header;
1149
1152 int i;
1153
1154 static const int8_t default_loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME] =
1155 { 1, 0, 0, 0, -1, 0, -1, -1 };
1156
1157 memset(frameheader_obu, 0, sizeof(*frameheader_obu));
1158
1159 frameheader_obu->header.obu_type = AV1_OBU_FRAME_HEADER;
1160
1161 d3d12va_pic->pic_ctl.DataSize = sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA);
1162 d3d12va_pic->pic_ctl.pAV1PicData = av_mallocz(d3d12va_pic->pic_ctl.DataSize);
1163 if (!d3d12va_pic->pic_ctl.pAV1PicData)
1164 return AVERROR(ENOMEM);
1165
1166 // Initialize frame type and reference frame management
1167 switch(pic->type) {
1170 fh->refresh_frame_flags = 0xFF;
1171 fh->base_q_idx = priv->q_idx_idr;
1172 hpic->slot = 0;
1173 hpic->last_idr_frame = pic->display_order;
1175 break;
1176
1179 fh->base_q_idx = priv->q_idx_p;
1181
1182 ref = pic->refs[0][pic->nb_refs[0] - 1];
1183 href = ref->codec_priv;
1184
1185 /**
1186 * The encoder uses a simple alternating reference frame strategy:
1187 * - For P-frames, it uses the last reconstructed frame as a reference.
1188 * - To simplify the reference model of the encoder, the encoder alternates between
1189 * two reference frame slots (typically slot 0 and slot 1) for storing reconstructed
1190 * images and providing prediction references for the next frame.
1191 */
1192 if (base_ctx->ref_l0 > 1) {
1193 hpic->slot = !href->slot;
1194 } else {
1195 hpic->slot = 0;
1196 }
1197 hpic->last_idr_frame = href->last_idr_frame;
1198 fh->refresh_frame_flags = 1 << hpic->slot;
1199
1200 // Set the nearest frame in L0 as all reference frame.
1201 for (i = 0; i < AV1_REFS_PER_FRAME; i++)
1202 fh->ref_frame_idx[i] = href->slot;
1203
1204 fh->primary_ref_frame = href->slot;
1205 fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame;
1206
1207 // Set the 2nd nearest frame in L0 as Golden frame.
1208 if (pic->nb_refs[0] > 1) {
1209 ref = pic->refs[0][pic->nb_refs[0] - 2];
1210 href = ref->codec_priv;
1211 // Reference frame index 3 is the GOLDEN_FRAME
1212 fh->ref_frame_idx[3] = href->slot;
1213 fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame;
1214 } else if (base_ctx->ref_l0 == 1) {
1215 fh->ref_order_hint[!href->slot] = cbctx->ref[!href->slot].order_hint;
1216 }
1217 break;
1218
1220 av_log(avctx, AV_LOG_ERROR, "D3D12 AV1 video encode on this device requires B-frame support, "
1221 "but it's not implemented.\n");
1222 return AVERROR_PATCHWELCOME;
1223 default:
1224 av_log(avctx, AV_LOG_ERROR, "Unsupported picture type %d.\n", pic->type);
1225 }
1226
1227
1228 cbctx->seen_frame_header = 0;
1229
1230 fh->show_frame = pic->display_order <= pic->encode_order;
1232 fh->order_hint = pic->display_order - hpic->last_idr_frame;
1233 fh->frame_width_minus_1 = ctx->resolution.Width - 1;
1234 fh->frame_height_minus_1 = ctx->resolution.Height - 1;
1237 fh->is_filter_switchable = 1;
1239
1241 fh->tile_cols = priv->tile_cols;
1242 fh->tile_rows = priv->tile_rows;
1243 fh->tile_cols_log2 = priv->tile_cols_log2;
1244 fh->tile_rows_log2 = priv->tile_rows_log2;
1247 for (i = 0; i < priv->tile_cols; i++)
1249 for (i = 0; i < priv->tile_rows; i++)
1251
1252 memcpy(fh->loop_filter_ref_deltas, default_loop_filter_ref_deltas,
1253 AV1_TOTAL_REFS_PER_FRAME * sizeof(int8_t));
1254
1255 if (fh->frame_type == AV1_FRAME_KEY && fh->show_frame)
1256 fh->error_resilient_mode = 1;
1257
1260
1261 d3d12va_pic->pic_ctl.pAV1PicData->FrameType = fh->frame_type;
1262 d3d12va_pic->pic_ctl.pAV1PicData->TxMode = fh->tx_mode;
1263 d3d12va_pic->pic_ctl.pAV1PicData->RefreshFrameFlags = fh->refresh_frame_flags;
1264 d3d12va_pic->pic_ctl.pAV1PicData->TemporalLayerIndexPlus1 = hpic->temporal_id + 1;
1265 d3d12va_pic->pic_ctl.pAV1PicData->SpatialLayerIndexPlus1 = hpic->spatial_id + 1;
1266 d3d12va_pic->pic_ctl.pAV1PicData->PictureIndex = pic->display_order;
1267 d3d12va_pic->pic_ctl.pAV1PicData->InterpolationFilter = D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_SWITCHABLE;
1268 d3d12va_pic->pic_ctl.pAV1PicData->PrimaryRefFrame = fh->primary_ref_frame;
1269 if (fh->error_resilient_mode)
1270 d3d12va_pic->pic_ctl.pAV1PicData->Flags |= D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_ERROR_RESILIENT_MODE;
1271
1272 if (pic->type == FF_HW_PICTURE_TYPE_IDR)
1273 {
1274 for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
1275 d3d12va_pic->pic_ctl.pAV1PicData->ReferenceFramesReconPictureDescriptors[i].ReconstructedPictureResourceIndex =
1277 }
1278 } else if (pic->type == FF_HW_PICTURE_TYPE_P) {
1279 for (i = 0; i < pic->nb_refs[0]; i++) {
1280 FFHWBaseEncodePicture *ref_pic = pic->refs[0][i];
1281 d3d12va_pic->pic_ctl.pAV1PicData->ReferenceFramesReconPictureDescriptors[i].ReconstructedPictureResourceIndex =
1282 ((D3D12VAEncodeAV1Picture*)ref_pic->codec_priv)->slot;
1283 }
1284 }
1285 // Set reference frame management
1286 memset(d3d12va_pic->pic_ctl.pAV1PicData->ReferenceIndices, 0, sizeof(UINT) * AV1_REFS_PER_FRAME);
1287 if (pic->type == FF_HW_PICTURE_TYPE_P) {
1288 for (i = 0; i < AV1_REFS_PER_FRAME; i++)
1289 d3d12va_pic->pic_ctl.pAV1PicData->ReferenceIndices[i] = fh->ref_frame_idx[i];
1290 }
1291
1292 // Process ROI side data if present and supported
1293 if (base_ctx->roi_allowed && d3d12va_pic->qp_map && d3d12va_pic->qp_map_size > 0) {
1294 d3d12va_pic->pic_ctl.pAV1PicData->QPMapValuesCount = d3d12va_pic->qp_map_size;
1295 d3d12va_pic->pic_ctl.pAV1PicData->pRateControlQPMap = (INT16 *)d3d12va_pic->qp_map;
1296 }
1297
1299}
1300
1301
1303 .profiles = d3d12va_encode_av1_profiles,
1304
1305 .d3d12_codec = D3D12_VIDEO_ENCODER_CODEC_AV1,
1306
1307 .flags = FF_HW_FLAG_B_PICTURES |
1310
1311 .default_quality = 25,
1312
1313 .get_encoder_caps = &d3d12va_encode_av1_get_encoder_caps,
1314
1315 .configure = &d3d12va_encode_av1_configure,
1316
1317 .set_level = &d3d12va_encode_av1_set_level,
1318
1319 .set_tile = &d3d12va_encode_av1_set_tile,
1320
1321 .picture_priv_data_size = sizeof(D3D12VAEncodeAV1Picture),
1322
1323 .init_sequence_params = &d3d12va_encode_av1_init_sequence_params,
1324
1325 .init_picture_params = &d3d12va_encode_av1_init_picture_params,
1326
1327 .free_picture_params = &d3d12va_encode_av1_free_picture_params,
1328
1330
1331#ifdef CONFIG_AV1_D3D12VA_ENCODER
1332 .get_coded_data = &d3d12va_encode_av1_get_coded_data,
1333#endif
1334};
1335
1337{
1339 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
1340
1341 ctx->codec = &d3d12va_encode_type_av1;
1342
1343 if (avctx->profile == AV_PROFILE_UNKNOWN)
1344 avctx->profile = priv->profile;
1345 if (avctx->level == AV_LEVEL_UNKNOWN)
1346 avctx->level = priv->level;
1347
1348 if (avctx->level != AV_LEVEL_UNKNOWN && avctx->level & ~0xff) {
1349 av_log(avctx, AV_LOG_ERROR, "Invalid level %d: must fit "
1350 "in 8-bit unsigned integer.\n", avctx->level);
1351 return AVERROR(EINVAL);
1352 }
1353
1354 if (priv->qp > 0)
1355 ctx->explicit_qp = priv->qp;
1356
1358
1359 return ff_d3d12va_encode_init(avctx);
1360}
1361
1363{
1364 D3D12VAEncodeAV1Context *priv = avctx->priv_data;
1365
1366 ff_cbs_fragment_free(&priv->current_obu);
1367 ff_cbs_close(&priv->cbc);
1368
1369 av_freep(&priv->common.codec_conf.pAV1Config);
1370 av_freep(&priv->common.gop.pAV1SequenceStructure);
1371 av_freep(&priv->common.level.pAV1LevelSetting);
1372 av_freep(&priv->common.subregions_layout.pTilesPartition_AV1);
1373
1375
1376 return ff_d3d12va_encode_close(avctx);
1377}
1378
1379#define OFFSET(x) offsetof(D3D12VAEncodeAV1Context, x)
1380#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1385
1386 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1387 OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, FLAGS },
1388
1389 { "profile", "Set profile (general_profile_idc)",
1391 { .i64 = AV_PROFILE_UNKNOWN }, AV_PROFILE_UNKNOWN, 0xff, FLAGS, "profile" },
1392
1393#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1394 { .i64 = value }, 0, 0, FLAGS, "profile"
1395 { PROFILE("main", AV_PROFILE_AV1_MAIN) },
1396 { PROFILE("high", AV_PROFILE_AV1_HIGH) },
1397 { PROFILE("professional", AV_PROFILE_AV1_PROFESSIONAL) },
1398#undef PROFILE
1399
1400 { "tier", "Set tier (general_tier_flag)",
1401 OFFSET(unit_opts.tier), AV_OPT_TYPE_INT,
1402 { .i64 = 0 }, 0, 1, FLAGS, "tier" },
1403 { "main", NULL, 0, AV_OPT_TYPE_CONST,
1404 { .i64 = 0 }, 0, 0, FLAGS, "tier" },
1405 { "high", NULL, 0, AV_OPT_TYPE_CONST,
1406 { .i64 = 1 }, 0, 0, FLAGS, "tier" },
1407
1408 { "level", "Set level (general_level_idc)",
1410 { .i64 = AV_LEVEL_UNKNOWN }, AV_LEVEL_UNKNOWN, 0xff, FLAGS, "level" },
1411
1412#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1413 { .i64 = value }, 0, 0, FLAGS, "level"
1414 { LEVEL("2.0", 0) },
1415 { LEVEL("2.1", 1) },
1416 { LEVEL("2.2", 2) },
1417 { LEVEL("2.3", 3) },
1418 { LEVEL("3.0", 4) },
1419 { LEVEL("3.1", 5) },
1420 { LEVEL("3.2", 6) },
1421 { LEVEL("3.3", 7) },
1422 { LEVEL("4.0", 8) },
1423 { LEVEL("4.1", 9) },
1424 { LEVEL("4.2", 10) },
1425 { LEVEL("4.3", 11) },
1426 { LEVEL("5.0", 12) },
1427 { LEVEL("5.1", 13) },
1428 { LEVEL("5.2", 14) },
1429 { LEVEL("5.3", 15) },
1430 { LEVEL("6.0", 16) },
1431 { LEVEL("6.1", 17) },
1432 { LEVEL("6.2", 18) },
1433 { LEVEL("6.3", 19) },
1434 { LEVEL("7.0", 20) },
1435 { LEVEL("7.1", 21) },
1436 { LEVEL("7.2", 22) },
1437 { LEVEL("7.3", 23) },
1438#undef LEVEL
1439
1440 { "tiles", "Tile columns x rows (Use minimal tile column/row number "
1441 "automatically by default)",
1442 OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, FLAGS },
1443
1444 { NULL },
1445};
1446
1448 { "b", "0" },
1449 { "bf", "0" },
1450 { "g", "120" },
1451 { "i_qfactor", "1" },
1452 { "i_qoffset", "0" },
1453 { "b_qfactor", "1" },
1454 { "b_qoffset", "0" },
1455 { "qmin", "-1" },
1456 { "qmax", "-1" },
1457 { "refs", "0" },
1458 { NULL },
1459};
1460
1462 .class_name = "av1_d3d12va",
1463 .item_name = av_default_item_name,
1465 .version = LIBAVUTIL_VERSION_INT,
1466};
1467
1469 .p.name = "av1_d3d12va",
1470 CODEC_LONG_NAME("D3D12VA av1 encoder"),
1471 .p.type = AVMEDIA_TYPE_VIDEO,
1472 .p.id = AV_CODEC_ID_AV1,
1473 .priv_data_size = sizeof(D3D12VAEncodeAV1Context),
1476 .close = &d3d12va_encode_av1_close,
1477 .p.priv_class = &d3d12va_encode_av1_class,
1478 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
1480 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
1482 .defaults = d3d12va_encode_av1_defaults,
1484 .hw_configs = ff_d3d12va_encode_hw_configs,
1485 .p.wrapper_name = "d3d12va",
1486};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const FFCodec ff_av1_d3d12va_encoder
static FILE * out
static AVFormatContext * ctx
static AVDictionary * opts
const AV1LevelDescriptor * ff_av1_guess_level(int64_t bitrate, int tier, int width, int height, int tiles, int tile_cols, float fps)
Guess the level of a stream from some parameters.
Definition av1_levels.c:48
static const AV1LevelDescriptor av1_levels[]
ignore entries which named in spec but no details.
Definition av1_levels.c:26
Libavcodec external API header.
static int FUNC tile_group_obu(CodedBitstreamContext *ctx, RWContext *rw, AV1RawTileGroup *current)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FLAGS
Definition cmdutils.c:598
#define CODEC_PIXFMTS(...)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_RECEIVE_PACKET_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
common internal and external API header
#define av_clip
Definition common.h:100
#define av_clip_uintp2
Definition common.h:124
#define NULL
Definition coverity.c:32
int ff_d3d12va_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
void ff_d3d12va_encode_check_encoder_feature_flags(void *log_ctx, D3D12_VIDEO_ENCODER_VALIDATION_FLAGS flags)
const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[]
int ff_d3d12va_encode_init(AVCodecContext *avctx)
int ff_d3d12va_encode_close(AVCodecContext *avctx)
#define D3D12VA_ENCODE_RC_OPTIONS
#define D3D12VA_ENCODE_COMMON_OPTIONS
#define MAX_PARAM_BUFFER_SIZE
#define D3D_PROFILE_DESC(name)
static int d3d12va_encode_av1_get_coded_data(AVCodecContext *avctx, D3D12VAEncodePicture *pic, AVPacket *pkt)
static int d3d12va_encode_av1_set_level(AVCodecContext *avctx)
static const AVOption d3d12va_encode_av1_options[]
static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_professional
static av_always_inline int d3d12va_encode_av1_tile_log2(int blksize, int target)
static int d3d12va_encode_av1_get_encoder_caps(AVCodecContext *avctx)
static int d3d12va_encode_av1_get_buffer_size(AVCodecContext *avctx, D3D12VAEncodePicture *pic, uint64_t tile_size_bytes, uint64_t *nb_subregions_out, D3D12VAEncodeAV1TileInfo **tiles_out, size_t *tile_payload_size_out)
#define D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION
static int d3d12va_encode_av1_init(AVCodecContext *avctx)
static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_main
#define D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION
static int d3d12va_encode_av1_init_picture_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
static const D3D12VAEncodeType d3d12va_encode_type_av1
static int d3d12va_encode_av1_write_sequence_header(AVCodecContext *avctx, char *data, size_t *data_len)
#define LEVEL(name, value)
static int d3d12va_encode_av1_write_picture_header(AVCodecContext *avctx, D3D12VAEncodePicture *pic, char *data, size_t *data_len)
static int d3d12va_encode_av1_set_tile(AVCodecContext *avctx)
static int d3d12va_hw_base_encode_init_params_av1(FFHWBaseEncodeContext *base_ctx, AVCodecContext *avctx, D3D12VAHWBaseEncodeAV1 *common, D3D12VAHWBaseEncodeAV1Opts *opts)
static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_high
static const FFCodecDefault d3d12va_encode_av1_defaults[]
static int d3d12va_encode_av1_add_obu(AVCodecContext *avctx, CodedBitstreamFragment *au, CodedBitstreamUnitType obu_type, void *obu_unit)
static int d3d12va_encode_av1_write_tile_group(AVCodecContext *avctx, uint8_t *tile_group, uint32_t tile_group_size, char *data, size_t *data_len)
static int d3d12va_encode_av1_close(AVCodecContext *avctx)
static const AVClass d3d12va_encode_av1_class
#define PROFILE(name, value)
static int d3d12va_encode_av1_configure(AVCodecContext *avctx)
#define OFFSET(x)
#define D3D12_VIDEO_ENCODER_AV1_INVALID_DPB_RESOURCE_INDEX
static int d3d12va_encode_av1_write_obu(AVCodecContext *avctx, char *data, size_t *data_len, CodedBitstreamFragment *obu)
static const D3D12VAEncodeProfile d3d12va_encode_av1_profiles[]
static int d3d12va_encode_av1_init_sequence_params(AVCodecContext *avctx)
static void d3d12va_encode_av1_free_picture_params(D3D12VAEncodePicture *pic)
static int d3d12va_encode_av1_update_current_frame_picture_header(AVCodecContext *avctx, D3D12VAEncodePicture *pic, AV1RawOBU *frameheader_obu)
#define AV_PROFILE_AV1_HIGH
Definition defs.h:170
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_LEVEL_UNKNOWN
Definition defs.h:209
#define AV_PROFILE_AV1_MAIN
Definition defs.h:169
#define AV_PROFILE_AV1_PROFESSIONAL
Definition defs.h:171
static AVPacket * pkt
int high
Definition dovi_rpuenc.c:39
int main
Definition dovi_rpuenc.c:38
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
#define fail
Definition test.h:479
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition opt.h:302
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition codec.h:133
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR(e)
Definition error.h:45
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition fifo.h:63
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int tile_rows
#define HW_BASE_ENCODE_COMMON_OPTIONS
@ FF_HW_FLAG_NON_IDR_KEY_PICTURES
@ FF_HW_FLAG_B_PICTURE_REFERENCES
@ FF_HW_FLAG_B_PICTURES
@ FF_HW_PICTURE_TYPE_P
@ FF_HW_PICTURE_TYPE_B
@ FF_HW_PICTURE_TYPE_IDR
#define b
Definition input.c:43
#define av_log2
Definition intmath.h:84
@ AV1_TX_MODE_LARGEST
Definition av1.h:182
@ AV1_TX_MODE_SELECT
Definition av1.h:183
@ AV1_OBU_TILE_GROUP
Definition av1.h:33
@ AV1_OBU_FRAME_HEADER
Definition av1.h:32
@ AV1_OBU_SEQUENCE_HEADER
Definition av1.h:30
@ AV1_FRAME_KEY
Definition av1.h:53
@ AV1_FRAME_INTER
Definition av1.h:54
@ AV1_CSP_COLOCATED
Definition av1.h:135
@ AV1_CSP_VERTICAL
Definition av1.h:134
@ AV1_CSP_UNKNOWN
Definition av1.h:133
@ AV1_MAX_TILE_WIDTH
Definition av1.h:79
@ AV1_PRIMARY_REF_NONE
Definition av1.h:87
@ AV1_NUM_REF_FRAMES
Definition av1.h:84
@ AV1_INTERPOLATION_FILTER_SWITCHABLE
Definition av1.h:104
@ AV1_MAX_TILE_COLS
Definition av1.h:82
@ AV1_SELECT_INTEGER_MV
Definition av1.h:99
@ AV1_REFS_PER_FRAME
Definition av1.h:85
@ AV1_TOTAL_REFS_PER_FRAME
Definition av1.h:86
@ AV1_MAX_TILE_ROWS
Definition av1.h:81
@ AV1_MAX_TILE_AREA
Definition av1.h:80
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition cbs.h:66
#define av_always_inline
Definition attributes.h:72
const char * desc
Definition libsvtav1.c:83
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition pixfmt.h:806
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition pixfmt.h:804
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
Definition pixfmt.h:440
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
#define FF_ARRAY_ELEMS(a)
uint8_t chroma_sample_position
Definition cbs_av1.h:63
uint8_t frame_type
Definition cbs_av1.h:180
uint8_t update_mode_delta[2]
Definition cbs_av1.h:270
uint8_t base_q_idx
Definition cbs_av1.h:239
uint8_t cdef_uv_pri_strength[8]
Definition cbs_av1.h:277
int8_t delta_q_v_ac
Definition cbs_av1.h:245
uint16_t render_height_minus_1
Definition cbs_av1.h:203
uint8_t using_qmatrix
Definition cbs_av1.h:246
uint8_t height_in_sbs_minus_1[AV1_MAX_TILE_ROWS]
Definition cbs_av1.h:230
uint8_t tile_rows_log2
Definition cbs_av1.h:226
uint8_t loop_filter_delta_enabled
Definition cbs_av1.h:266
uint8_t loop_filter_level[4]
Definition cbs_av1.h:264
int8_t ref_frame_idx[AV1_REFS_PER_FRAME]
Definition cbs_av1.h:213
uint8_t is_filter_switchable
Definition cbs_av1.h:217
uint8_t cdef_y_pri_strength[8]
Definition cbs_av1.h:275
uint8_t tx_mode
Definition cbs_av1.h:284
int8_t delta_q_v_dc
Definition cbs_av1.h:244
uint16_t tile_rows
Definition cbs_av1.h:237
uint8_t showable_frame
Definition cbs_av1.h:182
uint16_t tile_cols
Definition cbs_av1.h:236
uint8_t tile_size_bytes_minus1
Definition cbs_av1.h:232
int8_t delta_q_u_ac
Definition cbs_av1.h:243
uint8_t uniform_tile_spacing_flag
Definition cbs_av1.h:224
int8_t delta_q_y_dc
Definition cbs_av1.h:240
uint8_t cdef_bits
Definition cbs_av1.h:274
uint16_t render_width_minus_1
Definition cbs_av1.h:202
uint8_t delta_q_present
Definition cbs_av1.h:258
uint8_t cdef_damping_minus_3
Definition cbs_av1.h:273
uint8_t interpolation_filter
Definition cbs_av1.h:218
uint16_t frame_height_minus_1
Definition cbs_av1.h:198
uint8_t delta_q_res
Definition cbs_av1.h:259
int8_t delta_q_u_dc
Definition cbs_av1.h:242
int8_t loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME]
Definition cbs_av1.h:269
uint8_t update_ref_delta[AV1_TOTAL_REFS_PER_FRAME]
Definition cbs_av1.h:268
uint8_t refresh_frame_flags
Definition cbs_av1.h:207
uint8_t loop_filter_sharpness
Definition cbs_av1.h:265
uint8_t ref_order_hint[AV1_NUM_REF_FRAMES]
Definition cbs_av1.h:209
uint8_t show_frame
Definition cbs_av1.h:181
uint8_t primary_ref_frame
Definition cbs_av1.h:196
uint8_t error_resilient_mode
Definition cbs_av1.h:184
uint8_t order_hint
Definition cbs_av1.h:191
uint16_t context_update_tile_id
Definition cbs_av1.h:231
uint16_t frame_width_minus_1
Definition cbs_av1.h:197
int8_t loop_filter_mode_deltas[2]
Definition cbs_av1.h:271
uint8_t cdef_uv_sec_strength[8]
Definition cbs_av1.h:278
uint8_t tile_cols_log2
Definition cbs_av1.h:225
uint8_t width_in_sbs_minus_1[AV1_MAX_TILE_COLS]
Definition cbs_av1.h:229
uint8_t cdef_y_sec_strength[8]
Definition cbs_av1.h:276
uint8_t obu_has_size_field
Definition cbs_av1.h:42
uint8_t obu_type
Definition cbs_av1.h:40
AV1RawFrameHeader frame_header
Definition cbs_av1.h:420
AV1RawOBUHeader header
Definition cbs_av1.h:414
AV1RawSequenceHeader sequence_header
Definition cbs_av1.h:419
union AV1RawOBU::@016362317061177152367125047142162076164261250366 obu
uint8_t use_128x128_superblock
Definition cbs_av1.h:114
uint8_t enable_ref_frame_mvs
Definition cbs_av1.h:124
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 seq_force_integer_mv
Definition cbs_av1.h:129
uint8_t seq_profile
Definition cbs_av1.h:83
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 enable_masked_compound
Definition cbs_av1.h:118
uint8_t still_picture
Definition cbs_av1.h:84
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
uint8_t seq_tier[AV1_MAX_OPERATING_POINTS]
Definition cbs_av1.h:97
uint8_t seq_level_idx[AV1_MAX_OPERATING_POINTS]
Definition cbs_av1.h:96
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
uint8_t * data
Definition cbs_av1.h:301
size_t data_size
Definition cbs_av1.h:303
AVBufferRef * data_ref
Definition cbs_av1.h:302
uint16_t tg_start
Definition cbs_av1.h:312
AV1RawTileData tile_data
Definition cbs_av1.h:315
uint8_t tile_start_and_end_present_flag
Definition cbs_av1.h:311
uint16_t tg_end
Definition cbs_av1.h:313
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
int width
picture width / height.
Definition avcodec.h:604
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVRational framerate
Definition avcodec.h:563
int level
Encoding level descriptor.
Definition avcodec.h:1646
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
int profile
profile
Definition avcodec.h:1636
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition avcodec.h:688
float i_quant_factor
qscale factor between P- and I-frames If > 0 then the last P-frame quantizer will be used (q = lastp_...
Definition avcodec.h:806
void * priv_data
Definition avcodec.h:470
float i_quant_offset
qscale offset between P and I-frames
Definition avcodec.h:813
This struct is allocated as AVHWFramesContext.hwctx.
DXGI_FORMAT format
DXGI_FORMAT format.
Definition fifo.c:35
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AV1ReferenceFrameState ref[AV1_NUM_REF_FRAMES]
Definition cbs_av1.h:491
Context structure for coded bitstream operations.
Definition cbs.h:226
void * priv_data
Internal codec-specific data.
Definition cbs.h:247
Coded bitstream fragment structure, combining one or more units.
Definition cbs.h:129
size_t data_bit_padding
The number of bits which should be ignored in the final byte.
Definition cbs.h:146
size_t data_size
The number of bytes in the bitstream.
Definition cbs.h:142
uint8_t * data
Pointer to the bitstream form of this fragment.
Definition cbs.h:135
D3D12VAHWBaseEncodeAV1Opts unit_opts
CodedBitstreamFragment current_obu
D3D12VAHWBaseEncodeAV1 units
uint8_t height_in_sbs_minus_1[AV1_MAX_TILE_ROWS]
CodedBitstreamContext * cbc
D3D12VAEncodeContext common
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS post_encode_values_flag
uint8_t width_in_sbs_minus_1[AV1_MAX_TILE_COLS]
D3D12_VIDEO_ENCODER_AV1_LEVELS d3d12_level
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop
D3D12_VIDEO_ENCODER_LEVEL_SETTING level
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA subregions_layout
AVBufferRef * output_buffer_ref
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl
ID3D12Resource * resolved_metadata
ID3D12Resource * output_buffer
AVHWFramesContext * input_frames
int nb_refs[MAX_REFERENCE_LIST_NUM]
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
uint8_t level
Definition svq3.c:208
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
int tiles
Definition av1_levels.c:72
float framerate
Definition av1_levels.c:29
int tile_cols
Definition av1_levels.c:73
static int ref[MAX_W *MAX_W]
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
color_range
static int write_sequence_header(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, uint8_t *data, size_t *data_len)