[x265] [PATCH] rd Level: improve bitrate and psnr in rd level 2

sumalatha at multicorewareinc.com sumalatha at multicorewareinc.com
Tue Jan 21 09:24:08 CET 2014


# HG changeset patch
# User Sumalatha Polureddy
# Date 1390292628 -19800
# Node ID 198abc660360d629326333e865995c40041239c0
# Parent  ce41ee0f5c8c6bf0a8b5ab268c172c7d6194f1d7
rd Level: improve bitrate and psnr in rd level 2

a. Always allow intra mode for mode decision
b. increase more skips at each depth(do encode of best merge candidates initially and if the merge is skipped, dont do inter modes)

Results are below
CLI: input.y4m -o bitstream.hevc -r recon.y4m --preset veryfast --rd 2

rd3 / previous rd2 / latest rd2
BasketballDrive_1920x1080_50
fps: 3.34/3.90/4.0
psnr: 39.177/39.152/39.152
birate: 13729/14364/13942

Kimono1_1920x1080_24
fps: 3.67/3.72/3.85
psnr: 41.245/41.205/41.195
birate: 4596/4854/4701

FourPeople_1280x720_60
fps: 10.71/12.37/12.2
psnr: 41.309/41.387/41.296
birate: 1266/1359/1285

big_buck_bunny_360p24
fps: 43.17/42.68/48.01
psnr: 40.638/40.679/40.567
birate: 56/60/56

Johnny_1280x720_60
fps: 10.7/12.41/13.44
psnr: 42.541/42.644/42.525
birate: 841/943/849

diff -r ce41ee0f5c8c -r 198abc660360 source/Lib/TLibCommon/TComDataCU.cpp
--- a/source/Lib/TLibCommon/TComDataCU.cpp	Tue Jan 21 10:11:44 2014 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.cpp	Tue Jan 21 13:53:48 2014 +0530
@@ -235,6 +235,7 @@
     m_cuPelY           = (cuAddr / pic->getFrameWidthInCU()) * g_maxCUHeight;
     m_absIdxInLCU      = 0;
     m_totalCost        = MAX_INT64;
+    m_sa8dCost         = MAX_INT64;
     m_totalDistortion  = 0;
     m_totalBits        = 0;
     m_numPartitions    = pic->getNumPartInCU();
@@ -338,6 +339,7 @@
 void TComDataCU::initEstData(uint32_t depth, int qp)
 {
     m_totalCost        = MAX_INT64;
+    m_sa8dCost         = MAX_INT64;
     m_totalDistortion  = 0;
     m_totalBits        = 0;
 
@@ -391,6 +393,7 @@
     m_cuPelY           = cu->getCUPelY() + (g_maxCUHeight >> depth) * (partUnitIdx >> 1);
 
     m_totalCost        = MAX_INT64;
+    m_sa8dCost         = MAX_INT64;
     m_totalDistortion  = 0;
     m_totalBits        = 0;
     m_numPartitions    = cu->getTotalNumPart() >> 2;
@@ -463,6 +466,7 @@
     m_cuPelY           = cu->getCUPelY() + (g_maxCUHeight >> depth) * (partUnitIdx >> 1);
 
     m_totalCost        = MAX_INT64;
+    m_sa8dCost         = MAX_INT64;
     m_totalDistortion  = 0;
     m_totalBits        = 0;
     m_numPartitions    = cu->getTotalNumPart() >> 2;
diff -r ce41ee0f5c8c -r 198abc660360 source/Lib/TLibCommon/TComDataCU.h
--- a/source/Lib/TLibCommon/TComDataCU.h	Tue Jan 21 10:11:44 2014 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.h	Tue Jan 21 13:53:48 2014 +0530
@@ -182,6 +182,7 @@
     uint32_t      m_totalBits;       ///< sum of partition signal bits
     uint64_t      m_avgCost[4];      // stores the avg cost of CU's in frame for each depth
     uint32_t      m_count[4];
+    uint64_t      m_sa8dCost;
 
     // -------------------------------------------------------------------------------------------------------------------
     // create / destroy / initialize / copy
diff -r ce41ee0f5c8c -r 198abc660360 source/encoder/compress.cpp
--- a/source/encoder/compress.cpp	Tue Jan 21 10:11:44 2014 +0530
+++ b/source/encoder/compress.cpp	Tue Jan 21 13:53:48 2014 +0530
@@ -280,7 +280,9 @@
     outTempCU->m_totalBits = outBestCU->m_totalBits;
     outTempCU->m_totalDistortion = outBestCU->m_totalDistortion;
     outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
-    if (m_cfg->param.rdLevel > 2)
+    outTempCU->m_sa8dCost = outTempCU->m_totalCost;
+    outBestCU->m_sa8dCost = outTempCU->m_totalCost;
+    if (m_cfg->param.rdLevel >= 2)
     {
         //calculate the motion compensation for chroma for the best mode selected
         int numPart = outBestCU->getNumPartInter();
@@ -490,17 +492,17 @@
 
                     m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],
                                                         m_bestResiYuv[depth], m_bestRecoYuv[depth], false);
-                }
-                if (m_bestMergeCU[depth]->m_totalCost < outBestCU->m_totalCost)
-                {
-                    outBestCU = m_bestMergeCU[depth];
-                    tempYuv = m_modePredYuv[3][depth];
-                    m_modePredYuv[3][depth] = m_bestPredYuv[depth];
-                    m_bestPredYuv[depth] = tempYuv;
+                    if (m_bestMergeCU[depth]->m_totalCost < outBestCU->m_totalCost)
+                    {
+                        outBestCU = m_bestMergeCU[depth];
+                        tempYuv = m_modePredYuv[3][depth];
+                        m_modePredYuv[3][depth] = m_bestPredYuv[depth];
+                        m_bestPredYuv[depth] = tempYuv;
 
-                    tempYuv = m_bestRecoYuv[depth];
-                    m_bestRecoYuv[depth] = m_bestMergeRecoYuv[depth];
-                    m_bestMergeRecoYuv[depth] = tempYuv;
+                        tempYuv = m_bestRecoYuv[depth];
+                        m_bestRecoYuv[depth] = m_bestMergeRecoYuv[depth];
+                        m_bestMergeRecoYuv[depth] = tempYuv;
+                    }
                 }
 
                 /* Check for Intra in inter frames only if its a P-slice*/
@@ -513,12 +515,6 @@
                         bdoIntra = (outBestCU->getCbf(0, TEXT_LUMA) ||  outBestCU->getCbf(0, TEXT_CHROMA_U) ||
                                     outBestCU->getCbf(0, TEXT_CHROMA_V));
                     }
-                    else
-                    {
-                        uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
-                        int index = 4 - g_convertToBit[outBestCU->getWidth(0)];
-                        bdoIntra = (outBestCU->m_totalDistortion > threshold[index]);
-                    }
                     if (bdoIntra)
                     {
                         xComputeCostIntraInInter(m_intraInInterCU[depth], SIZE_2Nx2N);
@@ -540,7 +536,35 @@
                         }
                     }
                 }
-                if (m_cfg->param.rdLevel <= 2)
+                if (m_cfg->param.rdLevel == 2)
+                {
+                    if (m_bestMergeCU[depth]->m_sa8dCost < outBestCU->m_totalCost)
+                    {
+                        outBestCU = m_bestMergeCU[depth];
+                        tempYuv = m_modePredYuv[3][depth];
+                        m_modePredYuv[3][depth] = m_bestPredYuv[depth];
+                        m_bestPredYuv[depth] = tempYuv;
+
+                        tempYuv = m_bestRecoYuv[depth];
+                        m_bestRecoYuv[depth] = m_bestMergeRecoYuv[depth];
+                        m_bestMergeRecoYuv[depth] = tempYuv;
+                    }
+                    else if (outBestCU->getPredictionMode(0) == MODE_INTER)
+                    {
+                        int numPart = outBestCU->getNumPartInter();
+                        for (int partIdx = 0; partIdx < numPart; partIdx++)
+                        {
+                            m_search->motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, partIdx, false, true);
+                        }
+                        m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],
+                                                                m_bestResiYuv[depth], m_bestRecoYuv[depth], false);
+                    }
+                    else if (outBestCU->getPredictionMode(0) == MODE_INTRA)
+                    {
+                        xEncodeIntraInInter(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],  m_bestRecoYuv[depth]);
+                    }
+                }
+                if (m_cfg->param.rdLevel == 1)
                 {
                     if (outBestCU->getPredictionMode(0) == MODE_INTER)
                     {
@@ -549,52 +573,12 @@
                         {
                             m_search->motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, partIdx, false, true);
                         }
-
-                        if (m_cfg->param.rdLevel == 2)
-                        {
-                            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)
-                        {
-                            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);
-                        }
+                        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 == 2)
-                            xEncodeIntraInInter(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],  m_bestRecoYuv[depth]);
-                        else if (m_cfg->param.rdLevel == 1)
-                        {
-                            m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
-                        }
-                    }
-                    //Check Merge-skip
-                    if (m_cfg->param.rdLevel == 2)
-                    {
-                        if (!(outBestCU->getPredictionMode(0) == MODE_INTER && outBestCU->getPartitionSize(0) == SIZE_2Nx2N && outBestCU->getMergeFlag(0)))
-                        {
-                            int numPart = m_mergeCU[depth]->getNumPartInter();
-                            for (int partIdx = 0; partIdx < numPart; partIdx++)
-                            {
-                                m_search->motionCompensation(m_mergeCU[depth], bestMergePred, REF_PIC_LIST_X, partIdx, false, true);
-                            }
-                        }
-                        m_search->encodeResAndCalcRdInterCU(m_mergeCU[depth], m_origYuv[depth], bestMergePred, m_tmpResiYuv[depth],
-                                                            m_bestResiYuv[depth], m_tmpRecoYuv[depth], true);
-
-                        if (m_mergeCU[depth]->m_totalCost < outBestCU->m_totalCost)
-                        {
-                            outBestCU = m_mergeCU[depth];
-                            tempYuv = m_bestRecoYuv[depth];
-                            m_bestRecoYuv[depth] = m_tmpRecoYuv[depth];
-                            m_tmpRecoYuv[depth] = tempYuv;
-                            if (bestMergePred != m_bestPredYuv[depth])
-                            {
-                                bestMergePred->copyPartToPartYuv(m_bestPredYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0));
-                            }
-                        }
+                        m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
                     }
                 }
             }


More information about the x265-devel mailing list