On Fri, Sep 11, 2015 at 05:32:06PM +0800, Agatha Hu wrote: > From: ahu <ahu@ubuntu.(none)> > > --- > libavcodec/nvenc.c | 59 > +++++++++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 54 insertions(+), 5 deletions(-) > > diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c > index 3174b01..fd90f7b 100644 > --- a/libavcodec/nvenc.c > +++ b/libavcodec/nvenc.c > @@ -610,8 +610,17 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > if (ctx->preset) { > if (!strcmp(ctx->preset, "hp")) { > encoder_preset = NV_ENC_PRESET_HP_GUID; > + } else if (!strcmp(ctx->preset, "fast")) { > + ctx->twopass = 0; > + encoder_preset = NV_ENC_PRESET_HQ_GUID; > } else if (!strcmp(ctx->preset, "hq")) { > encoder_preset = NV_ENC_PRESET_HQ_GUID; > + } else if (!strcmp(ctx->preset, "medium")) { > + ctx->twopass = 0; > + encoder_preset = NV_ENC_PRESET_HQ_GUID; > + } else if (!strcmp(ctx->preset, "slow")) { > + ctx->twopass = 1; > + encoder_preset = NV_ENC_PRESET_HQ_GUID; > } else if (!strcmp(ctx->preset, "bd")) { > encoder_preset = NV_ENC_PRESET_BD_GUID; > } else if (!strcmp(ctx->preset, "ll")) { > @@ -632,7 +641,7 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > } 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: hp, hq, bd, ll, llhp, llhq, lossless, losslesshp, default\n", > ctx->preset); > + 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); > res = AVERROR(EINVAL); > goto error; > } > @@ -710,6 +719,7 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > switch (avctx->codec->id) { > case AV_CODEC_ID_H264: > ctx->encode_config.encodeCodecConfig.h264Config.maxNumRefFrames > = avctx->refs; > + > ctx->encode_config.encodeCodecConfig.h264Config.hierarchicalPFrames = 1; > break; > case AV_CODEC_ID_H265: > > ctx->encode_config.encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB = > avctx->refs; > @@ -770,7 +780,7 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > avctx->qmin = -1; > avctx->qmax = -1; > } else if (ctx->cbr) { > - if (!ctx->twopass) { > + if (ctx->twopass < 1) { > ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_CBR; > } else if (ctx->twopass == 1 || isLL) { > ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_2_PASS_QUALITY; > @@ -799,7 +809,7 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > ctx->encode_config.encodeCodecConfig.h264Config.fmoMode = > NV_ENC_H264_FMO_DISABLE; > } > } else { > - ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_VBR; > + ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_VBR_MINQP; > } > > ctx->encode_config.rcParams.enableMinQP = 1; > @@ -812,6 +822,45 @@ static av_cold int nvenc_encode_init(AVCodecContext > *avctx) > ctx->encode_config.rcParams.maxQP.qpInterB = avctx->qmax; > ctx->encode_config.rcParams.maxQP.qpInterP = avctx->qmax; > ctx->encode_config.rcParams.maxQP.qpIntra = avctx->qmax; > + > + { > + uint32_t qpInterP = (avctx->qmax + 3*avctx->qmin)/4; // biased > towards Qmin > + ctx->encode_config.rcParams.initialRCQP.qpInterP = qpInterP; > + if(avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) > { > + ctx->encode_config.rcParams.initialRCQP.qpIntra = qpInterP * > fabs(avctx->i_quant_factor); > + ctx->encode_config.rcParams.initialRCQP.qpIntra += qpInterP > * (avctx->i_quant_offset); > + ctx->encode_config.rcParams.initialRCQP.qpInterB = qpInterP > * fabs(avctx->b_quant_factor); > + ctx->encode_config.rcParams.initialRCQP.qpInterB += qpInterP > * (avctx->b_quant_offset); > + } else { > + ctx->encode_config.rcParams.initialRCQP.qpIntra = qpInterP; > + ctx->encode_config.rcParams.initialRCQP.qpInterB = qpInterP; > + } > + } > + ctx->encode_config.rcParams.enableInitialRCQP = 1; > + } else { > + if (ctx->twopass < 1) { > + ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_VBR; > + } else { > + ctx->encode_config.rcParams.rateControlMode = > NV_ENC_PARAMS_RC_2_PASS_VBR; > + } > + > + { > + uint32_t qpInterP = 26; // default to 26 > + ctx->encode_config.rcParams.initialRCQP.qpInterP = qpInterP; > + > + if(avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) > { > + > + ctx->encode_config.rcParams.initialRCQP.qpIntra = qpInterP * > fabs(avctx->i_quant_factor); > + ctx->encode_config.rcParams.initialRCQP.qpIntra += qpInterP > * (avctx->i_quant_offset); > + > + ctx->encode_config.rcParams.initialRCQP.qpInterB = qpInterP > * fabs(avctx->b_quant_factor); > + ctx->encode_config.rcParams.initialRCQP.qpInterB += qpInterP > * (avctx->b_quant_offset); > + } else { > + ctx->encode_config.rcParams.initialRCQP.qpIntra = qpInterP; > + ctx->encode_config.rcParams.initialRCQP.qpInterB = qpInterP; > + } > + } > + ctx->encode_config.rcParams.enableInitialRCQP = 1; > } > > if (avctx->rc_buffer_size > 0) > @@ -1415,12 +1464,12 @@ static const enum AVPixelFormat pix_fmts_nvenc[] = { > #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 hq, hp, bd, ll, llhq, llhp, > default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "hq" }, 0, 0, VE }, > + { "preset", "Set the encoding preset (one of one of slow=hq 2pass, > medium= hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default)", OFFSET(preset), > AV_OPT_TYPE_STRING, { .str = "hq" }, 0, 0, VE }, > { "profile", "Set the encoding profile (high, main or baseline)", > OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 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, { 0 }, 0, 0, VE > }, > { "tier", "Set the encoding tier (main or high)", OFFSET(tier), > AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, > { "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_INT, { .i64 = > 0 }, 0, 1, VE },
> - { "2pass", "Use 2pass cbr encoding mode", OFFSET(twopass), > AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, > + { "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_INT, > { .i64 = 0 }, 0, 1, VE }, I believe you want to keep the 3 state bool (note: you probably want to use AV_OPT_TYPE_BOOL here so "auto", "true", "false" are recognized), and change ctx->twopass to sth else in nvenc_encode_init() if and only if it is set to "auto" (-1). That way, you can detect cases where the users try to set this 2pass option with a preset where it is unsupported (and raise an appropriate error). Regards, -- Clément B.
pgpf4KbA2NJU9.pgp
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel