avcodec/nvenc: use AVOptions to select presets
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
parent
e1de62c5be
commit
faffff88c2
@ -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;
|
||||
|
||||
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 = (ctx->flags & NVENC_LOWLATENCY) != 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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");
|
||||
|
||||
if (ctx->twopass < 0) {
|
||||
ctx->twopass = isLL;
|
||||
}
|
||||
memcpy(&ctx->encode_config, &preset_config.presetCfg, sizeof(ctx->encode_config));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
ctx->init_encode_params.encodeGUID = codec;
|
||||
ctx->init_encode_params.encodeHeight = avctx->height;
|
||||
ctx->init_encode_params.encodeWidth = avctx->width;
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user