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

sagar at multicorewareinc.com sagar at multicorewareinc.com
Thu Mar 6 09:06:23 CET 2014


# 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>
 #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;
+        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;
+            }
+            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;
+
     /*== Intra Coding Tools ==*/
 
     /* Enable constrained intra prediction. This causes intra prediction to


More information about the x265-devel mailing list