FFmpeg
Loading...
Searching...
No Matches
d3d12va_encode.h
Go to the documentation of this file.
1/*
2 * Direct3D 12 HW acceleration video encoder
3 *
4 * Copyright (c) 2024 Intel Corporation
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef AVCODEC_D3D12VA_ENCODE_H
24#define AVCODEC_D3D12VA_ENCODE_H
25
26#include "libavutil/fifo.h"
27#include "libavutil/hwcontext.h"
30#include "avcodec.h"
31#include "internal.h"
32#include "hwconfig.h"
33#include "hw_base_encode.h"
34
36
38
39#define MAX_PARAM_BUFFER_SIZE 4096
40#define D3D12VA_VIDEO_ENC_ASYNC_DEPTH 8
41
42typedef struct D3D12VAEncodePicture {
45
48
50 ID3D12Resource *output_buffer;
51
52 ID3D12Resource *encoded_metadata;
53 ID3D12Resource *resolved_metadata;
54
56
57 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl;
58
60
61 // ROI delta QP map (void* to support both INT8 for H.264/HEVC and INT16 for AV1)
62 void *qp_map;
65
66typedef struct D3D12VAEncodeProfile {
67 /**
68 * lavc profile value (AV_PROFILE_*).
69 */
71
72 /**
73 * Supported bit depth.
74 */
75 int depth;
76
77 /**
78 * Number of components.
79 */
81
82 /**
83 * Chroma subsampling in width dimension.
84 */
86
87 /**
88 * Chroma subsampling in height dimension.
89 */
91
92 /**
93 * D3D12 profile value.
94 */
95 D3D12_VIDEO_ENCODER_PROFILE_DESC d3d12_profile;
97
98enum {
105};
106
107
108typedef struct D3D12VAEncodeRCMode {
109 /**
110 * Mode from above enum (RC_MODE_*).
111 */
112 int mode;
113
114 /**
115 * Name.
116 *
117 */
118 const char *name;
119
120 /**
121 * Uses bitrate parameters.
122 *
123 */
125
126 /**
127 * Supports maxrate distinct from bitrate.
128 *
129 */
131
132 /**
133 * Uses quality value.
134 *
135 */
137
138 /**
139 * Supports HRD/VBV parameters.
140 *
141 */
142 int hrd;
143
144 /**
145 * D3D12 mode value.
146 */
147 D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_mode;
149
150typedef struct D3D12VAEncodeContext {
152
153 /**
154 * Codec-specific hooks.
155 */
157
158 /**
159 * Max frame size
160 */
162
163 /**
164 * Explicitly set RC mode (otherwise attempt to pick from
165 * available modes).
166 */
168
169 /**
170 * Explicitly-set QP, for use with the "qp" options.
171 * (Forces CQP mode when set, overriding everything else.)
172 */
174
175 /**
176 * RC quality level - meaning depends on codec and RC mode.
177 * In CQP mode this sets the fixed quantiser value.
178 */
180
181 /**
182 * Chosen encoding profile details.
183 */
185
187
188 /**
189 * ID3D12Device3 interface.
190 */
191 ID3D12Device3 *device3;
192
193 /**
194 * ID3D12VideoDevice3 interface.
195 */
196 ID3D12VideoDevice3 *video_device3;
197
198 /**
199 * Pool of (reusable) bitstream output buffers.
200 */
202
203 /**
204 * Flag indicates if the HW is texture array mode.
205 */
207
208 /**
209 * The number of planes in the input DXGI FORMAT.
210 */
212
213 /**
214 * D3D12 video encoder.
215 */
217
218 ID3D12VideoEncoder *encoder;
219
220 /**
221 * D3D12 video encoder heap.
222 */
223 ID3D12VideoEncoderHeap *encoder_heap;
224
225 /**
226 * A cached queue for reusing the D3D12 command allocators.
227 *
228 * @see https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#id3d12commandallocator
229 */
231
232 /**
233 * D3D12 command queue.
234 */
235 ID3D12CommandQueue *command_queue;
236
237 /**
238 * D3D12 video encode command list.
239 */
240 ID3D12VideoEncodeCommandList2 *command_list;
241
242 /**
243 * The sync context used to sync command queue.
244 */
246
247 /**
248 * The bi_not_empty feature.
249 */
251
252 /**
253 * D3D12_FEATURE structures.
254 */
255 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req;
256
257 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS res_limits;
258
259 /**
260 * D3D12_VIDEO_ENCODER structures.
261 */
262 D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC resolution;
263
264 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf;
265
266 D3D12_VIDEO_ENCODER_RATE_CONTROL rc;
267
268 D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop;
269
270 D3D12_VIDEO_ENCODER_LEVEL_SETTING level;
271
272 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA subregions_layout;
273
274 D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE subregion_mode;
275
276 /**
277 * Intra refresh configuration
278 */
279 D3D12_VIDEO_ENCODER_INTRA_REFRESH intra_refresh;
280
281 /**
282 * Current frame index within intra refresh cycle
283 */
285
286 /**
287 * Motion estimation precision mode
288 */
289 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE me_precision;
290
291 /**
292 * QP map region pixel size (block size for QP map)
293 */
295
298
299typedef struct D3D12VAEncodeType {
300 /**
301 * List of supported profiles.
302 */
304
305 /**
306 * D3D12 codec name.
307 */
308 D3D12_VIDEO_ENCODER_CODEC d3d12_codec;
309
310 /**
311 * Codec feature flags.
312 */
313 int flags;
314
315 /**
316 * Default quality for this codec - used as quantiser or RC quality
317 * factor depending on RC mode.
318 */
320
321 /**
322 * Query codec configuration and determine encode parameters like
323 * block sizes for surface alignment and slices. If not set, assume
324 * that all blocks are 16x16 and that surfaces should be aligned to match
325 * this.
326 */
328
329 /**
330 * Perform any extra codec-specific configuration.
331 */
332 int (*configure)(AVCodecContext *avctx);
333
334 /**
335 * Set codec-specific level setting.
336 */
337 int (*set_level)(AVCodecContext *avctx);
338
339 /**
340 * Set codec-specific tile setting.
341 */
342 int (*set_tile)(AVCodecContext *avctx);
343
344 /**
345 * The size of any private data structure associated with each
346 * picture (can be zero if not required).
347 */
349
350 /**
351 * Fill the corresponding parameters.
352 */
354
356 FFHWBaseEncodePicture *base_pic);
357
359
360 /**
361 * Write the packed header data to the provided buffer.
362 */
364 char *data, size_t *data_len);
365
366 /**
367 * Fill the coded data into AVPacket
368 */
372
374
377
379 D3D12_VIDEO_ENCODER_VALIDATION_FLAGS flags);
380
381#define D3D12VA_ENCODE_INTRA_REFRESH_MODE(name, mode, desc) \
382 { #name, desc, 0, AV_OPT_TYPE_CONST, { .i64 = D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_ ## mode }, \
383 0, 0, FLAGS, .unit = "intra_refresh_mode" }
384
385#if CONFIG_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
386#define D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_EIGHTH_PIXEL
387#else
388#define D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_QUARTER_PIXEL
389#endif
390
391#define D3D12VA_ENCODE_ME_PRECISION_MODE(name, mode, desc) \
392 { #name, #desc " pixel precision", 0, AV_OPT_TYPE_CONST, \
393 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_ ## mode }, \
394 0, 0, FLAGS, .unit = "me_precision" }
395
396#if CONFIG_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
397#define FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL \
398 , D3D12VA_ENCODE_ME_PRECISION_MODE(eighth_pixel, EIGHTH_PIXEL, Eighth)
399#else
400#define FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
401#endif
402
403#define D3D12VA_ENCODE_COMMON_OPTIONS \
404 { "max_frame_size", \
405 "Maximum frame size (in bytes)",\
406 OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
407 { .i64 = 0 }, 0, INT_MAX / 8, FLAGS }, \
408 { "intra_refresh_mode", \
409 "Set intra refresh mode", \
410 OFFSET(common.intra_refresh.Mode), AV_OPT_TYPE_INT, \
411 { .i64 = D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE }, \
412 D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE, \
413 D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_ROW_BASED, FLAGS, .unit = "intra_refresh_mode" }, \
414 D3D12VA_ENCODE_INTRA_REFRESH_MODE(none, NONE, "Disable intra refresh"), \
415 D3D12VA_ENCODE_INTRA_REFRESH_MODE(row_based, ROW_BASED, "Row-based intra refresh"), \
416 { "intra_refresh_duration", \
417 "Number of frames over which to spread intra refresh (0 = GOP size)", \
418 OFFSET(common.intra_refresh.IntraRefreshDuration), AV_OPT_TYPE_INT, \
419 { .i64 = 0 }, 0, INT_MAX, FLAGS }, \
420 { "me_precision", "Motion estimation precision mode", \
421 OFFSET(common.me_precision), AV_OPT_TYPE_INT, \
422 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM }, \
423 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM, \
424 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE, \
425 FLAGS, .unit = "me_precision" }, \
426 { "maximum", "Maximum (best quality, slowest)", 0, AV_OPT_TYPE_CONST, \
427 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM }, \
428 0, 0, FLAGS, .unit = "me_precision" }, \
429 D3D12VA_ENCODE_ME_PRECISION_MODE(full_pixel, FULL_PIXEL, Full), \
430 D3D12VA_ENCODE_ME_PRECISION_MODE(half_pixel, HALF_PIXEL, Half), \
431 D3D12VA_ENCODE_ME_PRECISION_MODE(quarter_pixel, QUARTER_PIXEL, Quarter) \
432 FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
433
434#define D3D12VA_ENCODE_RC_MODE(name, desc) \
435 { #name, desc, 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_ ## name }, \
436 0, 0, FLAGS, .unit = "rc_mode" }
437#define D3D12VA_ENCODE_RC_OPTIONS \
438 { "rc_mode",\
439 "Set rate control mode", \
440 OFFSET(common.explicit_rc_mode), AV_OPT_TYPE_INT, \
441 { .i64 = RC_MODE_AUTO }, RC_MODE_AUTO, RC_MODE_MAX, FLAGS, .unit = "rc_mode" }, \
442 { "auto", "Choose mode automatically based on other parameters", \
443 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_AUTO }, 0, 0, FLAGS, .unit = "rc_mode" }, \
444 D3D12VA_ENCODE_RC_MODE(CQP, "Constant-quality"), \
445 D3D12VA_ENCODE_RC_MODE(CBR, "Constant-bitrate"), \
446 D3D12VA_ENCODE_RC_MODE(VBR, "Variable-bitrate"), \
447 D3D12VA_ENCODE_RC_MODE(QVBR, "Quality-defined variable-bitrate")
448
449#endif /* AVCODEC_D3D12VA_ENCODE_H */
Libavcodec external API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[]
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)
@ RC_MODE_MAX
@ RC_MODE_AUTO
@ RC_MODE_CQP
@ RC_MODE_QVBR
@ RC_MODE_CBR
@ RC_MODE_VBR
int ff_d3d12va_encode_init(AVCodecContext *avctx)
int ff_d3d12va_encode_close(AVCodecContext *avctx)
static AVPacket * pkt
A generic FIFO API.
An API-specific header for AV_HWDEVICE_TYPE_D3D12VA.
common internal api header.
const char data[16]
Definition mxf.c:149
The buffer pool.
A reference to a data buffer.
Definition buffer.h:82
main external API structure.
Definition avcodec.h:443
This struct is allocated as AVHWDeviceContext.hwctx.
D3D12VA frame descriptor for pool allocation.
This struct is used to sync d3d12 execution.
Definition fifo.c:35
This structure stores compressed data.
Definition packet.h:580
ID3D12VideoEncoder * encoder
ID3D12VideoEncodeCommandList2 * command_list
D3D12 video encode command list.
UINT intra_refresh_frame_index
Current frame index within intra refresh cycle.
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC resolution
D3D12_VIDEO_ENCODER structures.
AVD3D12VADeviceContext * hwctx
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE me_precision
Motion estimation precision mode.
int is_texture_array
Flag indicates if the HW is texture array mode.
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf
int explicit_rc_mode
Explicitly set RC mode (otherwise attempt to pick from available modes).
ID3D12VideoEncoderHeap * encoder_heap
D3D12 video encoder heap.
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req
D3D12_FEATURE structures.
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop
AVD3D12VASyncContext sync_ctx
The sync context used to sync command queue.
int plane_count
The number of planes in the input DXGI FORMAT.
ID3D12Device3 * device3
ID3D12Device3 interface.
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE subregion_mode
const struct D3D12VAEncodeType * codec
Codec-specific hooks.
D3D12_VIDEO_ENCODER_INTRA_REFRESH intra_refresh
Intra refresh configuration.
int qp_map_region_size
QP map region pixel size (block size for QP map)
int bi_not_empty
The bi_not_empty feature.
D3D12_VIDEO_ENCODER_RATE_CONTROL rc
D3D12_VIDEO_ENCODER_LEVEL_SETTING level
AVBufferRef * encoder_ref
D3D12 video encoder.
int max_frame_size
Max frame size.
const D3D12VAEncodeProfile * profile
Chosen encoding profile details.
int rc_quality
RC quality level - meaning depends on codec and RC mode.
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA subregions_layout
AVBufferPool * output_buffer_pool
Pool of (reusable) bitstream output buffers.
ID3D12VideoDevice3 * video_device3
ID3D12VideoDevice3 interface.
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS res_limits
int explicit_qp
Explicitly-set QP, for use with the "qp" options.
ID3D12CommandQueue * command_queue
D3D12 command queue.
FFHWBaseEncodeContext base
AVFifo * allocator_queue
A cached queue for reusing the D3D12 command allocators.
AVBufferRef * output_buffer_ref
ID3D12Resource * encoded_metadata
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl
ID3D12Resource * resolved_metadata
AVD3D12VAFrame * recon_surface
AVD3D12VAFrame * input_surface
ID3D12Resource * output_buffer
int depth
Supported bit depth.
int av_profile
lavc profile value (AV_PROFILE_*).
int nb_components
Number of components.
D3D12_VIDEO_ENCODER_PROFILE_DESC d3d12_profile
D3D12 profile value.
int log2_chroma_w
Chroma subsampling in width dimension.
int log2_chroma_h
Chroma subsampling in height dimension.
int hrd
Supports HRD/VBV parameters.
const char * name
Name.
int mode
Mode from above enum (RC_MODE_*).
int quality
Uses quality value.
D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_mode
D3D12 mode value.
int maxrate
Supports maxrate distinct from bitrate.
int bitrate
Uses bitrate parameters.
int flags
Codec feature flags.
int(* get_coded_data)(AVCodecContext *avctx, D3D12VAEncodePicture *pic, AVPacket *pkt)
Fill the coded data into AVPacket.
const D3D12VAEncodeProfile * profiles
List of supported profiles.
int(* init_sequence_params)(AVCodecContext *avctx)
Fill the corresponding parameters.
D3D12_VIDEO_ENCODER_CODEC d3d12_codec
D3D12 codec name.
int(* configure)(AVCodecContext *avctx)
Perform any extra codec-specific configuration.
int(* set_tile)(AVCodecContext *avctx)
Set codec-specific tile setting.
void(* free_picture_params)(D3D12VAEncodePicture *pic)
int(* write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len)
Write the packed header data to the provided buffer.
int(* init_picture_params)(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
int(* get_encoder_caps)(AVCodecContext *avctx)
Query codec configuration and determine encode parameters like block sizes for surface alignment and ...
size_t picture_priv_data_size
The size of any private data structure associated with each picture (can be zero if not required).
int default_quality
Default quality for this codec - used as quantiser or RC quality factor depending on RC mode.
int(* set_level)(AVCodecContext *avctx)
Set codec-specific level setting.