64 { 10, D3D12_VIDEO_ENCODER_LEVELS_H264_1 },
65 { 11, D3D12_VIDEO_ENCODER_LEVELS_H264_11 },
66 { 12, D3D12_VIDEO_ENCODER_LEVELS_H264_12 },
67 { 13, D3D12_VIDEO_ENCODER_LEVELS_H264_13 },
68 { 20, D3D12_VIDEO_ENCODER_LEVELS_H264_2 },
69 { 21, D3D12_VIDEO_ENCODER_LEVELS_H264_21 },
70 { 22, D3D12_VIDEO_ENCODER_LEVELS_H264_22 },
71 { 30, D3D12_VIDEO_ENCODER_LEVELS_H264_3 },
72 { 31, D3D12_VIDEO_ENCODER_LEVELS_H264_31 },
73 { 32, D3D12_VIDEO_ENCODER_LEVELS_H264_32 },
74 { 40, D3D12_VIDEO_ENCODER_LEVELS_H264_4 },
75 { 41, D3D12_VIDEO_ENCODER_LEVELS_H264_41 },
76 { 42, D3D12_VIDEO_ENCODER_LEVELS_H264_42 },
77 { 50, D3D12_VIDEO_ENCODER_LEVELS_H264_5 },
78 { 51, D3D12_VIDEO_ENCODER_LEVELS_H264_51 },
79 { 52, D3D12_VIDEO_ENCODER_LEVELS_H264_52 },
80 { 60, D3D12_VIDEO_ENCODER_LEVELS_H264_6 },
81 { 61, D3D12_VIDEO_ENCODER_LEVELS_H264_61 },
82 { 62, D3D12_VIDEO_ENCODER_LEVELS_H264_62 },
85 static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_main = D3D12_VIDEO_ENCODER_PROFILE_H264_MAIN;
86 static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_high = D3D12_VIDEO_ENCODER_PROFILE_H264_HIGH;
87 static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_high_10 = D3D12_VIDEO_ENCODER_PROFILE_H264_HIGH_10;
89 #define D3D_PROFILE_DESC(name) \
90 { sizeof(D3D12_VIDEO_ENCODER_PROFILE_H264), { .pH264Profile = (D3D12_VIDEO_ENCODER_PROFILE_H264 *)&profile_ ## name } }
99 char *
data,
size_t *data_len,
105 err = ff_cbs_write_fragment_data(priv->
cbc, au);
113 "%zu < %zu.\n", *data_len,
131 err = ff_cbs_insert_unit_content(au, -1,
135 "type = %d.\n",
header->nal_unit_type);
143 char *
data,
size_t *data_len)
159 ff_cbs_fragment_reset(au);
171 D3D12_VIDEO_ENCODER_PROFILE_H264
profile = D3D12_VIDEO_ENCODER_PROFILE_H264_MAIN;
172 D3D12_VIDEO_ENCODER_LEVELS_H264
level = { 0 };
177 D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT support = {
179 .Codec = D3D12_VIDEO_ENCODER_CODEC_H264,
180 .InputFormat = hwctx->
format,
181 .RateControl =
ctx->rc,
182 .IntraRefresh =
ctx->intra_refresh.Mode,
183 .SubregionFrameEncoding = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
184 .ResolutionsListCount = 1,
185 .pResolutionList = &
ctx->resolution,
186 .CodecGopSequence =
ctx->gop,
188 .CodecConfiguration =
ctx->codec_conf,
189 .SuggestedProfile.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PROFILE_H264),
190 .SuggestedProfile.pH264Profile = &
profile,
191 .SuggestedLevel.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVELS_H264),
192 .SuggestedLevel.pH264LevelSetting = &
level,
193 .pResolutionDependentSupport = &
ctx->res_limits,
196 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT,
197 &support,
sizeof(support));
204 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK)) {
205 av_log(avctx,
AV_LOG_ERROR,
"Driver does not support requested features. ValidationFlags: %#x\n",
206 support.ValidationFlags);
211 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) {
212 ctx->is_texture_array = 1;
213 av_log(avctx,
AV_LOG_DEBUG,
"D3D12 video encode on this device uses texture array mode.\n");
217 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_DELTA_QP_AVAILABLE) {
220 ctx->qp_map_region_size =
ctx->res_limits.QPMapRegionPixelsSize;
222 "(QP map region size: %d pixels).\n",
ctx->qp_map_region_size);
225 av_log(avctx,
AV_LOG_DEBUG,
"ROI encoding not supported by hardware for current rate control mode \n");
229 if (
ctx->me_precision != D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM) {
230 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE)) {
232 "precision mode limits.\n");
236 "precision mode limits.\n");
243 sps->pic_height_in_map_units_minus1 = ((base_ctx->
surface_height + 0x0F) >> 4) - 1;
255 ctx->gop.pH264GroupOfPictures->pic_order_cnt_type =
sps->pic_order_cnt_type;
259 ctx->gop.pH264GroupOfPictures->log2_max_frame_num_minus4 =
sps->log2_max_frame_num_minus4;
260 pps->deblocking_filter_control_present_flag = 1;
272 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 *
config;
273 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264 h264_caps;
275 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codec_caps = {
277 .Codec = D3D12_VIDEO_ENCODER_CODEC_H264,
278 .Profile =
ctx->profile->d3d12_profile,
279 .CodecSupportLimits.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264),
282 codec_caps.CodecSupportLimits.pH264Support = &h264_caps;
283 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT,
284 &codec_caps,
sizeof(codec_caps));
285 if (!(SUCCEEDED(hr) && codec_caps.IsSupported))
288 ctx->codec_conf.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264);
290 if (!
ctx->codec_conf.pH264Config)
295 config->ConfigurationFlags = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_NONE;
299 if (h264_caps.DisableDeblockingFilterSupportedModes & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_FLAG_0_ALL_LUMA_CHROMA_SLICE_BLOCK_EDGES_ALWAYS_FILTERED) {
300 config->DisableDeblockingFilterConfig = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_0_ALL_LUMA_CHROMA_SLICE_BLOCK_EDGES_ALWAYS_FILTERED;
302 av_log(avctx,
AV_LOG_ERROR,
"Requested deblocking filter enable mode not supported by driver.\n");
306 if (h264_caps.DisableDeblockingFilterSupportedModes & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_FLAG_1_DISABLE_ALL_SLICE_BLOCK_EDGES) {
307 config->DisableDeblockingFilterConfig = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_1_DISABLE_ALL_SLICE_BLOCK_EDGES;
309 av_log(avctx,
AV_LOG_ERROR,
"Requested deblocking filter disable mode not supported by driver.\n");
316 if (h264_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_CABAC_ENCODING_SUPPORT) {
317 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_ENABLE_CABAC_ENCODING;
319 av_log(avctx,
AV_LOG_WARNING,
"CABAC entropy coding is not supported by the driver, falling back to CAVLC.\n");
335 int fixed_qp_idr, fixed_qp_p, fixed_qp_b;
343 if (
ctx->rc.Mode == D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP) {
344 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP *cqp_ctl;
350 fixed_qp_idr = fixed_qp_p;
355 fixed_qp_b = fixed_qp_p;
358 "%d / %d / %d for IDR- / P- / B-frames.\n",
359 fixed_qp_idr, fixed_qp_p, fixed_qp_b);
361 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP);
366 cqp_ctl->ConstantQP_FullIntracodedFrame = fixed_qp_idr;
367 cqp_ctl->ConstantQP_InterPredictedFrame_PrevRefOnly = fixed_qp_p;
368 cqp_ctl->ConstantQP_InterPredictedFrame_BiDirectionalRef = fixed_qp_b;
370 ctx->rc.ConfigParams.pConfiguration_CQP = cqp_ctl;
375 ctx->gop.DataSize =
sizeof(D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264);
377 if (!
ctx->gop.pH264GroupOfPictures)
380 ctx->gop.pH264GroupOfPictures->GOPLength = base_ctx->
gop_size;
381 ctx->gop.pH264GroupOfPictures->PPicturePeriod = base_ctx->
b_per_p + 1;
392 ctx->level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVELS_H264);
394 if (!
ctx->level.pH264LevelSetting)
414 if (!pic->
pic_ctl.pH264PicData)
419 av_freep(&pic->
pic_ctl.pH264PicData->pReferenceFramesReconPictureDescriptors);
432 D3D12_VIDEO_ENCODER_REFERENCE_PICTURE_DESCRIPTOR_H264 *pd =
NULL;
433 UINT *ref_list0 =
NULL, *ref_list1 =
NULL;
436 pic->
pic_ctl.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264);
438 if (!pic->
pic_ctl.pH264PicData)
451 switch(base_pic->
type) {
453 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_IDR_FRAME;
454 pic->
pic_ctl.pH264PicData->idr_pic_id =
ctx->idr_pic_id;
457 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_I_FRAME;
460 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_P_FRAME;
463 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_B_FRAME;
481 pic->
pic_ctl.pH264PicData->List0ReferenceFramesCount = base_pic->
nb_refs[0];
487 href =
ref->codec_priv;
490 pd[idx].ReconstructedPictureResourceIndex = idx;
501 pic->
pic_ctl.pH264PicData->List1ReferenceFramesCount = base_pic->
nb_refs[1];
507 href =
ref->codec_priv;
510 pd[idx].ReconstructedPictureResourceIndex = idx;
516 pic->
pic_ctl.pH264PicData->pList0ReferenceFrames = ref_list0;
517 pic->
pic_ctl.pH264PicData->pList1ReferenceFrames = ref_list1;
518 pic->
pic_ctl.pH264PicData->ReferenceFramesReconPictureDescriptorsCount = idx;
519 pic->
pic_ctl.pH264PicData->pReferenceFramesReconPictureDescriptors = pd;
524 pic->
pic_ctl.pH264PicData->pRateControlQPMap = (INT8 *)pic->
qp_map;
533 .d3d12_codec = D3D12_VIDEO_ENCODER_CODEC_H264,
539 .default_quality = 25,
572 "in 8-bit unsigned integer.\n", avctx->
level);
577 ctx->explicit_qp = priv->
qp;
587 ff_cbs_close(&priv->
cbc);
593 if (priv->
common.
rc.ConfigParams.pConfiguration_CQP !=
NULL) {
600 #define OFFSET(x) offsetof(D3D12VAEncodeH264Context, x)
601 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
607 {
"qp",
"Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
610 {
"profile",
"Set profile (general_profile_idc)",
614 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
615 { .i64 = value }, 0, 0, FLAGS, "profile"
621 {
"level",
"Set level (general_level_idc)",
625 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
626 { .i64 = value }, 0, 0, FLAGS, "level"
628 {
LEVEL(
"1.1", 11) },
629 {
LEVEL(
"1.2", 12) },
630 {
LEVEL(
"1.3", 13) },
632 {
LEVEL(
"2.1", 21) },
633 {
LEVEL(
"2.2", 22) },
635 {
LEVEL(
"3.1", 31) },
636 {
LEVEL(
"3.2", 32) },
638 {
LEVEL(
"4.1", 41) },
639 {
LEVEL(
"4.2", 42) },
641 {
LEVEL(
"5.1", 51) },
642 {
LEVEL(
"5.2", 52) },
644 {
LEVEL(
"6.1", 61) },
645 {
LEVEL(
"6.2", 62) },
648 {
"deblock",
"Deblocking filter mode",
651 {
"coder",
"Entropy coder type",
676 .
p.
name =
"h264_d3d12va",
692 .p.wrapper_name =
"d3d12va",