changeset 5729:e05b990cfb93

rd level: add functions to do residual encoding at depth 0 for best modes. This function will be used for rd level 0.
author Deepthi Devaki <deepthidevaki@multicorewareinc.com>
date Fri, 13 Dec 2013 16:20:00 +0530
parents c6ff3ede1f29
children d2a1b3409656
files source/Lib/TLibCommon/TComDataCU.cpp source/Lib/TLibCommon/TComDataCU.h source/Lib/TLibEncoder/TEncCu.h source/Lib/TLibEncoder/TEncSearch.h source/encoder/compress.cpp
diffstat 5 files changed, 214 insertions(+-), 7 deletions(-) [+]
line wrap: on
line diff
--- a/source/Lib/TLibCommon/TComDataCU.cpp	Fri Dec 13 16:37:23 2013 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.cpp	Fri Dec 13 16:20:00 2013 +0530
@@ -464,6 +464,49 @@ void TComDataCU::initSubCU(TComDataCU* c
     m_cuColocated[1] = cu->getCUColocated(REF_PIC_LIST_1);
 }
 
+void TComDataCU::copyToSubCU(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth)
+{
+    assert(partUnitIdx < 4);
+
+    uint32_t partOffset = (cu->getTotalNumPart() >> 2) * partUnitIdx;
+
+    m_pic              = cu->getPic();
+    m_slice            = m_pic->getSlice();
+    m_cuAddr           = cu->getAddr();
+    m_absIdxInLCU      = cu->getZorderIdxInCU() + partOffset;
+
+    m_cuPelX           = cu->getCUPelX() + (g_maxCUWidth >> depth) * (partUnitIdx & 1);
+    m_cuPelY           = cu->getCUPelY() + (g_maxCUHeight >> depth) * (partUnitIdx >> 1);
+
+    m_totalCost        = MAX_INT64;
+    m_totalDistortion  = 0;
+    m_totalBits        = 0;
+    m_numPartitions    = cu->getTotalNumPart() >> 2;
+
+    TComDataCU* rpcCU = m_pic->getCU(m_cuAddr);
+    int iSizeInUchar  = sizeof(UChar) * m_numPartitions;
+    int sizeInChar  = sizeof(char) * m_numPartitions;
+
+    memcpy(m_skipFlag, rpcCU->getSkipFlag() + m_absIdxInLCU, sizeof(*m_skipFlag) * m_numPartitions);
+    memcpy(m_qp, rpcCU->getQP() + m_absIdxInLCU, sizeInChar);
+
+    memcpy(m_partSizes, rpcCU->getPartitionSize() + m_absIdxInLCU, sizeof(*m_partSizes) * m_numPartitions);
+    memcpy(m_predModes, rpcCU->getPredictionMode() + m_absIdxInLCU, sizeof(*m_predModes) * m_numPartitions);
+
+    memcpy(m_lumaIntraDir, rpcCU->getLumaIntraDir() + m_absIdxInLCU, iSizeInUchar);
+    memcpy(m_depth, rpcCU->getDepth() + m_absIdxInLCU, iSizeInUchar);
+    memcpy(m_width, rpcCU->getWidth() + m_absIdxInLCU, iSizeInUchar);
+    memcpy(m_height, rpcCU->getHeight() + m_absIdxInLCU, iSizeInUchar);
+
+    uint32_t tmp = (g_maxCUWidth * g_maxCUHeight) >> (depth << 1);
+    uint32_t tmp2 = m_absIdxInLCU * m_pic->getMinCUWidth() * m_pic->getMinCUHeight();
+    memset(m_trCoeffY, 0, sizeof(TCoeff) * tmp);
+
+    tmp  = ((g_maxCUWidth >> m_hChromaShift) * (g_maxCUHeight >> m_hChromaShift)) >> (depth << 1);
+    tmp2 = m_absIdxInLCU * (m_pic->getMinCUWidth() >> m_hChromaShift) * (m_pic->getMinCUHeight() >> m_vChromaShift);
+    memset(m_trCoeffCb, 0, sizeof(TCoeff) * tmp);
+    memset(m_trCoeffCr, 0, sizeof(TCoeff) * tmp);
+}
 // --------------------------------------------------------------------------------------------------------------------
 // Copy
 // --------------------------------------------------------------------------------------------------------------------
@@ -603,6 +646,33 @@ void TComDataCU::copyToPic(UChar uhDepth
     memcpy(rpcCU->getPCMSampleCr() + tmp2, m_iPCMSampleCr, sizeof(Pel) * tmp);
 }
 
+void TComDataCU::copyCodedToPic(UChar depth)
+{
+    TComDataCU* rpcCU = m_pic->getCU(m_cuAddr);
+
+    int iSizeInUchar  = sizeof(UChar) * m_numPartitions;
+
+    memcpy(rpcCU->getSkipFlag() + m_absIdxInLCU, m_skipFlag, sizeof(*m_skipFlag) * m_numPartitions);
+    memcpy(rpcCU->getTransformIdx() + m_absIdxInLCU, m_trIdx, iSizeInUchar);
+    memcpy(rpcCU->getTransformSkip(TEXT_LUMA) + m_absIdxInLCU, m_transformSkip[0], iSizeInUchar);
+    memcpy(rpcCU->getTransformSkip(TEXT_CHROMA_U) + m_absIdxInLCU, m_transformSkip[1], iSizeInUchar);
+    memcpy(rpcCU->getTransformSkip(TEXT_CHROMA_V) + m_absIdxInLCU, m_transformSkip[2], iSizeInUchar);
+    memcpy(rpcCU->getChromaIntraDir() + m_absIdxInLCU, m_chromaIntraDir, iSizeInUchar);
+
+    memcpy(rpcCU->getCbf(TEXT_LUMA) + m_absIdxInLCU, m_cbf[0], iSizeInUchar);
+    memcpy(rpcCU->getCbf(TEXT_CHROMA_U) + m_absIdxInLCU, m_cbf[1], iSizeInUchar);
+    memcpy(rpcCU->getCbf(TEXT_CHROMA_V) + m_absIdxInLCU, m_cbf[2], iSizeInUchar);
+
+    uint32_t tmp  = (g_maxCUWidth * g_maxCUHeight) >> (depth << 1);
+    uint32_t tmp2 = m_absIdxInLCU * m_pic->getMinCUWidth() * m_pic->getMinCUHeight();
+    memcpy(rpcCU->getCoeffY() + tmp2, m_trCoeffY, sizeof(TCoeff) * tmp);
+
+    tmp  = ((g_maxCUWidth >> m_hChromaShift) * (g_maxCUHeight >> m_hChromaShift)) >> (depth << 1);
+    tmp2 = m_absIdxInLCU * (m_pic->getMinCUWidth() >> m_hChromaShift) * (m_pic->getMinCUHeight() >> m_vChromaShift);
+    memcpy(rpcCU->getCoeffCb() + tmp2, m_trCoeffCb, sizeof(TCoeff) * tmp);
+    memcpy(rpcCU->getCoeffCr() + tmp2, m_trCoeffCr, sizeof(TCoeff) * tmp);
+}
+
 void TComDataCU::copyToPic(UChar depth, uint32_t partIdx, uint32_t partDepth)
 {
     TComDataCU* cu = m_pic->getCU(m_cuAddr);
--- a/source/Lib/TLibCommon/TComDataCU.h	Fri Dec 13 16:37:23 2013 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.h	Fri Dec 13 16:20:00 2013 +0530
@@ -195,10 +195,12 @@ public:
     void          initEstData(uint32_t depth, int qp);
     void          initSubCU(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth, int qp);
 
+    void          copyToSubCU(TComDataCU* lcu, uint32_t partUnitIdx, uint32_t depth);
     void          copyPartFrom(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth, bool isRDObasedAnalysis = true);
 
     void          copyToPic(UChar depth);
     void          copyToPic(UChar depth, uint32_t partIdx, uint32_t partDepth);
+    void          copyCodedToPic(UChar depth);
 
     // -------------------------------------------------------------------------------------------------------------------
     // member functions for CU description
--- a/source/Lib/TLibEncoder/TEncCu.h	Fri Dec 13 16:37:23 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncCu.h	Fri Dec 13 16:20:00 2013 +0530
@@ -132,10 +132,8 @@ private:
 
 public:
 
-#if LOG_CU_STATISTICS
     StatisticLog  m_sliceTypeLog[3];
     StatisticLog* m_log;
-#endif
     TEncCu();
 
     void init(Encoder* top);
@@ -175,6 +173,7 @@ protected:
     void xComputeCostInter(TComDataCU* outTempCU, TComYuv* outPredYUV, PartSize partSize, bool bUseMRG = false);
     void xComputeCostMerge2Nx2N(TComDataCU*& outBestCU, TComDataCU*& outTempCU, TComYuv*& bestPredYuv, TComYuv*& tmpPredYuv);
     void xEncodeIntraInInter(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, TShortYUV* outResiYuv, TComYuv* outReconYuv);
+    void encodeResidue(TComDataCU* lcu, TComDataCU* cu, uint32_t absPartIdx, UChar depth, uint32_t partIndex);
     void xCheckRDCostIntra(TComDataCU*& outBestCU, TComDataCU*& outTempCU, PartSize partSize);
     void xCheckRDCostIntraInInter(TComDataCU*& outBestCU, TComDataCU*& outTempCU, PartSize partSize);
     void xCheckDQP(TComDataCU* cu);
--- a/source/Lib/TLibEncoder/TEncSearch.h	Fri Dec 13 16:37:23 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Fri Dec 13 16:20:00 2013 +0530
@@ -171,6 +171,13 @@ public:
     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);
+
+    void xEstimateResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth,
+                             uint64_t &rdCost, uint32_t &outBits, uint32_t &outDist, uint32_t *puiZeroDist, bool curUseRDOQ = true);
+    void xSetResidualQTData(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool bSpatial);
+
+    void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool curUseRDOQ = true);
+
     // -------------------------------------------------------------------------------------------------------------------
     // compute symbol bits
     // -------------------------------------------------------------------------------------------------------------------
@@ -245,11 +252,7 @@ protected:
     // -------------------------------------------------------------------------------------------------------------------
 
     void xEncodeResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t depth, bool bSubdivAndCbf, TextType ttype);
-    void xEstimateResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth,
-                             uint64_t &rdCost, uint32_t &outBits, uint32_t &outDist, uint32_t *puiZeroDist, bool curUseRDOQ = true);
-    void xSetResidualQTData(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool bSpatial);
-    void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool curUseRDOQ = true);
-
+    
     void setWpScalingDistParam(TComDataCU* cu, int refIdx, int picList);
 };
 }
--- a/source/encoder/compress.cpp	Fri Dec 13 16:37:23 2013 +0530
+++ b/source/encoder/compress.cpp	Fri Dec 13 16:20:00 2013 +0530
@@ -825,3 +825,136 @@ void TEncCu::xCompressInterCU(TComDataCU
     assert(outBestCU->getPredictionMode(0) != MODE_NONE);
     assert(outBestCU->m_totalCost != MAX_DOUBLE);
 }
+
+void TEncCu::encodeResidue(TComDataCU* lcu, TComDataCU* cu, uint32_t absPartIdx, UChar depth, uint32_t partIndex)
+{
+    UChar nextDepth = (UChar)(depth + 1);
+    TComDataCU* subTempPartCU = m_tempCU[nextDepth];
+    TComPic* pic = cu->getPic();
+    TComSlice* slice = cu->getPic()->getSlice();
+
+    if (depth != 0)
+    {
+        if (0 == partIndex) //initialize RD with previous depth buffer
+        {
+            m_rdSbacCoders[depth][CI_CURR_BEST]->load(m_rdSbacCoders[depth - 1][CI_CURR_BEST]);
+        }
+        else
+        {
+            m_rdSbacCoders[depth][CI_CURR_BEST]->load(m_rdSbacCoders[depth][CI_NEXT_BEST]);
+        }
+    }
+
+    if (((depth < lcu->getDepth(absPartIdx)) && (depth < (g_maxCUDepth - g_addCUDepth))))
+    {
+        uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;
+        for (uint32_t partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, absPartIdx += qNumParts)
+        {
+            uint32_t lpelx = lcu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];
+            uint32_t tpely = lcu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];
+            bool bInSlice = lcu->getSCUAddr() + absPartIdx < slice->getSliceCurEndCUAddr();
+            if (bInSlice && (lpelx < slice->getSPS()->getPicWidthInLumaSamples()) && (tpely < slice->getSPS()->getPicHeightInLumaSamples()))
+            {
+                subTempPartCU->copyToSubCU(cu, partUnitIdx, depth + 1);
+                encodeResidue(lcu, subTempPartCU, absPartIdx, depth + 1, partUnitIdx);
+            }
+        }
+
+        return;
+    }
+    if (lcu->getPredictionMode(absPartIdx) == MODE_INTER)
+    {
+        if (!lcu->getSkipFlag(absPartIdx))
+        {
+            //Calculate Residue
+            Pel* src2 = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+            Pel* src1 = m_origYuv[0]->getLumaAddr(absPartIdx);
+            int16_t* dst = m_tmpResiYuv[depth]->getLumaAddr(0);
+            uint32_t src2stride = m_bestPredYuv[0]->getStride();
+            uint32_t src1stride = m_origYuv[0]->getStride();
+            uint32_t dststride = m_tmpResiYuv[depth]->m_width;
+            int part = partitionFromSizes(cu->getWidth(0), cu->getWidth(0));
+            primitives.luma_sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+            src2 = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+            src1 = m_origYuv[0]->getCbAddr(absPartIdx);
+            dst = m_tmpResiYuv[depth]->getCbAddr(0);
+            src2stride = m_bestPredYuv[0]->getCStride();
+            src1stride = m_origYuv[0]->getCStride();
+            dststride = m_tmpResiYuv[depth]->m_cwidth;
+            primitives.chroma[m_cfg->param.internalCsp].sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+            src2 = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+            src1 = m_origYuv[0]->getCrAddr(absPartIdx);
+            dst = m_tmpResiYuv[depth]->getCrAddr(0);
+            dststride = m_tmpResiYuv[depth]->m_cwidth;
+            primitives.chroma[m_cfg->param.internalCsp].sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+            //Residual encoding
+            m_search->residualTransformQuantInter(cu, 0, 0, m_tmpResiYuv[depth], cu->getDepth(0), true);
+            m_search->xSetResidualQTData(cu, 0, 0, NULL, cu->getDepth(0), false);
+
+            if (lcu->getMergeFlag(absPartIdx) && cu->getPartitionSize(0) == SIZE_2Nx2N && !cu->getQtRootCbf(0))
+            {
+                cu->setSkipFlagSubParts(true, 0, depth);
+                cu->copyCodedToPic(depth);
+            }
+            else
+            {
+                cu->copyCodedToPic(depth);
+                m_search->xSetResidualQTData(cu, 0, 0, m_tmpResiYuv[depth], cu->getDepth(0), true);
+
+                //Generate Recon
+                Pel* pred = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+                int16_t* res = m_tmpResiYuv[depth]->getLumaAddr(0);
+                Pel* reco = m_bestRecoYuv[0]->getLumaAddr(absPartIdx);
+                dststride = m_bestRecoYuv[0]->getStride();
+                src1stride = m_bestPredYuv[0]->getStride();
+                src2stride = m_tmpResiYuv[depth]->m_width;
+                primitives.luma_add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+
+                pred = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+                res = m_tmpResiYuv[depth]->getCbAddr(0);
+                reco = m_bestRecoYuv[0]->getCbAddr(absPartIdx);
+                dststride = m_bestRecoYuv[0]->getCStride();
+                src1stride = m_bestPredYuv[0]->getCStride();
+                src2stride = m_tmpResiYuv[depth]->m_cwidth;
+                primitives.chroma[m_cfg->param.internalCsp].add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+
+                pred = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+                res = m_tmpResiYuv[depth]->getCrAddr(0);
+                reco = m_bestRecoYuv[0]->getCrAddr(absPartIdx);
+                primitives.chroma[m_cfg->param.internalCsp].add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+                m_bestRecoYuv[0]->copyToPicYuv(lcu->getPic()->getPicYuvRec(), lcu->getAddr(), 0);
+                return;
+            }
+        }
+
+        //Generate Recon
+        int part = partitionFromSizes(cu->getWidth(0), cu->getWidth(0));
+        Pel* src = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+        Pel* dst = m_bestRecoYuv[0]->getLumaAddr(absPartIdx);
+        uint32_t srcstride = m_bestPredYuv[0]->getStride();
+        uint32_t dststride = m_bestRecoYuv[0]->getStride();
+        primitives.luma_copy_pp[part](dst, dststride, src, srcstride);
+
+        src = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+        dst = m_bestRecoYuv[0]->getCbAddr(absPartIdx);
+        srcstride = m_bestPredYuv[0]->getCStride();
+        dststride = m_bestRecoYuv[0]->getCStride();
+        primitives.chroma[m_cfg->param.internalCsp].copy_pp[part](dst, dststride, src, srcstride);
+
+        src = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+        dst = m_bestRecoYuv[0]->getCrAddr(absPartIdx);
+        primitives.chroma[m_cfg->param.internalCsp].copy_pp[part](dst, dststride, src, srcstride);
+        m_bestRecoYuv[0]->copyToPicYuv(lcu->getPic()->getPicYuvRec(), lcu->getAddr(), 0);
+    }
+    else
+    {
+        m_origYuv[0]->copyPartToYuv(m_origYuv[depth], absPartIdx);
+        m_search->generateCoeffRecon(cu, m_origYuv[depth], m_modePredYuv[5][depth], m_tmpResiYuv[depth],  m_tmpRecoYuv[depth], false);
+        m_tmpRecoYuv[depth]->copyToPicYuv(cu->getPic()->getPicYuvRec(), lcu->getAddr(), absPartIdx);
+        m_tmpRecoYuv[depth]->copyToPartYuv(m_bestRecoYuv[0], absPartIdx);
+        cu->copyCodedToPic(depth);
+    }
+}