[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