[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