[x265] [PATCH 2 of 3] rd level: modify mode-decision logic for rd level 0

deepthidevaki at multicorewareinc.com deepthidevaki at multicorewareinc.com
Fri Dec 13 12:26:51 CET 2013


# HG changeset patch
# User Deepthi Devaki <deepthidevaki at multicorewareinc.com>
# Date 1386932319 -19800
# Node ID 4a547144db4800881e254b390f244b31e1cc30c6
# Parent  b39b6c3301686a28843bbf29fbd1a03c3dd2a320
rd level: modify mode-decision logic for rd level 0

In rd level 0, sa8d cost used for mode decision across depths. dct,quant is not done during mode-decision and no recon is generated. Hence Intra has to use original pixels as reference. Residual encoding is done at depth 0 and Intra prediction for the best mode will be done again with recon as reference.

diff -r b39b6c330168 -r 4a547144db48 source/encoder/compress.cpp
--- a/source/encoder/compress.cpp	Fri Dec 13 16:20:00 2013 +0530
+++ b/source/encoder/compress.cpp	Fri Dec 13 16:28:39 2013 +0530
@@ -553,11 +553,15 @@
                         m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],
                                                             m_bestResiYuv[depth], m_bestRecoYuv[depth], false);
                     }
-                    else if (m_cfg->param.rdLevel <= 1)
+                    else if (m_cfg->param.rdLevel == 1)
                     {
                         m_tmpResiYuv[depth]->subtract(m_origYuv[depth], m_bestPredYuv[depth], 0, outBestCU->getWidth(0));
                         m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
                     }
+                    else if (m_cfg->param.rdLevel == 0)
+                    {
+                        m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
+                    }
                 }
                 else
                 {
@@ -566,6 +570,10 @@
                     else if (m_cfg->param.rdLevel == 1)
                     {
                         m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
+                    }                    
+                    else if (m_cfg->param.rdLevel == 0)
+                    {
+                        m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
                     }
                 }
                 //Check Merge-skip
@@ -597,7 +605,7 @@
                             }
                         }
                     }
-                    else if (m_cfg->param.rdLevel <= 1)
+                    else if (m_cfg->param.rdLevel == 1)
                     {
                         uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
                         int index = 4 - g_convertToBit[outBestCU->getWidth(0)];
@@ -608,6 +616,21 @@
                             outBestCU = m_mergeCU[depth];
                         }
                     }
+                    else if (m_cfg->param.rdLevel == 0)
+                    {
+                        uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
+                        int index = 4 - g_convertToBit[outBestCU->getWidth(0)];
+                        if (m_mergeCU[depth]->m_totalDistortion < threshold[index])
+                        {
+                            m_mergeCU[depth]->setSkipFlagSubParts(true, 0, depth);
+                            outBestCU = m_mergeCU[depth];
+                            if (bestMergePred != m_bestPredYuv[depth])
+                            {
+                                bestMergePred->copyPartToPartYuv(m_bestPredYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0));
+                            }
+                            m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
+                        }
+                    }
                 }
             }
             
@@ -728,6 +751,8 @@
                 /* Adding costs from best SUbCUs */
                 outTempCU->copyPartFrom(subBestPartCU, nextDepth_partIndex, nextDepth, true); // Keep best part data to current temporary data.
                 xCopyYuv2Tmp(subBestPartCU->getTotalNumPart() * nextDepth_partIndex, nextDepth);
+                if(m_cfg->param.rdLevel == 0)
+                    m_bestPredYuv[nextDepth]->copyToPartYuv(m_tmpPredYuv[depth], subBestPartCU->getTotalNumPart() * nextDepth_partIndex);
             }
             else if (bInSlice)
             {
@@ -749,8 +774,6 @@
                 outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
         }
 
-        outTempCU->m_totalCost = m_rdCost->calcRdCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
-
         if ((g_maxCUWidth >> depth) == outTempCU->getSlice()->getPPS()->getMinCuDQPSize() && outTempCU->getSlice()->getPPS()->getUseDQP())
         {
             bool hasResidual = false;
@@ -799,6 +822,9 @@
                 tempYuv = m_tmpRecoYuv[depth];
                 m_tmpRecoYuv[depth] = m_bestRecoYuv[depth];
                 m_bestRecoYuv[depth] = tempYuv;
+                tempYuv = m_tmpPredYuv[depth];
+                m_tmpPredYuv[depth] = m_bestPredYuv[depth];
+                m_bestPredYuv[depth] = tempYuv;
             }
         }
         else
@@ -807,6 +833,9 @@
             tempYuv = m_tmpRecoYuv[depth];
             m_tmpRecoYuv[depth] = m_bestRecoYuv[depth];
             m_bestRecoYuv[depth] = tempYuv;
+            tempYuv = m_tmpPredYuv[depth];
+            m_tmpPredYuv[depth] = m_bestPredYuv[depth];
+            m_bestPredYuv[depth] = tempYuv;
         }
     }
 
@@ -814,8 +843,15 @@
     /* Copy Best data to Picture for next partition prediction. */
     outBestCU->copyToPic((UChar)depth);
 
-    /* Copy Yuv data to picture Yuv */
-    xCopyYuv2Pic(outBestCU->getPic(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth, depth, outBestCU, lpelx, tpely);
+     if(m_cfg->param.rdLevel == 0 && depth == 0)
+    {
+            encodeResidue(outBestCU, outBestCU, 0, 0, 0);
+    }
+    else
+    {
+        /* Copy Yuv data to picture Yuv */
+        xCopyYuv2Pic(outBestCU->getPic(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth, depth, outBestCU, lpelx, tpely);
+    }
 
     if (bBoundary || (bSliceEnd && bInsidePicture)) return;
 


More information about the x265-devel mailing list