43 uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->
fence);
44 if (completion < psync_ctx->fence_value) {
45 if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->
fence, psync_ctx->
fence_value, psync_ctx->
event)))
48 WaitForSingleObjectEx(psync_ctx->
event, INFINITE, FALSE);
58 DX_CHECK(ID3D12CommandQueue_Signal(
ctx->command_queue,
ctx->sync_ctx.fence, ++
ctx->sync_ctx.fence_value));
77 uint64_t completion = ID3D12Fence_GetCompletedValue(
ctx->sync_ctx.fence);
85 hr = ID3D12Device_CreateCommandAllocator(
ctx->hwctx->device, D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
86 &IID_ID3D12CommandAllocator, (
void **)ppAllocator);
101 .fence_value = fence_value,
123 completion = ID3D12Fence_GetCompletedValue(
ctx->sync_ctx.fence);
124 if (completion < pic->fence_value) {
125 if (FAILED(ID3D12Fence_SetEventOnCompletion(
ctx->sync_ctx.fence, pic->
fence_value,
126 ctx->sync_ctx.event)))
129 WaitForSingleObjectEx(
ctx->sync_ctx.event, INFINITE, FALSE);
146 int width =
sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) +
sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA);
147 D3D12_HEAP_PROPERTIES encoded_meta_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }, resolved_meta_props;
148 D3D12_HEAP_TYPE resolved_heap_type = D3D12_HEAP_TYPE_READBACK;
151 D3D12_RESOURCE_DESC meta_desc = {
152 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
154 .Width =
ctx->req.MaxEncoderOutputMetadataBufferSize,
156 .DepthOrArraySize = 1,
158 .Format = DXGI_FORMAT_UNKNOWN,
159 .SampleDesc = { .Count = 1, .Quality = 0 },
160 .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
161 .Flags = D3D12_RESOURCE_FLAG_NONE,
164 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &encoded_meta_props, D3D12_HEAP_FLAG_NONE,
165 &meta_desc, D3D12_RESOURCE_STATE_COMMON,
NULL,
172 ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(
ctx->hwctx->device, &resolved_meta_props, 0, resolved_heap_type);
174 meta_desc.Width =
width;
176 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &resolved_meta_props, D3D12_HEAP_FLAG_NONE,
177 &meta_desc, D3D12_RESOURCE_STATE_COMMON,
NULL,
200 ID3D12CommandAllocator *command_allocator =
NULL;
201 ID3D12VideoEncodeCommandList2 *cmd_list =
ctx->command_list;
202 D3D12_RESOURCE_BARRIER barriers[32] = { 0 };
203 D3D12_VIDEO_ENCODE_REFERENCE_FRAMES d3d12_refs = { 0 };
205 D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS input_args = {
206 .SequenceControlDesc = {
207 .Flags = D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_NONE,
208 .IntraRefreshConfig = { 0 },
209 .RateControl =
ctx->rc,
210 .PictureTargetResolution =
ctx->resolution,
211 .SelectedLayoutMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
212 .FrameSubregionsLayoutData = { 0 },
213 .CodecGopSequence =
ctx->gop,
216 .InputFrameSubresource = 0,
219 D3D12_VIDEO_ENCODER_ENCODEFRAME_OUTPUT_ARGUMENTS output_args = { 0 };
221 D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS input_metadata = {
222 .EncoderCodec =
ctx->codec->d3d12_codec,
223 .EncoderProfile =
ctx->profile->d3d12_profile,
224 .EncoderInputFormat = frames_hwctx->
format,
225 .EncodedPictureEffectiveResolution =
ctx->resolution,
228 D3D12_VIDEO_ENCODER_RESOLVE_METADATA_OUTPUT_ARGUMENTS output_metadata = { 0 };
290 if (
ctx->codec->init_picture_params) {
291 err =
ctx->codec->init_picture_params(avctx, pic);
294 "parameters: %d.\n", err);
300 if (
ctx->codec->write_sequence_header) {
301 bit_len = 8 *
sizeof(
data);
302 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
305 "header: %d.\n", err);
325 d3d12_refs.NumTexture2Ds = base_pic->
nb_refs[0] + base_pic->
nb_refs[1];
326 if (d3d12_refs.NumTexture2Ds) {
327 d3d12_refs.ppTexture2Ds =
av_calloc(d3d12_refs.NumTexture2Ds,
328 sizeof(*d3d12_refs.ppTexture2Ds));
329 if (!d3d12_refs.ppTexture2Ds) {
335 for (j = 0; j < base_pic->
nb_refs[0]; j++)
337 for (j = 0; j < base_pic->
nb_refs[1]; j++)
341 input_args.PictureControlDesc.IntraRefreshFrameIndex = 0;
343 input_args.PictureControlDesc.Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_USED_AS_REFERENCE_PICTURE;
345 input_args.PictureControlDesc.PictureControlCodecData = pic->
pic_ctl;
346 input_args.PictureControlDesc.ReferenceFrames = d3d12_refs;
347 input_args.CurrentFrameBitstreamMetadataSize = pic->
header_size;
350 output_args.Bitstream.FrameStartOffset = pic->
header_size;
352 output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
354 output_args.EncoderOutputMetadata.Offset = 0;
357 input_metadata.HWLayoutMetadata.Offset = 0;
360 output_metadata.ResolvedLayoutMetadata.Offset = 0;
366 hr = ID3D12CommandAllocator_Reset(command_allocator);
372 hr = ID3D12VideoEncodeCommandList2_Reset(cmd_list, command_allocator);
378 #define TRANSITION_BARRIER(res, before, after) \
379 (D3D12_RESOURCE_BARRIER) { \
380 .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, \
381 .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, \
384 .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, \
385 .StateBefore = before, \
386 .StateAfter = after, \
391 D3D12_RESOURCE_STATE_COMMON,
392 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
394 D3D12_RESOURCE_STATE_COMMON,
395 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
397 D3D12_RESOURCE_STATE_COMMON,
398 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
400 D3D12_RESOURCE_STATE_COMMON,
401 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
403 D3D12_RESOURCE_STATE_COMMON,
404 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
406 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 5, barriers);
408 if (d3d12_refs.NumTexture2Ds) {
409 D3D12_RESOURCE_BARRIER refs_barriers[3];
411 for (
i = 0;
i < d3d12_refs.NumTexture2Ds;
i++)
413 D3D12_RESOURCE_STATE_COMMON,
414 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
416 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, d3d12_refs.NumTexture2Ds,
420 ID3D12VideoEncodeCommandList2_EncodeFrame(cmd_list,
ctx->encoder,
ctx->encoder_heap,
421 &input_args, &output_args);
424 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
425 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
427 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 1, &barriers[3]);
429 ID3D12VideoEncodeCommandList2_ResolveEncoderOutputMetadata(cmd_list, &input_metadata, &output_metadata);
431 if (d3d12_refs.NumTexture2Ds) {
432 D3D12_RESOURCE_BARRIER refs_barriers[3];
434 for (
i = 0;
i < d3d12_refs.NumTexture2Ds;
i++)
436 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
437 D3D12_RESOURCE_STATE_COMMON);
439 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, d3d12_refs.NumTexture2Ds,
444 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
445 D3D12_RESOURCE_STATE_COMMON);
447 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
448 D3D12_RESOURCE_STATE_COMMON);
450 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
451 D3D12_RESOURCE_STATE_COMMON);
453 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
454 D3D12_RESOURCE_STATE_COMMON);
456 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
457 D3D12_RESOURCE_STATE_COMMON);
459 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 5, barriers);
461 hr = ID3D12VideoEncodeCommandList2_Close(cmd_list);
474 ID3D12CommandQueue_ExecuteCommandLists(
ctx->command_queue, 1, (ID3D12CommandList **)&
ctx->command_list);
483 hr = ID3D12CommandQueue_Signal(
ctx->command_queue,
ctx->sync_ctx.fence, ++
ctx->sync_ctx.fence_value);
495 if (d3d12_refs.ppTexture2Ds)
501 if (command_allocator)
504 if (d3d12_refs.ppTexture2Ds)
507 if (
ctx->codec->free_picture_params)
508 ctx->codec->free_picture_params(pic);
525 "%"PRId64
"/%"PRId64
".\n",
542 switch (
ctx->rc.Mode)
544 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP:
545 av_freep(&
ctx->rc.ConfigParams.pConfiguration_CQP);
547 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR:
548 av_freep(&
ctx->rc.ConfigParams.pConfiguration_CBR);
550 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR:
551 av_freep(&
ctx->rc.ConfigParams.pConfiguration_VBR);
553 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR:
554 av_freep(&
ctx->rc.ConfigParams.pConfiguration_QVBR);
573 if (
ctx->codec->picture_priv_data_size > 0) {
595 if (
ctx->codec->free_picture_params)
596 ctx->codec->free_picture_params(pic);
608 D3D12_VIDEO_ENCODER_OUTPUT_METADATA *meta =
NULL;
619 meta = (D3D12_VIDEO_ENCODER_OUTPUT_METADATA *)
data;
621 if (meta->EncodeErrorFlags != D3D12_VIDEO_ENCODER_ENCODE_ERROR_FLAG_NO_ERROR) {
627 if (meta->EncodedBitstreamWrittenBytesCount == 0) {
633 *
size = meta->EncodedBitstreamWrittenBytesCount;
644 uint8_t *ptr, *mapped_data;
645 size_t total_size = 0;
666 memcpy(ptr, mapped_data, total_size);
716 depth =
desc->comp[0].depth;
717 for (
i = 1;
i <
desc->nb_components;
i++) {
718 if (
desc->comp[
i].depth != depth) {
728 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
734 if (
desc->nb_components > 1 &&
758 {
RC_MODE_CQP,
"CQP", 0, 0, 1, 0, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP },
759 {
RC_MODE_CBR,
"CBR", 1, 0, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR },
760 {
RC_MODE_VBR,
"VBR", 1, 1, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR },
761 {
RC_MODE_QVBR,
"QVBR", 1, 1, 1, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR },
768 D3D12_FEATURE_DATA_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_rc_mode = {
769 .Codec =
ctx->codec->d3d12_codec,
775 d3d12_rc_mode.IsSupported = 0;
776 d3d12_rc_mode.RateControlMode =
rc_mode->d3d12_mode;
778 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
779 D3D12_FEATURE_VIDEO_ENCODER_RATE_CONTROL_MODE,
780 &d3d12_rc_mode,
sizeof(d3d12_rc_mode));
786 return d3d12_rc_mode.IsSupported;
792 int64_t rc_target_bitrate;
793 int64_t rc_peak_bitrate;
795 int64_t hrd_buffer_size;
796 int64_t hrd_initial_buffer_fullness;
812 #define TRY_RC_MODE(mode, fail) do { \
813 rc_mode = &d3d12va_encode_rc_modes[mode]; \
814 if (!(rc_mode->d3d12_mode && check_rate_control_support(avctx, rc_mode))) { \
816 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
817 "RC mode.\n", rc_mode->name); \
818 return AVERROR(EINVAL); \
820 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
821 "RC mode.\n", rc_mode->name); \
824 goto rc_mode_found; \
828 if (
ctx->explicit_rc_mode)
831 if (
ctx->explicit_qp)
858 "RC mode compatible with selected options.\n");
873 "bitrate (%"PRId64
") must not be greater than "
874 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
878 rc_target_bitrate = avctx->
bit_rate;
885 rc_target_bitrate = avctx->
bit_rate;
886 rc_peak_bitrate = 2 * avctx->
bit_rate;
891 "in %s RC mode.\n",
rc_mode->name);
893 rc_target_bitrate = avctx->
bit_rate;
897 rc_target_bitrate = 0;
902 if (
ctx->explicit_qp) {
903 rc_quality =
ctx->explicit_qp;
910 rc_quality =
ctx->codec->default_quality;
912 "using default (%d).\n", rc_quality);
928 "must have initial buffer size (%d) <= "
929 "buffer size (%"PRId64
").\n",
935 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
940 "in %s RC mode.\n",
rc_mode->name);
944 hrd_initial_buffer_fullness = 0;
947 if (rc_target_bitrate > UINT32_MAX ||
948 hrd_buffer_size > UINT32_MAX ||
949 hrd_initial_buffer_fullness > UINT32_MAX) {
951 "greater are not supported by D3D12.\n");
955 ctx->rc_quality = rc_quality;
964 "initial fullness %"PRId64
" bits.\n",
965 hrd_buffer_size, hrd_initial_buffer_fullness);
976 fr_num, fr_den, (
double)fr_num / fr_den);
978 ctx->rc.Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
979 ctx->rc.TargetFrameRate.Numerator = fr_num;
980 ctx->rc.TargetFrameRate.Denominator = fr_den;
989 D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR *cbr_ctl;
991 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR);
996 cbr_ctl->TargetBitRate = rc_target_bitrate;
997 cbr_ctl->VBVCapacity = hrd_buffer_size;
998 cbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
999 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1001 if (avctx->
qmin > 0 || avctx->
qmax > 0) {
1002 cbr_ctl->MinQP = avctx->
qmin;
1003 cbr_ctl->MaxQP = avctx->
qmax;
1004 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1007 ctx->rc.ConfigParams.pConfiguration_CBR = cbr_ctl;
1011 D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR *vbr_ctl;
1013 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR);
1018 vbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1019 vbr_ctl->PeakBitRate = rc_peak_bitrate;
1020 vbr_ctl->VBVCapacity = hrd_buffer_size;
1021 vbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
1022 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1024 if (avctx->
qmin > 0 || avctx->
qmax > 0) {
1025 vbr_ctl->MinQP = avctx->
qmin;
1026 vbr_ctl->MaxQP = avctx->
qmax;
1027 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1030 ctx->rc.ConfigParams.pConfiguration_VBR = vbr_ctl;
1034 D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR *qvbr_ctl;
1036 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR);
1041 qvbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1042 qvbr_ctl->PeakBitRate = rc_peak_bitrate;
1043 qvbr_ctl->ConstantQualityTarget = rc_quality;
1045 if (avctx->
qmin > 0 || avctx->
qmax > 0) {
1046 qvbr_ctl->MinQP = avctx->
qmin;
1047 qvbr_ctl->MaxQP = avctx->
qmax;
1048 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1051 ctx->rc.ConfigParams.pConfiguration_QVBR = qvbr_ctl;
1064 uint32_t ref_l0, ref_l1;
1067 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT support;
1069 D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_H264 h264;
1070 D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_HEVC hevc;
1073 support.NodeIndex = 0;
1074 support.Codec =
ctx->codec->d3d12_codec;
1075 support.Profile =
ctx->profile->d3d12_profile;
1077 switch (
ctx->codec->d3d12_codec) {
1078 case D3D12_VIDEO_ENCODER_CODEC_H264:
1079 support.PictureSupport.DataSize =
sizeof(codec_support.h264);
1080 support.PictureSupport.pH264Support = &codec_support.h264;
1083 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1084 support.PictureSupport.DataSize =
sizeof(codec_support.hevc);
1085 support.PictureSupport.pHEVCSupport = &codec_support.hevc;
1092 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT,
1093 &support,
sizeof(support));
1097 if (support.IsSupported) {
1098 switch (
ctx->codec->d3d12_codec) {
1099 case D3D12_VIDEO_ENCODER_CODEC_H264:
1100 ref_l0 =
FFMIN(support.PictureSupport.pH264Support->MaxL0ReferencesForP,
1101 support.PictureSupport.pH264Support->MaxL1ReferencesForB);
1102 ref_l1 = support.PictureSupport.pH264Support->MaxL1ReferencesForB;
1105 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1106 ref_l0 =
FFMIN(support.PictureSupport.pHEVCSupport->MaxL0ReferencesForP,
1107 support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB);
1108 ref_l1 = support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB;
1115 ref_l0 = ref_l1 = 0;
1118 if (ref_l0 > 0 && ref_l1 > 0 &&
ctx->bi_not_empty) {
1121 "replacing them with B-frames.\n");
1138 D3D12_VIDEO_ENCODER_DESC
desc = {
1140 .Flags = D3D12_VIDEO_ENCODER_FLAG_NONE,
1141 .EncodeCodec =
ctx->codec->d3d12_codec,
1142 .EncodeProfile =
ctx->profile->d3d12_profile,
1143 .InputFormat = frames_hwctx->
format,
1144 .CodecConfiguration =
ctx->codec_conf,
1145 .MaxMotionEstimationPrecision = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM,
1148 hr = ID3D12VideoDevice3_CreateVideoEncoder(
ctx->video_device3, &
desc, &IID_ID3D12VideoEncoder,
1149 (
void **)&
ctx->encoder);
1163 D3D12_VIDEO_ENCODER_HEAP_DESC
desc = {
1165 .Flags = D3D12_VIDEO_ENCODER_FLAG_NONE,
1166 .EncodeCodec =
ctx->codec->d3d12_codec,
1167 .EncodeProfile =
ctx->profile->d3d12_profile,
1168 .EncodeLevel =
ctx->level,
1169 .ResolutionsListCount = 1,
1170 .pResolutionList = &
ctx->resolution,
1173 hr = ID3D12VideoDevice3_CreateVideoEncoderHeap(
ctx->video_device3, &
desc,
1174 &IID_ID3D12VideoEncoderHeap, (
void **)&
ctx->encoder_heap);
1185 ID3D12Resource *pResource;
1187 pResource = (ID3D12Resource *)
data;
1196 ID3D12Resource *pResource =
NULL;
1199 D3D12_HEAP_PROPERTIES heap_props;
1200 D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_READBACK;
1202 D3D12_RESOURCE_DESC
desc = {
1203 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
1206 D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT),
1208 .DepthOrArraySize = 1,
1210 .Format = DXGI_FORMAT_UNKNOWN,
1211 .SampleDesc = { .Count = 1, .Quality = 0 },
1212 .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
1213 .Flags = D3D12_RESOURCE_FLAG_NONE,
1216 ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(
ctx->hwctx->device, &heap_props, 0, heap_type);
1218 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &heap_props, D3D12_HEAP_FLAG_NONE,
1219 &
desc, D3D12_RESOURCE_STATE_COMMON,
NULL, &IID_ID3D12Resource,
1220 (
void **)&pResource);
1246 ctx->req.NodeIndex = 0;
1247 ctx->req.Codec =
ctx->codec->d3d12_codec;
1248 ctx->req.Profile =
ctx->profile->d3d12_profile;
1249 ctx->req.InputFormat = frames_ctx->
format;
1250 ctx->req.PictureTargetResolution =
ctx->resolution;
1252 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
1253 D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS,
1254 &
ctx->req,
sizeof(
ctx->req));
1256 av_log(avctx,
AV_LOG_ERROR,
"Failed to check encoder resource requirements support.\n");
1260 if (!
ctx->req.IsSupported) {
1267 if (!
ctx->output_buffer_pool)
1276 ID3D12CommandAllocator *command_allocator =
NULL;
1280 D3D12_COMMAND_QUEUE_DESC queue_desc = {
1281 .Type = D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
1283 .Flags = D3D12_COMMAND_QUEUE_FLAG_NONE,
1289 if (!
ctx->allocator_queue)
1292 hr = ID3D12Device_CreateFence(
ctx->hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
1293 &IID_ID3D12Fence, (
void **)&
ctx->sync_ctx.fence);
1300 ctx->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE,
NULL);
1301 if (!
ctx->sync_ctx.event)
1308 hr = ID3D12Device_CreateCommandQueue(
ctx->hwctx->device, &queue_desc,
1309 &IID_ID3D12CommandQueue, (
void **)&
ctx->command_queue);
1316 hr = ID3D12Device_CreateCommandList(
ctx->hwctx->device, 0, queue_desc.Type,
1317 command_allocator,
NULL, &IID_ID3D12CommandList,
1318 (
void **)&
ctx->command_list);
1325 hr = ID3D12VideoEncodeCommandList2_Close(
ctx->command_list);
1332 ID3D12CommandQueue_ExecuteCommandLists(
ctx->command_queue, 1, (ID3D12CommandList **)&
ctx->command_list);
1372 hwctx->
flags = D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY |
1373 D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
1378 "frame context: %d.\n", err);
1404 D3D12_FEATURE_DATA_VIDEO_FEATURE_AREA_SUPPORT support = { 0 };
1419 hr = ID3D12Device_QueryInterface(
ctx->hwctx->device, &IID_ID3D12Device3, (
void **)&
ctx->device3);
1426 hr = ID3D12Device3_QueryInterface(
ctx->device3, &IID_ID3D12VideoDevice3, (
void **)&
ctx->video_device3);
1433 if (FAILED(ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_FEATURE_AREA_SUPPORT,
1434 &support,
sizeof(support))) && !support.VideoEncodeSupport) {
1448 if (
ctx->codec->get_encoder_caps) {
1449 err =
ctx->codec->get_encoder_caps(avctx);
1460 "but this codec does not support controlling slices.\n");
1475 if (
ctx->codec->configure) {
1476 err =
ctx->codec->configure(avctx);
1481 if (
ctx->codec->init_sequence_params) {
1482 err =
ctx->codec->init_sequence_params(avctx);
1485 "failed: %d.\n", err);
1490 if (
ctx->codec->set_level) {
1491 err =
ctx->codec->set_level(avctx);
1521 int num_allocator = 0;
1527 if (!base_ctx->
frame)
1530 for (pic = base_ctx->
pic_start; pic; pic = next) {
1542 if (
ctx->allocator_queue) {
1548 av_log(avctx,
AV_LOG_VERBOSE,
"Total number of command allocators reused: %d\n", num_allocator);
1554 if (
ctx->sync_ctx.event)
1555 CloseHandle(
ctx->sync_ctx.event);