mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/nvenc: add rate control option
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
parent
40df468ab1
commit
f84dfbc74a
|
@ -40,6 +40,10 @@
|
|||
#include "libavutil/hwcontext_cuda.h"
|
||||
#endif
|
||||
|
||||
#define IS_CBR(rc) (rc == NV_ENC_PARAMS_RC_CBR || \
|
||||
rc == NV_ENC_PARAMS_RC_2_PASS_QUALITY || \
|
||||
rc == NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP)
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define LOAD_FUNC(l, s) GetProcAddress(l, s)
|
||||
#define DL_CLOSE_FUNC(l) FreeLibrary(l)
|
||||
|
@ -485,45 +489,121 @@ static void nvenc_map_preset(NvencContext *ctx)
|
|||
static av_cold void set_constqp(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
|
||||
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
ctx->encode_config.rcParams.constQP.qpInterB = avctx->global_quality;
|
||||
ctx->encode_config.rcParams.constQP.qpInterP = avctx->global_quality;
|
||||
ctx->encode_config.rcParams.constQP.qpIntra = avctx->global_quality;
|
||||
rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
rc->constQP.qpInterB = avctx->global_quality;
|
||||
rc->constQP.qpInterP = avctx->global_quality;
|
||||
rc->constQP.qpIntra = avctx->global_quality;
|
||||
|
||||
avctx->qmin = -1;
|
||||
avctx->qmax = -1;
|
||||
}
|
||||
|
||||
static av_cold void set_vbr(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
|
||||
int qp_inter_p;
|
||||
|
||||
ctx->encode_config.rcParams.enableMinQP = 1;
|
||||
ctx->encode_config.rcParams.enableMaxQP = 1;
|
||||
if (avctx->qmin >= 0 && avctx->qmax >= 0) {
|
||||
rc->enableMinQP = 1;
|
||||
rc->enableMaxQP = 1;
|
||||
|
||||
ctx->encode_config.rcParams.minQP.qpInterB = avctx->qmin;
|
||||
ctx->encode_config.rcParams.minQP.qpInterP = avctx->qmin;
|
||||
ctx->encode_config.rcParams.minQP.qpIntra = avctx->qmin;
|
||||
rc->minQP.qpInterB = avctx->qmin;
|
||||
rc->minQP.qpInterP = avctx->qmin;
|
||||
rc->minQP.qpIntra = avctx->qmin;
|
||||
|
||||
ctx->encode_config.rcParams.maxQP.qpInterB = avctx->qmax;
|
||||
ctx->encode_config.rcParams.maxQP.qpInterP = avctx->qmax;
|
||||
ctx->encode_config.rcParams.maxQP.qpIntra = avctx->qmax;
|
||||
rc->maxQP.qpInterB = avctx->qmax;
|
||||
rc->maxQP.qpInterP = avctx->qmax;
|
||||
rc->maxQP.qpIntra = avctx->qmax;
|
||||
|
||||
qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
|
||||
} else {
|
||||
qp_inter_p = 26; // default to 26
|
||||
}
|
||||
|
||||
rc->enableInitialRCQP = 1;
|
||||
rc->initialRCQP.qpInterP = qp_inter_p;
|
||||
|
||||
if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
|
||||
rc->initialRCQP.qpIntra = av_clip(
|
||||
qp_inter_p * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
|
||||
rc->initialRCQP.qpInterB = av_clip(
|
||||
qp_inter_p * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
|
||||
} else {
|
||||
rc->initialRCQP.qpIntra = qp_inter_p;
|
||||
rc->initialRCQP.qpInterB = qp_inter_p;
|
||||
}
|
||||
}
|
||||
|
||||
static av_cold void set_lossless(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
|
||||
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
ctx->encode_config.rcParams.constQP.qpInterB = 0;
|
||||
ctx->encode_config.rcParams.constQP.qpInterP = 0;
|
||||
ctx->encode_config.rcParams.constQP.qpIntra = 0;
|
||||
rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
rc->constQP.qpInterB = 0;
|
||||
rc->constQP.qpInterP = 0;
|
||||
rc->constQP.qpIntra = 0;
|
||||
|
||||
avctx->qmin = -1;
|
||||
avctx->qmax = -1;
|
||||
}
|
||||
|
||||
static void nvenc_override_rate_control(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
|
||||
|
||||
switch (ctx->rc) {
|
||||
case NV_ENC_PARAMS_RC_CONSTQP:
|
||||
if (avctx->global_quality <= 0) {
|
||||
av_log(avctx, AV_LOG_WARNING,
|
||||
"The constant quality rate-control requires "
|
||||
"the 'global_quality' option set.\n");
|
||||
return;
|
||||
}
|
||||
set_constqp(avctx);
|
||||
return;
|
||||
case NV_ENC_PARAMS_RC_2_PASS_VBR:
|
||||
case NV_ENC_PARAMS_RC_VBR:
|
||||
if (avctx->qmin < 0 && avctx->qmax < 0) {
|
||||
av_log(avctx, AV_LOG_WARNING,
|
||||
"The variable bitrate rate-control requires "
|
||||
"the 'qmin' and/or 'qmax' option set.\n");
|
||||
set_vbr(avctx);
|
||||
return;
|
||||
}
|
||||
case NV_ENC_PARAMS_RC_VBR_MINQP:
|
||||
if (avctx->qmin < 0) {
|
||||
av_log(avctx, AV_LOG_WARNING,
|
||||
"The variable bitrate rate-control requires "
|
||||
"the 'qmin' option set.\n");
|
||||
set_vbr(avctx);
|
||||
return;
|
||||
}
|
||||
set_vbr(avctx);
|
||||
break;
|
||||
case NV_ENC_PARAMS_RC_CBR:
|
||||
break;
|
||||
case NV_ENC_PARAMS_RC_2_PASS_QUALITY:
|
||||
case NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP:
|
||||
if (!(ctx->flags & NVENC_LOWLATENCY)) {
|
||||
av_log(avctx, AV_LOG_WARNING,
|
||||
"The multipass rate-control requires "
|
||||
"a low-latency preset.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rc->rateControlMode = ctx->rc;
|
||||
}
|
||||
|
||||
static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
|
||||
{
|
||||
NvencContext *ctx = avctx->priv_data;
|
||||
|
||||
int qp_inter_p;
|
||||
|
||||
if (avctx->bit_rate > 0) {
|
||||
ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate;
|
||||
} else if (ctx->encode_config.rcParams.averageBitRate > 0) {
|
||||
|
@ -533,72 +613,37 @@ 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;
|
||||
|
||||
if (ctx->flags & NVENC_LOSSLESS) {
|
||||
set_lossless(avctx);
|
||||
if (ctx->rc < 0) {
|
||||
if (ctx->flags & NVENC_ONE_PASS)
|
||||
ctx->twopass = 0;
|
||||
if (ctx->flags & NVENC_TWO_PASSES)
|
||||
ctx->twopass = 1;
|
||||
|
||||
avctx->qmin = -1;
|
||||
avctx->qmax = -1;
|
||||
} else if (ctx->cbr) {
|
||||
if (!ctx->twopass) {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR;
|
||||
if (ctx->twopass < 0)
|
||||
ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;
|
||||
|
||||
if (ctx->cbr) {
|
||||
if (ctx->twopass) {
|
||||
ctx->rc = NV_ENC_PARAMS_RC_2_PASS_QUALITY;
|
||||
} else {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_2_PASS_QUALITY;
|
||||
|
||||
if (avctx->codec->id == AV_CODEC_ID_H264) {
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE;
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.fmoMode = NV_ENC_H264_FMO_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (avctx->codec->id == AV_CODEC_ID_H264) {
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.outputBufferingPeriodSEI = 1;
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.outputPictureTimingSEI = 1;
|
||||
} else if (avctx->codec->id == AV_CODEC_ID_H265) {
|
||||
ctx->encode_config.encodeCodecConfig.hevcConfig.outputBufferingPeriodSEI = 1;
|
||||
ctx->encode_config.encodeCodecConfig.hevcConfig.outputPictureTimingSEI = 1;
|
||||
ctx->rc = NV_ENC_PARAMS_RC_CBR;
|
||||
}
|
||||
} else if (avctx->global_quality > 0) {
|
||||
set_constqp(avctx);
|
||||
|
||||
avctx->qmin = -1;
|
||||
avctx->qmax = -1;
|
||||
} else {
|
||||
if (avctx->qmin >= 0 && avctx->qmax >= 0) {
|
||||
set_vbr(avctx);
|
||||
|
||||
qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
|
||||
|
||||
if (ctx->twopass) {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_2_PASS_VBR;
|
||||
if (avctx->codec->id == AV_CODEC_ID_H264) {
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE;
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.fmoMode = NV_ENC_H264_FMO_DISABLE;
|
||||
ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
} else if (ctx->twopass) {
|
||||
ctx->rc = NV_ENC_PARAMS_RC_2_PASS_VBR;
|
||||
} else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
|
||||
ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;
|
||||
}
|
||||
} else {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR_MINQP;
|
||||
}
|
||||
} else {
|
||||
qp_inter_p = 26; // default to 26
|
||||
|
||||
if (ctx->twopass) {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_2_PASS_VBR;
|
||||
if (ctx->flags & NVENC_LOSSLESS) {
|
||||
set_lossless(avctx);
|
||||
} else if (ctx->rc > 0) {
|
||||
nvenc_override_rate_control(avctx);
|
||||
} else {
|
||||
ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->encode_config.rcParams.enableInitialRCQP = 1;
|
||||
ctx->encode_config.rcParams.initialRCQP.qpInterP = qp_inter_p;
|
||||
|
||||
if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
|
||||
ctx->encode_config.rcParams.initialRCQP.qpIntra = av_clip(
|
||||
qp_inter_p * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
|
||||
ctx->encode_config.rcParams.initialRCQP.qpInterB = av_clip(
|
||||
qp_inter_p * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
|
||||
} else {
|
||||
ctx->encode_config.rcParams.initialRCQP.qpIntra = qp_inter_p;
|
||||
ctx->encode_config.rcParams.initialRCQP.qpInterB = qp_inter_p;
|
||||
}
|
||||
set_vbr(avctx);
|
||||
}
|
||||
|
||||
if (avctx->rc_buffer_size > 0) {
|
||||
|
@ -634,9 +679,28 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
|
|||
|
||||
h264->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
|
||||
h264->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
|
||||
|
||||
h264->outputAUD = 1;
|
||||
|
||||
if (avctx->refs >= 0) {
|
||||
/* 0 means "let the hardware decide" */
|
||||
h264->maxNumRefFrames = avctx->refs;
|
||||
}
|
||||
if (avctx->gop_size >= 0) {
|
||||
h264->idrPeriod = cc->gopLength;
|
||||
}
|
||||
|
||||
if (IS_CBR(cc->rcParams.rateControlMode)) {
|
||||
h264->outputBufferingPeriodSEI = 1;
|
||||
h264->outputPictureTimingSEI = 1;
|
||||
}
|
||||
|
||||
if (cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_2_PASS_QUALITY ||
|
||||
cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP ||
|
||||
cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_2_PASS_VBR) {
|
||||
h264->adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE;
|
||||
h264->fmoMode = NV_ENC_H264_FMO_DISABLE;
|
||||
}
|
||||
|
||||
if (ctx->flags & NVENC_LOSSLESS) {
|
||||
h264->qpPrimeYZeroTransformBypassFlag = 1;
|
||||
} else {
|
||||
|
@ -699,9 +763,21 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
|
|||
|
||||
hevc->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
|
||||
hevc->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
|
||||
|
||||
hevc->outputAUD = 1;
|
||||
|
||||
if (avctx->refs >= 0) {
|
||||
/* 0 means "let the hardware decide" */
|
||||
hevc->maxNumRefFramesInDPB = avctx->refs;
|
||||
}
|
||||
if (avctx->gop_size >= 0) {
|
||||
hevc->idrPeriod = cc->gopLength;
|
||||
}
|
||||
|
||||
if (IS_CBR(cc->rcParams.rateControlMode)) {
|
||||
hevc->outputBufferingPeriodSEI = 1;
|
||||
hevc->outputPictureTimingSEI = 1;
|
||||
}
|
||||
|
||||
/* No other profile is supported in the current SDK version 5 */
|
||||
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
|
||||
avctx->profile = FF_PROFILE_HEVC_MAIN;
|
||||
|
@ -751,15 +827,6 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -811,19 +878,6 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
|||
ctx->init_encode_params.enableEncodeAsync = 0;
|
||||
ctx->init_encode_params.enablePTD = 1;
|
||||
|
||||
if (avctx->refs >= 0) {
|
||||
/* 0 means "let the hardware decide" */
|
||||
switch (avctx->codec->id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.maxNumRefFrames = avctx->refs;
|
||||
break;
|
||||
case AV_CODEC_ID_H265:
|
||||
ctx->encode_config.encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB = avctx->refs;
|
||||
break;
|
||||
/* Earlier switch/case will return if unknown codec is passed. */
|
||||
}
|
||||
}
|
||||
|
||||
if (avctx->gop_size > 0) {
|
||||
if (avctx->max_b_frames >= 0) {
|
||||
/* 0 is intra-only, 1 is I/P only, 2 is one B Frame, 3 two B frames, and so on. */
|
||||
|
@ -831,27 +885,9 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
|
|||
}
|
||||
|
||||
ctx->encode_config.gopLength = avctx->gop_size;
|
||||
switch (avctx->codec->id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.idrPeriod = avctx->gop_size;
|
||||
break;
|
||||
case AV_CODEC_ID_H265:
|
||||
ctx->encode_config.encodeCodecConfig.hevcConfig.idrPeriod = avctx->gop_size;
|
||||
break;
|
||||
/* Earlier switch/case will return if unknown codec is passed. */
|
||||
}
|
||||
} else if (avctx->gop_size == 0) {
|
||||
ctx->encode_config.frameIntervalP = 0;
|
||||
ctx->encode_config.gopLength = 1;
|
||||
switch (avctx->codec->id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
ctx->encode_config.encodeCodecConfig.h264Config.idrPeriod = 1;
|
||||
break;
|
||||
case AV_CODEC_ID_H265:
|
||||
ctx->encode_config.encodeCodecConfig.hevcConfig.idrPeriod = 1;
|
||||
break;
|
||||
/* Earlier switch/case will return if unknown codec is passed. */
|
||||
}
|
||||
}
|
||||
|
||||
/* when there're b frames, set dts offset */
|
||||
|
|
|
@ -170,6 +170,7 @@ typedef struct NvencContext
|
|||
int profile;
|
||||
int level;
|
||||
int tier;
|
||||
int rc;
|
||||
int cbr;
|
||||
int twopass;
|
||||
int gpu;
|
||||
|
|
|
@ -68,6 +68,14 @@ static const AVOption options[] = {
|
|||
{ "5", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" },
|
||||
{ "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" },
|
||||
{ "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_51 }, 0, 0, VE, "level" },
|
||||
{ "rc", "Override the preset rate-control", OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "rc" },
|
||||
{ "constqp", "Constant QP mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CONSTQP }, 0, 0, VE, "rc" },
|
||||
{ "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR }, 0, 0, VE, "rc" },
|
||||
{ "cbr", "Constant bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR }, 0, 0, VE, "rc" },
|
||||
{ "vbr_minqp", "Variable bitrate mode with MinQP", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR_MINQP }, 0, 0, VE, "rc" },
|
||||
{ "ll_2pass_quality", "Multi-pass optimized for image quality (only for low-latency presets)", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_QUALITY }, 0, 0, VE, "rc" },
|
||||
{ "ll_2pass_size", "Multi-pass optimized for constant frame size (only for low-latency presets)", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP }, 0, 0, VE, "rc" },
|
||||
{ "vbr_2pass", "Multi-pass variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_VBR }, 0, 0, VE, "rc" },
|
||||
{ "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
|
||||
{ "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
|
||||
{ "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
|
||||
|
|
|
@ -65,6 +65,14 @@ static const AVOption options[] = {
|
|||
{ "tier", "Set the encoding tier", OFFSET(tier), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TIER_HEVC_MAIN }, NV_ENC_TIER_HEVC_MAIN, NV_ENC_TIER_HEVC_HIGH, VE, "tier"},
|
||||
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TIER_HEVC_MAIN }, 0, 0, VE, "tier" },
|
||||
{ "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TIER_HEVC_HIGH }, 0, 0, VE, "tier" },
|
||||
{ "rc", "Override the preset rate-control", OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "rc" },
|
||||
{ "constqp", "Constant QP mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CONSTQP }, 0, 0, VE, "rc" },
|
||||
{ "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR }, 0, 0, VE, "rc" },
|
||||
{ "cbr", "Constant bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CBR }, 0, 0, VE, "rc" },
|
||||
{ "vbr_minqp", "Variable bitrate mode with MinQP", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR_MINQP }, 0, 0, VE, "rc" },
|
||||
{ "ll_2pass_quality", "Multi-pass optimized for image quality (only for low-latency presets)", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_QUALITY }, 0, 0, VE, "rc" },
|
||||
{ "ll_2pass_size", "Multi-pass optimized for constant frame size (only for low-latency presets)", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP }, 0, 0, VE, "rc" },
|
||||
{ "vbr_2pass", "Multi-pass variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_2_PASS_VBR }, 0, 0, VE, "rc" },
|
||||
{ "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
|
||||
{ "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
|
||||
{ "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
|
||||
|
|
Loading…
Reference in New Issue