[x265] [PATCH] rdcost: allow psy-rd factor to be adjusted by CU size [EXPERIMENTAL]

Steve Borho steve at borho.org
Wed Feb 4 22:45:35 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 e5360f3e3172daa14a4753177203e74a7d44102f
# Parent  f8da0be4329f9e95a59d70d1c76628374b89bda4
rdcost: allow psy-rd factor to be adjusted by CU size [EXPERIMENTAL]

diff -r f8da0be4329f -r e5360f3e3172 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Wed Feb 04 15:43:39 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.setCULog2Size(*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.setCULog2Size(*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.setCULog2Size(*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.setCULog2Size(*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.setCULog2Size(*parentCTU.m_slice, cuGeom.log2CUSize);
 
     if (m_param->analysisMode == X265_ANALYSIS_LOAD)
     {
diff -r f8da0be4329f -r e5360f3e3172 source/encoder/rdcost.h
--- a/source/encoder/rdcost.h	Wed Feb 04 15:43:39 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,26 @@
         m_chromaDistWeight[1] = lambdaOffset;
     }
 
+    void setCULog2Size(const Slice& slice, uint32_t cuLog2Size)
+    {
+        /* 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 */
+        static const uint32_t psySizeScaleFix8[4] = { 96, 128, 256, 276 }; /* 64x64, 32x32, 16x16, 8x8 */
+        m_psyRd = (m_psyRd * psySizeScaleFix8[cuLog2Size - 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 +96,7 @@
 
     inline uint64_t calcRdCost(uint32_t distortion, uint32_t bits) const
     {
+        X265_CHECK(!m_psyRdBase, "setCULog2Size() 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);


More information about the x265-devel mailing list