[FFmpeg-cvslog] avcodec/nvenc: use AVOptions to select presets
Andrey Turkin
git at videolan.org
Tue May 31 15:52:46 CEST 2016
ffmpeg | branch: master | Andrey Turkin <andrey.turkin at gmail.com> | Wed May 25 17:05:50 2016 +0300| [faffff88c21c24765e5a3c87ffc657b191c4efc0] | committer: Timo Rothenpieler
avcodec/nvenc: use AVOptions to select presets
Signed-off-by: Timo Rothenpieler <timo at rothenpieler.org>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=faffff88c21c24765e5a3c87ffc657b191c4efc0
---
libavcodec/nvenc.c | 255 +++++++++++++++++++++++------------------------
libavcodec/nvenc.h | 25 ++++-
libavcodec/nvenc_h264.c | 14 ++-
libavcodec/nvenc_hevc.c | 14 ++-
4 files changed, 177 insertions(+), 131 deletions(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 4e42202..7166b9d 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -302,7 +302,7 @@ static av_cold int nvenc_check_cuda(AVCodecContext *avctx)
goto error;
}
- if (!strncmp(ctx->preset, "lossless", 8))
+ if (ctx->preset >= PRESET_LOSSLESS_DEFAULT)
target_smver = 0x52;
if (!nvenc_dyload_cuda(avctx))
@@ -444,6 +444,17 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx)
CUresult cu_res;
CUcontext cu_context_curr;
+ switch (avctx->codec->id) {
+ case AV_CODEC_ID_H264:
+ ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_H264_GUID;
+ break;
+ case AV_CODEC_ID_HEVC:
+ ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_HEVC_GUID;
+ break;
+ default:
+ return AVERROR_BUG;
+ }
+
ctx->data_pix_fmt = avctx->pix_fmt;
#if CONFIG_CUDA
@@ -512,6 +523,34 @@ static av_cold int nvenc_open_session(AVCodecContext *avctx)
return 0;
}
+typedef struct GUIDTuple {
+ const GUID guid;
+ int flags;
+} GUIDTuple;
+
+static void nvenc_map_preset(NvencContext *ctx)
+{
+ GUIDTuple presets[] = {
+ { NV_ENC_PRESET_DEFAULT_GUID },
+ { NV_ENC_PRESET_HQ_GUID, NVENC_TWO_PASSES }, /* slow */
+ { NV_ENC_PRESET_HQ_GUID, NVENC_ONE_PASS }, /* medium */
+ { NV_ENC_PRESET_HP_GUID, NVENC_ONE_PASS }, /* fast */
+ { NV_ENC_PRESET_HP_GUID },
+ { NV_ENC_PRESET_HQ_GUID },
+ { NV_ENC_PRESET_BD_GUID },
+ { NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID, NVENC_LOWLATENCY },
+ { NV_ENC_PRESET_LOW_LATENCY_HQ_GUID, NVENC_LOWLATENCY },
+ { NV_ENC_PRESET_LOW_LATENCY_HP_GUID, NVENC_LOWLATENCY },
+ { NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID, NVENC_LOSSLESS },
+ { NV_ENC_PRESET_LOSSLESS_HP_GUID, NVENC_LOSSLESS },
+ };
+
+ GUIDTuple *t = &presets[ctx->preset];
+
+ ctx->init_encode_params.presetGUID = t->guid;
+ ctx->flags = t->flags;
+}
+
static av_cold void set_constqp(AVCodecContext *avctx)
{
NvencContext *ctx = avctx->priv_data;
@@ -548,7 +587,7 @@ static av_cold void set_lossless(AVCodecContext *avctx)
ctx->encode_config.rcParams.constQP.qpIntra = 0;
}
-static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx, int lossless)
+static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
{
NvencContext *ctx = avctx->priv_data;
@@ -563,7 +602,7 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx, int lossless
if (avctx->rc_max_rate > 0)
ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
- if (lossless) {
+ if (ctx->flags & NVENC_LOSSLESS) {
if (avctx->codec->id == AV_CODEC_ID_H264)
ctx->encode_config.encodeCodecConfig.h264Config.qpPrimeYZeroTransformBypassFlag = 1;
@@ -641,65 +680,68 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx, int lossless
}
}
-static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx, int lossless)
+static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
{
- NvencContext *ctx = avctx->priv_data;
+ NvencContext *ctx = avctx->priv_data;
+ NV_ENC_CONFIG *cc = &ctx->encode_config;
+ NV_ENC_CONFIG_H264 *h264 = &cc->encodeCodecConfig.h264Config;
+ NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui = &h264->h264VUIParameters;
int res;
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.colourMatrix = avctx->colorspace;
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.colourPrimaries = avctx->color_primaries;
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.transferCharacteristics = avctx->color_trc;
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
+ vui->colourMatrix = avctx->colorspace;
+ vui->colourPrimaries = avctx->color_primaries;
+ vui->transferCharacteristics = avctx->color_trc;
+ vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
|| ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.colourDescriptionPresentFlag =
+ vui->colourDescriptionPresentFlag =
(avctx->colorspace != 2 || avctx->color_primaries != 2 || avctx->color_trc != 2);
- ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.videoSignalTypePresentFlag =
- (ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.colourDescriptionPresentFlag
- || ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.videoFormat != 5
- || ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag != 0);
+ vui->videoSignalTypePresentFlag =
+ (vui->colourDescriptionPresentFlag
+ || vui->videoFormat != 5
+ || vui->videoFullRangeFlag != 0);
- ctx->encode_config.encodeCodecConfig.h264Config.sliceMode = 3;
- ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData = 1;
+ h264->sliceMode = 3;
+ h264->sliceModeData = 1;
- ctx->encode_config.encodeCodecConfig.h264Config.disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
- ctx->encode_config.encodeCodecConfig.h264Config.repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
+ h264->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
+ h264->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
- ctx->encode_config.encodeCodecConfig.h264Config.outputAUD = 1;
+ h264->outputAUD = 1;
- if (!ctx->profile && !lossless) {
+ if (!ctx->profile && !(ctx->flags & NVENC_LOSSLESS)) {
switch (avctx->profile) {
case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
break;
case FF_PROFILE_H264_BASELINE:
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
break;
case FF_PROFILE_H264_MAIN:
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
break;
case FF_PROFILE_H264_HIGH:
case FF_PROFILE_UNKNOWN:
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
break;
default:
av_log(avctx, AV_LOG_WARNING, "Unsupported profile requested, falling back to high\n");
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
break;
}
- } else if (!lossless) {
+ } else if (!(ctx->flags & NVENC_LOSSLESS)) {
if (!strcmp(ctx->profile, "high")) {
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
avctx->profile = FF_PROFILE_H264_HIGH;
} else if (!strcmp(ctx->profile, "main")) {
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
avctx->profile = FF_PROFILE_H264_MAIN;
} else if (!strcmp(ctx->profile, "baseline")) {
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
avctx->profile = FF_PROFILE_H264_BASELINE;
} else if (!strcmp(ctx->profile, "high444p")) {
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
} else {
av_log(avctx, AV_LOG_FATAL, "Profile \"%s\" is unknown! Supported profiles: high, main, baseline\n", ctx->profile);
@@ -709,21 +751,21 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx, int lossless)
// force setting profile as high444p if input is AV_PIX_FMT_YUV444P
if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P) {
- ctx->encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
}
- ctx->encode_config.encodeCodecConfig.h264Config.chromaFormatIDC = avctx->profile == FF_PROFILE_H264_HIGH_444_PREDICTIVE ? 3 : 1;
+ h264->chromaFormatIDC = avctx->profile == FF_PROFILE_H264_HIGH_444_PREDICTIVE ? 3 : 1;
if (ctx->level) {
- res = input_string_to_uint32(avctx, nvenc_h264_level_pairs, ctx->level, &ctx->encode_config.encodeCodecConfig.h264Config.level);
+ res = input_string_to_uint32(avctx, nvenc_h264_level_pairs, ctx->level, &h264->level);
if (res) {
av_log(avctx, AV_LOG_FATAL, "Level \"%s\" is unknown! Supported levels: auto, 1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2, 5, 5.1\n", ctx->level);
return res;
}
} else {
- ctx->encode_config.encodeCodecConfig.h264Config.level = NV_ENC_LEVEL_AUTOSELECT;
+ h264->level = NV_ENC_LEVEL_AUTOSELECT;
}
return 0;
@@ -731,51 +773,54 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx, int lossless)
static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
{
- NvencContext *ctx = avctx->priv_data;
+ NvencContext *ctx = avctx->priv_data;
+ NV_ENC_CONFIG *cc = &ctx->encode_config;
+ NV_ENC_CONFIG_HEVC *hevc = &cc->encodeCodecConfig.hevcConfig;
+ NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui = &hevc->hevcVUIParameters;
int res;
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourMatrix = avctx->colorspace;
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourPrimaries = avctx->color_primaries;
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.transferCharacteristics = avctx->color_trc;
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
+ vui->colourMatrix = avctx->colorspace;
+ vui->colourPrimaries = avctx->color_primaries;
+ vui->transferCharacteristics = avctx->color_trc;
+ vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
|| ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourDescriptionPresentFlag =
+ vui->colourDescriptionPresentFlag =
(avctx->colorspace != 2 || avctx->color_primaries != 2 || avctx->color_trc != 2);
- ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoSignalTypePresentFlag =
- (ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourDescriptionPresentFlag
- || ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFormat != 5
- || ctx->encode_config.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag != 0);
+ vui->videoSignalTypePresentFlag =
+ (vui->colourDescriptionPresentFlag
+ || vui->videoFormat != 5
+ || vui->videoFullRangeFlag != 0);
- ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode = 3;
- ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData = 1;
+ hevc->sliceMode = 3;
+ hevc->sliceModeData = 1;
- ctx->encode_config.encodeCodecConfig.hevcConfig.disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
- ctx->encode_config.encodeCodecConfig.hevcConfig.repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
+ hevc->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
+ hevc->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
- ctx->encode_config.encodeCodecConfig.hevcConfig.outputAUD = 1;
+ hevc->outputAUD = 1;
/* No other profile is supported in the current SDK version 5 */
- ctx->encode_config.profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
+ cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
avctx->profile = FF_PROFILE_HEVC_MAIN;
if (ctx->level) {
- res = input_string_to_uint32(avctx, nvenc_hevc_level_pairs, ctx->level, &ctx->encode_config.encodeCodecConfig.hevcConfig.level);
+ res = input_string_to_uint32(avctx, nvenc_hevc_level_pairs, ctx->level, &hevc->level);
if (res) {
av_log(avctx, AV_LOG_FATAL, "Level \"%s\" is unknown! Supported levels: auto, 1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 5.1, 5.2, 6, 6.1, 6.2\n", ctx->level);
return res;
}
} else {
- ctx->encode_config.encodeCodecConfig.hevcConfig.level = NV_ENC_LEVEL_AUTOSELECT;
+ hevc->level = NV_ENC_LEVEL_AUTOSELECT;
}
if (ctx->tier) {
if (!strcmp(ctx->tier, "main")) {
- ctx->encode_config.encodeCodecConfig.hevcConfig.tier = NV_ENC_TIER_HEVC_MAIN;
+ hevc->tier = NV_ENC_TIER_HEVC_MAIN;
} else if (!strcmp(ctx->tier, "high")) {
- ctx->encode_config.encodeCodecConfig.hevcConfig.tier = NV_ENC_TIER_HEVC_HIGH;
+ hevc->tier = NV_ENC_TIER_HEVC_HIGH;
} else {
av_log(avctx, AV_LOG_FATAL, "Tier \"%s\" is unknown! Supported tiers: main, high\n", ctx->tier);
return AVERROR(EINVAL);
@@ -785,12 +830,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
return 0;
}
-static av_cold int nvenc_setup_codec_config(AVCodecContext *avctx, int lossless)
+static av_cold int nvenc_setup_codec_config(AVCodecContext *avctx)
{
switch (avctx->codec->id) {
case AV_CODEC_ID_H264:
- return nvenc_setup_h264_config(avctx, lossless);
- case AV_CODEC_ID_H265:
+ return nvenc_setup_h264_config(avctx);
+ case AV_CODEC_ID_HEVC:
return nvenc_setup_hevc_config(avctx);
/* Earlier switch/case will return if unknown codec is passed. */
}
@@ -805,13 +850,9 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
NV_ENC_PRESET_CONFIG preset_config = { 0 };
- GUID encoder_preset = NV_ENC_PRESET_HQ_GUID;
- GUID codec;
NVENCSTATUS nv_status = NV_ENC_SUCCESS;
AVCPBProperties *cpb_props;
int num_mbs;
- int isLL = 0;
- int lossless = 0;
int res = 0;
int dw, dh;
@@ -819,72 +860,36 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
ctx->encode_config.version = NV_ENC_CONFIG_VER;
ctx->init_encode_params.version = NV_ENC_INITIALIZE_PARAMS_VER;
- preset_config.version = NV_ENC_PRESET_CONFIG_VER;
- preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
- if (ctx->preset) {
- if (!strcmp(ctx->preset, "slow")) {
- encoder_preset = NV_ENC_PRESET_HQ_GUID;
- ctx->twopass = 1;
- } else if (!strcmp(ctx->preset, "medium")) {
- encoder_preset = NV_ENC_PRESET_HQ_GUID;
- ctx->twopass = 0;
- } else if (!strcmp(ctx->preset, "fast")) {
- encoder_preset = NV_ENC_PRESET_HP_GUID;
- ctx->twopass = 0;
- } else if (!strcmp(ctx->preset, "hq")) {
- encoder_preset = NV_ENC_PRESET_HQ_GUID;
- } else if (!strcmp(ctx->preset, "hp")) {
- encoder_preset = NV_ENC_PRESET_HP_GUID;
- } else if (!strcmp(ctx->preset, "bd")) {
- encoder_preset = NV_ENC_PRESET_BD_GUID;
- } else if (!strcmp(ctx->preset, "ll")) {
- encoder_preset = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID;
- isLL = 1;
- } else if (!strcmp(ctx->preset, "llhp")) {
- encoder_preset = NV_ENC_PRESET_LOW_LATENCY_HP_GUID;
- isLL = 1;
- } else if (!strcmp(ctx->preset, "llhq")) {
- encoder_preset = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID;
- isLL = 1;
- } else if (!strcmp(ctx->preset, "lossless")) {
- encoder_preset = NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID;
- lossless = 1;
- } else if (!strcmp(ctx->preset, "losslesshp")) {
- encoder_preset = NV_ENC_PRESET_LOSSLESS_HP_GUID;
- lossless = 1;
- } else if (!strcmp(ctx->preset, "default")) {
- encoder_preset = NV_ENC_PRESET_DEFAULT_GUID;
- } else {
- av_log(avctx, AV_LOG_FATAL, "Preset \"%s\" is unknown! Supported presets: slow, medium, fast, hp, hq, bd, ll, llhp, llhq, lossless, losslesshp, default\n", ctx->preset);
- return AVERROR(EINVAL);
- }
- }
+ ctx->init_encode_params.encodeHeight = avctx->height;
+ ctx->init_encode_params.encodeWidth = avctx->width;
+
+ ctx->init_encode_params.encodeConfig = &ctx->encode_config;
+
+ nvenc_map_preset(ctx);
+
+ if (ctx->flags & NVENC_ONE_PASS)
+ ctx->twopass = 0;
+ if (ctx->flags & NVENC_TWO_PASSES)
+ ctx->twopass = 1;
if (ctx->twopass < 0) {
- ctx->twopass = isLL;
+ ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;
}
- switch (avctx->codec->id) {
- case AV_CODEC_ID_H264:
- codec = NV_ENC_CODEC_H264_GUID;
- break;
- case AV_CODEC_ID_H265:
- codec = NV_ENC_CODEC_HEVC_GUID;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");
- return AVERROR(EINVAL);
- }
+ preset_config.version = NV_ENC_PRESET_CONFIG_VER;
+ preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
- nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder, codec, encoder_preset, &preset_config);
- if (nv_status != NV_ENC_SUCCESS) {
- return nvenc_print_error(avctx, nv_status, "GetEncodePresetConfig failed");
- }
+ 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");
- ctx->init_encode_params.encodeGUID = codec;
- ctx->init_encode_params.encodeHeight = avctx->height;
- ctx->init_encode_params.encodeWidth = avctx->width;
+ memcpy(&ctx->encode_config, &preset_config.presetCfg, sizeof(ctx->encode_config));
+
+ ctx->encode_config.version = NV_ENC_CONFIG_VER;
if (avctx->sample_aspect_ratio.num && avctx->sample_aspect_ratio.den &&
(avctx->sample_aspect_ratio.num != 1 || avctx->sample_aspect_ratio.num != 1)) {
@@ -923,12 +928,6 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
ctx->init_encode_params.enableEncodeAsync = 0;
ctx->init_encode_params.enablePTD = 1;
- ctx->init_encode_params.presetGUID = encoder_preset;
-
- ctx->init_encode_params.encodeConfig = &ctx->encode_config;
- memcpy(&ctx->encode_config, &preset_config.presetCfg, sizeof(ctx->encode_config));
- ctx->encode_config.version = NV_ENC_CONFIG_VER;
-
if (avctx->refs >= 0) {
/* 0 means "let the hardware decide" */
switch (avctx->codec->id) {
@@ -976,7 +975,7 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
if (ctx->encode_config.frameIntervalP >= 2)
ctx->last_dts = -2;
- nvenc_setup_rate_control(avctx, lossless);
+ nvenc_setup_rate_control(avctx);
if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
@@ -984,7 +983,7 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME;
}
- res = nvenc_setup_codec_config(avctx, lossless);
+ res = nvenc_setup_codec_config(avctx);
if (res)
return res;
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index fdb6350..5b81fc8 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -104,6 +104,28 @@ typedef struct NvencDynLoadFunctions
} NvencDynLoadFunctions;
+enum {
+ PRESET_DEFAULT = 0,
+ PRESET_SLOW,
+ PRESET_MEDIUM,
+ PRESET_FAST,
+ PRESET_HP,
+ PRESET_HQ,
+ PRESET_BD ,
+ PRESET_LOW_LATENCY_DEFAULT ,
+ PRESET_LOW_LATENCY_HQ ,
+ PRESET_LOW_LATENCY_HP,
+ PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones
+ PRESET_LOSSLESS_HP,
+};
+
+enum {
+ NVENC_LOWLATENCY = 1,
+ NVENC_LOSSLESS = 2,
+ NVENC_ONE_PASS = 4,
+ NVENC_TWO_PASSES = 8,
+};
+
typedef struct NvencContext
{
AVClass *avclass;
@@ -137,13 +159,14 @@ typedef struct NvencContext
void *nvencoder;
- char *preset;
+ int preset;
char *profile;
char *level;
char *tier;
int cbr;
int twopass;
int gpu;
+ int flags;
int buffer_delay;
} NvencContext;
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index f91cafa..0ed3f7c 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -26,7 +26,19 @@
#define OFFSET(x) offsetof(NvencContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "preset", "Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, lossless, losslesshp, default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE },
+ { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
+ { "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" },
+ { "fast", "hp 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_FAST }, 0, 0, VE, "preset" },
+ { "hp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HP }, 0, 0, VE, "preset" },
+ { "hq", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HQ }, 0, 0, VE, "preset" },
+ { "bd", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_BD }, 0, 0, VE, "preset" },
+ { "ll", "low latency", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_DEFAULT }, 0, 0, VE, "preset" },
+ { "llhq", "low latency hq", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HQ }, 0, 0, VE, "preset" },
+ { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" },
+ { "lossless", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" },
+ { "losslesshp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" },
{ "profile", "Set the encoding profile (high, main, baseline or high444p)", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE },
{ "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, VE },
{ "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 5f8d661..28e28b3 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -26,7 +26,19 @@
#define OFFSET(x) offsetof(NvencContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "preset", "Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, lossless, losslesshp, default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE },
+ { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" },
+ { "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" },
+ { "fast", "hp 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_FAST }, 0, 0, VE, "preset" },
+ { "hp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HP }, 0, 0, VE, "preset" },
+ { "hq", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HQ }, 0, 0, VE, "preset" },
+ { "bd", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_BD }, 0, 0, VE, "preset" },
+ { "ll", "low latency", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_DEFAULT }, 0, 0, VE, "preset" },
+ { "llhq", "low latency hq", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HQ }, 0, 0, VE, "preset" },
+ { "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" },
{ "profile", "Set the encoding profile (high, main, baseline or high444p)", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE },
{ "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, VE },
{ "tier", "Set the encoding tier (main or high)", OFFSET(tier), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE },
More information about the ffmpeg-cvslog
mailing list