changeset 5695:298470fa2d19

rdlevel: implement rdlevel 1 At each depth, dct, quant, iquant, idct is done on best mode. No RD done during TU selection. Recon is generated for intra prediction in neighbouring quadtree is not broken
author Deepthi Devaki <deepthidevaki@multicorewareinc.com>
date Tue, 10 Dec 2013 17:42:00 +0530
parents 14ddc3ed548a
children c5f84164ef36
files source/Lib/TLibEncoder/TEncSearch.cpp source/Lib/TLibEncoder/TEncSearch.h source/encoder/compress.cpp
diffstat 3 files changed, 94 insertions(+-), 27 deletions(-) [+]
line wrap: on
line diff
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Tue Dec 10 17:40:42 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Tue Dec 10 17:42:00 2013 +0530
@@ -3259,6 +3259,38 @@ void TEncSearch::encodeResAndCalcRdInter
     cu->setQPSubParts(qpBest, 0, cu->getDepth(0));
 }
 
+void TEncSearch::generateCoeffRecon(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, TShortYUV* resiYuv, TComYuv* reconYuv, bool skipRes)
+{
+    if (skipRes && cu->getPredictionMode(0) == MODE_INTER && cu->getMergeFlag(0) && cu->getPartitionSize(0) == SIZE_2Nx2N)
+    {
+        predYuv->copyToPartYuv(reconYuv, 0);
+        cu->setCbfSubParts(0, TEXT_LUMA, 0, 0, cu->getDepth(0));
+        cu->setCbfSubParts(0, TEXT_CHROMA_U, 0, 0, cu->getDepth(0));
+        cu->setCbfSubParts(0, TEXT_CHROMA_V, 0, 0, cu->getDepth(0));
+        return;
+    }
+    if (cu->getPredictionMode(0) == MODE_INTER)
+    {
+        residualTransformQuantInter(cu, 0, 0, resiYuv, cu->getDepth(0), true);
+        xSetResidualQTData(cu, 0, 0, NULL, cu->getDepth(0), false);
+        uint32_t width  = cu->getWidth(0);
+        xSetResidualQTData(cu, 0, 0, resiYuv, cu->getDepth(0), true);
+        reconYuv->addClip(predYuv, resiYuv, 0, width);
+
+        if (cu->getMergeFlag(0) && cu->getPartitionSize(0) == SIZE_2Nx2N && cu->getQtRootCbf(0) == 0)
+        {
+            cu->setSkipFlagSubParts(true, 0, cu->getDepth(0));
+        }
+    }
+    else if (cu->getPredictionMode(0) == MODE_INTRA)
+    {
+        uint32_t initTrDepth = cu->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
+        residualTransformQuantIntra(cu, initTrDepth, 0, true, fencYuv, predYuv, resiYuv, reconYuv);
+        getBestIntraModeChroma(cu, fencYuv, predYuv);
+        residualQTIntrachroma(cu, 0, 0, fencYuv, predYuv, resiYuv, reconYuv);
+    }
+}
+
 #if _MSC_VER
 #pragma warning(disable: 4701) // potentially uninitialized local variable
 #endif
--- a/source/Lib/TLibEncoder/TEncSearch.h	Tue Dec 10 17:40:42 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Tue Dec 10 17:42:00 2013 +0530
@@ -170,6 +170,7 @@ public:
                              uint64_t& dRDCost);
     void xSetIntraResultQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, bool bLumaOnly, TComYuv* reconYuv);
 
+    void generateCoeffRecon(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, TShortYUV* resiYuv, TComYuv* reconYuv, bool skipRes);
     // -------------------------------------------------------------------------------------------------------------------
     // compute symbol bits
     // -------------------------------------------------------------------------------------------------------------------
--- a/source/encoder/compress.cpp	Tue Dec 10 17:40:42 2013 +0530
+++ b/source/encoder/compress.cpp	Tue Dec 10 17:42:00 2013 +0530
@@ -290,6 +290,8 @@ void TEncCu::xComputeCostMerge2Nx2N(TCom
     outTempCU->setInterDirSubParts(interDirNeighbours[bestMergeCand], 0, 0, depth);
     outTempCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField(mvFieldNeighbours[0 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
     outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[1 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
+    outTempCU->m_totalBits = outBestCU->m_totalBits;
+    outTempCU->m_totalDistortion = outBestCU->m_totalDistortion;
     if (m_cfg->param.rdLevel > 2)
     {
         //calculate the motion compensation for chroma for the best mode selected
@@ -491,7 +493,6 @@ void TEncCu::xCompressInterCU(TComDataCU
 
                     m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],
                                                         m_bestResiYuv[depth], m_bestRecoYuv[depth], false);
-                    xCheckDQP(outBestCU);
                 }
                 if (m_bestMergeCU[depth]->m_totalCost < outBestCU->m_totalCost)
                 {
@@ -563,49 +564,82 @@ void TEncCu::xCompressInterCU(TComDataCU
                         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);
-                    xCheckDQP(outBestCU);
+                    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);
+                    }
                 }
                 else
                 {
-                    xEncodeIntraInInter(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],  m_bestRecoYuv[depth]);
-                }
-                //Check Merge-skip
-                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++)
+                    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->motionCompensation(m_mergeCU[depth], bestMergePred, REF_PIC_LIST_X, partIdx, false, true);
+                        m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
                     }
                 }
-
-                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)
+                //Check Merge-skip
+                if (m_cfg->param.rdLevel <= 2)
                 {
-                    outBestCU = m_mergeCU[depth];
-                    tempYuv = m_bestRecoYuv[depth];
-                    m_bestRecoYuv[depth] = m_tmpRecoYuv[depth];
-                    m_tmpRecoYuv[depth] = tempYuv;
-                    if (bestMergePred != m_bestPredYuv[depth])
+                    if (!(outBestCU->getPredictionMode(0) == MODE_INTER && outBestCU->getPartitionSize(0) == SIZE_2Nx2N && outBestCU->getMergeFlag(0)))
                     {
-                        bestMergePred->copyPartToPartYuv(m_bestPredYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(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);
+                        }
+                    }
+
+                    if (m_cfg->param.rdLevel == 2)
+                    {
+                        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));
+                            }
+                        }
+                    }
+                    else if (m_cfg->param.rdLevel <= 1)
+                    {
+                        uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
+                        if (m_mergeCU[depth]->m_totalDistortion < threshold[depth])
+                        {
+                            m_mergeCU[depth]->setSkipFlagSubParts(true, 0, depth);
+                            m_search->generateCoeffRecon(m_mergeCU[depth], m_origYuv[depth], bestMergePred, m_tmpResiYuv[depth], m_bestRecoYuv[depth], true);
+                            outBestCU = m_mergeCU[depth];
+                        }
                     }
                 }
             }
+            
+            xCheckDQP(outBestCU);
             /* Disable recursive analysis for whole CUs temporarily */
             if ((outBestCU != 0) && (outBestCU->isSkipped(0)))
                 bSubBranch = false;
             else
                 bSubBranch = true;
 
-            m_entropyCoder->resetBits();
-            m_entropyCoder->encodeSplitFlag(outBestCU, 0, depth, true);
-            outBestCU->m_totalBits += m_entropyCoder->getNumberOfWrittenBits(); // split bits
-            outBestCU->m_totalCost  = m_rdCost->calcRdCost(outBestCU->m_totalDistortion, outBestCU->m_totalBits);
+            if (m_cfg->param.rdLevel > 1)
+            {
+                m_entropyCoder->resetBits();
+                m_entropyCoder->encodeSplitFlag(outBestCU, 0, depth, true);
+                outBestCU->m_totalBits += m_entropyCoder->getNumberOfWrittenBits(); // split bits
+                outBestCU->m_totalCost  = m_rdCost->calcRdCost(outBestCU->m_totalDistortion, outBestCU->m_totalBits);
+            }
         }
         else if (!(bSliceEnd && bInsidePicture))
         {