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,
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,
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,
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,
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,
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 },
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;
131 #define D3D_PROFILE_DESC(name) \
132 { sizeof(D3D12_VIDEO_ENCODER_PROFILE_HEVC), { .pHEVCProfile = (D3D12_VIDEO_ENCODER_PROFILE_HEVC *)&profile_ ## name } }
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;
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;
164 char *
data,
size_t *data_len,
170 err = ff_cbs_write_fragment_data(priv->
cbc, au);
178 "%zu < %zu.\n", *data_len,
196 err = ff_cbs_insert_unit_content(au, -1,
200 "type = %d.\n",
header->nal_unit_type);
208 char *
data,
size_t *data_len)
228 ff_cbs_fragment_reset(au);
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;
248 D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT support = {
250 .Codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
251 .InputFormat = hwctx->
format,
252 .RateControl =
ctx->rc,
253 .IntraRefresh =
ctx->intra_refresh.Mode,
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,
267 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT,
268 &support,
sizeof(support));
275 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK)) {
277 support.ValidationFlags);
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");
287 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_DELTA_QP_AVAILABLE) {
290 ctx->qp_map_region_size =
ctx->res_limits.QPMapRegionPixelsSize;
292 "(QP map region size: %d pixels).\n",
ctx->qp_map_region_size);
295 av_log(avctx,
AV_LOG_DEBUG,
"ROI encoding not supported by hardware for current rate control mode \n");
299 if (
ctx->me_precision != D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM) {
300 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE)) {
302 "precision mode limits.\n");
306 "precision mode limits.\n");
328 av_assert0(
ctx->res_limits.SubregionBlockPixelsSize % min_cu_size == 0);
331 ctx->res_limits.SubregionBlockPixelsSize);
333 ctx->res_limits.SubregionBlockPixelsSize);
335 if (avctx->
width !=
sps->pic_width_in_luma_samples ||
336 avctx->
height !=
sps->pic_height_in_luma_samples) {
337 sps->conformance_window_flag = 1;
338 sps->conf_win_left_offset = 0;
339 sps->conf_win_right_offset =
340 (
sps->pic_width_in_luma_samples - avctx->
width) >>
desc->log2_chroma_w;
341 sps->conf_win_top_offset = 0;
342 sps->conf_win_bottom_offset =
343 (
sps->pic_height_in_luma_samples - avctx->
height) >>
desc->log2_chroma_h;
345 sps->conformance_window_flag = 0;
348 sps->log2_max_pic_order_cnt_lsb_minus4 =
ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4;
350 sps->log2_min_luma_coding_block_size_minus3 = (uint8_t)(
av_log2(min_cu_size) - 3);
351 sps->log2_diff_max_min_luma_coding_block_size = (uint8_t)(
av_log2(max_cu_size) -
av_log2(min_cu_size));
352 sps->log2_min_luma_transform_block_size_minus2 = (uint8_t)(
av_log2(min_tu_size) - 2);
353 sps->log2_diff_max_min_luma_transform_block_size = (uint8_t)(
av_log2(max_tu_size) -
av_log2(min_tu_size));
355 sps->max_transform_hierarchy_depth_inter =
ctx->codec_conf.pHEVCConfig->max_transform_hierarchy_depth_inter;
356 sps->max_transform_hierarchy_depth_intra =
ctx->codec_conf.pHEVCConfig->max_transform_hierarchy_depth_intra;
358 sps->amp_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
359 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_ASYMETRIC_MOTION_PARTITION);
360 sps->sample_adaptive_offset_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
361 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_SAO_FILTER);
363 pps->cabac_init_present_flag = 1;
365 pps->init_qp_minus26 = 0;
367 pps->transform_skip_enabled_flag = !!(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
368 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING);
370 pps->pps_slice_chroma_qp_offsets_present_flag = 1;
372 pps->tiles_enabled_flag = 0;
374 pps->pps_loop_filter_across_slices_enabled_flag = !(
ctx->codec_conf.pHEVCConfig->ConfigurationFlags &
375 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES);
377 pps->deblocking_filter_control_present_flag = 1;
386 uint8_t min_cu_size, max_cu_size;
389 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC *
config;
390 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC hevc_caps;
392 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codec_caps = {
394 .Codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
395 .Profile =
ctx->profile->d3d12_profile,
396 .CodecSupportLimits.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC),
401 codec_caps.CodecSupportLimits.pHEVCSupport = &hevc_caps;
402 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT,
403 &codec_caps,
sizeof(codec_caps));
404 if (SUCCEEDED(hr) && codec_caps.IsSupported)
413 ctx->codec_conf.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC);
415 if (!
ctx->codec_conf.pHEVCConfig)
420 config->ConfigurationFlags = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_NONE;
421 config->MinLumaCodingUnitSize = hevc_caps.MinLumaCodingUnitSize;
422 config->MaxLumaCodingUnitSize = hevc_caps.MaxLumaCodingUnitSize;
423 config->MinLumaTransformUnitSize = hevc_caps.MinLumaTransformUnitSize;
424 config->MaxLumaTransformUnitSize = hevc_caps.MaxLumaTransformUnitSize;
425 config->max_transform_hierarchy_depth_inter = hevc_caps.max_transform_hierarchy_depth_inter;
426 config->max_transform_hierarchy_depth_intra = hevc_caps.max_transform_hierarchy_depth_intra;
428 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_ASYMETRIC_MOTION_PARTITION_SUPPORT ||
429 hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_ASYMETRIC_MOTION_PARTITION_REQUIRED)
430 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_ASYMETRIC_MOTION_PARTITION;
432 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_SAO_FILTER_SUPPORT)
433 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_SAO_FILTER;
435 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_DISABLING_LOOP_FILTER_ACROSS_SLICES_SUPPORT)
436 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES;
438 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_TRANSFORM_SKIP_SUPPORT)
439 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING;
441 if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_P_FRAMES_IMPLEMENTED_AS_LOW_DELAY_B_FRAMES)
442 ctx->bi_not_empty = 1;
449 "min CB size %dx%d.\n", max_cu_size, max_cu_size,
450 min_cu_size, min_cu_size);
463 int fixed_qp_idr, fixed_qp_p, fixed_qp_b;
471 if (
ctx->rc.Mode == D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP) {
472 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP *cqp_ctl;
478 fixed_qp_idr = fixed_qp_p;
483 fixed_qp_b = fixed_qp_p;
486 "%d / %d / %d for IDR- / P- / B-frames.\n",
487 fixed_qp_idr, fixed_qp_p, fixed_qp_b);
489 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP);
494 cqp_ctl->ConstantQP_FullIntracodedFrame = fixed_qp_idr;
495 cqp_ctl->ConstantQP_InterPredictedFrame_PrevRefOnly = fixed_qp_p;
496 cqp_ctl->ConstantQP_InterPredictedFrame_BiDirectionalRef = fixed_qp_b;
498 ctx->rc.ConfigParams.pConfiguration_CQP = cqp_ctl;
502 ctx->gop.DataSize =
sizeof(D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC);
504 if (!
ctx->gop.pHEVCGroupOfPictures)
507 ctx->gop.pHEVCGroupOfPictures->GOPLength = base_ctx->
gop_size;
508 ctx->gop.pHEVCGroupOfPictures->PPicturePeriod = base_ctx->
b_per_p + 1;
511 ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4 =
514 ctx->gop.pHEVCGroupOfPictures->log2_max_pic_order_cnt_lsb_minus4 =
526 ctx->level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC);
528 if (!
ctx->level.pHEVCLevelSetting)
544 D3D12_VIDEO_ENCODER_TIER_HEVC_MAIN :
545 D3D12_VIDEO_ENCODER_TIER_HEVC_HIGH;
552 if (!pic->
pic_ctl.pHEVCPicData)
557 av_freep(&pic->
pic_ctl.pHEVCPicData->pReferenceFramesReconPictureDescriptors);
569 D3D12_VIDEO_ENCODER_REFERENCE_PICTURE_DESCRIPTOR_HEVC *pd =
NULL;
570 UINT *ref_list0 =
NULL, *ref_list1 =
NULL;
573 pic->
pic_ctl.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC);
575 if (!pic->
pic_ctl.pHEVCPicData)
587 switch(base_pic->
type) {
589 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_IDR_FRAME;
592 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_I_FRAME;
595 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_P_FRAME;
598 pic->
pic_ctl.pHEVCPicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_HEVC_B_FRAME;
604 pic->
pic_ctl.pHEVCPicData->slice_pic_parameter_set_id = 0;
616 pic->
pic_ctl.pHEVCPicData->List0ReferenceFramesCount = base_pic->
nb_refs[0];
622 href =
ref->codec_priv;
625 pd[idx].ReconstructedPictureResourceIndex = idx;
626 pd[idx].IsRefUsedByCurrentPic = TRUE;
637 pic->
pic_ctl.pHEVCPicData->List1ReferenceFramesCount = base_pic->
nb_refs[1];
643 href =
ref->codec_priv;
646 pd[idx].ReconstructedPictureResourceIndex = idx;
647 pd[idx].IsRefUsedByCurrentPic = TRUE;
653 pic->
pic_ctl.pHEVCPicData->pList0ReferenceFrames = ref_list0;
654 pic->
pic_ctl.pHEVCPicData->pList1ReferenceFrames = ref_list1;
655 pic->
pic_ctl.pHEVCPicData->ReferenceFramesReconPictureDescriptorsCount = idx;
656 pic->
pic_ctl.pHEVCPicData->pReferenceFramesReconPictureDescriptors = pd;
661 pic->
pic_ctl.pHEVCPicData->pRateControlQPMap = (INT8 *)pic->
qp_map;
670 .d3d12_codec = D3D12_VIDEO_ENCODER_CODEC_HEVC,
676 .default_quality = 25,
709 "in 8-bit unsigned integer.\n", avctx->
level);
714 ctx->explicit_qp = priv->
qp;
724 ff_cbs_close(&priv->
cbc);
733 #define OFFSET(x) offsetof(D3D12VAEncodeHEVCContext, x)
734 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
740 {
"qp",
"Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
743 {
"profile",
"Set profile (general_profile_idc)",
747 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
748 { .i64 = value }, 0, 0, FLAGS, "profile"
753 {
"tier",
"Set tier (general_tier_flag)",
755 { .i64 = 0 }, 0, 1,
FLAGS,
"tier" },
757 { .i64 = 0 }, 0, 0,
FLAGS,
"tier" },
759 { .i64 = 1 }, 0, 0,
FLAGS,
"tier" },
761 {
"level",
"Set level (general_level_idc)",
765 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
766 { .i64 = value }, 0, 0, FLAGS, "level"
769 {
LEVEL(
"2.1", 63) },
771 {
LEVEL(
"3.1", 93) },
773 {
LEVEL(
"4.1", 123) },
775 {
LEVEL(
"5.1", 153) },
776 {
LEVEL(
"5.2", 156) },
778 {
LEVEL(
"6.1", 183) },
779 {
LEVEL(
"6.2", 186) },
789 {
"i_qfactor",
"1" },
790 {
"i_qoffset",
"0" },
791 {
"b_qfactor",
"1" },
792 {
"b_qoffset",
"0" },
807 .
p.
name =
"hevc_d3d12va",
823 .p.wrapper_name =
"d3d12va",