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 */
27
36
41
44
45 // User options.
49
50 // Writer structures.
53
57
62
64 {
65 {
66 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_NONE,
67 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8,
68 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32,
69 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4,
70 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32,
71 3,
72 3,
73 },
74 {
75 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_NONE,
76 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8,
77 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32,
78 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4,
79 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32,
80 0,
81 0,
82 },
83 {
84 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_NONE,
85 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8,
86 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32,
87 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4,
88 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32,
89 2,
90 2,
91 },
92 {
93 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_NONE,
94 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8,
95 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64,
96 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4,
97 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32,
98 2,
99 2,
100 },
101 {
102 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_NONE,
103 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8,
104 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64,
105 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4,
106 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32,
107 4,
108 4,
109 },
110 };
111
113 { 30, D3D12_VIDEO_ENCODER_LEVELS_HEVC_1 },
114 { 60, D3D12_VIDEO_ENCODER_LEVELS_HEVC_2 },
115 { 63, D3D12_VIDEO_ENCODER_LEVELS_HEVC_21 },
116 { 90, D3D12_VIDEO_ENCODER_LEVELS_HEVC_3 },
117 { 93, D3D12_VIDEO_ENCODER_LEVELS_HEVC_31 },
118 { 120, D3D12_VIDEO_ENCODER_LEVELS_HEVC_4 },
119 { 123, D3D12_VIDEO_ENCODER_LEVELS_HEVC_41 },
120 { 150, D3D12_VIDEO_ENCODER_LEVELS_HEVC_5 },
121 { 153, D3D12_VIDEO_ENCODER_LEVELS_HEVC_51 },
122 { 156, D3D12_VIDEO_ENCODER_LEVELS_HEVC_52 },
123 { 180, D3D12_VIDEO_ENCODER_LEVELS_HEVC_6 },
124 { 183, D3D12_VIDEO_ENCODER_LEVELS_HEVC_61 },
125 { 186, D3D12_VIDEO_ENCODER_LEVELS_HEVC_62 },
126 };
127
128 static const D3D12_VIDEO_ENCODER_PROFILE_HEVC
profile_main = D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN;
129 static const D3D12_VIDEO_ENCODER_PROFILE_HEVC
profile_main10 = D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN10;
130
131 #define D3D_PROFILE_DESC(name) \
132 { sizeof(D3D12_VIDEO_ENCODER_PROFILE_HEVC), { .pHEVCProfile = (D3D12_VIDEO_ENCODER_PROFILE_HEVC *)&profile_ ## name } }
137 };
138
140 {
141 switch (cusize) {
142 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8: return 8;
143 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_16x16: return 16;
144 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32: return 32;
145 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64: return 64;
147 }
148 return 0;
149 }
150
152 {
153 switch (tusize) {
154 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4: return 4;
155 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_8x8: return 8;
156 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_16x16: return 16;
157 case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32: return 32;
159 }
160 return 0;
161 }
162
164 char *
data,
size_t *data_len,
166 {
168 int err;
169
170 err = ff_cbs_write_fragment_data(priv->
cbc, au);
171 if (err < 0) {
173 return err;
174 }
175
178 "%zu < %zu.\n", *data_len,
181 }
182
185
186 return 0;
187 }
188
191 void *nal_unit)
192 {
194 int err;
195
196 err = ff_cbs_insert_unit_content(au, -1,
198 if (err < 0) {
200 "type = %d.\n",
header->nal_unit_type);
201 return err;
202 }
203
204 return 0;
205 }
206
208 char *
data,
size_t *data_len)
209 {
212 int err;
213
215 if (err < 0)
217
219 if (err < 0)
221
223 if (err < 0)
225
228 ff_cbs_fragment_reset(au);
229 return err;
230
231 }
232
234 {
241 D3D12_VIDEO_ENCODER_PROFILE_HEVC
profile = D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN;
242 D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC
level = { 0 };
244 uint8_t min_cu_size, max_cu_size, min_tu_size, max_tu_size;
245 HRESULT hr;
246 int err;
247
248 D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT support = {
249 .NodeIndex = 0,
250 .Codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
251 .InputFormat = hwctx->
format,
252 .RateControl =
ctx->rc,
253 .IntraRefresh = D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE,
254 .SubregionFrameEncoding = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
255 .ResolutionsListCount = 1,
256 .pResolutionList = &
ctx->resolution,
257 .CodecGopSequence =
ctx->gop,
259 .CodecConfiguration =
ctx->codec_conf,
260 .SuggestedProfile.DataSize = sizeof(D3D12_VIDEO_ENCODER_PROFILE_HEVC),
261 .SuggestedProfile.pHEVCProfile = &
profile,
262 .SuggestedLevel.DataSize = sizeof(D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC),
263 .SuggestedLevel.pHEVCLevelSetting = &
level,
264 .pResolutionDependentSupport = &
ctx->res_limits,
265 };
266
267 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT,
268 &support, sizeof(support));
269
270 if (FAILED(hr)) {
273 }
274
275 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK)) {
277 support.ValidationFlags);
279 }
280
281 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) {
282 ctx->is_texture_array = 1;
283 av_log(avctx,
AV_LOG_DEBUG,
"D3D12 video encode on this device uses texture array mode.\n");
284 }
285
288
293
294 // cu_qp_delta always required to be 1 in https://github.com/microsoft/DirectX-Specs/blob/master/d3d/D3D12VideoEncoding.md
297
300 if (err < 0)
301 return err;
302
304
305 av_assert0(
ctx->res_limits.SubregionBlockPixelsSize % min_cu_size == 0);
306
308 ctx->res_limits.SubregionBlockPixelsSize);
310 ctx->res_limits.SubregionBlockPixelsSize);
311
312 if (avctx->
width !=
sps->pic_width_in_luma_samples ||
313 avctx->
height !=
sps->pic_height_in_luma_samples) {
314 sps->conformance_window_flag = 1;
315 sps->conf_win_left_offset = 0;
316 sps->conf_win_right_offset =
317 (
sps->pic_width_in_luma_samples - avctx->
width) >>
desc->log2_chroma_w;
318 sps->conf_win_top_offset = 0;
319 sps->conf_win_bottom_offset =
320 (
sps->pic_height_in_luma_samples - avctx->
height) >>
desc->log2_chroma_h;
321 } else {
322 sps->conformance_window_flag = 0;
323 }
324
325 sps->log2_max_pic_order_cnt_lsb_minus4 =
ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4;
326
327 sps->log2_min_luma_coding_block_size_minus3 = (uint8_t)(
av_log2(min_cu_size) - 3);
328 sps->log2_diff_max_min_luma_coding_block_size = (uint8_t)(
av_log2(max_cu_size) -
av_log2(min_cu_size));
329 sps->log2_min_luma_transform_block_size_minus2 = (uint8_t)(
av_log2(min_tu_size) - 2);
330 sps->log2_diff_max_min_luma_transform_block_size = (uint8_t)(
av_log2(max_tu_size) -
av_log2(min_tu_size));
331
332 sps->max_transform_hierarchy_depth_inter =
ctx->codec_conf.pHEVCConfig->max_transform_hierarchy_depth_inter;
333 sps->max_transform_hierarchy_depth_intra =
ctx->codec_conf.pHEVCConfig->max_transform_hierarchy_depth_intra;
334
335 sps->amp_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
336 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_ASYMETRIC_MOTION_PARTITION);
337 sps->sample_adaptive_offset_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
338 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_SAO_FILTER);
339
340 pps->cabac_init_present_flag = 1;
341
342 pps->init_qp_minus26 = 0;
343
344 pps->transform_skip_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
345 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING);
346
347 pps->pps_slice_chroma_qp_offsets_present_flag = 1;
348
349 pps->tiles_enabled_flag = 0;
// no tiling in D3D12
350
351 pps->pps_loop_filter_across_slices_enabled_flag = !(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
352 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES);
353
354 pps->deblocking_filter_control_present_flag = 1;
355
356 return 0;
357 }
358
360 {
362 HRESULT hr;
363 uint8_t min_cu_size, max_cu_size;
366 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC *
config;
367 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC hevc_caps;
368
369 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codec_caps = {
370 .NodeIndex = 0,
371 .Codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
372 .Profile =
ctx->profile->d3d12_profile,
373 .CodecSupportLimits.DataSize = sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC),
374 };
375
378 codec_caps.CodecSupportLimits.pHEVCSupport = &hevc_caps;
379 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT,
380 &codec_caps, sizeof(codec_caps));
381 if (SUCCEEDED(hr) && codec_caps.IsSupported)
382 break;
383 }
384
388 }
389
390 ctx->codec_conf.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC);
392 if (!
ctx->codec_conf.pHEVCConfig)
394
396
397 config->ConfigurationFlags = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_NONE;
398 config->MinLumaCodingUnitSize = hevc_caps.MinLumaCodingUnitSize;
399 config->MaxLumaCodingUnitSize = hevc_caps.MaxLumaCodingUnitSize;
400 config->MinLumaTransformUnitSize = hevc_caps.MinLumaTransformUnitSize;
401 config->MaxLumaTransformUnitSize = hevc_caps.MaxLumaTransformUnitSize;
402 config->max_transform_hierarchy_depth_inter = hevc_caps.max_transform_hierarchy_depth_inter;
403 config->max_transform_hierarchy_depth_intra = hevc_caps.max_transform_hierarchy_depth_intra;
404
405 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_ASYMETRIC_MOTION_PARTITION_SUPPORT ||
406 hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_ASYMETRIC_MOTION_PARTITION_REQUIRED)
407 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_ASYMETRIC_MOTION_PARTITION;
408
409 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_SAO_FILTER_SUPPORT)
410 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_SAO_FILTER;
411
412 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_DISABLING_LOOP_FILTER_ACROSS_SLICES_SUPPORT)
413 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES;
414
415 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_TRANSFORM_SKIP_SUPPORT)
416 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING;
417
418 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_P_FRAMES_IMPLEMENTED_AS_LOW_DELAY_B_FRAMES)
419 ctx->bi_not_empty = 1;
420
421 // block sizes
424
426 "min CB size %dx%d.\n", max_cu_size, max_cu_size,
427 min_cu_size, min_cu_size);
428
431
432 return 0;
433 }
434
436 {
440 int fixed_qp_idr, fixed_qp_p, fixed_qp_b;
441 int err;
442
444 if (err < 0)
445 return err;
446
447 // Rate control
448 if (
ctx->rc.Mode == D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP) {
449 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP *cqp_ctl;
454 else
455 fixed_qp_idr = fixed_qp_p;
459 else
460 fixed_qp_b = fixed_qp_p;
461
463 "%d / %d / %d for IDR- / P- / B-frames.\n",
464 fixed_qp_idr, fixed_qp_p, fixed_qp_b);
465
466 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP);
468 if (!cqp_ctl)
470
471 cqp_ctl->ConstantQP_FullIntracodedFrame = fixed_qp_idr;
472 cqp_ctl->ConstantQP_InterPredictedFrame_PrevRefOnly = fixed_qp_p;
473 cqp_ctl->ConstantQP_InterPredictedFrame_BiDirectionalRef = fixed_qp_b;
474
475 ctx->rc.ConfigParams.pConfiguration_CQP = cqp_ctl;
476 }
477
478 // GOP
479 ctx->gop.DataSize =
sizeof(D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC);
481 if (!
ctx->gop.pHEVCGroupOfPictures)
483
484 ctx->gop.pHEVCGroupOfPictures->GOPLength = base_ctx->
gop_size;
485 ctx->gop.pHEVCGroupOfPictures->PPicturePeriod = base_ctx->
b_per_p + 1;
486 // Power of 2
488 ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4 =
490 else
491 ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4 =
493
494 return 0;
495 }
496
498 {
502
503 ctx->level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC);
505 if (!
ctx->level.pHEVCLevelSetting)
507
511 break;
512 }
513 }
514
518 }
519
521 D3D12_VIDEO_ENCODER_TIER_HEVC_MAIN :
522 D3D12_VIDEO_ENCODER_TIER_HEVC_HIGH;
523
524 return 0;
525 }
526
528 {
529 if (!pic->
pic_ctl.pHEVCPicData)
530 return;
531
534 av_freep(&pic->
pic_ctl.pHEVCPicData->pReferenceFramesReconPictureDescriptors);
536 }
537
540 {
545 D3D12_VIDEO_ENCODER_REFERENCE_PICTURE_DESCRIPTOR_HEVC *pd =
NULL;
546 UINT *ref_list0 =
NULL, *ref_list1 =
NULL;
548
549 pic->
pic_ctl.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC);
551 if (!pic->
pic_ctl.pHEVCPicData)
553
557 } else {
560 }
562
563 switch(base_pic->
type) {
565 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_IDR_FRAME;
566 break;
568 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_I_FRAME;
569 break;
571 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_P_FRAME;
572 break;
574 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_B_FRAME;
575 break;
576 default:
578 }
579
580 pic->
pic_ctl.pHEVCPicData->slice_pic_parameter_set_id = 0;
582
585 if (!pd)
587
589 if (!ref_list0)
591
592 pic->
pic_ctl.pHEVCPicData->List0ReferenceFramesCount = base_pic->
nb_refs[0];
596
598 href =
ref->codec_priv;
599
601 pd[idx].ReconstructedPictureResourceIndex = idx;
602 pd[idx].IsRefUsedByCurrentPic = TRUE;
604 idx++;
605 }
606 }
607
610 if (!ref_list1)
612
613 pic->
pic_ctl.pHEVCPicData->List1ReferenceFramesCount = base_pic->
nb_refs[1];
617
619 href =
ref->codec_priv;
620
622 pd[idx].ReconstructedPictureResourceIndex = idx;
623 pd[idx].IsRefUsedByCurrentPic = TRUE;
625 idx++;
626 }
627 }
628
629 pic->
pic_ctl.pHEVCPicData->pList0ReferenceFrames = ref_list0;
630 pic->
pic_ctl.pHEVCPicData->pList1ReferenceFrames = ref_list1;
631 pic->
pic_ctl.pHEVCPicData->ReferenceFramesReconPictureDescriptorsCount = idx;
632 pic->
pic_ctl.pHEVCPicData->pReferenceFramesReconPictureDescriptors = pd;
633
634 return 0;
635 }
636
639
640 .d3d12_codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
641
645
646 .default_quality = 25,
647
649
651
653
655
657
659
661
663 };
664
666 {
669
671
676
679 "in 8-bit unsigned integer.\n", avctx->
level);
681 }
682
684 ctx->explicit_qp = priv->
qp;
685
687 }
688
690 {
692
694 ff_cbs_close(&priv->
cbc);
695
699
701 }
702
703 #define OFFSET(x) offsetof(D3D12VAEncodeHEVCContext, x)
704 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
709
710 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
712
713 { "profile", "Set profile (general_profile_idc)",
716
717 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
718 { .i64 = value }, 0, 0, FLAGS, "profile"
721 #undef PROFILE
722
723 { "tier", "Set tier (general_tier_flag)",
725 { .i64 = 0 }, 0, 1,
FLAGS,
"tier" },
727 { .i64 = 0 }, 0, 0,
FLAGS,
"tier" },
729 { .i64 = 1 }, 0, 0,
FLAGS,
"tier" },
730
731 { "level", "Set level (general_level_idc)",
734
735 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
736 { .i64 = value }, 0, 0, FLAGS, "level"
739 {
LEVEL(
"2.1", 63) },
741 {
LEVEL(
"3.1", 93) },
743 {
LEVEL(
"4.1", 123) },
745 {
LEVEL(
"5.1", 153) },
746 {
LEVEL(
"5.2", 156) },
748 {
LEVEL(
"6.1", 183) },
749 {
LEVEL(
"6.2", 186) },
750 #undef LEVEL
751
753 };
754
756 { "b", "0" },
757 { "bf", "2" },
758 { "g", "120" },
759 { "i_qfactor", "1" },
760 { "i_qoffset", "0" },
761 { "b_qfactor", "1" },
762 { "b_qoffset", "0" },
763 { "qmin", "-1" },
764 { "qmax", "-1" },
765 { "refs", "0" },
767 };
768
774 };
775
777 .
p.
name =
"hevc_d3d12va",
793 .p.wrapper_name = "d3d12va",
794 };