65 { 10, D3D12_VIDEO_ENCODER_LEVELS_H264_1 },
66 { 11, D3D12_VIDEO_ENCODER_LEVELS_H264_11 },
67 { 12, D3D12_VIDEO_ENCODER_LEVELS_H264_12 },
68 { 13, D3D12_VIDEO_ENCODER_LEVELS_H264_13 },
69 { 20, D3D12_VIDEO_ENCODER_LEVELS_H264_2 },
70 { 21, D3D12_VIDEO_ENCODER_LEVELS_H264_21 },
71 { 22, D3D12_VIDEO_ENCODER_LEVELS_H264_22 },
72 { 30, D3D12_VIDEO_ENCODER_LEVELS_H264_3 },
73 { 31, D3D12_VIDEO_ENCODER_LEVELS_H264_31 },
74 { 32, D3D12_VIDEO_ENCODER_LEVELS_H264_32 },
75 { 40, D3D12_VIDEO_ENCODER_LEVELS_H264_4 },
76 { 41, D3D12_VIDEO_ENCODER_LEVELS_H264_41 },
77 { 42, D3D12_VIDEO_ENCODER_LEVELS_H264_42 },
78 { 50, D3D12_VIDEO_ENCODER_LEVELS_H264_5 },
79 { 51, D3D12_VIDEO_ENCODER_LEVELS_H264_51 },
80 { 52, D3D12_VIDEO_ENCODER_LEVELS_H264_52 },
81 { 60, D3D12_VIDEO_ENCODER_LEVELS_H264_6 },
82 { 61, D3D12_VIDEO_ENCODER_LEVELS_H264_61 },
83 { 62, D3D12_VIDEO_ENCODER_LEVELS_H264_62 },
86static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_main = D3D12_VIDEO_ENCODER_PROFILE_H264_MAIN;
87static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_high = D3D12_VIDEO_ENCODER_PROFILE_H264_HIGH;
88static const D3D12_VIDEO_ENCODER_PROFILE_H264
profile_high_10 = D3D12_VIDEO_ENCODER_PROFILE_H264_HIGH_10;
90#define D3D_PROFILE_DESC(name) \
91 { sizeof(D3D12_VIDEO_ENCODER_PROFILE_H264), { .pH264Profile = (D3D12_VIDEO_ENCODER_PROFILE_H264 *)&profile_ ## name } }
100 char *
data,
size_t *data_len,
106 err = ff_cbs_write_fragment_data(priv->
cbc, au);
114 "%zu < %zu.\n", *data_len,
132 err = ff_cbs_insert_unit_content(au, -1,
136 "type = %d.\n",
header->nal_unit_type);
144 char *
data,
size_t *data_len)
160 ff_cbs_fragment_reset(au);
172 D3D12_VIDEO_ENCODER_PROFILE_H264
profile = D3D12_VIDEO_ENCODER_PROFILE_H264_MAIN;
173 D3D12_VIDEO_ENCODER_LEVELS_H264
level = { 0 };
178 D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT support = {
180 .Codec = D3D12_VIDEO_ENCODER_CODEC_H264,
181 .InputFormat = hwctx->
format,
182 .RateControl =
ctx->rc,
183 .IntraRefresh =
ctx->intra_refresh.Mode,
184 .SubregionFrameEncoding = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
185 .ResolutionsListCount = 1,
186 .pResolutionList = &
ctx->resolution,
187 .CodecGopSequence =
ctx->gop,
189 .CodecConfiguration =
ctx->codec_conf,
190 .SuggestedProfile.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PROFILE_H264),
191 .SuggestedProfile.pH264Profile = &
profile,
192 .SuggestedLevel.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVELS_H264),
193 .SuggestedLevel.pH264LevelSetting = &
level,
194 .pResolutionDependentSupport = &
ctx->res_limits,
197 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT,
198 &support,
sizeof(support));
205 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK)) {
206 av_log(avctx,
AV_LOG_ERROR,
"Driver does not support requested features. ValidationFlags: %#x\n",
207 support.ValidationFlags);
212 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) {
213 ctx->is_texture_array = 1;
214 av_log(avctx,
AV_LOG_DEBUG,
"D3D12 video encode on this device uses texture array mode.\n");
218 if (support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_DELTA_QP_AVAILABLE) {
221 ctx->qp_map_region_size =
ctx->res_limits.QPMapRegionPixelsSize;
223 "(QP map region size: %d pixels).\n",
ctx->qp_map_region_size);
226 av_log(avctx,
AV_LOG_DEBUG,
"ROI encoding not supported by hardware for current rate control mode \n");
230 if (
ctx->me_precision != D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM) {
231 if (!(support.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE)) {
233 "precision mode limits.\n");
237 "precision mode limits.\n");
244 sps->pic_height_in_map_units_minus1 = ((base_ctx->
surface_height + 0x0F) >> 4) - 1;
256 ctx->gop.pH264GroupOfPictures->pic_order_cnt_type =
sps->pic_order_cnt_type;
260 ctx->gop.pH264GroupOfPictures->log2_max_frame_num_minus4 =
sps->log2_max_frame_num_minus4;
261 pps->deblocking_filter_control_present_flag = 1;
274 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 *config;
275 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264 h264_caps;
277 D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codec_caps = {
279 .Codec = D3D12_VIDEO_ENCODER_CODEC_H264,
280 .Profile =
ctx->profile->d3d12_profile,
281 .CodecSupportLimits.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264),
284 codec_caps.CodecSupportLimits.pH264Support = &h264_caps;
285 hr = ID3D12VideoDevice3_CheckFeatureSupport(
ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT,
286 &codec_caps,
sizeof(codec_caps));
287 if (!(SUCCEEDED(hr) && codec_caps.IsSupported))
290 ctx->codec_conf.DataSize =
sizeof(D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264);
292 if (!
ctx->codec_conf.pH264Config)
295 config =
ctx->codec_conf.pH264Config;
297 config->ConfigurationFlags = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_NONE;
301 if (h264_caps.DisableDeblockingFilterSupportedModes & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_FLAG_0_ALL_LUMA_CHROMA_SLICE_BLOCK_EDGES_ALWAYS_FILTERED) {
302 config->DisableDeblockingFilterConfig = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_0_ALL_LUMA_CHROMA_SLICE_BLOCK_EDGES_ALWAYS_FILTERED;
304 av_log(avctx,
AV_LOG_ERROR,
"Requested deblocking filter enable mode not supported by driver.\n");
308 if (h264_caps.DisableDeblockingFilterSupportedModes & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_FLAG_1_DISABLE_ALL_SLICE_BLOCK_EDGES) {
309 config->DisableDeblockingFilterConfig = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_1_DISABLE_ALL_SLICE_BLOCK_EDGES;
311 av_log(avctx,
AV_LOG_ERROR,
"Requested deblocking filter disable mode not supported by driver.\n");
318 if (h264_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_CABAC_ENCODING_SUPPORT) {
319 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_ENABLE_CABAC_ENCODING;
321 av_log(avctx,
AV_LOG_WARNING,
"CABAC entropy coding is not supported by the driver, falling back to CAVLC.\n");
328 if (h264_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_CONSTRAINED_INTRAPREDICTION_SUPPORT) {
329 config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_CONSTRAINED_INTRAPREDICTION;
331 av_log(avctx,
AV_LOG_WARNING,
"Constrained intra prediction is not supported by the driver, disabling.\n");
347 int fixed_qp_idr, fixed_qp_p, fixed_qp_b;
355 if (
ctx->rc.Mode == D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP) {
356 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP *cqp_ctl;
362 fixed_qp_idr = fixed_qp_p;
367 fixed_qp_b = fixed_qp_p;
370 "%d / %d / %d for IDR- / P- / B-frames.\n",
371 fixed_qp_idr, fixed_qp_p, fixed_qp_b);
373 ctx->rc.ConfigParams.DataSize =
sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP);
378 cqp_ctl->ConstantQP_FullIntracodedFrame = fixed_qp_idr;
379 cqp_ctl->ConstantQP_InterPredictedFrame_PrevRefOnly = fixed_qp_p;
380 cqp_ctl->ConstantQP_InterPredictedFrame_BiDirectionalRef = fixed_qp_b;
382 ctx->rc.ConfigParams.pConfiguration_CQP = cqp_ctl;
387 ctx->gop.DataSize =
sizeof(D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264);
389 if (!
ctx->gop.pH264GroupOfPictures)
392 ctx->gop.pH264GroupOfPictures->GOPLength = base_ctx->
gop_size;
393 ctx->gop.pH264GroupOfPictures->PPicturePeriod = base_ctx->
b_per_p + 1;
404 ctx->level.DataSize =
sizeof(D3D12_VIDEO_ENCODER_LEVELS_H264);
406 if (!
ctx->level.pH264LevelSetting)
426 if (!pic->
pic_ctl.pH264PicData)
431 av_freep(&pic->
pic_ctl.pH264PicData->pReferenceFramesReconPictureDescriptors);
444 D3D12_VIDEO_ENCODER_REFERENCE_PICTURE_DESCRIPTOR_H264 *pd =
NULL;
445 UINT *ref_list0 =
NULL, *ref_list1 =
NULL;
448 pic->
pic_ctl.DataSize =
sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264);
450 if (!pic->
pic_ctl.pH264PicData)
463 switch(base_pic->
type) {
465 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_IDR_FRAME;
466 pic->
pic_ctl.pH264PicData->idr_pic_id =
ctx->idr_pic_id;
469 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_I_FRAME;
472 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_P_FRAME;
475 pic->
pic_ctl.pH264PicData->FrameType = D3D12_VIDEO_ENCODER_FRAME_TYPE_H264_B_FRAME;
493 pic->
pic_ctl.pH264PicData->List0ReferenceFramesCount = base_pic->
nb_refs[0];
499 href =
ref->codec_priv;
502 pd[idx].ReconstructedPictureResourceIndex = idx;
513 pic->
pic_ctl.pH264PicData->List1ReferenceFramesCount = base_pic->
nb_refs[1];
519 href =
ref->codec_priv;
522 pd[idx].ReconstructedPictureResourceIndex = idx;
528 pic->
pic_ctl.pH264PicData->pList0ReferenceFrames = ref_list0;
529 pic->
pic_ctl.pH264PicData->pList1ReferenceFrames = ref_list1;
530 pic->
pic_ctl.pH264PicData->ReferenceFramesReconPictureDescriptorsCount = idx;
531 pic->
pic_ctl.pH264PicData->pReferenceFramesReconPictureDescriptors = pd;
536 pic->
pic_ctl.pH264PicData->pRateControlQPMap = (INT8 *)pic->
qp_map;
545 .d3d12_codec = D3D12_VIDEO_ENCODER_CODEC_H264,
551 .default_quality = 25,
584 "in 8-bit unsigned integer.\n", avctx->
level);
589 ctx->explicit_qp = priv->
qp;
599 ff_cbs_close(&priv->
cbc);
605 if (priv->
common.
rc.ConfigParams.pConfiguration_CQP !=
NULL) {
612#define OFFSET(x) offsetof(D3D12VAEncodeH264Context, x)
613#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
619 {
"qp",
"Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
622 {
"profile",
"Set profile (general_profile_idc)",
626#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
627 { .i64 = value }, 0, 0, FLAGS, "profile"
633 {
"level",
"Set level (general_level_idc)",
637#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
638 { .i64 = value }, 0, 0, FLAGS, "level"
640 {
LEVEL(
"1.1", 11) },
641 {
LEVEL(
"1.2", 12) },
642 {
LEVEL(
"1.3", 13) },
644 {
LEVEL(
"2.1", 21) },
645 {
LEVEL(
"2.2", 22) },
647 {
LEVEL(
"3.1", 31) },
648 {
LEVEL(
"3.2", 32) },
650 {
LEVEL(
"4.1", 41) },
651 {
LEVEL(
"4.2", 42) },
653 {
LEVEL(
"5.1", 51) },
654 {
LEVEL(
"5.2", 52) },
656 {
LEVEL(
"6.1", 61) },
657 {
LEVEL(
"6.2", 62) },
660 {
"deblock",
"Deblocking filter mode",
663 {
"coder",
"Entropy coder type",
668 {
"constrained_intra_pred",
"Constrained intra prediction (constrained_intra_pred_flag)",
684 .class_name =
"h264_d3d12va",
691 .p.name =
"h264_d3d12va",
707 .p.wrapper_name =
"d3d12va",
const FFCodec ff_h264_d3d12va_encoder
static AVFormatContext * ctx
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
#define i(width, name, range_min, range_max)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
#define CODEC_PIXFMTS(...)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_RECEIVE_PACKET_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
common internal and external API header
int ff_d3d12va_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
void ff_d3d12va_encode_check_encoder_feature_flags(void *log_ctx, D3D12_VIDEO_ENCODER_VALIDATION_FLAGS flags)
const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[]
int ff_d3d12va_encode_init(AVCodecContext *avctx)
int ff_d3d12va_encode_close(AVCodecContext *avctx)
#define D3D12VA_ENCODE_RC_OPTIONS
#define D3D12VA_ENCODE_COMMON_OPTIONS
static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_main
static const D3D12_VIDEO_ENCODER_AV1_PROFILE profile_high
#define D3D_PROFILE_DESC(name)
static const AVOption d3d12va_encode_h264_options[]
static const D3D12VAEncodeH264Level h264_levels[]
static void d3d12va_encode_h264_free_picture_params(D3D12VAEncodePicture *pic)
static int d3d12va_encode_h264_close(AVCodecContext *avctx)
static int d3d12va_encode_h264_add_nal(AVCodecContext *avctx, CodedBitstreamFragment *au, void *nal_unit)
static int d3d12va_encode_h264_configure(AVCodecContext *avctx)
static const D3D12_VIDEO_ENCODER_PROFILE_H264 profile_high_10
static int d3d12va_encode_h264_get_encoder_caps(AVCodecContext *avctx)
#define LEVEL(name, value)
static const D3D12VAEncodeType d3d12va_encode_type_h264
static int d3d12va_encode_h264_init_picture_params(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
static int d3d12va_encode_h264_write_sequence_header(AVCodecContext *avctx, char *data, size_t *data_len)
static const AVClass d3d12va_encode_h264_class
#define PROFILE(name, value)
static const FFCodecDefault d3d12va_encode_h264_defaults[]
static int d3d12va_encode_h264_write_access_unit(AVCodecContext *avctx, char *data, size_t *data_len, CodedBitstreamFragment *au)
static int d3d12va_encode_h264_set_level(AVCodecContext *avctx)
static int d3d12va_encode_h264_init(AVCodecContext *avctx)
static const D3D12VAEncodeProfile d3d12va_encode_h264_profiles[]
static int d3d12va_encode_h264_init_sequence_params(AVCodecContext *avctx)
#define AV_PROFILE_H264_MAIN
#define AV_PROFILE_UNKNOWN
#define AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH_10
int(* init)(AVBSFContext *ctx)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
#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.
const char * av_default_item_name(void *ptr)
Return the context name.
#define LIBAVUTIL_VERSION_INT
#define MAX_PICTURE_REFERENCES
#define HW_BASE_ENCODE_COMMON_OPTIONS
@ FF_HW_FLAG_NON_IDR_KEY_PICTURES
@ FF_HW_FLAG_B_PICTURE_REFERENCES
int ff_hw_base_encode_init_params_h264(FFHWBaseEncodeContext *base_ctx, AVCodecContext *avctx, FFHWBaseEncodeH264 *common, FFHWBaseEncodeH264Opts *opts)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
static void deblock(const RV60Context *s, AVFrame *frame, int xpos, int ypos, int size, int dpos)
static const uint8_t header[24]
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
main external API structure.
int width
picture width / height.
float b_quant_offset
qscale offset between IP and B-frames
float b_quant_factor
qscale factor between IP and B-frames If > 0 then the last P-frame quantizer will be used (q= lastp_q...
int level
Encoding level descriptor.
float i_quant_factor
qscale factor between P- and I-frames If > 0 then the last P-frame quantizer will be used (q = lastp_...
float i_quant_offset
qscale offset between P and I-frames
This struct is allocated as AVHWFramesContext.hwctx.
DXGI_FORMAT format
DXGI_FORMAT format.
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.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Context structure for coded bitstream operations.
Coded bitstream fragment structure, combining one or more units.
size_t data_bit_padding
The number of bits which should be ignored in the final byte.
size_t data_size
The number of bytes in the bitstream.
uint8_t * data
Pointer to the bitstream form of this fragment.
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop
D3D12_VIDEO_ENCODER_RATE_CONTROL rc
D3D12_VIDEO_ENCODER_LEVEL_SETTING level
int constrained_intra_pred
FFHWBaseEncodeH264Opts unit_opts
CodedBitstreamContext * cbc
D3D12VAEncodeContext common
CodedBitstreamFragment current_access_unit
D3D12_VIDEO_ENCODER_LEVELS_H264 d3d12_level
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl
AVHWFramesContext * input_frames
struct FFHWBaseEncodePicture * prev
int nb_refs[MAX_REFERENCE_LIST_NUM]
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
static int ref[MAX_W *MAX_W]
static int write_sequence_header(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, uint8_t *data, size_t *data_len)