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.

Attachment: pgpf4KbA2NJU9.pgp
Description: PGP signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to