[x265] [PATCH] rdcost: [EXPERIMENTAL] allow psy-rd factor to be adjusted by CU size
Steve Borho
steve at borho.org
Fri Feb 6 02:08:28 CET 2015
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1423085727 21600
# Wed Feb 04 15:35:27 2015 -0600
# Node ID d6386941ecfc78462b4b42c48f3575e0e47db40f
# Parent bea0d617f62547562122399e3688e8ce34c4500f
rdcost: [EXPERIMENTAL] allow psy-rd factor to be adjusted by CU size
This commit does not change outputs, but it allows the user to tune psy-rd per
CU size. The --psy-rd-scales argument takes four floats seperated by commas with
no spaces. 1.0 implies no change from the default psy-rd scale. All values are
relative to the default psy-rd scale. 8x8, 16x16, 32x32, 64x64
The CLI option will be removed once a consensus is reached about the best depth
scaling factor(s)
diff -r bea0d617f625 -r d6386941ecfc source/common/constants.cpp
--- a/source/common/constants.cpp Thu Feb 05 12:57:40 2015 -0600
+++ b/source/common/constants.cpp Wed Feb 04 15:35:27 2015 -0600
@@ -119,6 +119,8 @@
65535
};
+uint32_t x265_psySizeScaleFix8[4] = { 256, 256, 256, 256 }; /* 8x8, 16x16, 32x32, 64x64 */
+
uint32_t g_maxLog2CUSize = MAX_LOG2_CU_SIZE;
uint32_t g_maxCUSize = MAX_CU_SIZE;
uint32_t g_maxFullDepth = NUM_FULL_DEPTH - 1;
diff -r bea0d617f625 -r d6386941ecfc source/common/constants.h
--- a/source/common/constants.h Thu Feb 05 12:57:40 2015 -0600
+++ b/source/common/constants.h Wed Feb 04 15:35:27 2015 -0600
@@ -35,6 +35,7 @@
extern double x265_lambda_tab[QP_MAX_MAX + 1];
extern double x265_lambda2_tab[QP_MAX_MAX + 1];
extern const uint16_t x265_chroma_lambda2_offset_tab[MAX_CHROMA_LAMBDA_OFFSET + 1];
+extern uint32_t x265_psySizeScaleFix8[4];
enum { ChromaQPMappingTableSize = 70 };
enum { AngleMapping422TableSize = 36 };
diff -r bea0d617f625 -r d6386941ecfc source/common/param.cpp
--- a/source/common/param.cpp Thu Feb 05 12:57:40 2015 -0600
+++ b/source/common/param.cpp Wed Feb 04 15:35:27 2015 -0600
@@ -640,6 +640,20 @@
else
p->psyRd = 0.0;
}
+ OPT("psy-rd-scales")
+ {
+ float a8x8, a16x16, a32x32, a64x64;
+ if (4 == sscanf(value, "%f,%f,%f,%f", &a8x8, &a16x16, &a32x32, &a64x64))
+ {
+ /* float to FIX8 */
+ x265_psySizeScaleFix8[0] = (uint32_t)(a8x8 * 256.0);
+ x265_psySizeScaleFix8[1] = (uint32_t)(a16x16 * 256.0);
+ x265_psySizeScaleFix8[2] = (uint32_t)(a32x32 * 256.0);
+ x265_psySizeScaleFix8[3] = (uint32_t)(a64x64 * 256.0);
+ }
+ else
+ bError = true;
+ }
OPT("psy-rdoq")
{
int bval = atobool(value);
diff -r bea0d617f625 -r d6386941ecfc source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Thu Feb 05 12:57:40 2015 -0600
+++ b/source/encoder/analysis.cpp Wed Feb 04 15:35:27 2015 -0600
@@ -221,6 +221,7 @@
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
+ m_rdCost.setLog2CUSize(*parentCTU.m_slice, cuGeom.log2CUSize);
if (m_param->analysisMode == X265_ANALYSIS_LOAD)
{
@@ -404,6 +405,7 @@
slave->m_slice = m_slice;
slave->m_frame = m_frame;
slave->setQP(*m_slice, m_rdCost.m_qp);
+ slave->m_rdCost.setLog2CUSize(*m_slice, m_curGeom->log2CUSize);
slave->invalidateContexts(0);
}
@@ -524,6 +526,7 @@
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
+ m_rdCost.setLog2CUSize(*parentCTU.m_slice, cuGeom.log2CUSize);
uint32_t minDepth = m_param->rdLevel <= 4 ? topSkipMinDepth(parentCTU, cuGeom) : 0;
X265_CHECK(m_param->rdLevel >= 2, "compressInterCU_dist does not support RD 0 or 1\n");
@@ -797,6 +800,7 @@
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
+ m_rdCost.setLog2CUSize(*parentCTU.m_slice, cuGeom.log2CUSize);
uint32_t minDepth = topSkipMinDepth(parentCTU, cuGeom);
if (mightNotSplit && depth >= minDepth)
@@ -1080,6 +1084,7 @@
bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
+ m_rdCost.setLog2CUSize(*parentCTU.m_slice, cuGeom.log2CUSize);
if (m_param->analysisMode == X265_ANALYSIS_LOAD)
{
diff -r bea0d617f625 -r d6386941ecfc source/encoder/rdcost.h
--- a/source/encoder/rdcost.h Thu Feb 05 12:57:40 2015 -0600
+++ b/source/encoder/rdcost.h Wed Feb 04 15:35:27 2015 -0600
@@ -47,17 +47,7 @@
void setQP(const Slice& slice, int qp)
{
m_qp = qp;
-
- /* Scale PSY RD factor by a slice type factor */
- static const uint32_t psyScaleFix8[3] = { 300, 256, 96 }; /* B, P, I */
- m_psyRd = (m_psyRdBase * psyScaleFix8[slice.m_sliceType]) >> 8;
-
- /* Scale PSY RD factor by QP, at high QP psy-rd can cause artifacts */
- if (qp >= 40)
- {
- int scale = qp >= QP_MAX_SPEC ? 0 : (QP_MAX_SPEC - qp) * 23;
- m_psyRd = (m_psyRd * scale) >> 8;
- }
+ m_psyRd = 0;
int qpCb, qpCr;
setLambda(x265_lambda2_tab[qp], x265_lambda_tab[qp]);
@@ -78,6 +68,27 @@
m_chromaDistWeight[1] = lambdaOffset;
}
+ void setLog2CUSize(const Slice& slice, uint32_t log2CUSize)
+ {
+ X265_CHECK(log2CUSize >= 2 && log2CUSize <= 6, "CU size range check failure\n");
+
+ /* Scale PSY RD factor by a slice type factor */
+ static const uint32_t psySliceScaleFix8[3] = { 300, 256, 96 }; /* B, P, I */
+ m_psyRd = (m_psyRdBase * psySliceScaleFix8[slice.m_sliceType]) >> 8;
+
+ /* Scale PSY RD factor by a CU size */
+ m_psyRd = (m_psyRd * x265_psySizeScaleFix8[log2CUSize - 2]) >> 8;
+
+ /* Scale PSY RD factor by QP, at high QP psy-rd can cause artifacts */
+ if (m_qp >= 40)
+ {
+ int scale = m_qp >= QP_MAX_SPEC ? 0 : (QP_MAX_SPEC - m_qp) * 23;
+ m_psyRd = (m_psyRd * scale) >> 8;
+ }
+
+ /* TODO: also scale lambda by depth? */
+ }
+
void setLambda(double lambda2, double lambda)
{
m_lambda2 = (uint64_t)floor(256.0 * lambda2);
@@ -86,6 +97,7 @@
inline uint64_t calcRdCost(uint32_t distortion, uint32_t bits) const
{
+ X265_CHECK(!m_psyRdBase, "setLog2CUSize() was not called\n");
X265_CHECK(bits <= (UINT64_MAX - 128) / m_lambda2,
"calcRdCost wrap detected dist: %u, bits %u, lambda: "X265_LL"\n", distortion, bits, m_lambda2);
return distortion + ((bits * m_lambda2 + 128) >> 8);
diff -r bea0d617f625 -r d6386941ecfc source/x265cli.h
--- a/source/x265cli.h Thu Feb 05 12:57:40 2015 -0600
+++ b/source/x265cli.h Wed Feb 04 15:35:27 2015 -0600
@@ -137,6 +137,7 @@
{ "crqpoffs", required_argument, NULL, 0 },
{ "rd", required_argument, NULL, 0 },
{ "psy-rd", required_argument, NULL, 0 },
+ { "psy-rd-scales", required_argument, NULL, 0 },
{ "psy-rdoq", required_argument, NULL, 0 },
{ "no-psy-rd", no_argument, NULL, 0 },
{ "no-psy-rdoq", no_argument, NULL, 0 },
@@ -270,6 +271,8 @@
H0(" --rd <0..6> Level of RD in mode decision 0:least....6:full RDO. Default %d\n", param->rdLevel);
H0(" --[no-]psy-rd <0..2.0> Strength of psycho-visual rate distortion optimization, 0 to disable. Default %.1f\n", param->psyRd);
H0(" --[no-]psy-rdoq <0..50.0> Strength of psycho-visual optimization in quantization, 0 to disable. Default %.1f\n", param->psyRdoq);
+ H0(" --psy-rd-scales <float>,<float>,<float>,<float>\n");
+ H0(" Adjust psy-rd factor at each CU depth (8x8 to 64x64). 1.0 implies no change, Default flat\n");
H0(" --[no-]early-skip Enable early SKIP detection. Default %s\n", OPT(param->bEnableEarlySkip));
H1(" --[no-]fast-cbf Enable early outs based on whether residual is coded. Default %s\n", OPT(param->bEnableCbfFastMode));
H1(" --[no-]tskip-fast Enable fast intra transform skipping. Default %s\n", OPT(param->bEnableTSkipFast));
More information about the x265-devel
mailing list