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;
64
65 // Hidden-frame (AV1 show_existing_frame) support
68 size_t tail_size;
70
71typedef struct D3D12VAEncodeProfile {
72 /**
73 * lavc profile value (AV_PROFILE_*).
74 */
76
77 /**
78 * Supported bit depth.
79 */
80 int depth;
81
82 /**
83 * Number of components.
84 */
86
87 /**
88 * Chroma subsampling in width dimension.
89 */
91
92 /**
93 * Chroma subsampling in height dimension.
94 */
96
97 /**
98 * D3D12 profile value.
99 */
100 D3D12_VIDEO_ENCODER_PROFILE_DESC d3d12_profile;
102
103enum {
110};
111
112
113typedef struct D3D12VAEncodeRCMode {
114 /**
115 * Mode from above enum (RC_MODE_*).
116 */
117 int mode;
118
119 /**
120 * Name.
121 *
122 */
123 const char *name;
124
125 /**
126 * Uses bitrate parameters.
127 *
128 */
130
131 /**
132 * Supports maxrate distinct from bitrate.
133 *
134 */
136
137 /**
138 * Uses quality value.
139 *
140 */
142
143 /**
144 * Supports HRD/VBV parameters.
145 *
146 */
147 int hrd;
148
149 /**
150 * D3D12 mode value.
151 */
152 D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_mode;
154
155typedef struct D3D12VAEncodeContext {
157
158 /**
159 * Codec-specific hooks.
160 */
162
163 /**
164 * Max frame size
165 */
167
168 /**
169 * Explicitly set RC mode (otherwise attempt to pick from
170 * available modes).
171 */
173
174 /**
175 * Explicitly-set QP, for use with the "qp" options.
176 * (Forces CQP mode when set, overriding everything else.)
177 */
179
180 /**
181 * RC quality level - meaning depends on codec and RC mode.
182 * In CQP mode this sets the fixed quantiser value.
183 */
185
186 /**
187 * Chosen encoding profile details.
188 */
190
192
193 /**
194 * ID3D12Device3 interface.
195 */
196 ID3D12Device3 *device3;
197
198 /**
199 * ID3D12VideoDevice3 interface.
200 */
201 ID3D12VideoDevice3 *video_device3;
202
203 /**
204 * Pool of (reusable) bitstream output buffers.
205 */
207
208 /**
209 * Flag indicates if the HW is texture array mode.
210 */
212
213 /**
214 * The number of planes in the input DXGI FORMAT.
215 */
217
218 /**
219 * D3D12 video encoder.
220 */
222
223 ID3D12VideoEncoder *encoder;
224
225 /**
226 * D3D12 video encoder heap.
227 */
228 ID3D12VideoEncoderHeap *encoder_heap;
229
230 /**
231 * A cached queue for reusing the D3D12 command allocators.
232 *
233 * @see https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#id3d12commandallocator
234 */
236
237 /**
238 * D3D12 command queue.
239 */
240 ID3D12CommandQueue *command_queue;
241
242 /**
243 * D3D12 video encode command list.
244 */
245 ID3D12VideoEncodeCommandList2 *command_list;
246
247 /**
248 * The sync context used to sync command queue.
249 */
251
252 /**
253 * The bi_not_empty feature.
254 */
256
257 /**
258 * D3D12_FEATURE structures.
259 */
260 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req;
261
262 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS res_limits;
263
264 /**
265 * D3D12_VIDEO_ENCODER structures.
266 */
267 D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC resolution;
268
269 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf;
270
271 D3D12_VIDEO_ENCODER_RATE_CONTROL rc;
272
273 D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop;
274
275 D3D12_VIDEO_ENCODER_LEVEL_SETTING level;
276
277 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA subregions_layout;
278
279 D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE subregion_mode;
280
281 /**
282 * Intra refresh configuration
283 */
284 D3D12_VIDEO_ENCODER_INTRA_REFRESH intra_refresh;
285
286 /**
287 * Current frame index within intra refresh cycle
288 */
290
291 /**
292 * Motion estimation precision mode
293 */
294 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE me_precision;
295
296 /**
297 * QP map region pixel size (block size for QP map)
298 */
300
303
304typedef struct D3D12VAEncodeType {
305 /**
306 * List of supported profiles.
307 */
309
310 /**
311 * D3D12 codec name.
312 */
313 D3D12_VIDEO_ENCODER_CODEC d3d12_codec;
314
315 /**
316 * Codec feature flags.
317 */
318 int flags;
319
320 /**
321 * Default quality for this codec - used as quantiser or RC quality
322 * factor depending on RC mode.
323 */
325
326 /**
327 * Query codec configuration and determine encode parameters like
328 * block sizes for surface alignment and slices. If not set, assume
329 * that all blocks are 16x16 and that surfaces should be aligned to match
330 * this.
331 */
333
334 /**
335 * Perform any extra codec-specific configuration.
336 */
337 int (*configure)(AVCodecContext *avctx);
338
339 /**
340 * Set codec-specific level setting.
341 */
342 int (*set_level)(AVCodecContext *avctx);
343
344 /**
345 * Set codec-specific tile setting.
346 */
347 int (*set_tile)(AVCodecContext *avctx);
348
349 /**
350 * The size of any private data structure associated with each
351 * picture (can be zero if not required).
352 */
354
355 /**
356 * Fill the corresponding parameters.
357 */
359
361 FFHWBaseEncodePicture *base_pic);
362
364
365 /**
366 * Write the packed header data to the provided buffer.
367 */
369 char *data, size_t *data_len);
370
371 /**
372 * Fill the coded data into AVPacket
373 */
377
379
382
384 D3D12_VIDEO_ENCODER_VALIDATION_FLAGS flags);
385
386#define D3D12VA_ENCODE_INTRA_REFRESH_MODE(name, mode, desc) \
387 { #name, desc, 0, AV_OPT_TYPE_CONST, { .i64 = D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_ ## mode }, \
388 0, 0, FLAGS, .unit = "intra_refresh_mode" }
389
390#if CONFIG_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
391#define D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_EIGHTH_PIXEL
392#else
393#define D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_QUARTER_PIXEL
394#endif
395
396#define D3D12VA_ENCODE_ME_PRECISION_MODE(name, mode, desc) \
397 { #name, #desc " pixel precision", 0, AV_OPT_TYPE_CONST, \
398 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_ ## mode }, \
399 0, 0, FLAGS, .unit = "me_precision" }
400
401#if CONFIG_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
402#define FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL \
403 , D3D12VA_ENCODE_ME_PRECISION_MODE(eighth_pixel, EIGHTH_PIXEL, Eighth)
404#else
405#define FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
406#endif
407
408#define D3D12VA_ENCODE_COMMON_OPTIONS \
409 { "max_frame_size", \
410 "Maximum frame size (in bytes)",\
411 OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
412 { .i64 = 0 }, 0, INT_MAX / 8, FLAGS }, \
413 { "intra_refresh_mode", \
414 "Set intra refresh mode", \
415 OFFSET(common.intra_refresh.Mode), AV_OPT_TYPE_INT, \
416 { .i64 = D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE }, \
417 D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE, \
418 D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_ROW_BASED, FLAGS, .unit = "intra_refresh_mode" }, \
419 D3D12VA_ENCODE_INTRA_REFRESH_MODE(none, NONE, "Disable intra refresh"), \
420 D3D12VA_ENCODE_INTRA_REFRESH_MODE(row_based, ROW_BASED, "Row-based intra refresh"), \
421 { "intra_refresh_duration", \
422 "Number of frames over which to spread intra refresh (0 = GOP size)", \
423 OFFSET(common.intra_refresh.IntraRefreshDuration), AV_OPT_TYPE_INT, \
424 { .i64 = 0 }, 0, INT_MAX, FLAGS }, \
425 { "me_precision", "Motion estimation precision mode", \
426 OFFSET(common.me_precision), AV_OPT_TYPE_INT, \
427 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM }, \
428 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM, \
429 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAX_VALUE, \
430 FLAGS, .unit = "me_precision" }, \
431 { "maximum", "Maximum (best quality, slowest)", 0, AV_OPT_TYPE_CONST, \
432 { .i64 = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM }, \
433 0, 0, FLAGS, .unit = "me_precision" }, \
434 D3D12VA_ENCODE_ME_PRECISION_MODE(full_pixel, FULL_PIXEL, Full), \
435 D3D12VA_ENCODE_ME_PRECISION_MODE(half_pixel, HALF_PIXEL, Half), \
436 D3D12VA_ENCODE_ME_PRECISION_MODE(quarter_pixel, QUARTER_PIXEL, Quarter) \
437 FFPP_D3D12VA_ME_PRECISION_EIGHTH_PIXEL
438
439#define D3D12VA_ENCODE_RC_MODE(name, desc) \
440 { #name, desc, 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_ ## name }, \
441 0, 0, FLAGS, .unit = "rc_mode" }
442#define D3D12VA_ENCODE_RC_OPTIONS \
443 { "rc_mode",\
444 "Set rate control mode", \
445 OFFSET(common.explicit_rc_mode), AV_OPT_TYPE_INT, \
446 { .i64 = RC_MODE_AUTO }, RC_MODE_AUTO, RC_MODE_MAX, FLAGS, .unit = "rc_mode" }, \
447 { "auto", "Choose mode automatically based on other parameters", \
448 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_AUTO }, 0, 0, FLAGS, .unit = "rc_mode" }, \
449 D3D12VA_ENCODE_RC_MODE(CQP, "Constant-quality"), \
450 D3D12VA_ENCODE_RC_MODE(CBR, "Constant-bitrate"), \
451 D3D12VA_ENCODE_RC_MODE(VBR, "Variable-bitrate"), \
452 D3D12VA_ENCODE_RC_MODE(QVBR, "Quality-defined variable-bitrate")
453
454#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)
#define MAX_PARAM_BUFFER_SIZE
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
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
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.