[FFmpeg-devel] [PATCH] Optimize nvenc parameters, add 3 more presets: fast, medium, slow

Agatha Hu ahu at nvidia.com
Thu Sep 10 10:19:20 CEST 2015


---
  libavcodec/nvenc.c | 59
+++++++++++++++++++++++++++++++++++++++++++++++++-----
  1 file changed, 54 insertions(+), 5 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 5490652..7c683ea 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 },
      { "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 },
      { "delay", "Delays frame output by the given amount of frames.",
OFFSET(buffer_delay), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE },
      { NULL }
-- 
1.9.5.github.0




More information about the ffmpeg-devel mailing list