[x265] [PATCH] rc: adapt qpfile feature from x264

Steve Borho steve at borho.org
Thu Mar 6 21:08:07 CET 2014


On Thu, Mar 6, 2014 at 2:06 AM,  <sagar at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Sagar Kotecha <sagar at multicorewareinc.com>
> # Date 1394092937 -19800
> #      Thu Mar 06 13:32:17 2014 +0530
> # Node ID 7d5f475351e2ed728e5c814a0edd61e5d91a2a28
> # Parent  ba92d06951162b20af133384f87234f7c6fd67ea
> rc: adapt qpfile feature from x264
>
> the qpfile will provide the slice type and base QP for each frame, overriding
> lookahead and rate control.
>
> diff -r ba92d0695116 -r 7d5f475351e2 source/Lib/TLibCommon/TComPic.cpp
> --- a/source/Lib/TLibCommon/TComPic.cpp Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/Lib/TLibCommon/TComPic.cpp Thu Mar 06 13:32:17 2014 +0530
> @@ -81,6 +81,7 @@
>      m_avgQpRc = 0;
>      m_avgQpAq = 0;
>      m_bChromaPlanesExtended = false;
> +    m_qpforce = X265_QP_AUTO;
>  }
>
>  TComPic::~TComPic()
> diff -r ba92d0695116 -r 7d5f475351e2 source/Lib/TLibCommon/TComPic.h
> --- a/source/Lib/TLibCommon/TComPic.h   Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/Lib/TLibCommon/TComPic.h   Thu Mar 06 13:32:17 2014 +0530
> @@ -114,6 +114,7 @@
>      double*               m_qpaRc;
>      double                m_avgQpRc; //avg QP as decided by ratecontrol
>      double                m_avgQpAq; //avg QP as decided by AQ in addition to ratecontrol
> +    int                   m_qpforce; // Force to use the qp specified in qp file
>
>      TComPic();
>      virtual ~TComPic();
> diff -r ba92d0695116 -r 7d5f475351e2 source/common/common.cpp
> --- a/source/common/common.cpp  Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/common/common.cpp  Thu Mar 06 13:32:17 2014 +0530
> @@ -147,3 +147,36 @@
>
>      return -10.0 * log10(inv_ssim);
>  }
> +
> +int parseQPFile(FILE *qpfile, int &qpForce, int frameNum, int &sliceType)
> +{
> +    int num = -1, qp, ret;
> +    char type;
> +    uint32_t filePos;
> +    while (num < frameNum)
> +    {
> +        filePos = ftell(qpfile);
> +        qp = -1;
> +        ret = fscanf(qpfile, "%d %c%*[ \t]%d\n", &num, &type, &qp);
> +
> +        qpForce = X265_QP_AUTO;
> +        if (num > frameNum || ret == EOF)
> +        {
> +            fseek(qpfile, filePos, SEEK_SET);
> +            break;
> +        }
> +        if (num < frameNum && ret >= 2)
> +            continue;
> +        if (ret == 3 && qp >= 0)
> +            qpForce = qp + 1;
> +        if     (type == 'I') sliceType = X265_TYPE_IDR;
> +        else if (type == 'i') sliceType = X265_TYPE_I;
> +        else if (type == 'P') sliceType = X265_TYPE_P;
> +        else if (type == 'B') sliceType = X265_TYPE_BREF;
> +        else if (type == 'b') sliceType = X265_TYPE_B;
> +        else ret = 0;
> +        if (ret < 2 || qp < -1 || qp > MAX_QP)
> +            return 0;
> +    }
> +    return 1;
> +}
> diff -r ba92d0695116 -r 7d5f475351e2 source/common/common.h
> --- a/source/common/common.h    Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/common/common.h    Thu Mar 06 13:32:17 2014 +0530
> @@ -24,6 +24,7 @@
>  #ifndef X265_COMMON_H
>  #define X265_COMMON_H
>
> +#include <cstdio>

this change is unnecessary on tip now

>  #include <cstdlib>
>  #include <cstring>
>  #include "x265.h"
> @@ -116,4 +117,6 @@
>
>  double x265_ssim2dB(double ssim);
>
> +int parseQPFile(FILE *qpfile, int &qpForce, int frameNum, int &sliceType);
> +
>  #endif // ifndef X265_COMMON_H
> diff -r ba92d0695116 -r 7d5f475351e2 source/common/param.cpp
> --- a/source/common/param.cpp   Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/common/param.cpp   Thu Mar 06 13:32:17 2014 +0530
> @@ -748,6 +748,7 @@
>          p->vui.bEnableNalHrdParametersPresentFlag = 1;
>          p->vui.bEnableSubPicHrdParamsPresentFlag = atobool(value);
>      }
> +    OPT("qpfile") p->qpfilen = value;
>      else
>          return X265_PARAM_BAD_NAME;
>  #undef OPT
> diff -r ba92d0695116 -r 7d5f475351e2 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/encoder/encoder.cpp        Thu Mar 06 13:32:17 2014 +0530
> @@ -73,6 +73,7 @@
>      m_packetData = NULL;
>      m_outputCount = 0;
>      m_csvfpt = NULL;
> +    m_qpfile = NULL;
>
>  #if ENC_DEC_TRACE
>      g_hTrace = fopen("TraceEnc.txt", "wb");
> @@ -133,6 +134,15 @@
>              }
>          }
>      }
> +    if (param->qpfilen)
> +    {
> +        m_qpfile = fopen(param->qpfilen, "rb");
> +        if (!m_qpfile)
> +        {
> +            x265_log(param, X265_LOG_ERROR, "%s qpfile not found\n", param->qpfilen);
> +            m_aborted = true;
> +        }
> +    }
>  }
>
>  void Encoder::destroy()
> @@ -173,6 +183,8 @@
>      X265_FREE(m_packetData);
>      if (m_csvfpt)
>          fclose(m_csvfpt);
> +    if (m_qpfile)
> +        fclose(m_qpfile);
>  }
>
>  void Encoder::init()
> @@ -333,7 +345,19 @@
>          ATOMIC_INC(&pic->m_countRefEncoders);
>          if (param->rc.aqMode || param->bEnableWeightedPred)
>              m_rateControl->calcAdaptiveQuantFrame(pic);
> -        m_lookahead->addPicture(pic, pic_in->sliceType);
> +        int sliceType = pic_in->sliceType;
> +        int qpForce = 0;

this should be X265_QP_AUTO

> +        if (m_qpfile)
> +        {
> +            if (!parseQPFile(m_qpfile, qpForce, pic_in->poc, sliceType))
> +            {
> +                x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for frame %d\n", pic_in->poc);
> +                fclose(m_qpfile);
> +                m_qpfile = NULL;
> +            }

should there be an else here?

> +            pic->m_qpforce = qpForce;
> +        }
> +        m_lookahead->addPicture(pic, sliceType);
>      }
>
>      if (flush)
> diff -r ba92d0695116 -r 7d5f475351e2 source/encoder/encoder.h
> --- a/source/encoder/encoder.h  Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/encoder/encoder.h  Thu Mar 06 13:32:17 2014 +0530
> @@ -97,6 +97,7 @@
>      EncStats           m_analyzeP;
>      EncStats           m_analyzeB;
>      FILE*              m_csvfpt;
> +    FILE*              m_qpfile;
>      int64_t            m_encodeStartTime;
>
>      // quality control
> diff -r ba92d0695116 -r 7d5f475351e2 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp    Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/encoder/ratecontrol.cpp    Thu Mar 06 13:32:17 2014 +0530
> @@ -436,6 +436,11 @@
>          leadingNoBSatd = currentSatd;
>      }
>      rce->leadingNoBSatd = leadingNoBSatd;
> +    if (pic->m_qpforce != X265_QP_AUTO)
> +    {
> +        qp = int(pic->m_qpforce + 0.5) - 1;
> +        rce->qpaRc = pic->m_avgQpRc = pic->m_avgQpAq = qp;
> +    }
>      framesDone++;
>      /* set the final QP to slice structure */
>      curSlice->setSliceQp(qp);
> diff -r ba92d0695116 -r 7d5f475351e2 source/x265.cpp
> --- a/source/x265.cpp   Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/x265.cpp   Thu Mar 06 13:32:17 2014 +0530
> @@ -87,6 +87,7 @@
>      { "frames",         required_argument, NULL, 'f' },
>      { "recon",          required_argument, NULL, 'r' },
>      { "recon-depth",    required_argument, NULL, 0 },
> +    { "qpfile",         required_argument, NULL, 0 },
>      { "no-wpp",               no_argument, NULL, 0 },
>      { "wpp",                  no_argument, NULL, 0 },
>      { "ctu",            required_argument, NULL, 's' },
> @@ -312,6 +313,10 @@
>      H0("   --input-csp <string>          Source color space: i420 or i444, auto-detected if Y4M. Default: i420\n");
>      H0("   --fps <float|rational>        Source frame rate (float or num/denom), auto-detected if Y4M\n");
>      H0("   --seek <integer>              First frame to encode\n");
> +    H0( "  --qpfile <string>             Force frametypes and QPs for some or all frames\n"
> +        "                                Format of each line: framenumber frametype QP\n"
> +        "                                QP is optional (none lets x265 choose). Frametypes: I,i,P,B,b.\n"
> +        "                                QPs are restricted by qpmin/qpmax.\n" );
>      H0("\nPresets:\n");
>      H0("-f/--frames <integer>            Maximum number of frames to encode. Default all\n");
>      H0("-p/--preset <string>             Trade off performance for compression efficiency. Default medium\n");
> diff -r ba92d0695116 -r 7d5f475351e2 source/x265.h
> --- a/source/x265.h     Wed Mar 05 21:32:47 2014 -0600
> +++ b/source/x265.h     Thu Mar 06 13:32:17 2014 +0530
> @@ -212,6 +212,7 @@
>  #define X265_AQ_NONE                 0
>  #define X265_AQ_VARIANCE             1
>  #define X265_AQ_AUTO_VARIANCE        2
> +#define X265_QP_AUTO                 0
>  #define IS_X265_TYPE_I(x) ((x) == X265_TYPE_I || (x) == X265_TYPE_IDR)
>  #define IS_X265_TYPE_B(x) ((x) == X265_TYPE_B || (x) == X265_TYPE_BREF)
>
> @@ -469,6 +470,9 @@
>       * should detect scene cuts. The default (40) is recommended. */
>      int       scenecutThreshold;
>
> +    /* To manually override standard ratecontrol provided in qp file (qpfilen) */
> +    const char *qpfilen;
> +

changes to the public API require bumping X265_BUILD

>      /*== Intra Coding Tools ==*/
>
>      /* Enable constrained intra prediction. This causes intra prediction to
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel



-- 
Steve Borho


More information about the x265-devel mailing list