avcodec/nvenc: add new Video SDK 10 features
1. new Nvenc presets 2. new multipass encode modes 3. low delay key frame scale Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
parent
f3dc38a186
commit
9115d77222
@ -42,6 +42,12 @@
|
||||
rc == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || \
|
||||
rc == NV_ENC_PARAMS_RC_CBR_HQ)
|
||||
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
#define IS_SDK10_PRESET(p) ((p) >= PRESET_P1 && (p) <= PRESET_P7)
|
||||
#else
|
||||
#define IS_SDK10_PRESET(p) 0
|
||||
#endif
|
||||
|
||||
const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
|
||||
AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_NV12,
|
||||
@ -145,8 +151,14 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
|
||||
|
||||
static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
|
||||
{
|
||||
#if NVENCAPI_CHECK_VERSION(9, 2)
|
||||
#if NVENCAPI_CHECK_VERSION(10, 1)
|
||||
const char *minver = "(unknown)";
|
||||
#elif NVENCAPI_CHECK_VERSION(10, 0)
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
const char *minver = "450.51";
|
||||
# else
|
||||
const char *minver = "445.87";
|
||||
# endif
|
||||
#elif NVENCAPI_CHECK_VERSION(9, 1)
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
const char *minver = "436.15";
|
||||
@ -650,6 +662,15 @@ static void nvenc_map_preset(NvencContext *ctx)
|
||||
PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY),
|
||||
PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS),
|
||||
PRESET(LOSSLESS_HP, NVENC_LOSSLESS),
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
PRESET(P1),
|
||||
PRESET(P2),
|
||||
PRESET(P3),
|
||||
PRESET(P4),
|
||||
PRESET(P5),
|
||||
PRESET(P6),
|
||||
PRESET(P7),
|
||||
#endif
|
||||
};
|
||||
|
||||
GUIDTuple *t = &presets[ctx->preset];
|
||||
@ -859,6 +880,12 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
|
||||
if (avctx->rc_max_rate > 0)
|
||||
ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
|
||||
|
||||
#ifdef NVENC_HAVE_MULTIPASS
|
||||
ctx->encode_config.rcParams.multiPass = ctx->multipass;
|
||||
if (ctx->encode_config.rcParams.multiPass != NV_ENC_MULTI_PASS_DISABLED)
|
||||
ctx->flags |= NVENC_TWO_PASSES;
|
||||
#endif
|
||||
|
||||
if (ctx->rc < 0) {
|
||||
if (ctx->flags & NVENC_ONE_PASS)
|
||||
ctx->twopass = 0;
|
||||
@ -893,6 +920,11 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
|
||||
ctx->rc &= ~RC_MODE_DEPRECATED;
|
||||
}
|
||||
|
||||
#ifdef NVENC_HAVE_LDKFS
|
||||
if (ctx->ldkfs)
|
||||
ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs;
|
||||
#endif
|
||||
|
||||
if (ctx->flags & NVENC_LOSSLESS) {
|
||||
set_lossless(avctx);
|
||||
} else if (ctx->rc >= 0) {
|
||||
@ -1202,10 +1234,27 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
||||
preset_config.version = NV_ENC_PRESET_CONFIG_VER;
|
||||
preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
|
||||
|
||||
nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
|
||||
ctx->init_encode_params.encodeGUID,
|
||||
ctx->init_encode_params.presetGUID,
|
||||
&preset_config);
|
||||
if (IS_SDK10_PRESET(ctx->preset)) {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
ctx->init_encode_params.tuningInfo = ctx->tuning_info;
|
||||
|
||||
nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
|
||||
ctx->init_encode_params.encodeGUID,
|
||||
ctx->init_encode_params.presetGUID,
|
||||
ctx->init_encode_params.tuningInfo,
|
||||
&preset_config);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
// Turn off tuning info parameter if older presets are on
|
||||
ctx->init_encode_params.tuningInfo = 0;
|
||||
#endif
|
||||
|
||||
nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
|
||||
ctx->init_encode_params.encodeGUID,
|
||||
ctx->init_encode_params.presetGUID,
|
||||
&preset_config);
|
||||
}
|
||||
if (nv_status != NV_ENC_SUCCESS)
|
||||
return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration");
|
||||
|
||||
@ -1228,6 +1277,17 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
||||
ctx->init_encode_params.enableEncodeAsync = 0;
|
||||
ctx->init_encode_params.enablePTD = 1;
|
||||
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
/* If lookahead isn't set from CLI, use value from preset.
|
||||
* P6 & P7 presets may enable lookahead for better quality.
|
||||
* */
|
||||
if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead)
|
||||
ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth;
|
||||
|
||||
if (ctx->init_encode_params.tuningInfo == NV_ENC_TUNING_INFO_LOSSLESS)
|
||||
ctx->flags |= NVENC_LOSSLESS;
|
||||
#endif
|
||||
|
||||
if (ctx->weighted_pred == 1)
|
||||
ctx->init_encode_params.enableWeightedPrediction = 1;
|
||||
|
||||
|
@ -62,6 +62,13 @@ typedef void ID3D11Device;
|
||||
#define NVENC_HAVE_GETLASTERRORSTRING
|
||||
#endif
|
||||
|
||||
// SDK 10.0 compile time feature checks
|
||||
#if NVENCAPI_CHECK_VERSION(10, 0)
|
||||
#define NVENC_HAVE_NEW_PRESETS
|
||||
#define NVENC_HAVE_MULTIPASS
|
||||
#define NVENC_HAVE_LDKFS
|
||||
#endif
|
||||
|
||||
typedef struct NvencSurface
|
||||
{
|
||||
NV_ENC_INPUT_PTR input_surface;
|
||||
@ -98,6 +105,15 @@ enum {
|
||||
PRESET_LOW_LATENCY_HP,
|
||||
PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones
|
||||
PRESET_LOSSLESS_HP,
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
PRESET_P1,
|
||||
PRESET_P2,
|
||||
PRESET_P3,
|
||||
PRESET_P4,
|
||||
PRESET_P5,
|
||||
PRESET_P6,
|
||||
PRESET_P7,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -198,6 +214,9 @@ typedef struct NvencContext
|
||||
int a53_cc;
|
||||
int s12m_tc;
|
||||
int dpb_size;
|
||||
int tuning_info;
|
||||
int multipass;
|
||||
int ldkfs;
|
||||
} NvencContext;
|
||||
|
||||
int ff_nvenc_encode_init(AVCodecContext *avctx);
|
||||
|
@ -26,7 +26,11 @@
|
||||
#define OFFSET(x) offsetof(NvencContext, x)
|
||||
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
||||
static const AVOption options[] = {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" },
|
||||
#else
|
||||
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
|
||||
#endif
|
||||
{ "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" },
|
||||
{ "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" },
|
||||
{ "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" },
|
||||
@ -39,6 +43,20 @@ static const AVOption options[] = {
|
||||
{ "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" },
|
||||
{ "lossless", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" },
|
||||
{ "losslesshp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" },
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
{ "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" },
|
||||
{ "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" },
|
||||
{ "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" },
|
||||
{ "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" },
|
||||
{ "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" },
|
||||
{ "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" },
|
||||
{ "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" },
|
||||
{ "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" },
|
||||
{ "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" },
|
||||
{ "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" },
|
||||
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" },
|
||||
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" },
|
||||
#endif
|
||||
{ "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_H264_PROFILE_MAIN }, NV_ENC_H264_PROFILE_BASELINE, NV_ENC_H264_PROFILE_HIGH_444P, VE, "profile" },
|
||||
{ "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_BASELINE }, 0, 0, VE, "profile" },
|
||||
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_MAIN }, 0, 0, VE, "profile" },
|
||||
@ -142,6 +160,18 @@ static const AVOption options[] = {
|
||||
{ "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
|
||||
{ "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)",
|
||||
OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
|
||||
#ifdef NVENC_HAVE_MULTIPASS
|
||||
{ "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" },
|
||||
{ "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" },
|
||||
{ "qres", "Two Pass encoding is enabled where first Pass is quarter resolution",
|
||||
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" },
|
||||
{ "fullres", "Two Pass encoding is enabled where first Pass is full resolution",
|
||||
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" },
|
||||
#endif
|
||||
#ifdef NVENC_HAVE_LDKFS
|
||||
{ "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR",
|
||||
OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,11 @@
|
||||
#define OFFSET(x) offsetof(NvencContext, x)
|
||||
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
||||
static const AVOption options[] = {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" },
|
||||
#else
|
||||
{ "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
|
||||
#endif
|
||||
{ "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" },
|
||||
{ "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" },
|
||||
{ "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" },
|
||||
@ -39,6 +43,20 @@ static const AVOption options[] = {
|
||||
{ "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" },
|
||||
{ "lossless", "lossless", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" },
|
||||
{ "losslesshp", "lossless hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" },
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
{ "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" },
|
||||
{ "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" },
|
||||
{ "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" },
|
||||
{ "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" },
|
||||
{ "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" },
|
||||
{ "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" },
|
||||
{ "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" },
|
||||
{ "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" },
|
||||
{ "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" },
|
||||
{ "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" },
|
||||
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" },
|
||||
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" },
|
||||
#endif
|
||||
{ "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile" },
|
||||
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
|
||||
{ "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" },
|
||||
@ -133,6 +151,18 @@ static const AVOption options[] = {
|
||||
{ "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
|
||||
{ "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)",
|
||||
OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
|
||||
#ifdef NVENC_HAVE_MULTIPASS
|
||||
{ "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" },
|
||||
{ "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" },
|
||||
{ "qres", "Two Pass encoding is enabled where first Pass is quarter resolution",
|
||||
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" },
|
||||
{ "fullres", "Two Pass encoding is enabled where first Pass is full resolution",
|
||||
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" },
|
||||
#endif
|
||||
#ifdef NVENC_HAVE_LDKFS
|
||||
{ "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR",
|
||||
OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 58
|
||||
#define LIBAVCODEC_VERSION_MINOR 93
|
||||
#define LIBAVCODEC_VERSION_MICRO 101
|
||||
#define LIBAVCODEC_VERSION_MICRO 102
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user