32#include "config_components.h"
43 D3D12_VIDEO_ENCODER_VALIDATION_FLAGS
flags)
45 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_CODEC_NOT_SUPPORTED)
47 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_INPUT_FORMAT_NOT_SUPPORTED)
49 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_CODEC_CONFIGURATION_NOT_SUPPORTED)
51 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_RATE_CONTROL_MODE_NOT_SUPPORTED)
53 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_RATE_CONTROL_CONFIGURATION_NOT_SUPPORTED)
55 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_INTRA_REFRESH_MODE_NOT_SUPPORTED)
57 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_SUBREGION_LAYOUT_MODE_NOT_SUPPORTED)
59 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_RESOLUTION_NOT_SUPPORTED_IN_LIST)
61 if (
flags & D3D12_VIDEO_ENCODER_VALIDATION_FLAG_GOP_STRUCTURE_NOT_SUPPORTED)
67 uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->
fence);
68 if (completion < psync_ctx->fence_value) {
69 if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->
fence, psync_ctx->
fence_value, psync_ctx->
event)))
72 WaitForSingleObjectEx(psync_ctx->
event, INFINITE, FALSE);
82 DX_CHECK(ID3D12CommandQueue_Signal(
ctx->command_queue,
ctx->sync_ctx.fence, ++
ctx->sync_ctx.fence_value));
101 uint64_t completion = ID3D12Fence_GetCompletedValue(
ctx->sync_ctx.fence);
109 hr = ID3D12Device_CreateCommandAllocator(
ctx->hwctx->device, D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
110 &IID_ID3D12CommandAllocator, (
void **)ppAllocator);
124 .command_allocator = pAllocator,
125 .fence_value = fence_value,
147 completion = ID3D12Fence_GetCompletedValue(
ctx->sync_ctx.fence);
148 if (completion < pic->fence_value) {
149 if (FAILED(ID3D12Fence_SetEventOnCompletion(
ctx->sync_ctx.fence, pic->
fence_value,
150 ctx->sync_ctx.event)))
153 WaitForSingleObjectEx(
ctx->sync_ctx.event, INFINITE, FALSE);
174 int block_width, block_height;
175 int block_size, qp_range;
179 block_size =
ctx->qp_map_region_size;
182 switch (
ctx->codec->d3d12_codec) {
183 case D3D12_VIDEO_ENCODER_CODEC_H264:
184 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
188#if CONFIG_AV1_D3D12VA_ENCODER
189 case D3D12_VIDEO_ENCODER_CODEC_AV1:
200 block_width = (avctx->
width + block_size - 1) / block_size;
201 block_height = (avctx->
height + block_size - 1) / block_size;
216 nb_roi =
size / roi_size;
219 for (
i = nb_roi - 1;
i >= 0;
i--) {
220 int startx, endx, starty, endy;
227 starty =
FFMIN(block_height, roi->
top / block_size);
228 endy =
FFMIN(block_height, (roi->
bottom + block_size - 1) / block_size);
229 startx =
FFMIN(block_width, roi->
left / block_size);
230 endx =
FFMIN(block_width, (roi->
right + block_size - 1) / block_size);
246 int16_t *qp_map_int16 = (int16_t *)pic->
qp_map;
248 for (y = starty; y < endy; y++)
249 for (x = startx; x < endx; x++)
250 qp_map_int16[x + y * block_width] = delta_qp;
252 int8_t *qp_map_int8 = (int8_t *)pic->
qp_map;
254 for (y = starty; y < endy; y++)
255 for (x = startx; x < endx; x++)
256 qp_map_int8[x + y * block_width] = delta_qp;
269 int num_subregions =
ctx->num_subregions > 0 ?
ctx->num_subregions : 1;
270 int width =
sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) +
271 sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA) * num_subregions;
272#if CONFIG_AV1_D3D12VA_ENCODER
273 if (
ctx->codec->d3d12_codec == D3D12_VIDEO_ENCODER_CODEC_AV1) {
274 width +=
sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES)
275 +
sizeof(D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES);
278 D3D12_HEAP_PROPERTIES encoded_meta_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }, resolved_meta_props;
279 D3D12_HEAP_TYPE resolved_heap_type = D3D12_HEAP_TYPE_READBACK;
282 D3D12_RESOURCE_DESC meta_desc = {
283 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
285 .Width =
ctx->req.MaxEncoderOutputMetadataBufferSize,
287 .DepthOrArraySize = 1,
289 .Format = DXGI_FORMAT_UNKNOWN,
290 .SampleDesc = { .Count = 1, .Quality = 0 },
291 .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
292 .Flags = D3D12_RESOURCE_FLAG_NONE,
295 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &encoded_meta_props, D3D12_HEAP_FLAG_NONE,
296 &meta_desc, D3D12_RESOURCE_STATE_COMMON,
NULL,
303 ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(
ctx->hwctx->device, &resolved_meta_props, 0, resolved_heap_type);
305 meta_desc.Width =
width;
307 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &resolved_meta_props, D3D12_HEAP_FLAG_NONE,
308 &meta_desc, D3D12_RESOURCE_STATE_COMMON,
NULL,
331 ID3D12CommandAllocator *command_allocator =
NULL;
332 ID3D12VideoEncodeCommandList2 *cmd_list =
ctx->command_list;
333 D3D12_RESOURCE_BARRIER barriers[32] = { 0 };
334 D3D12_VIDEO_ENCODE_REFERENCE_FRAMES d3d12_refs = { 0 };
335 int barriers_ref_index = 0;
336 D3D12_RESOURCE_BARRIER *barriers_ref =
NULL;
338 D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS seq_flags = D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_NONE;
341 if (
ctx->intra_refresh.Mode != D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE) {
342 seq_flags |= D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_REQUEST_INTRA_REFRESH;
345 D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS input_args = {
346 .SequenceControlDesc = {
348 .IntraRefreshConfig =
ctx->intra_refresh,
349 .RateControl =
ctx->rc,
350 .PictureTargetResolution =
ctx->resolution,
351 .SelectedLayoutMode =
ctx->subregion_mode,
352 .FrameSubregionsLayoutData =
ctx->subregions_layout,
353 .CodecGopSequence =
ctx->gop,
356 .InputFrameSubresource = 0,
359 D3D12_VIDEO_ENCODER_ENCODEFRAME_OUTPUT_ARGUMENTS output_args = { 0 };
361 D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS input_metadata = {
362 .EncoderCodec =
ctx->codec->d3d12_codec,
363 .EncoderProfile =
ctx->profile->d3d12_profile,
364 .EncoderInputFormat = frames_hwctx->
format,
365 .EncodedPictureEffectiveResolution =
ctx->resolution,
368 D3D12_VIDEO_ENCODER_RESOLVE_METADATA_OUTPUT_ARGUMENTS output_metadata = { 0 };
435 input_args.SequenceControlDesc.RateControl.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
436 av_log(avctx,
AV_LOG_DEBUG,
"ROI delta QP map created with %d blocks (region size: %d pixels).\n",
440 if (
ctx->codec->init_picture_params) {
441 err =
ctx->codec->init_picture_params(avctx, base_pic);
444 "parameters: %d.\n", err);
450 if (
ctx->codec->write_sequence_header) {
451 bit_len = 8 *
sizeof(
data);
452 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
455 "header: %d.\n", err);
474 d3d12_refs.NumTexture2Ds = base_pic->
nb_refs[0] + base_pic->
nb_refs[1];
475 if (d3d12_refs.NumTexture2Ds) {
476 d3d12_refs.ppTexture2Ds =
av_calloc(d3d12_refs.NumTexture2Ds,
477 sizeof(*d3d12_refs.ppTexture2Ds));
478 if (!d3d12_refs.ppTexture2Ds) {
483 if (
ctx->is_texture_array) {
484 d3d12_refs.pSubresources =
av_calloc(d3d12_refs.NumTexture2Ds,
485 sizeof(*d3d12_refs.pSubresources));
486 if (!d3d12_refs.pSubresources) {
493 for (j = 0; j < base_pic->
nb_refs[0]; j++) {
495 if (
ctx->is_texture_array)
499 for (j = 0; j < base_pic->
nb_refs[1]; j++) {
501 if (
ctx->is_texture_array)
507 input_args.PictureControlDesc.IntraRefreshFrameIndex =
ctx->intra_refresh_frame_index;
509 input_args.PictureControlDesc.Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_USED_AS_REFERENCE_PICTURE;
511 input_args.PictureControlDesc.PictureControlCodecData = pic->
pic_ctl;
512 input_args.PictureControlDesc.ReferenceFrames = d3d12_refs;
518 output_args.ReconstructedPicture.ReconstructedPictureSubresource =
ctx->is_texture_array ? pic->
subresource_index : 0;
520 output_args.EncoderOutputMetadata.Offset = 0;
523 input_metadata.HWLayoutMetadata.Offset = 0;
526 output_metadata.ResolvedLayoutMetadata.Offset = 0;
532 hr = ID3D12CommandAllocator_Reset(command_allocator);
538 hr = ID3D12VideoEncodeCommandList2_Reset(cmd_list, command_allocator);
544#define TRANSITION_BARRIER(res, subres, before, after) \
545 (D3D12_RESOURCE_BARRIER) { \
546 .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, \
547 .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, \
550 .Subresource = subres, \
551 .StateBefore = before, \
552 .StateAfter = after, \
557 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
558 D3D12_RESOURCE_STATE_COMMON,
559 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
561 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
562 D3D12_RESOURCE_STATE_COMMON,
563 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
565 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
566 D3D12_RESOURCE_STATE_COMMON,
567 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
569 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
570 D3D12_RESOURCE_STATE_COMMON,
571 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
573 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, barriers);
575 if (
ctx->is_texture_array)
577 sizeof(D3D12_RESOURCE_BARRIER));
581 if (
ctx->is_texture_array) {
582 D3D12_RESOURCE_DESC references_tex_array_desc = { 0 };
585 for (uint32_t reference_subresource = 0; reference_subresource < references_tex_array_desc.DepthOrArraySize;
586 reference_subresource++) {
588 uint32_t array_size = references_tex_array_desc.DepthOrArraySize;
589 uint32_t mip_slice = reference_subresource % references_tex_array_desc.MipLevels;
590 uint32_t array_slice = (reference_subresource / references_tex_array_desc.MipLevels) % array_size;
592 for (uint32_t plane_slice = 0; plane_slice <
ctx->plane_count; plane_slice++) {
593 uint32_t outputSubresource = mip_slice + array_slice * references_tex_array_desc.MipLevels +
594 plane_slice * references_tex_array_desc.MipLevels * array_size;
597 D3D12_RESOURCE_STATE_COMMON,
598 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
601 D3D12_RESOURCE_STATE_COMMON,
602 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
608 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
609 D3D12_RESOURCE_STATE_COMMON,
610 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
612 if (d3d12_refs.NumTexture2Ds) {
613 for (
i = 0;
i < d3d12_refs.NumTexture2Ds;
i++)
615 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
616 D3D12_RESOURCE_STATE_COMMON,
617 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
620 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, barriers_ref_index, barriers_ref);
622 ID3D12VideoEncodeCommandList2_EncodeFrame(cmd_list,
ctx->encoder,
ctx->encoder_heap,
623 &input_args, &output_args);
626 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
627 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
628 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
630 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 1, &barriers[3]);
632 ID3D12VideoEncodeCommandList2_ResolveEncoderOutputMetadata(cmd_list, &input_metadata, &output_metadata);
634 if (barriers_ref_index > 0) {
635 for (
i = 0;
i < barriers_ref_index;
i++)
636 FFSWAP(D3D12_RESOURCE_STATES, barriers_ref[
i].Transition.StateBefore, barriers_ref[
i].Transition.StateAfter);
638 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, barriers_ref_index,
643 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
644 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
645 D3D12_RESOURCE_STATE_COMMON);
647 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
648 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
649 D3D12_RESOURCE_STATE_COMMON);
651 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
652 D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
653 D3D12_RESOURCE_STATE_COMMON);
655 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
656 D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
657 D3D12_RESOURCE_STATE_COMMON);
659 ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, barriers);
661 hr = ID3D12VideoEncodeCommandList2_Close(cmd_list);
674 ID3D12CommandQueue_ExecuteCommandLists(
ctx->command_queue, 1, (ID3D12CommandList **)&
ctx->command_list);
683 hr = ID3D12CommandQueue_Signal(
ctx->command_queue,
ctx->sync_ctx.fence, ++
ctx->sync_ctx.fence_value);
696 if (
ctx->intra_refresh.Mode != D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE) {
697 ctx->intra_refresh_frame_index =
698 (
ctx->intra_refresh_frame_index + 1) %
ctx->intra_refresh.IntraRefreshDuration;
701 if (d3d12_refs.ppTexture2Ds)
704 if (
ctx->is_texture_array && d3d12_refs.pSubresources)
705 av_freep(&d3d12_refs.pSubresources);
713 if (command_allocator)
716 if (d3d12_refs.ppTexture2Ds)
719 if (
ctx->is_texture_array && d3d12_refs.pSubresources)
720 av_freep(&d3d12_refs.pSubresources);
725 if (
ctx->codec->free_picture_params)
726 ctx->codec->free_picture_params(pic);
744 "%"PRId64
"/%"PRId64
".\n",
761 switch (
ctx->rc.Mode)
763 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP:
764 av_freep(&
ctx->rc.ConfigParams.pConfiguration_CQP);
766 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR:
767 av_freep(&
ctx->rc.ConfigParams.pConfiguration_CBR);
769 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR:
770 av_freep(&
ctx->rc.ConfigParams.pConfiguration_VBR);
772 case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR:
773 av_freep(&
ctx->rc.ConfigParams.pConfiguration_QVBR);
788 if (
ctx->codec->picture_priv_data_size > 0) {
807 if (
ctx->codec->free_picture_params)
808 ctx->codec->free_picture_params(priv);
819 D3D12_VIDEO_ENCODER_OUTPUT_METADATA *meta =
NULL;
830 meta = (D3D12_VIDEO_ENCODER_OUTPUT_METADATA *)
data;
832 if (meta->EncodeErrorFlags != D3D12_VIDEO_ENCODER_ENCODE_ERROR_FLAG_NO_ERROR) {
838 if (meta->EncodedBitstreamWrittenBytesCount == 0) {
844 *
size = meta->EncodedBitstreamWrittenBytesCount;
855 uint8_t *ptr, *mapped_data;
856 size_t total_size = 0;
883 memcpy(ptr, mapped_data, total_size);
906 if (
ctx->codec->get_coded_data)
907 err =
ctx->codec->get_coded_data(avctx, pic,
pkt);
956 depth =
desc->comp[0].depth;
957 for (
i = 1;
i <
desc->nb_components;
i++) {
958 if (
desc->comp[
i].depth != depth) {
968 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
974 if (
desc->nb_components > 1 &&
998 {
RC_MODE_CQP,
"CQP", 0, 0, 1, 0, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP },
999 {
RC_MODE_CBR,
"CBR", 1, 0, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR },
1000 {
RC_MODE_VBR,
"VBR", 1, 1, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR },
1001 {
RC_MODE_QVBR,
"QVBR", 1, 1, 1, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR },
1008 D3D12_FEATURE_DATA_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_rc_mode = {
1009 .Codec =
ctx->codec->d3d12_codec,
1015 d3d12_rc_mode.IsSupported = 0;
1016 d3d12_rc_mode.RateControlMode =
rc_mode->d3d12_mode;
1018 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
1019 D3D12_FEATURE_VIDEO_ENCODER_RATE_CONTROL_MODE,
1020 &d3d12_rc_mode,
sizeof(d3d12_rc_mode));
1026 return d3d12_rc_mode.IsSupported;
1036 int64_t hrd_initial_buffer_fullness;
1040#define SET_QP_RANGE(ctl) do { \
1041 if (avctx->qmin > 0 || avctx->qmax > 0) { \
1042 ctl->MinQP = avctx->qmin; \
1043 ctl->MaxQP = avctx->qmax; \
1044 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE; \
1048#define SET_MAX_FRAME_SIZE(ctl) do { \
1049 if (ctx->max_frame_size > 0) { \
1050 ctl->MaxFrameBitSize = ctx->max_frame_size * 8; \
1051 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_MAX_FRAME_SIZE; \
1067#define TRY_RC_MODE(mode, fail) do { \
1068 rc_mode = &d3d12va_encode_rc_modes[mode]; \
1069 if (!(rc_mode->d3d12_mode && check_rate_control_support(avctx, rc_mode))) { \
1071 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1072 "RC mode.\n", rc_mode->name); \
1073 return AVERROR(EINVAL); \
1075 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1076 "RC mode.\n", rc_mode->name); \
1079 goto rc_mode_found; \
1083 if (
ctx->explicit_rc_mode)
1086 if (
ctx->explicit_qp)
1113 "RC mode compatible with selected options.\n");
1128 "bitrate (%"PRId64
") must not be greater than "
1129 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
1133 rc_target_bitrate = avctx->
bit_rate;
1140 rc_target_bitrate = avctx->
bit_rate;
1141 rc_peak_bitrate = 2 * avctx->
bit_rate;
1146 "in %s RC mode.\n",
rc_mode->name);
1148 rc_target_bitrate = avctx->
bit_rate;
1149 rc_peak_bitrate = 0;
1152 rc_target_bitrate = 0;
1153 rc_peak_bitrate = 0;
1157 if (
ctx->explicit_qp) {
1158 rc_quality =
ctx->explicit_qp;
1165 rc_quality =
ctx->codec->default_quality;
1167 "using default (%d).\n", rc_quality);
1183 "must have initial buffer size (%d) <= "
1184 "buffer size (%"PRId64
").\n",
1190 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1195 "in %s RC mode.\n",
rc_mode->name);
1198 hrd_buffer_size = 0;
1199 hrd_initial_buffer_fullness = 0;
1202 if (rc_target_bitrate > UINT32_MAX ||
1203 hrd_buffer_size > UINT32_MAX ||
1204 hrd_initial_buffer_fullness > UINT32_MAX) {
1206 "greater are not supported by D3D12.\n");
1210 ctx->rc_quality = rc_quality;
1219 "initial fullness %"PRId64
" bits.\n",
1220 hrd_buffer_size, hrd_initial_buffer_fullness);
1231 fr_num, fr_den, (
double)fr_num / fr_den);
1233 ctx->rc.Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
1234 ctx->rc.TargetFrameRate.Numerator = fr_num;
1235 ctx->rc.TargetFrameRate.Denominator = fr_den;
1243 D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR *cbr_ctl;
1245 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR);
1250 cbr_ctl->TargetBitRate = rc_target_bitrate;
1251 cbr_ctl->VBVCapacity = hrd_buffer_size;
1252 cbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
1253 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1258 ctx->rc.ConfigParams.pConfiguration_CBR = cbr_ctl;
1262 D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR *vbr_ctl;
1264 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR);
1269 vbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1270 vbr_ctl->PeakBitRate = rc_peak_bitrate;
1271 vbr_ctl->VBVCapacity = hrd_buffer_size;
1272 vbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
1273 ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1278 ctx->rc.ConfigParams.pConfiguration_VBR = vbr_ctl;
1282 D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR *qvbr_ctl;
1284 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR);
1289 qvbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1290 qvbr_ctl->PeakBitRate = rc_peak_bitrate;
1291 qvbr_ctl->ConstantQualityTarget = rc_quality;
1296 ctx->rc.ConfigParams.pConfiguration_QVBR = qvbr_ctl;
1309 uint32_t ref_l0, ref_l1;
1312 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT support;
1314 D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_H264 h264;
1315 D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_HEVC hevc;
1316#if CONFIG_AV1_D3D12VA_ENCODER
1317 D3D12_VIDEO_ENCODER_CODEC_AV1_PICTURE_CONTROL_SUPPORT av1;
1321 support.NodeIndex = 0;
1322 support.Codec =
ctx->codec->d3d12_codec;
1323 support.Profile =
ctx->profile->d3d12_profile;
1325 switch (
ctx->codec->d3d12_codec) {
1326 case D3D12_VIDEO_ENCODER_CODEC_H264:
1327 support.PictureSupport.DataSize =
sizeof(codec_support.h264);
1328 support.PictureSupport.pH264Support = &codec_support.h264;
1331 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1332 support.PictureSupport.DataSize =
sizeof(codec_support.hevc);
1333 support.PictureSupport.pHEVCSupport = &codec_support.hevc;
1336#if CONFIG_AV1_D3D12VA_ENCODER
1337 case D3D12_VIDEO_ENCODER_CODEC_AV1:
1338 memset(&codec_support.av1, 0,
sizeof(codec_support.av1));
1339 codec_support.av1.PredictionMode = D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE_SINGLE_REFERENCE;
1340 support.PictureSupport.DataSize =
sizeof(codec_support.av1);
1341 support.PictureSupport.pAV1Support = &codec_support.av1;
1348 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT,
1349 &support,
sizeof(support));
1353 if (support.IsSupported) {
1354 switch (
ctx->codec->d3d12_codec) {
1355 case D3D12_VIDEO_ENCODER_CODEC_H264:
1356 ref_l0 =
FFMIN(support.PictureSupport.pH264Support->MaxL0ReferencesForP,
1357 support.PictureSupport.pH264Support->MaxL1ReferencesForB ?
1358 support.PictureSupport.pH264Support->MaxL1ReferencesForB : UINT_MAX);
1359 ref_l1 = support.PictureSupport.pH264Support->MaxL1ReferencesForB;
1362 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1363 ref_l0 =
FFMIN(support.PictureSupport.pHEVCSupport->MaxL0ReferencesForP,
1364 support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB ?
1365 support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB : UINT_MAX);
1366 ref_l1 = support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB;
1369#if CONFIG_AV1_D3D12VA_ENCODER
1370 case D3D12_VIDEO_ENCODER_CODEC_AV1:
1371 ref_l0 = support.PictureSupport.pAV1Support->MaxUniqueReferencesPerFrame;
1372 memset(&codec_support.av1, 0,
sizeof(codec_support.av1));
1373 codec_support.av1.PredictionMode = D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE_COMPOUND_REFERENCE;
1374 support.PictureSupport.DataSize =
sizeof(codec_support.av1);
1375 support.PictureSupport.pAV1Support = &codec_support.av1;
1377 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
1378 D3D12_FEATURE_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT,
1379 &support,
sizeof(support));
1383 ref_l1 = support.IsSupported ? 1 : 0;
1390 ref_l0 = ref_l1 = 0;
1393 if (ref_l0 > 0 && ref_l1 > 0 &&
ctx->bi_not_empty) {
1396 "replacing them with B-frames.\n");
1411 if (
ctx->intra_refresh.Mode == D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE)
1415#if CONFIG_D3D12_INTRA_REFRESH
1417 D3D12_VIDEO_ENCODER_LEVEL_SETTING
level = { 0 };
1418 D3D12_VIDEO_ENCODER_LEVELS_H264 h264_level = { 0 };
1419 D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC hevc_level = { 0 };
1420#if CONFIG_AV1_D3D12VA_ENCODER
1421 D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS av1_level = { 0 };
1424 switch (
ctx->codec->d3d12_codec) {
1425 case D3D12_VIDEO_ENCODER_CODEC_H264:
1426 level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVELS_H264);
1427 level.pH264LevelSetting = &h264_level;
1429 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1430 level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC);
1431 level.pHEVCLevelSetting = &hevc_level;
1433#if CONFIG_AV1_D3D12VA_ENCODER
1434 case D3D12_VIDEO_ENCODER_CODEC_AV1:
1435 level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS);
1436 level.pAV1LevelSetting = &av1_level;
1443 D3D12_FEATURE_DATA_VIDEO_ENCODER_INTRA_REFRESH_MODE intra_refresh_support = {
1445 .Codec =
ctx->codec->d3d12_codec,
1446 .Profile =
ctx->profile->d3d12_profile,
1448 .IntraRefreshMode =
ctx->intra_refresh.Mode,
1451 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
1452 D3D12_FEATURE_VIDEO_ENCODER_INTRA_REFRESH_MODE,
1453 &intra_refresh_support,
sizeof(intra_refresh_support));
1455 if (FAILED(hr) || !intra_refresh_support.IsSupported) {
1456 av_log(avctx,
AV_LOG_ERROR,
"Requested intra refresh mode not supported by driver.\n");
1462 "Support will be validated during encoder initialization.\n");
1466 if (
ctx->intra_refresh.IntraRefreshDuration == 0) {
1467 ctx->intra_refresh.IntraRefreshDuration = base_ctx->
gop_size;
1469 ctx->intra_refresh.IntraRefreshDuration);
1473 ctx->intra_refresh_frame_index = 0;
1476 ctx->intra_refresh.Mode,
ctx->intra_refresh.IntraRefreshDuration);
1488 D3D12_VIDEO_ENCODER_DESC
desc = {
1490 .Flags = D3D12_VIDEO_ENCODER_FLAG_NONE,
1491 .EncodeCodec =
ctx->codec->d3d12_codec,
1492 .EncodeProfile =
ctx->profile->d3d12_profile,
1493 .InputFormat = frames_hwctx->
format,
1494 .CodecConfiguration =
ctx->codec_conf,
1495 .MaxMotionEstimationPrecision =
ctx->me_precision,
1498 hr = ID3D12VideoDevice3_CreateVideoEncoder(
ctx->video_device3, &
desc, &IID_ID3D12VideoEncoder,
1499 (
void **)&
ctx->encoder);
1513 D3D12_VIDEO_ENCODER_HEAP_DESC
desc = {
1515 .Flags = D3D12_VIDEO_ENCODER_HEAP_FLAG_NONE,
1516 .EncodeCodec =
ctx->codec->d3d12_codec,
1517 .EncodeProfile =
ctx->profile->d3d12_profile,
1518 .EncodeLevel =
ctx->level,
1519 .ResolutionsListCount = 1,
1520 .pResolutionList = &
ctx->resolution,
1523 hr = ID3D12VideoDevice3_CreateVideoEncoderHeap(
ctx->video_device3, &
desc,
1524 &IID_ID3D12VideoEncoderHeap, (
void **)&
ctx->encoder_heap);
1535 ID3D12Resource *pResource;
1537 pResource = (ID3D12Resource *)
data;
1546 ID3D12Resource *pResource =
NULL;
1549 D3D12_HEAP_PROPERTIES heap_props;
1550 D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_READBACK;
1552 D3D12_RESOURCE_DESC
desc = {
1553 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
1556 D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT),
1558 .DepthOrArraySize = 1,
1560 .Format = DXGI_FORMAT_UNKNOWN,
1561 .SampleDesc = { .Count = 1, .Quality = 0 },
1562 .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
1563 .Flags = D3D12_RESOURCE_FLAG_NONE,
1566 ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(
ctx->hwctx->device, &heap_props, 0, heap_type);
1568 hr = ID3D12Device_CreateCommittedResource(
ctx->hwctx->device, &heap_props, D3D12_HEAP_FLAG_NONE,
1569 &
desc, D3D12_RESOURCE_STATE_COMMON,
NULL, &IID_ID3D12Resource,
1570 (
void **)&pResource);
1596 ctx->req.NodeIndex = 0;
1597 ctx->req.Codec =
ctx->codec->d3d12_codec;
1598 ctx->req.Profile =
ctx->profile->d3d12_profile;
1599 ctx->req.InputFormat = frames_ctx->
format;
1600 ctx->req.PictureTargetResolution =
ctx->resolution;
1602 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3,
1603 D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS,
1604 &
ctx->req,
sizeof(
ctx->req));
1606 av_log(avctx,
AV_LOG_ERROR,
"Failed to check encoder resource requirements support.\n");
1610 if (!
ctx->req.IsSupported) {
1617 if (!
ctx->output_buffer_pool)
1626 ID3D12CommandAllocator *command_allocator =
NULL;
1630 D3D12_COMMAND_QUEUE_DESC queue_desc = {
1631 .Type = D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
1633 .Flags = D3D12_COMMAND_QUEUE_FLAG_NONE,
1639 if (!
ctx->allocator_queue)
1642 hr = ID3D12Device_CreateFence(
ctx->hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
1643 &IID_ID3D12Fence, (
void **)&
ctx->sync_ctx.fence);
1650 ctx->sync_ctx.event = CreateEvent(
NULL, FALSE, FALSE,
NULL);
1651 if (!
ctx->sync_ctx.event)
1658 hr = ID3D12Device_CreateCommandQueue(
ctx->hwctx->device, &queue_desc,
1659 &IID_ID3D12CommandQueue, (
void **)&
ctx->command_queue);
1666 hr = ID3D12Device_CreateCommandList(
ctx->hwctx->device, 0, queue_desc.Type,
1667 command_allocator,
NULL, &IID_ID3D12CommandList,
1668 (
void **)&
ctx->command_list);
1675 hr = ID3D12VideoEncodeCommandList2_Close(
ctx->command_list);
1682 ID3D12CommandQueue_ExecuteCommandLists(
ctx->command_queue, 1, (ID3D12CommandList **)&
ctx->command_list);
1723 hwctx->
resource_flags = D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY |
1724 D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
1725 if (
ctx->is_texture_array) {
1733 "frame context: %d.\n", err);
1761 D3D12_FEATURE_DATA_VIDEO_FEATURE_AREA_SUPPORT support = { 0 };
1762 D3D12_FEATURE_DATA_FORMAT_INFO format_info = { 0 };
1777 hr = ID3D12Device_QueryInterface(
ctx->hwctx->device, &IID_ID3D12Device3, (
void **)&
ctx->device3);
1784 hr = ID3D12Device3_QueryInterface(
ctx->device3, &IID_ID3D12VideoDevice3, (
void **)&
ctx->video_device3);
1791 if (FAILED(ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_FEATURE_AREA_SUPPORT,
1792 &support,
sizeof(support))) && !support.VideoEncodeSupport) {
1799 if (FAILED(ID3D12VideoDevice_CheckFeatureSupport(
ctx->hwctx->device, D3D12_FEATURE_FORMAT_INFO,
1800 &format_info,
sizeof(format_info)))) {
1805 ctx->plane_count = format_info.PlaneCount;
1815 if (
ctx->codec->get_encoder_caps) {
1816 err =
ctx->codec->get_encoder_caps(avctx);
1821 if (
ctx->codec->set_tile) {
1822 err =
ctx->codec->set_tile(avctx);
1837 "but this codec does not support controlling slices.\n");
1848 if (
ctx->codec->configure) {
1849 err =
ctx->codec->configure(avctx);
1854 if (
ctx->codec->init_sequence_params) {
1855 err =
ctx->codec->init_sequence_params(avctx);
1858 "failed: %d.\n", err);
1863 if (
ctx->codec->set_level) {
1864 err =
ctx->codec->set_level(avctx);
1890 if (
ctx->codec->write_sequence_header &&
1893 size_t header_bit_len = 8 *
sizeof(header_data);
1895 err =
ctx->codec->write_sequence_header(avctx, header_data, &header_bit_len);
1898 "for global header: %d.\n", err);
1919 int num_allocator = 0;
1925 if (!base_ctx->
frame)
1928 for (pic = base_ctx->
pic_start; pic; pic = next) {
1940 if (
ctx->allocator_queue) {
1946 av_log(avctx,
AV_LOG_VERBOSE,
"Total number of command allocators reused: %d\n", num_allocator);
1952 if (
ctx->sync_ctx.event)
1953 CloseHandle(
ctx->sync_ctx.event);
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
common internal and external API header
static int d3d12va_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
#define TRY_RC_MODE(mode, fail)
int ff_d3d12va_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
static int d3d12va_discard_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator *pAllocator, uint64_t fence_value)
static int d3d12va_encode_prepare_output_buffers(AVCodecContext *avctx)
static const D3D12VAEncodeRCMode d3d12va_encode_rc_modes[]
static int d3d12va_fence_completion(AVD3D12VASyncContext *psync_ctx)
static int d3d12va_sync_with_gpu(AVCodecContext *avctx)
static int d3d12va_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
static int d3d12va_encode_free_rc_params(AVCodecContext *avctx)
static void d3d12va_encode_free_buffer(void *opaque, uint8_t *data)
static int d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
static int d3d12va_encode_init_rate_control(AVCodecContext *avctx)
static int d3d12va_get_valid_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator **ppAllocator)
void ff_d3d12va_encode_check_encoder_feature_flags(void *log_ctx, D3D12_VIDEO_ENCODER_VALIDATION_FLAGS flags)
#define TRANSITION_BARRIER(res, subres, before, after)
const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[]
static int d3d12va_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
static int check_rate_control_support(AVCodecContext *avctx, const D3D12VAEncodeRCMode *rc_mode)
static const FFHWEncodePictureOperation d3d12va_type
#define SET_MAX_FRAME_SIZE(ctl)
static int d3d12va_encode_discard(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
#define SET_QP_RANGE(ctl)
static int d3d12va_create_encoder_heap(AVCodecContext *avctx)
static int d3d12va_encode_get_coded_data(AVCodecContext *avctx, D3D12VAEncodePicture *pic, AVPacket *pkt)
int ff_d3d12va_encode_init(AVCodecContext *avctx)
static int d3d12va_encode_setup_roi(AVCodecContext *avctx, D3D12VAEncodePicture *pic, const uint8_t *data, size_t size)
static int d3d12va_encode_get_buffer_size(AVCodecContext *avctx, D3D12VAEncodePicture *pic, size_t *size)
int ff_d3d12va_encode_close(AVCodecContext *avctx)
static int d3d12va_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
static int d3d12va_encode_set_profile(AVCodecContext *avctx)
static int d3d12va_encode_create_metadata_buffers(AVCodecContext *avctx, D3D12VAEncodePicture *pic)
static int d3d12va_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
static int d3d12va_encode_create_recon_frames(AVCodecContext *avctx)
static int d3d12va_create_encoder(AVCodecContext *avctx)
static AVBufferRef * d3d12va_encode_alloc_output_buffer(void *opaque, size_t size)
static int d3d12va_encode_init_intra_refresh(AVCodecContext *avctx)
static int d3d12va_encode_create_command_objects(AVCodecContext *avctx)
#define D3D12VA_VIDEO_ENC_ASYNC_DEPTH
#define MAX_PARAM_BUFFER_SIZE
#define AV_PROFILE_UNKNOWN
int(* init)(AVBSFContext *ctx)
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
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.
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
int av_fifo_peek(const AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
@ AV_FRAME_DATA_REGIONS_OF_INTEREST
Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of array element is ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
int ff_hw_base_init_gop_structure(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1, int flags, int prediction_pre_only)
int ff_hw_base_get_recon_format(FFHWBaseEncodeContext *ctx, const void *hwconfig, enum AVPixelFormat *fmt)
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
@ FF_HW_FLAG_SLICE_CONTROL
@ FF_HW_FLAG_CONSTANT_QUALITY_ONLY
@ FF_HW_FLAG_TIMESTAMP_NO_DELAY
static const char * ff_hw_base_encode_get_pictype_name(const int type)
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
An API-specific header for AV_HWDEVICE_TYPE_D3D12VA.
@ AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY
Indicates that frame data should be allocated using a texture array resource.
#define D3D12_OBJECT_RELEASE(pInterface)
A release macro used by D3D12 objects highly frequently.
#define DX_CHECK(hr)
A check macro used by D3D12 functions highly frequently.
common internal API header
#define FFSWAP(type, a, b)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
A reference to a data buffer.
uint8_t * data
The data buffer.
main external API structure.
int width
picture width / height.
int rc_buffer_size
decoder bitstream buffer size
int global_quality
Global quality for codecs which cannot change it per frame.
int64_t bit_rate
the average bitrate
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
int64_t rc_max_rate
maximum bitrate
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
int flags
AV_CODEC_FLAG_*.
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
int slices
Number of slices.
D3D12VA frame descriptor for pool allocation.
ID3D12Resource * texture
The texture in which the frame is located.
AVD3D12VASyncContext sync_ctx
The sync context for the texture.
int subresource_index
Index of the subresource within the texture.
This struct is allocated as AVHWFramesContext.hwctx.
D3D12_RESOURCE_FLAGS resource_flags
Options for working with resources.
AVD3D12VAFrameFlags flags
A combination of AVD3D12VAFrameFlags.
DXGI_FORMAT format
DXGI_FORMAT format.
This struct is used to sync d3d12 execution.
HANDLE event
A handle to the event object that's raised when the fence reaches a certain value.
ID3D12Fence * fence
D3D12 fence object.
uint64_t fence_value
The fence value used for sync.
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
This struct describes a set or pool of "hardware" frames (i.e.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
int initial_pool_size
Initial size of the frame pool.
int width
The allocated dimensions of the frames in this pool.
This structure stores compressed data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Structure describing a single Region Of Interest.
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
AVRational qoffset
Quantisation offset.
int top
Distance in pixels from the top edge of the frame to the top and bottom edges and from the left edge ...
ID3D12CommandAllocator * command_allocator
AVBufferRef * output_buffer_ref
ID3D12Resource * encoded_metadata
int non_independent_frame
char tail_data[MAX_PARAM_BUFFER_SIZE]
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl
ID3D12Resource * resolved_metadata
AVD3D12VAFrame * recon_surface
AVD3D12VAFrame * input_surface
ID3D12Resource * output_buffer
AVBufferRef * recon_frames_ref
AVHWFramesContext * input_frames
AVHWDeviceContext * device
const struct FFHWEncodePictureOperation * op
AVPacket * tail_pkt
Tail data of a pic, now only used for av1 repeat frame header.
FFHWBaseEncodePicture * pic_start
AVHWFramesContext * recon_frames
struct FFHWBaseEncodePicture * next
int nb_refs[MAX_REFERENCE_LIST_NUM]
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
static int ref[MAX_W *MAX_W]