mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec/nvenc: fix lossless tuning logic
Relying on the order of the enum is bad. It clashes with the new presets having to sit at the end of the list, so that they can be properly filtered out by the options parser on builds with older SDKs. So this refactors nvenc.c to instead rely on the internal NVENC_LOSSLESS flag. For this, the preset mapping has to happen much earlier, so it's moved from nvenc_setup_encoder to nvenc_setup_device and thus runs before the device capability check.
This commit is contained in:
parent
d43b26b30d
commit
988f2e9eb0
@ -152,6 +152,70 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct GUIDTuple {
|
||||
const GUID guid;
|
||||
int flags;
|
||||
} GUIDTuple;
|
||||
|
||||
#define PRESET_ALIAS(alias, name, ...) \
|
||||
[PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ }
|
||||
|
||||
#define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__)
|
||||
|
||||
static void nvenc_map_preset(NvencContext *ctx)
|
||||
{
|
||||
GUIDTuple presets[] = {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
PRESET(P1),
|
||||
PRESET(P2),
|
||||
PRESET(P3),
|
||||
PRESET(P4),
|
||||
PRESET(P5),
|
||||
PRESET(P6),
|
||||
PRESET(P7),
|
||||
PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES),
|
||||
PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS),
|
||||
PRESET_ALIAS(FAST, P1, NVENC_ONE_PASS),
|
||||
// Compat aliases
|
||||
PRESET_ALIAS(DEFAULT, P4, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(HP, P1, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(HQ, P7, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(BD, P5, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOW_LATENCY_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOW_LATENCY_HQ, P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
|
||||
PRESET_ALIAS(LOSSLESS_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
|
||||
#else
|
||||
PRESET(DEFAULT),
|
||||
PRESET(HP),
|
||||
PRESET(HQ),
|
||||
PRESET(BD),
|
||||
PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES),
|
||||
PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS),
|
||||
PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS),
|
||||
PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY),
|
||||
PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY),
|
||||
PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY),
|
||||
PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS),
|
||||
PRESET(LOSSLESS_HP, NVENC_LOSSLESS),
|
||||
#endif
|
||||
};
|
||||
|
||||
GUIDTuple *t = &presets[ctx->preset];
|
||||
|
||||
ctx->init_encode_params.presetGUID = t->guid;
|
||||
ctx->flags = t->flags;
|
||||
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
if (ctx->tuning_info == NV_ENC_TUNING_INFO_LOSSLESS)
|
||||
ctx->flags |= NVENC_LOSSLESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef PRESET
|
||||
#undef PRESET_ALIAS
|
||||
|
||||
static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
|
||||
{
|
||||
#if NVENCAPI_CHECK_VERSION(11, 1)
|
||||
@ -366,7 +430,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE);
|
||||
if (ctx->preset >= PRESET_LOSSLESS_DEFAULT && ret <= 0) {
|
||||
if (ctx->flags & NVENC_LOSSLESS && ret <= 0) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Lossless encoding not supported\n");
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
@ -556,6 +620,11 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx)
|
||||
return AVERROR_BUG;
|
||||
}
|
||||
|
||||
nvenc_map_preset(ctx);
|
||||
|
||||
if (ctx->flags & NVENC_DEPRECATED_PRESET)
|
||||
av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n");
|
||||
|
||||
if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11 || avctx->hw_frames_ctx || avctx->hw_device_ctx) {
|
||||
AVHWFramesContext *frames_ctx;
|
||||
AVHWDeviceContext *hwdev_ctx;
|
||||
@ -646,65 +715,6 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct GUIDTuple {
|
||||
const GUID guid;
|
||||
int flags;
|
||||
} GUIDTuple;
|
||||
|
||||
#define PRESET_ALIAS(alias, name, ...) \
|
||||
[PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ }
|
||||
|
||||
#define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__)
|
||||
|
||||
static void nvenc_map_preset(NvencContext *ctx)
|
||||
{
|
||||
GUIDTuple presets[] = {
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
PRESET(P1),
|
||||
PRESET(P2),
|
||||
PRESET(P3),
|
||||
PRESET(P4),
|
||||
PRESET(P5),
|
||||
PRESET(P6),
|
||||
PRESET(P7),
|
||||
PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES),
|
||||
PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS),
|
||||
PRESET_ALIAS(FAST, P1, NVENC_ONE_PASS),
|
||||
// Compat aliases
|
||||
PRESET_ALIAS(DEFAULT, P4, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(HP, P1, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(HQ, P7, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(BD, P5, NVENC_DEPRECATED_PRESET),
|
||||
PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOW_LATENCY_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOW_LATENCY_HQ, P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
|
||||
PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
|
||||
PRESET_ALIAS(LOSSLESS_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
|
||||
#else
|
||||
PRESET(DEFAULT),
|
||||
PRESET(HP),
|
||||
PRESET(HQ),
|
||||
PRESET(BD),
|
||||
PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES),
|
||||
PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS),
|
||||
PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS),
|
||||
PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY),
|
||||
PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY),
|
||||
PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY),
|
||||
PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS),
|
||||
PRESET(LOSSLESS_HP, NVENC_LOSSLESS),
|
||||
#endif
|
||||
};
|
||||
|
||||
GUIDTuple *t = &presets[ctx->preset];
|
||||
|
||||
ctx->init_encode_params.presetGUID = t->guid;
|
||||
ctx->flags = t->flags;
|
||||
}
|
||||
|
||||
#undef PRESET
|
||||
#undef PRESET_ALIAS
|
||||
|
||||
static av_cold void set_constqp(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
@ -1262,18 +1272,15 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
||||
|
||||
ctx->init_encode_params.encodeConfig = &ctx->encode_config;
|
||||
|
||||
nvenc_map_preset(ctx);
|
||||
|
||||
if (ctx->flags & NVENC_DEPRECATED_PRESET)
|
||||
av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n");
|
||||
|
||||
preset_config.version = NV_ENC_PRESET_CONFIG_VER;
|
||||
preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
|
||||
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
ctx->init_encode_params.tuningInfo = ctx->tuning_info;
|
||||
|
||||
if (ctx->flags & NVENC_LOWLATENCY)
|
||||
if (ctx->flags & NVENC_LOSSLESS)
|
||||
ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOSSLESS;
|
||||
else if (ctx->flags & NVENC_LOWLATENCY)
|
||||
ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOW_LATENCY;
|
||||
|
||||
nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
|
||||
@ -1315,9 +1322,6 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
||||
* */
|
||||
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)
|
||||
|
@ -103,7 +103,7 @@ enum {
|
||||
PRESET_LOW_LATENCY_DEFAULT ,
|
||||
PRESET_LOW_LATENCY_HQ ,
|
||||
PRESET_LOW_LATENCY_HP,
|
||||
PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones
|
||||
PRESET_LOSSLESS_DEFAULT,
|
||||
PRESET_LOSSLESS_HP,
|
||||
#ifdef NVENC_HAVE_NEW_PRESETS
|
||||
PRESET_P1,
|
||||
|
Loading…
Reference in New Issue
Block a user