[x265] [PATCH] cli: added qpfile feature to force frame qp and slicetype using file

gopu at multicorewareinc.com gopu at multicorewareinc.com
Wed May 7 07:19:12 CEST 2014


# HG changeset patch
# User Gopu Govindaswamy
# Date 1399439942 -19800
#      Wed May 07 10:49:02 2014 +0530
# Node ID 76d6fee3f0e2a7592ae2a911ba9352f67597c6fa
# Parent  8963bc3aa2e1cad51c11cab1854810d33b558fb4
cli: added qpfile feature to force frame qp and slicetype using file

diff -r 8963bc3aa2e1 -r 76d6fee3f0e2 source/Lib/TLibCommon/TComPic.h
--- a/source/Lib/TLibCommon/TComPic.h	Tue May 06 21:43:35 2014 -0500
+++ b/source/Lib/TLibCommon/TComPic.h	Wed May 07 10:49:02 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
+    int32_t               m_forceqp; // Force to use the qp specified in qp file
 
     TComPic();
     virtual ~TComPic();
diff -r 8963bc3aa2e1 -r 76d6fee3f0e2 source/encoder/api.cpp
--- a/source/encoder/api.cpp	Tue May 06 21:43:35 2014 -0500
+++ b/source/encoder/api.cpp	Wed May 07 10:49:02 2014 +0530
@@ -188,6 +188,7 @@
 
     pic->bitDepth = param->internalBitDepth;
     pic->colorSpace = param->internalCsp;
+    pic->forceqp = X265_QP_AUTO;
 }
 
 extern "C"
diff -r 8963bc3aa2e1 -r 76d6fee3f0e2 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Tue May 06 21:43:35 2014 -0500
+++ b/source/encoder/encoder.cpp	Wed May 07 10:49:02 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 8963bc3aa2e1 -r 76d6fee3f0e2 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Tue May 06 21:43:35 2014 -0500
+++ b/source/encoder/ratecontrol.cpp	Wed May 07 10:49:02 2014 +0530
@@ -429,6 +429,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 8963bc3aa2e1 -r 76d6fee3f0e2 source/x265.cpp
--- a/source/x265.cpp	Tue May 06 21:43:35 2014 -0500
+++ b/source/x265.cpp	Wed May 07 10:49:02 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);
+                    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 8963bc3aa2e1 -r 76d6fee3f0e2 source/x265.h
--- a/source/x265.h	Tue May 06 21:43:35 2014 -0500
+++ b/source/x265.h	Wed May 07 10:49:02 2014 +0530
@@ -131,6 +131,9 @@
      * output */
     void*   userData;
 
+    /* force quantizer for != X265_QP_AUTO */
+    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;
@@ -208,6 +211,7 @@
 #define X265_TYPE_P             0x0003
 #define X265_TYPE_BREF          0x0004  /* Non-disposable B-frame */
 #define X265_TYPE_B             0x0005
+#define X265_QP_AUTO                 0
 
 #define X265_AQ_NONE                 0
 #define X265_AQ_VARIANCE             1


More information about the x265-devel mailing list