[x265] [PATCH] Modify TEncSearch structure to support multiple color space formats

ashok at multicorewareinc.com ashok at multicorewareinc.com
Fri Dec 20 14:46:07 CET 2013


# HG changeset patch
# User ashok at multicorewareinc.com
# Date 1387546426 -19800
#      Fri Dec 20 19:03:46 2013 +0530
# Node ID 1a1badd42498293c628db0d65a81e53c0197fe24
# Parent  60f78cbfacc8d0a8c5cf10616bde1d07d8d16235
Modify TEncSearch structure to support multiple color space formats

diff -r 60f78cbfacc8 -r 1a1badd42498 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Nov 06 17:51:53 2013 -0600
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Fri Dec 20 19:03:46 2013 +0530
@@ -234,13 +234,10 @@
 
     if (bChroma)
     {
-        if (trSizeLog2 > 2)
-        {
-            if (trDepth == 0 || cu->getCbf(absPartIdx, TEXT_CHROMA_U, trDepth - 1))
-                m_entropyCoder->encodeQtCbf(cu, absPartIdx, TEXT_CHROMA_U, trDepth);
-            if (trDepth == 0 || cu->getCbf(absPartIdx, TEXT_CHROMA_V, trDepth - 1))
-                m_entropyCoder->encodeQtCbf(cu, absPartIdx, TEXT_CHROMA_V, trDepth);
-        }
+        if (trDepth == 0 || cu->getCbf(absPartIdx, TEXT_CHROMA_U, trDepth - 1))
+            m_entropyCoder->encodeQtCbf(cu, absPartIdx, TEXT_CHROMA_U, trDepth);
+        if (trDepth == 0 || cu->getCbf(absPartIdx, TEXT_CHROMA_V, trDepth - 1))
+            m_entropyCoder->encodeQtCbf(cu, absPartIdx, TEXT_CHROMA_V, trDepth);
     }
 
     if (subdiv)
@@ -280,7 +277,7 @@
         return;
     }
 
-    if (ttype != TEXT_LUMA && trSizeLog2 == 2)
+    if ( (ttype != TEXT_LUMA) && (trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
     {
         assert(trDepth > 0);
         trDepth--;
@@ -293,9 +290,11 @@
     }
 
     //===== coefficients =====
-    uint32_t width = cu->getWidth(0) >> (trDepth + chroma);
-    uint32_t height = cu->getHeight(0) >> (trDepth + chroma);
-    uint32_t coeffOffset = (cu->getPic()->getMinCUWidth() * cu->getPic()->getMinCUHeight() * absPartIdx) >> (chroma << 1);
+    int cspx = chroma ? m_hChromaShift : 0;
+    int cspy = chroma ? m_vChromaShift : 0;
+    uint32_t width = cu->getWidth(0) >> (trDepth + cspx);
+    uint32_t height = cu->getHeight(0) >> (trDepth + cspy);
+    uint32_t coeffOffset = (cu->getPic()->getMinCUWidth() >> cspx) * (cu->getPic()->getMinCUHeight() >> cspy) * absPartIdx;
     uint32_t qtLayer = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
     TCoeff* coeff = 0;
     switch (ttype)
@@ -368,12 +367,23 @@
             }
         }
     }
+
     if (bChroma)
     {
         // chroma prediction mode
-        if (absPartIdx == 0)
+        if ((cu->getPartitionSize(0) == SIZE_2Nx2N) || !(cu->getChromaFormat() == CHROMA_444))
         {
-            m_entropyCoder->encodeIntraDirModeChroma(cu, 0, true);
+            if (absPartIdx == 0)
+            {
+                m_entropyCoder->encodeIntraDirModeChroma(cu, absPartIdx, true);
+            }
+        }
+        else
+        {
+            uint32_t qtNumParts = cu->getTotalNumPart() >> 2;
+            assert(trDepth > 0);
+            if ((absPartIdx%qtNumParts) == 0)
+                m_entropyCoder->encodeIntraDirModeChroma(cu, absPartIdx, true);
         }
     }
 }
@@ -477,7 +487,7 @@
     int lastPos = -1;
     cu->setTrIdxSubParts(trDepth, absPartIdx, fullDepth);
 
-    m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0);
+    m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0, cu->getChromaFormat());
     m_trQuant->selectLambda(TEXT_LUMA);
 
     absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, width, height, TEXT_LUMA, absPartIdx, &lastPos, useTransformSkip);
@@ -522,7 +532,7 @@
     uint32_t fullDepth   = cu->getDepth(0) + trDepth;
     uint32_t trSizeLog2  = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> fullDepth] + 2;
 
-    if (trSizeLog2 == 2)
+    if ((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
     {
         assert(trDepth > 0);
         trDepth--;
@@ -545,7 +555,7 @@
     Pel*     recon          = (chromaId > 0 ? predYuv->getCrAddr(absPartIdx) : predYuv->getCbAddr(absPartIdx));
 
     uint32_t qtlayer        = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
-    uint32_t numCoeffPerInc = (cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight() >> (cu->getSlice()->getSPS()->getMaxCUDepth() << 1)) >> 2;
+    uint32_t numCoeffPerInc = (cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight() >> (cu->getSlice()->getSPS()->getMaxCUDepth() << 1)) >> (m_hChromaShift + m_vChromaShift);
     TCoeff*  coeff          = (chromaId > 0 ? m_qtTempCoeffCr[qtlayer] : m_qtTempCoeffCb[qtlayer]) + numCoeffPerInc * absPartIdx;
     int16_t* reconQt        = (chromaId > 0 ? m_qtTempTComYuv[qtlayer].getCrAddr(absPartIdx) : m_qtTempTComYuv[qtlayer].getCbAddr(absPartIdx));
     uint32_t reconQtStride  = m_qtTempTComYuv[qtlayer].m_cwidth;
@@ -558,7 +568,7 @@
     //===== update chroma mode =====
     if (chromaPredMode == DM_CHROMA_IDX)
     {
-        chromaPredMode = cu->getLumaIntraDir(0);
+        chromaPredMode = cu->getLumaIntraDir(absPartIdx);
     }
 
     //===== init availability pattern =====
@@ -610,7 +620,7 @@
         {
             curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();
         }
-        m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+        m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
         m_trQuant->selectLambda(TEXT_CHROMA);
 
@@ -1290,7 +1300,7 @@
         uint32_t trSizeLog2 = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> fullDepth] + 2;
 
         uint32_t actualTrDepth = trDepth;
-        if (trSizeLog2 == 2)
+        if ((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
         {
             assert(trDepth > 0);
             actualTrDepth--;
@@ -1436,7 +1446,7 @@
         uint32_t qtlayer    = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
 
         bool bChromaSame  = false;
-        if (trSizeLog2 == 2)
+        if ((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
         {
             assert(trDepth > 0);
             uint32_t qpdiv = cu->getPic()->getNumPartInCU() >> ((cu->getDepth(0) + trDepth - 1) << 1);
@@ -1451,9 +1461,11 @@
         uint32_t numCoeffC = (cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight()) >> (fullDepth << 1);
         if (!bChromaSame)
         {
-            numCoeffC >>= 2;
+            numCoeffC = ((cu->getSlice()->getSPS()->getMaxCUWidth() >> m_hChromaShift) * (cu->getSlice()->getSPS()->getMaxCUHeight() >> m_vChromaShift)) >> (fullDepth << 1);
         }
-        uint32_t numCoeffIncC = (cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight()) >> ((cu->getSlice()->getSPS()->getMaxCUDepth() << 1) + 2);
+
+        uint32_t numCoeffIncC = ((cu->getSlice()->getSPS()->getMaxCUWidth() >> m_hChromaShift) * (cu->getSlice()->getSPS()->getMaxCUHeight() >> m_vChromaShift)) >> (cu->getSlice()->getSPS()->getMaxCUDepth() << 1);
+
         TCoeff* coeffSrcU = m_qtTempCoeffCb[qtlayer] + (numCoeffIncC * absPartIdx);
         TCoeff* coeffSrcV = m_qtTempCoeffCr[qtlayer] + (numCoeffIncC * absPartIdx);
         TCoeff* coeffDstU = cu->getCoeffCb()         + (numCoeffIncC * absPartIdx);
@@ -1462,7 +1474,7 @@
         ::memcpy(coeffDstV, coeffSrcV, sizeof(TCoeff) * numCoeffC);
 
         //===== copy reconstruction =====
-        uint32_t trSizeCLog2 = (bChromaSame ? trSizeLog2 : trSizeLog2 - 1);
+        uint32_t trSizeCLog2 = (bChromaSame || (cu->getChromaFormat() == CHROMA_444))  ? trSizeLog2 : trSizeLog2 - 1;
         m_qtTempTComYuv[qtlayer].copyPartToPartChroma(reconYuv, absPartIdx, 1 << trSizeCLog2, 1 << trSizeCLog2);
     }
     else
@@ -1881,6 +1893,22 @@
     cu->m_totalDistortion = overallDistY + overallDistC;
 }
 
+bool TEncSearch::isNextSection()
+{
+    if (m_splitMode == DONT_SPLIT)
+    {
+        m_section++;
+        return false;
+    }
+    else
+    {
+        m_absPartIdxTURelCU += m_absPartIdxStep;
+
+        m_section++;
+        return m_section< (1 << m_splitMode);
+    }
+}
+
 void TEncSearch::estIntraPredChromaQT(TComDataCU* cu,
                                       TComYuv*    fencYuv,
                                       TComYuv*    predYuv,
@@ -1888,60 +1916,94 @@
                                       TComYuv*    reconYuv,
                                       uint32_t    preCalcDistC)
 {
-    uint32_t depth     = cu->getDepth(0);
-    uint32_t bestMode  = 0;
-    uint32_t bestDist  = 0;
-    UInt64 bestCost  = MAX_INT64;
-
-    //----- init mode list -----
-    uint32_t minMode = 0;
-    uint32_t maxMode = NUM_CHROMA_MODE;
-    uint32_t modeList[NUM_CHROMA_MODE];
-
-    cu->getAllowedChromaDir(0, modeList);
-
-    //----- check chroma modes -----
-    for (uint32_t mode = minMode; mode < maxMode; mode++)
+    uint32_t depth              = cu->getDepth(0);
+    uint32_t initTrDepth        = (cu->getPartitionSize(0) != SIZE_2Nx2N) && (cu->getChromaFormat() == CHROMA_444 ? 1 : 0);
+    m_splitMode                 = (initTrDepth == 0) ? DONT_SPLIT : QUAD_SPLIT;
+    m_absPartIdxStep            = (cu->getPic()->getNumPartInCU() >> (depth << 1)) >> partIdxStepShift[m_splitMode];
+    m_partOffset   = 0;
+    m_section = 0;
+    m_absPartIdxTURelCU = 0;
+
+    do
     {
-        //----- restore context models -----
-        m_rdGoOnSbacCoder->load(m_rdSbacCoders[depth][CI_CURR_BEST]);
-
-        //----- chroma coding -----
-        uint32_t dist = 0;
-        cu->setChromIntraDirSubParts(modeList[mode], 0, depth);
-        xRecurIntraChromaCodingQT(cu, 0, 0, fencYuv, predYuv, resiYuv, dist);
-        if (cu->getSlice()->getPPS()->getUseTransformSkip())
+        uint32_t bestMode           = 0;
+        uint32_t bestDist           = 0;
+        UInt64 bestCost             = MAX_INT64;
+
+        //----- init mode list -----
+        uint32_t minMode = 0;
+        uint32_t maxMode = NUM_CHROMA_MODE;
+        uint32_t modeList[NUM_CHROMA_MODE];
+
+        m_partOffset = m_absPartIdxTURelCU;
+
+        cu->getAllowedChromaDir(m_partOffset, modeList);
+
+        //----- check chroma modes -----
+        for (uint32_t mode = minMode; mode < maxMode; mode++)
         {
+            //----- restore context models -----
             m_rdGoOnSbacCoder->load(m_rdSbacCoders[depth][CI_CURR_BEST]);
+
+            //----- chroma coding -----
+            uint32_t dist = 0;
+
+            cu->setChromIntraDirSubParts(modeList[mode], m_partOffset, depth + initTrDepth);
+
+            xRecurIntraChromaCodingQT(cu, initTrDepth, m_absPartIdxTURelCU, fencYuv, predYuv, resiYuv, dist);
+
+            if (cu->getSlice()->getPPS()->getUseTransformSkip())
+            {
+                m_rdGoOnSbacCoder->load(m_rdSbacCoders[depth][CI_CURR_BEST]);
+            }
+
+            uint32_t   bits = xGetIntraBitsQT(cu, initTrDepth, m_absPartIdxTURelCU, false, true);
+            UInt64 cost  = m_rdCost->calcRdCost(dist, bits);
+
+            //----- compare -----
+            if (cost < bestCost)
+            {
+                bestCost = cost;
+                bestDist = dist;
+                bestMode = modeList[mode];
+                xSetIntraResultChromaQT(cu, initTrDepth, m_absPartIdxTURelCU, reconYuv);
+                ::memcpy(m_qtTempCbf[1], cu->getCbf(TEXT_CHROMA_U)+m_partOffset, m_absPartIdxStep * sizeof(UChar));
+                ::memcpy(m_qtTempCbf[2], cu->getCbf(TEXT_CHROMA_V)+m_partOffset, m_absPartIdxStep * sizeof(UChar));
+                ::memcpy(m_qtTempTransformSkipFlag[1], cu->getTransformSkip(TEXT_CHROMA_U)+m_partOffset, m_absPartIdxStep * sizeof(UChar));
+                ::memcpy(m_qtTempTransformSkipFlag[2], cu->getTransformSkip(TEXT_CHROMA_V)+m_partOffset, m_absPartIdxStep * sizeof(UChar));
+            }
         }
 
-        uint32_t   bits = xGetIntraBitsQT(cu, 0, 0, false, true);
-        UInt64 cost  = m_rdCost->calcRdCost(dist, bits);
-
-        //----- compare -----
-        if (cost < bestCost)
+        //----- set data -----
+        ::memcpy(cu->getCbf(TEXT_CHROMA_U)+m_partOffset, m_qtTempCbf[1], m_absPartIdxStep * sizeof(UChar));
+        ::memcpy(cu->getCbf(TEXT_CHROMA_V)+m_partOffset, m_qtTempCbf[2], m_absPartIdxStep * sizeof(UChar));
+        ::memcpy(cu->getTransformSkip(TEXT_CHROMA_U)+m_partOffset, m_qtTempTransformSkipFlag[1], m_absPartIdxStep * sizeof(UChar));
+        ::memcpy(cu->getTransformSkip(TEXT_CHROMA_V)+m_partOffset, m_qtTempTransformSkipFlag[2], m_absPartIdxStep * sizeof(UChar));
+        cu->setChromIntraDirSubParts(bestMode, m_partOffset, depth + initTrDepth);
+        cu->m_totalDistortion += bestDist - preCalcDistC;
+
+    } while(isNextSection());
+
+
+    //----- restore context models -----
+
+    if (initTrDepth != 0)
+    {   // set Cbf for all blocks
+        uint32_t uiCombCbfU = 0;
+        uint32_t uiCombCbfV = 0;
+        uint32_t uiPartIdx  = 0;
+        for (uint32_t uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += m_absPartIdxStep)
         {
-            bestCost = cost;
-            bestDist = dist;
-            bestMode = modeList[mode];
-            uint32_t qpn = cu->getPic()->getNumPartInCU() >> (depth << 1);
-            xSetIntraResultChromaQT(cu, 0, 0, reconYuv);
-            ::memcpy(m_qtTempCbf[1], cu->getCbf(TEXT_CHROMA_U), qpn * sizeof(UChar));
-            ::memcpy(m_qtTempCbf[2], cu->getCbf(TEXT_CHROMA_V), qpn * sizeof(UChar));
-            ::memcpy(m_qtTempTransformSkipFlag[1], cu->getTransformSkip(TEXT_CHROMA_U), qpn * sizeof(UChar));
-            ::memcpy(m_qtTempTransformSkipFlag[2], cu->getTransformSkip(TEXT_CHROMA_V), qpn * sizeof(UChar));
+            uiCombCbfU |= cu->getCbf(uiPartIdx, TEXT_CHROMA_U, 1);
+            uiCombCbfV |= cu->getCbf(uiPartIdx, TEXT_CHROMA_V, 1);
+        }
+        for (uint32_t uiOffs = 0; uiOffs < 4 * m_absPartIdxStep; uiOffs++)
+        {
+            cu->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
+            cu->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
         }
     }
 
-    //----- set data -----
-    uint32_t qpn = cu->getPic()->getNumPartInCU() >> (depth << 1);
-    ::memcpy(cu->getCbf(TEXT_CHROMA_U), m_qtTempCbf[1], qpn * sizeof(UChar));
-    ::memcpy(cu->getCbf(TEXT_CHROMA_V), m_qtTempCbf[2], qpn * sizeof(UChar));
-    ::memcpy(cu->getTransformSkip(TEXT_CHROMA_U), m_qtTempTransformSkipFlag[1], qpn * sizeof(UChar));
-    ::memcpy(cu->getTransformSkip(TEXT_CHROMA_V), m_qtTempTransformSkipFlag[2], qpn * sizeof(UChar));
-    cu->setChromIntraDirSubParts(bestMode, 0, depth);
-    cu->m_totalDistortion += bestDist - preCalcDistC;
-
     //----- restore context models -----
     m_rdGoOnSbacCoder->load(m_rdSbacCoders[depth][CI_CURR_BEST]);
 }
@@ -2801,10 +2863,11 @@
         outResiYuv->clear();
 
         predYuv->copyToPartYuv(outReconYuv, 0);
-
+        //Luma
         int part = partitionFromSizes(width, height);
         distortion = primitives.sse_pp[part](fencYuv->getLumaAddr(), fencYuv->getStride(), outReconYuv->getLumaAddr(), outReconYuv->getStride());
-        part = partitionFromSizes(width >> 1, height >> 1);
+        //Chroma
+        part = partitionFromSizes(width >> m_hChromaShift, height >> m_vChromaShift);
         distortion += m_rdCost->scaleChromaDistCb(primitives.sse_pp[part](fencYuv->getCbAddr(), fencYuv->getCStride(), outReconYuv->getCbAddr(), outReconYuv->getCStride()));
         distortion += m_rdCost->scaleChromaDistCr(primitives.sse_pp[part](fencYuv->getCrAddr(), fencYuv->getCStride(), outReconYuv->getCrAddr(), outReconYuv->getCStride()));
 
@@ -2924,7 +2987,7 @@
     // update with clipped distortion and cost (qp estimation loop uses unclipped values)
     int part = partitionFromSizes(width, height);
     bdist = primitives.sse_pp[part](fencYuv->getLumaAddr(), fencYuv->getStride(), outReconYuv->getLumaAddr(), outReconYuv->getStride());
-    part = partitionFromSizes(width >> 1, height >> 1);
+    part = partitionFromSizes(width >> cu->getHorzChromaShift(), height >> cu->getVertChromaShift());
     bdist += m_rdCost->scaleChromaDistCb(primitives.sse_pp[part](fencYuv->getCbAddr(), fencYuv->getCStride(), outReconYuv->getCbAddr(), outReconYuv->getCStride()));
     bdist += m_rdCost->scaleChromaDistCr(primitives.sse_pp[part](fencYuv->getCrAddr(), fencYuv->getCStride(), outReconYuv->getCrAddr(), outReconYuv->getCStride()));
     bcost = m_rdCost->calcRdCost(bdist, bestBits);
@@ -2959,6 +3022,7 @@
     assert(cu->getDepth(0) == cu->getDepth(absPartIdx));
     const uint32_t trMode = depth - cu->getDepth(0);
     const uint32_t trSizeLog2 = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> depth] + 2;
+    uint32_t  trSizeCLog2 = g_convertToBit[(cu->getSlice()->getSPS()->getMaxCUWidth() >> m_hChromaShift) >> depth] + 2;;
 
     bool bSplitFlag = ((cu->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && cu->getPredictionMode(absPartIdx) == MODE_INTER && (cu->getPartitionSize(absPartIdx) != SIZE_2Nx2N));
     bool bCheckFull;
@@ -2971,12 +3035,11 @@
 
     bool  bCodeChroma = true;
     uint32_t  trModeC     = trMode;
-    uint32_t  trSizeCLog2 = trSizeLog2 - 1;
-    if (trSizeLog2 == 2)
+    if ((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
     {
         trSizeCLog2++;
         trModeC--;
-        uint32_t qpdiv = cu->getPic()->getNumPartInCU() >> ((cu->getDepth(0) + trModeC) << 1);
+        uint32_t qpdiv = cu->getPic()->getNumPartInCU() >> ((depth - 1) << 1);
         bCodeChroma = ((absPartIdx % qpdiv) == 0);
     }
 
@@ -2996,8 +3059,8 @@
         const uint32_t numCoeffPerAbsPartIdxIncrement = cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight() >> (cu->getSlice()->getSPS()->getMaxCUDepth() << 1);
         const uint32_t qtlayer = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
         TCoeff *coeffCurY = m_qtTempCoeffY[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx);
-        TCoeff *coeffCurU = m_qtTempCoeffCb[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
-        TCoeff *coeffCurV = m_qtTempCoeffCr[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
+        TCoeff *coeffCurU = m_qtTempCoeffCb[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
+        TCoeff *coeffCurV = m_qtTempCoeffCr[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
 
         int trWidth = 0, trHeight = 0, trWidthC = 0, trHeightC = 0;
         uint32_t absTUPartIdxC = absPartIdx;
@@ -3026,7 +3089,7 @@
             m_entropyCoder->estimateBit(m_trQuant->m_estBitsSbac, trWidth, trHeight, TEXT_LUMA);
         }
 
-        m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0);
+        m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0, cu->getChromaFormat());
         m_trQuant->selectLambda(TEXT_LUMA);
 
         absSumY = m_trQuant->transformNxN(cu, resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,
@@ -3040,17 +3103,17 @@
             {
                 m_entropyCoder->estimateBit(m_trQuant->m_estBitsSbac, trWidthC, trHeightC, TEXT_CHROMA);
             }
-
+            //Cb transform
             int curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCbQpOffset() + cu->getSlice()->getSliceQpDeltaCb();
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
             m_trQuant->selectLambda(TEXT_CHROMA);
 
             absSumU = m_trQuant->transformNxN(cu, resiYuv->getCbAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurU,
                                               trWidthC, trHeightC, TEXT_CHROMA_U, absPartIdx, &lastPosU, false, curuseRDOQ);
-
+            //Cr transform
             curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
             absSumV = m_trQuant->transformNxN(cu, resiYuv->getCrAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurV,
                                               trWidthC, trHeightC, TEXT_CHROMA_V, absPartIdx, &lastPosV, false, curuseRDOQ);
 
@@ -3092,7 +3155,7 @@
         {
             int16_t *curResiY = m_qtTempTComYuv[qtlayer].getLumaAddr(absTUPartIdx);
 
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0, cu->getChromaFormat());
 
             int scalingListType = 3 + g_eTTable[(int)TEXT_LUMA];
             assert(scalingListType < 6);
@@ -3164,7 +3227,7 @@
                 int16_t *pcResiCurrU = m_qtTempTComYuv[qtlayer].getCbAddr(absTUPartIdxC);
 
                 int curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCbQpOffset() + cu->getSlice()->getSliceQpDeltaCb();
-                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
                 int scalingListType = 3 + g_eTTable[(int)TEXT_CHROMA_U];
                 assert(scalingListType < 6);
@@ -3230,7 +3293,7 @@
             {
                 int16_t *curResiV = m_qtTempTComYuv[qtlayer].getCrAddr(absTUPartIdxC);
                 int curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();
-                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
                 int scalingListType = 3 + g_eTTable[(int)TEXT_CHROMA_V];
                 assert(scalingListType < 6);
@@ -3321,7 +3384,7 @@
                 m_entropyCoder->estimateBit(m_trQuant->m_estBitsSbac, trWidth, trHeight, TEXT_LUMA);
             }
 
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0, cu->getChromaFormat());
 
             m_trQuant->selectLambda(TEXT_LUMA);
             absSumTransformSkipY = m_trQuant->transformNxN(cu, resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,
@@ -3335,7 +3398,7 @@
                 m_entropyCoder->encodeCoeffNxN(cu, coeffCurY, absPartIdx, trWidth, trHeight, depth, TEXT_LUMA);
                 const uint32_t skipSingleBitsY = m_entropyCoder->getNumberOfWrittenBits();
 
-                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0);
+                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, cu->getSlice()->getSPS()->getQpBDOffsetY(), 0, cu->getChromaFormat());
 
                 int scalingListType = 3 + g_eTTable[(int)TEXT_LUMA];
                 assert(scalingListType < 6);
@@ -3401,13 +3464,13 @@
             }
 
             int curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCbQpOffset() + cu->getSlice()->getSliceQpDeltaCb();
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
             m_trQuant->selectLambda(TEXT_CHROMA);
 
             absSumTransformSkipU = m_trQuant->transformNxN(cu, resiYuv->getCbAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurU,
                                                            trWidthC, trHeightC, TEXT_CHROMA_U, absPartIdx, &lastPosTransformSkipU, true, curuseRDOQ);
             curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();
-            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+            m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
             absSumTransformSkipV = m_trQuant->transformNxN(cu, resiYuv->getCrAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurV,
                                                            trWidthC, trHeightC, TEXT_CHROMA_V, absPartIdx, &lastPosTransformSkipV, true, curuseRDOQ);
 
@@ -3425,7 +3488,7 @@
                 singleBitsU = m_entropyCoder->getNumberOfWrittenBits();
 
                 curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCbQpOffset() + cu->getSlice()->getSliceQpDeltaCb();
-                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
                 int scalingListType = 3 + g_eTTable[(int)TEXT_CHROMA_U];
                 assert(scalingListType < 6);
@@ -3463,7 +3526,7 @@
                 singleBitsV = m_entropyCoder->getNumberOfWrittenBits() - singleBitsU;
 
                 curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();
-                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset);
+                m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, cu->getChromaFormat());
 
                 int scalingListType = 3 + g_eTTable[(int)TEXT_CHROMA_V];
                 assert(scalingListType < 6);
@@ -3616,6 +3679,7 @@
     const uint32_t trMode = cu->getTransformIdx(absPartIdx);
     const bool bSubdiv = curTrMode != trMode;
     const uint32_t trSizeLog2 = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> depth] + 2;
+    uint32_t  trSizeCLog2 = g_convertToBit[(cu->getSlice()->getSPS()->getMaxCUWidth() >> m_hChromaShift) >> depth] + 2;
 
     if (bSubdivAndCbf && trSizeLog2 <= cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() && trSizeLog2 > cu->getQuadtreeTULog2MinSizeInCU(absPartIdx))
     {
@@ -3623,10 +3687,23 @@
     }
 
     assert(cu->getPredictionMode(absPartIdx) != MODE_INTRA);
+
+    bool mCodeAll = true;
+    if ((ttype == TEXT_CHROMA_U) || (ttype == TEXT_CHROMA_V))
+    {
+        int width  = 1 << trSizeLog2;
+        int height = 1 << trSizeLog2;
+        const uint32_t numPels = (width >> cu->getHorzChromaShift()) * (height >> cu->getHorzChromaShift());
+        if(numPels < (MIN_TU_SIZE * MIN_TU_SIZE))
+        {
+            mCodeAll = false;
+        }
+    }
+
     if (bSubdivAndCbf)
     {
         const bool bFirstCbfOfCU = curTrMode == 0;
-        if (bFirstCbfOfCU || trSizeLog2 > 2)
+        if (bFirstCbfOfCU || mCodeAll)
         {
             if (bFirstCbfOfCU || cu->getCbf(absPartIdx, TEXT_CHROMA_U, curTrMode - 1))
             {
@@ -3637,7 +3714,7 @@
                 m_entropyCoder->encodeQtCbf(cu, absPartIdx, TEXT_CHROMA_V, curTrMode);
             }
         }
-        else if (trSizeLog2 == 2)
+        else
         {
             assert(cu->getCbf(absPartIdx, TEXT_CHROMA_U, curTrMode) == cu->getCbf(absPartIdx, TEXT_CHROMA_U, curTrMode - 1));
             assert(cu->getCbf(absPartIdx, TEXT_CHROMA_V, curTrMode) == cu->getCbf(absPartIdx, TEXT_CHROMA_V, curTrMode - 1));
@@ -3646,21 +3723,21 @@
 
     if (!bSubdiv)
     {
+        //Luma
         const uint32_t numCoeffPerAbsPartIdxIncrement = cu->getSlice()->getSPS()->getMaxCUWidth() * cu->getSlice()->getSPS()->getMaxCUHeight() >> (cu->getSlice()->getSPS()->getMaxCUDepth() << 1);
         //assert( 16 == uiNumCoeffPerAbsPartIdxIncrement ); // check
         const uint32_t qtlayer = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
         TCoeff *coeffCurY = m_qtTempCoeffY[qtlayer] +  numCoeffPerAbsPartIdxIncrement * absPartIdx;
-        TCoeff *coeffCurU = m_qtTempCoeffCb[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
-        TCoeff *coeffCurV = m_qtTempCoeffCr[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
+
+        //Chroma
+        TCoeff *coeffCurU = m_qtTempCoeffCb[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
+        TCoeff *coeffCurV = m_qtTempCoeffCr[qtlayer] + (numCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
 
         bool  bCodeChroma = true;
-        uint32_t  trModeC     = trMode;
-        uint32_t  trSizeCLog2 = trSizeLog2 - 1;
-        if (trSizeLog2 == 2)
+        if ((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
         {
             trSizeCLog2++;
-            trModeC--;
-            uint32_t qpdiv = cu->getPic()->getNumPartInCU() >> ((cu->getDepth(0) + trModeC) << 1);
+            uint32_t qpdiv = cu->getPic()->getNumPartInCU() >> ((depth - 1) << 1);
             bCodeChroma = ((absPartIdx % qpdiv) == 0);
         }
 
@@ -3672,21 +3749,18 @@
         {
             if (ttype == TEXT_LUMA && cu->getCbf(absPartIdx, TEXT_LUMA, trMode))
             {
-                int trWidth  = 1 << trSizeLog2;
-                int trHeight = 1 << trSizeLog2;
-                m_entropyCoder->encodeCoeffNxN(cu, coeffCurY, absPartIdx, trWidth, trHeight, depth, TEXT_LUMA);
+                m_entropyCoder->encodeCoeffNxN(cu, coeffCurY, absPartIdx, 1 << trSizeLog2, 1 << trSizeLog2, depth, TEXT_LUMA);
             }
+
             if (bCodeChroma)
             {
-                int trWidth  = 1 << trSizeCLog2;
-                int trHeight = 1 << trSizeCLog2;
                 if (ttype == TEXT_CHROMA_U && cu->getCbf(absPartIdx, TEXT_CHROMA_U, trMode))
                 {
-                    m_entropyCoder->encodeCoeffNxN(cu, coeffCurU, absPartIdx, trWidth, trHeight, depth, TEXT_CHROMA_U);
+                    m_entropyCoder->encodeCoeffNxN(cu, coeffCurU, absPartIdx, 1 << trSizeCLog2, 1 << trSizeCLog2, depth, TEXT_CHROMA_U);
                 }
                 if (ttype == TEXT_CHROMA_V && cu->getCbf(absPartIdx, TEXT_CHROMA_V, trMode))
                 {
-                    m_entropyCoder->encodeCoeffNxN(cu, coeffCurV, absPartIdx, trWidth, trHeight, depth, TEXT_CHROMA_V);
+                    m_entropyCoder->encodeCoeffNxN(cu, coeffCurV, absPartIdx, 1 << trSizeCLog2, 1 << trSizeCLog2, depth, TEXT_CHROMA_V);
                 }
             }
         }
@@ -3712,13 +3786,13 @@
 
     if (curTrMode == trMode)
     {
-        const uint32_t trSizeLog2 = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> depth] + 2;
+        const uint32_t trSizeLog2   = g_convertToBit[cu->getSlice()->getSPS()->getMaxCUWidth() >> depth] + 2;
+        uint32_t  trSizeCLog2 = g_convertToBit[(cu->getSlice()->getSPS()->getMaxCUWidth() >> cu->getHorzChromaShift()) >> depth] + 2;;
         const uint32_t qtlayer = cu->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - trSizeLog2;
 
         bool  bCodeChroma   = true;
         uint32_t  trModeC     = trMode;
-        uint32_t  trSizeCLog2 = trSizeLog2 - 1;
-        if (trSizeLog2 == 2)
+        if((trSizeLog2 == 2) && !(cu->getChromaFormat() == CHROMA_444))
         {
             trSizeCLog2++;
             trModeC--;
@@ -3747,10 +3821,10 @@
             if (bCodeChroma)
             {
                 uint32_t    uiNumCoeffC = (1 << (trSizeCLog2 << 1));
-                TCoeff* pcCoeffSrcU = m_qtTempCoeffCb[qtlayer] + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
-                TCoeff* pcCoeffSrcV = m_qtTempCoeffCr[qtlayer] + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
-                TCoeff* pcCoeffDstU = cu->getCoeffCb() + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
-                TCoeff* pcCoeffDstV = cu->getCoeffCr() + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> 2);
+                TCoeff* pcCoeffSrcU = m_qtTempCoeffCb[qtlayer] + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
+                TCoeff* pcCoeffSrcV = m_qtTempCoeffCr[qtlayer] + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
+                TCoeff* pcCoeffDstU = cu->getCoeffCb() + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
+                TCoeff* pcCoeffDstV = cu->getCoeffCr() + (uiNumCoeffPerAbsPartIdxIncrement * absPartIdx >> (m_hChromaShift + m_vChromaShift));
                 ::memcpy(pcCoeffDstU, pcCoeffSrcU, sizeof(TCoeff) * uiNumCoeffC);
                 ::memcpy(pcCoeffDstV, pcCoeffSrcV, sizeof(TCoeff) * uiNumCoeffC);
             }
diff -r 60f78cbfacc8 -r 1a1badd42498 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Wed Nov 06 17:51:53 2013 -0600
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Fri Dec 20 19:03:46 2013 +0530
@@ -59,6 +59,13 @@
 namespace x265 {
 // private namespace
 
+#define DONT_SPLIT            0
+#define VERTICAL_SPLIT        1
+#define QUAD_SPLIT            2
+#define NUMBER_OF_SPLIT_MODES 3
+
+static const uint32_t partIdxStepShift[NUMBER_OF_SPLIT_MODES] = { 0, 1, 2 };
+
 class TEncCu;
 
 // ====================================================================================================================
@@ -113,6 +120,12 @@
     int             m_hChromaShift;
     int             m_vChromaShift;
 
+    uint32_t        m_section;
+    uint32_t        m_splitMode;
+    uint32_t        m_absPartIdxTURelCU;
+    uint32_t        m_absPartIdxStep;
+    uint32_t        m_partOffset;
+
 public:
 
     TEncSbac***     m_rdSbacCoders;
@@ -175,6 +188,8 @@
 
     uint32_t xSymbolBitsInter(TComDataCU* cu);
 
+    bool isNextSection();
+
 protected:
 
     // --------------------------------------------------------------------------------------------


More information about the x265-devel mailing list