[x265] [PATCH] x265: added qpfile feature to force frame qp and slicetype manualy using file
Steve Borho
steve at borho.org
Tue May 6 21:53:48 CEST 2014
On Tue, May 6, 2014 at 6:16 AM, <gopu at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Gopu Govindaswamy
> # Date 1399374957 -19800
> # Tue May 06 16:45:57 2014 +0530
> # Node ID 86b483e17962e276d66b780d13d85cdbccfa8492
> # Parent 4a78e823abdf875524ed07ac4485276160c52fb8
> x265: added qpfile feature to force frame qp and slicetype manualy using file
This is a good patch, but I have some nits.
instead of 'x265:', the prefix for this should be 'cli:'. 'manualy'
is misspelled and could be removed without losing any information
>
> diff -r 4a78e823abdf -r 86b483e17962 source/Lib/TLibCommon/TComPic.h
> --- a/source/Lib/TLibCommon/TComPic.h Tue May 06 12:49:33 2014 +0530
> +++ b/source/Lib/TLibCommon/TComPic.h Tue May 06 16:45:57 2014 +0530
> @@ -117,6 +117,7 @@
> double m_avgQpRc; //avg QP as decided by ratecontrol
> double m_avgQpAq; //avg QP as decided by AQ in addition to ratecontrol
> double m_rateFactor; //calculated based on the Frame QP
> + int m_forceqp; // Force to use the qp specified in qp file
>
> TComPic();
> virtual ~TComPic();
> diff -r 4a78e823abdf -r 86b483e17962 source/common/common.h
> --- a/source/common/common.h Tue May 06 12:49:33 2014 +0530
> +++ b/source/common/common.h Tue May 06 16:45:57 2014 +0530
> @@ -134,6 +134,8 @@
> #define MAX_NAL_UNITS 12
> #define MIN_FIFO_SIZE 1000
>
> +#define X265_QP_AUTO 0
shouldn't this be in an external header (x265.h)?
> +
> #define X265_MALLOC(type, count) (type*)x265_malloc(sizeof(type) * (count))
> #define X265_FREE(ptr) x265_free(ptr)
> #define CHECKED_MALLOC(var, type, count) \
> diff -r 4a78e823abdf -r 86b483e17962 source/encoder/api.cpp
> --- a/source/encoder/api.cpp Tue May 06 12:49:33 2014 +0530
> +++ b/source/encoder/api.cpp Tue May 06 16:45:57 2014 +0530
> @@ -188,6 +188,7 @@
>
> pic->bitDepth = param->internalBitDepth;
> pic->colorSpace = param->internalCsp;
> + pic->forceqp = X265_QP_AUTO;
> }
>
> extern "C"
> diff -r 4a78e823abdf -r 86b483e17962 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Tue May 06 12:49:33 2014 +0530
> +++ b/source/encoder/encoder.cpp Tue May 06 16:45:57 2014 +0530
> @@ -318,6 +318,7 @@
> pic->getPicYuvOrg()->copyFromPicture(*pic_in, m_pad);
> pic->m_userData = pic_in->userData;
> pic->m_pts = pic_in->pts;
> + pic->m_forceqp = pic_in->forceqp;
>
> if (m_pocLast == 0)
> m_firstPts = pic->m_pts;
> diff -r 4a78e823abdf -r 86b483e17962 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp Tue May 06 12:49:33 2014 +0530
> +++ b/source/encoder/ratecontrol.cpp Tue May 06 16:45:57 2014 +0530
> @@ -431,6 +431,11 @@
> leadingNoBSatd = currentSatd;
> }
> rce->leadingNoBSatd = leadingNoBSatd;
> + if (pic->m_forceqp)
> + {
> + qp = int32_t(pic->m_forceqp + 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 4a78e823abdf -r 86b483e17962 source/x265.cpp
> --- a/source/x265.cpp Tue May 06 12:49:33 2014 +0530
> +++ b/source/x265.cpp Tue May 06 16:45:57 2014 +0530
> @@ -169,6 +169,7 @@
> { "dither", no_argument, NULL, 0 },
> { "aud", no_argument, NULL, 0 },
> { "no-aud", no_argument, NULL, 0 },
> + { "qpfile", required_argument, NULL, 0 },
> { 0, 0, 0, 0 }
> };
>
> @@ -196,6 +197,7 @@
> int64_t startTime;
> int64_t prevUpdateTime;
> float frameRate;
> + FILE* qpfile;
>
> /* in microseconds */
> static const int UPDATE_INTERVAL = 250000;
> @@ -211,6 +213,7 @@
> startTime = x265_mdate();
> prevUpdateTime = 0;
> dither = false;
> + qpfile = NULL;
> }
>
> void destroy();
> @@ -219,6 +222,7 @@
> void printVersion(x265_param *param);
> void showHelp(x265_param *param);
> bool parse(int argc, char **argv, x265_param* param);
> + bool parseQPFile(x265_picture &pic_org);
> };
>
> void CLIOptions::destroy()
> @@ -229,6 +233,9 @@
> if (recon)
> recon->release();
> recon = NULL;
> + if (qpfile)
> + fclose(qpfile);
> + qpfile = NULL;
> }
>
> void CLIOptions::writeNALs(const x265_nal* nal, uint32_t nalcount)
> @@ -393,6 +400,10 @@
> H0(" --recon-depth <integer> Bit-depth of reconstructed raw image file. Defaults to input bit depth, or 8 if Y4M\n");
> H0("\nSEI options:\n");
> H0(" --hash <integer> Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param->decodedPictureHashSEI);
> + H0(" --qpfile <string> Force frametypes and QPs for some or all frames\n");
> + H0(" Format of each line: framenumber frametype QP\n");
> + H0(" QP is optional (none lets x265 choose). Frametypes: I,i,P,B,b.\n");
> + H0(" QPs are restricted by qpmin/qpmax.\n");
> #undef OPT
> #undef H0
> printf("\n\nFull documentation may be found at http://x265.readthedocs.org/en/default/cli.html\n");
> @@ -502,6 +513,15 @@
> OPT("y4m") bForceY4m = true;
> OPT("preset") /* handled above */;
> OPT("tune") /* handled above */;
> + OPT("qpfile")
> + {
> + this->qpfile = fopen(optarg, "rb");
> + if (!this->qpfile)
> + {
> + x265_log(param, X265_LOG_ERROR, "%s qpfile not found or Error in opening qp file \n", optarg);
Error doesn't need to be in caps
> + return false;
> + }
> + }
> else
> bError |= !!x265_param_parse(param, long_options[long_options_index].name, optarg);
>
> @@ -640,6 +660,40 @@
> return false;
> }
>
> +bool CLIOptions::parseQPFile(x265_picture &pic_org)
> +{
> + int32_t num = -1, qp, ret;
> + char type;
> + uint32_t filePos;
> + pic_org.forceqp = 0;
> + pic_org.sliceType = X265_TYPE_AUTO;
> + while (num < pic_org.poc)
> + {
> + filePos = ftell(qpfile);
> + qp = -1;
> + ret = fscanf(qpfile, "%d %c%*[ \t]%d\n", &num, &type, &qp);
> +
> + if (num > pic_org.poc || ret == EOF)
> + {
> + fseek(qpfile, filePos, SEEK_SET);
> + break;
> + }
> + if (num < pic_org.poc && ret >= 2)
> + continue;
> + if (ret == 3 && qp >= 0)
> + pic_org.forceqp = qp + 1;
> + if (type == 'I') pic_org.sliceType = X265_TYPE_IDR;
> + else if (type == 'i') pic_org.sliceType = X265_TYPE_I;
> + else if (type == 'P') pic_org.sliceType = X265_TYPE_P;
> + else if (type == 'B') pic_org.sliceType = X265_TYPE_BREF;
> + else if (type == 'b') pic_org.sliceType = X265_TYPE_B;
> + else ret = 0;
> + if (ret < 2 || qp < -1 || qp > 51)
> + return 0;
> + }
> + return 1;
> +}
> +
> int main(int argc, char **argv)
> {
> #if HAVE_VLD
> @@ -706,6 +760,15 @@
> while (pic_in && !b_ctrl_c)
> {
> pic_orig.poc = inFrameCount;
> + if (cliopt.qpfile)
> + {
> + if (!cliopt.parseQPFile(pic_orig))
> + {
> + x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for frame %d\n", pic_in->poc);
> + fclose(cliopt.qpfile);
> + cliopt.qpfile = NULL;
> + }
> + }
>
> if (cliopt.framesToBeEncoded && inFrameCount >= cliopt.framesToBeEncoded)
> pic_in = NULL;
> diff -r 4a78e823abdf -r 86b483e17962 source/x265.h
> --- a/source/x265.h Tue May 06 12:49:33 2014 +0530
> +++ b/source/x265.h Tue May 06 16:45:57 2014 +0530
> @@ -131,6 +131,9 @@
> * output */
> void* userData;
>
> + /* force quantizer for != X264_QP_AUTO */
s/X264/X265/g
This is a big hint that X265_QP_AUTO needs to be in this header, and
not in an internal header.
> + int forceqp;
> +
> /* new data members to this structure must be added to the end so that
> * users of x265_picture_alloc/free() can be assured of future safety */
> } x265_picture;
> _______________________________________________
> 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