23#ifndef AVCODEC_QSVENC_H
24#define AVCODEC_QSVENC_H
39#define QSV_HAVE_EXT_VP9_TILES QSV_VERSION_ATLEAST(1, 29)
40#define QSV_HAVE_EXT_AV1_PARAM QSV_VERSION_ATLEAST(2, 5)
42#if defined(_WIN32) || defined(__CYGWIN__)
43#define QSV_HAVE_AVBR 1
46#define QSV_HAVE_HE QSV_VERSION_ATLEAST(2, 4)
48#define QSV_HAVE_AVBR 0
50#define QSV_HAVE_MF !QSV_ONEVPL
54#define QSV_COMMON_OPTS \
55{ "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VE }, \
56{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = MFX_TARGETUSAGE_UNKNOWN }, MFX_TARGETUSAGE_UNKNOWN, MFX_TARGETUSAGE_BEST_SPEED, VE, .unit = "preset" }, \
57{ "veryfast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_SPEED }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
58{ "faster", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_6 }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
59{ "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_5 }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
60{ "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BALANCED }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
61{ "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_3 }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
62{ "slower", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_2 }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
63{ "veryslow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_QUALITY }, INT_MIN, INT_MAX, VE, .unit = "preset" }, \
64{ "forced_idr", "Forcing I frames as IDR frames", OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE }, \
65{ "low_power", "enable low power mode(experimental: many limitations by mfx version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, VE},\
66{ "qsv_params", "Set QSV encoder parameters as key1=value1:key2=value2:...", OFFSET(qsv.qsv_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
69#define QSV_HE_OPTIONS \
70{ "dual_gfx", "Prefer processing on both iGfx and dGfx simultaneously", OFFSET(qsv.dual_gfx), AV_OPT_TYPE_INT, { .i64 = MFX_HYPERMODE_OFF }, MFX_HYPERMODE_OFF, MFX_HYPERMODE_ADAPTIVE, VE, .unit = "dual_gfx" }, \
71{ "off", "Disable HyperEncode mode", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_OFF }, INT_MIN, INT_MAX, VE, .unit = "dual_gfx" }, \
72{ "on", "Enable HyperEncode mode and return error if incompatible parameters during initialization", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_ON }, INT_MIN, INT_MAX, VE, .unit = "dual_gfx" }, \
73{ "adaptive", "Enable HyperEncode mode or fallback to single GPU if incompatible parameters during initialization", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_ADAPTIVE }, INT_MIN, INT_MAX, VE, .unit = "dual_gfx" },
76#define QSV_OPTION_RDO \
77{ "rdo", "Enable rate distortion optimization", OFFSET(qsv.rdo), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
79#define QSV_OPTION_MAX_FRAME_SIZE \
80{ "max_frame_size", "Maximum encoded frame size in bytes", OFFSET(qsv.max_frame_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, \
81{ "max_frame_size_i", "Maximum encoded I frame size in bytes",OFFSET(qsv.max_frame_size_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, \
82{ "max_frame_size_p", "Maximum encoded P frame size in bytes",OFFSET(qsv.max_frame_size_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
84#define QSV_OPTION_MAX_SLICE_SIZE \
85{ "max_slice_size", "Maximum encoded slice size in bytes", OFFSET(qsv.max_slice_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
87#define QSV_OPTION_BITRATE_LIMIT \
88{ "bitrate_limit", "Toggle bitrate limitations", OFFSET(qsv.bitrate_limit), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
90#define QSV_OPTION_MBBRC \
91{ "mbbrc", "MB level bitrate control", OFFSET(qsv.mbbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
93#define QSV_OPTION_EXTBRC \
94{ "extbrc", "Extended bitrate control", OFFSET(qsv.extbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
96#define QSV_OPTION_ADAPTIVE_I \
97{ "adaptive_i", "Adaptive I-frame placement", OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
99#define QSV_OPTION_ADAPTIVE_B \
100{ "adaptive_b", "Adaptive B-frame placement", OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
102#define QSV_OPTION_P_STRATEGY \
103{ "p_strategy", "Enable P-pyramid: 0-default 1-simple 2-pyramid(bf need to be set to 0).", OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, VE },
105#define QSV_OPTION_B_STRATEGY \
106{ "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
108#define QSV_OPTION_DBLK_IDC \
109{ "dblk_idc", "This option disable deblocking. It has value in range 0~2.", OFFSET(qsv.dblk_idc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE},
111#define QSV_OPTION_LOW_DELAY_BRC \
112{ "low_delay_brc", "Allow to strictly obey avg frame size", OFFSET(qsv.low_delay_brc), AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE },
114#define QSV_OPTION_MAX_MIN_QP \
115{ "max_qp_i", "Maximum video quantizer scale for I frame", OFFSET(qsv.max_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE}, \
116{ "min_qp_i", "Minimum video quantizer scale for I frame", OFFSET(qsv.min_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE}, \
117{ "max_qp_p", "Maximum video quantizer scale for P frame", OFFSET(qsv.max_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE}, \
118{ "min_qp_p", "Minimum video quantizer scale for P frame", OFFSET(qsv.min_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE}, \
119{ "max_qp_b", "Maximum video quantizer scale for B frame", OFFSET(qsv.max_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE}, \
120{ "min_qp_b", "Minimum video quantizer scale for B frame", OFFSET(qsv.min_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE},
122#define QSV_OPTION_SCENARIO \
123{ "scenario", "A hint to encoder about the scenario for the encoding session", OFFSET(qsv.scenario), AV_OPT_TYPE_INT, { .i64 = MFX_SCENARIO_UNKNOWN }, \
124 MFX_SCENARIO_UNKNOWN, MFX_SCENARIO_REMOTE_GAMING, VE, .unit = "scenario" }, \
125{ "unknown", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_UNKNOWN }, .flags = VE, .unit = "scenario" }, \
126{ "displayremoting", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_DISPLAY_REMOTING }, .flags = VE, .unit = "scenario" }, \
127{ "videoconference", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_VIDEO_CONFERENCE }, .flags = VE, .unit = "scenario" }, \
128{ "archive", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_ARCHIVE }, .flags = VE, .unit = "scenario" }, \
129{ "livestreaming", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_LIVE_STREAMING }, .flags = VE, .unit = "scenario" }, \
130{ "cameracapture", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_CAMERA_CAPTURE }, .flags = VE, .unit = "scenario" }, \
131{ "videosurveillance", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_VIDEO_SURVEILLANCE }, .flags = VE, .unit = "scenario" }, \
132{ "gamestreaming", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_GAME_STREAMING }, .flags = VE, .unit = "scenario" }, \
133{ "remotegaming", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCENARIO_REMOTE_GAMING }, .flags = VE, .unit = "scenario" },
135#define QSV_OPTION_AVBR \
136{ "avbr_accuracy", "Accuracy of the AVBR ratecontrol (unit of tenth of percent)", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, \
137{ "avbr_convergence", "Convergence of the AVBR ratecontrol (unit of 100 frames)", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE },
139#define QSV_OPTION_SKIP_FRAME \
140{ "skip_frame", "Allow frame skipping", OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \
141 MFX_SKIPFRAME_NO_SKIP, MFX_SKIPFRAME_BRC_ONLY, VE, .unit = "skip_frame" }, \
142{ "no_skip", "Frame skipping is disabled", \
143 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_NO_SKIP }, .flags = VE, .unit = "skip_frame" }, \
144{ "insert_dummy", "Encoder inserts into bitstream frame where all macroblocks are encoded as skipped", \
145 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_DUMMY }, .flags = VE, .unit = "skip_frame" }, \
146{ "insert_nothing", "Encoder inserts nothing into bitstream", \
147 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_NOTHING }, .flags = VE, .unit = "skip_frame" }, \
148{ "brc_only", "skip_frame metadata indicates the number of missed frames before the current frame", \
149 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_BRC_ONLY }, .flags = VE, .unit = "skip_frame" },
174 mfxExtMultiFrameParam extmfp;
175 mfxExtMultiFrameControl extmfc;
179#if QSV_HAVE_EXT_AV1_PARAM
180 mfxExtAV1TileParam extav1tileparam;
181 mfxExtAV1BitstreamParam extav1bsparam;
184 mfxExtHyperModeParam exthypermodeparam;
187 mfxExtOpaqueSurfaceAlloc opaque_alloc;
188 mfxFrameSurface1 **opaque_surfaces;
Libavcodec external API header.
Convenience header that includes libavutil's core.
common internal and external API header
An API-specific header for AV_HWDEVICE_TYPE_QSV.
const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[]
int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
#define QSV_HAVE_EXT_AV1_PARAM
int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
int SetEncodeCtrlCB(AVCodecContext *avctx, const AVFrame *frame, mfxEncodeCtrl *enc_ctrl)
int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, AVPacket *pkt, const AVFrame *frame, int *got_packet)
A reference to a data buffer.
main external API structure.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
AVDictionary * qsv_params
int old_int_ref_cycle_size
mfxExtCodingOption3 extco3
mfxExtVP9Param extvp9param
SetEncodeCtrlCB * set_encode_ctrl_cb
int look_ahead_downsampling
mfxExtBuffer * extparam_internal[5+(QSV_HAVE_MF *2)+(QSV_HAVE_EXT_AV1_PARAM *2)+QSV_HAVE_HE]
mfxExtBuffer ** extparam_str
int old_rc_initial_buffer_occupancy
QSVFramesContext frames_ctx
mfxExtVideoSignalInfo extvsi
int max_dec_frame_buffering
int exthypermodeparam_idx
mfxExtHEVCTiles exthevctiles
mfxExtCodingOption2 extco2
int old_int_ref_cycle_dist