diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index dddee8cac1..b09ddbe0fa 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -144,6 +144,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) @@ -358,7 +422,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); } @@ -548,6 +612,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; @@ -638,65 +707,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; @@ -1254,18 +1264,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, @@ -1307,9 +1314,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) diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index fefc5f7f0b..314c270e74 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -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,