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

ashok at multicorewareinc.com ashok at multicorewareinc.com
Fri Jan 3 13:59:31 CET 2014


# HG changeset patch
# User ashok at multicorewareinc.com
# Date 1388753955 -19800
#      Fri Jan 03 18:29:15 2014 +0530
# Node ID 7e09261ecc4bac5e7dd8e0f8fcd77d344c1037d6
# Parent  6a602378d31b983db4f4293621c35e73f91f9922
Modify TComTrQuant structure to support multiple color space formats

diff -r 6a602378d31b -r 7e09261ecc4b source/Lib/TLibCommon/TComTrQuant.cpp
--- a/source/Lib/TLibCommon/TComTrQuant.cpp	Fri Jan 03 18:23:22 2014 +0530
+++ b/source/Lib/TLibCommon/TComTrQuant.cpp	Fri Jan 03 18:29:15 2014 +0530
@@ -104,7 +104,7 @@
  *
  * return void
  */
-void TComTrQuant::setQPforQuant(int qpy, TextType ttype, int qpBdOffset, int chromaQPOffset)
+void TComTrQuant::setQPforQuant(int qpy, TextType ttype, int qpBdOffset, int chromaQPOffset, int chFmt)
 {
     int qpScaled;
 
@@ -122,15 +122,18 @@
         }
         else
         {
-            qpScaled = g_chromaScale[qpScaled] + qpBdOffset;
+            qpScaled = g_chromaScale[chFmt][qpScaled] + qpBdOffset;
         }
     }
     m_qpParam.setQpParam(qpScaled);
 }
 
 // To minimize the distortion only. No rate is considered.
-void TComTrQuant::signBitHidingHDQ(TCoeff* qCoef, TCoeff* coef, uint32_t const *scan, int32_t* deltaU, int width, int height)
+void TComTrQuant::signBitHidingHDQ( TCoeff* qCoef, TCoeff* coef, int32_t* deltaU, const TUEntropyCodingParameters &codingParameters )
 {
+    const uint32_t width     = codingParameters.widthInGroups  << MLS_CG_LOG2_WIDTH;
+    const uint32_t height    = codingParameters.heightInGroups << MLS_CG_LOG2_HEIGHT;
+
     int lastCG = -1;
     int absSum = 0;
     int n;
@@ -143,7 +146,7 @@
 
         for (n = SCAN_SET_SIZE - 1; n >= 0; --n)
         {
-            if (qCoef[scan[n + subPos]])
+            if (qCoef[codingParameters.scan[n + subPos]])
             {
                 lastNZPosInCG = n;
                 break;
@@ -152,7 +155,7 @@
 
         for (n = 0; n < SCAN_SET_SIZE; n++)
         {
-            if (qCoef[scan[n + subPos]])
+            if (qCoef[codingParameters.scan[n + subPos]])
             {
                 firstNZPosInCG = n;
                 break;
@@ -161,7 +164,7 @@
 
         for (n = firstNZPosInCG; n <= lastNZPosInCG; n++)
         {
-            absSum += qCoef[scan[n + subPos]];
+            absSum += qCoef[codingParameters.scan[n + subPos]];
         }
 
         if (lastNZPosInCG >= 0 && lastCG == -1)
@@ -171,14 +174,14 @@
 
         if (lastNZPosInCG - firstNZPosInCG >= SBH_THRESHOLD)
         {
-            uint32_t signbit = (qCoef[scan[subPos + firstNZPosInCG]] > 0 ? 0 : 1);
+            uint32_t signbit = (qCoef[codingParameters.scan[subPos + firstNZPosInCG]] > 0 ? 0 : 1);
             if (signbit != (absSum & 0x1)) //compare signbit with sum_parity
             {
                 int minCostInc = MAX_INT,  minPos = -1, finalChange = 0, curCost = MAX_INT, curChange = 0;
 
                 for (n = (lastCG == 1 ? lastNZPosInCG : SCAN_SET_SIZE - 1); n >= 0; --n)
                 {
-                    uint32_t blkPos   = scan[n + subPos];
+                    uint32_t blkPos   = codingParameters.scan[n + subPos];
                     if (qCoef[blkPos] != 0)
                     {
                         if (deltaU[blkPos] > 0)
@@ -267,9 +270,8 @@
     }
     else
     {
-        const uint32_t log2BlockSize = g_convertToBit[width] + 2;
-        uint32_t scanIdx = cu->getCoefScanIdx(absPartIdx, width, ttype == TEXT_LUMA, cu->isIntra(absPartIdx));
-        const uint32_t *scan = g_sigLastScan[scanIdx][log2BlockSize - 1];
+        TUEntropyCodingParameters codingParameters;
+        getTUEntropyCodingParameters(cu, codingParameters, absPartIdx,  width, height, ttype);
 
         int deltaU[32 * 32];
 
@@ -288,7 +290,9 @@
         acSum += primitives.quant(coef, quantCoeff, deltaU, qCoef, qbits, add, numCoeff, lastPos);
 
         if (cu->getSlice()->getPPS()->getSignHideFlag() && acSum >= 2)
-            signBitHidingHDQ(qCoef, coef, scan, deltaU, width, height);
+        {
+            signBitHidingHDQ( qCoef, coef, deltaU, codingParameters ) ;
+        }
     }
 
     return acSum;
@@ -369,12 +373,12 @@
     }
 
     // Values need to pass as input parameter in dequant
-    int per = m_qpParam.m_per;
-    int rem = m_qpParam.m_rem;
-    bool useScalingList = getUseScalingList();
-    uint32_t log2TrSize = g_convertToBit[width] + 2;
-    int transformShift = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize;
-    int shift = QUANT_IQUANT_SHIFT - QUANT_SHIFT - transformShift;
+    int per              = m_qpParam.m_per;
+    int rem              = m_qpParam.m_rem;
+    bool useScalingList  = getUseScalingList();
+    uint32_t log2TrSize  = g_convertToBit[width] + 2;
+    int transformShift   = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize;
+    int shift            = QUANT_IQUANT_SHIFT - QUANT_SHIFT - transformShift;
     int32_t *dequantCoef = getDequantCoeff(scalingListType, m_qpParam.m_rem, log2TrSize - 2);
 
     if (!useScalingList)
@@ -488,6 +492,47 @@
     }
 }
 
+void TComTrQuant::getTUEntropyCodingParameters(TComDataCU* cu,
+                                             TUEntropyCodingParameters &result,
+                                             uint32_t absPartIdx,
+                                             uint32_t width,
+                                             uint32_t height,
+                                             TextType ttype)
+{
+    //set the local parameters
+    const uint32_t                 log2BlockWidth  = g_convertToBit[width]  + 2;
+    const uint32_t                 log2BlockHeight = g_convertToBit[height] + 2;
+
+    result.scanType = COEFF_SCAN_TYPE(cu->getCoefScanIdx(absPartIdx, width, ttype == TEXT_LUMA, cu->isIntra(absPartIdx)));
+
+    //set the group layout
+    result.widthInGroups  = width  >> MLS_CG_LOG2_WIDTH;
+    result.heightInGroups = height >> MLS_CG_LOG2_HEIGHT;
+
+    //set the scan orders
+    const uint32_t log2WidthInGroups  = g_convertToBit[result.widthInGroups  * 4];
+    const uint32_t log2HeightInGroups = g_convertToBit[result.heightInGroups * 4];
+
+    result.scan   = g_scanOrder[ SCAN_GROUPED_4x4 ][ result.scanType ][ log2BlockWidth    ][ log2BlockHeight    ];
+    result.scanCG = g_scanOrder[ SCAN_UNGROUPED   ][ result.scanType ][ log2WidthInGroups ][ log2HeightInGroups ];
+
+    //set the significance map context selection parameters
+    if ((width == 4) && (height == 4))
+    {
+        result.firstSignificanceMapContext = significanceMapContextSetStart[ttype][CONTEXT_TYPE_4x4];
+    }
+    else if ((width == 8) && (height == 8))
+    {
+        result.firstSignificanceMapContext = significanceMapContextSetStart[ttype][CONTEXT_TYPE_8x8];
+        if (result.scanType != SCAN_DIAG) 
+            result.firstSignificanceMapContext += nonDiagonalScan8x8ContextOffset[ttype];
+    }
+    else
+    {
+        result.firstSignificanceMapContext = significanceMapContextSetStart[ttype][CONTEXT_TYPE_NxN];
+    }
+}
+
 /** RDOQ with CABAC
  * \param cu pointer to coding unit structure
  * \param plSrcCoeff pointer to input buffer
@@ -504,22 +549,20 @@
 uint32_t TComTrQuant::xRateDistOptQuant(TComDataCU* cu, int32_t* srcCoeff, TCoeff* dstCoeff, uint32_t width, uint32_t height,
                                         TextType ttype, uint32_t absPartIdx, int32_t *lastPos)
 {
-    uint32_t log2TrSize = g_convertToBit[width] + 2;
-    uint32_t absSum = 0;
-    int transformShift = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize; // Represents scaling through forward transform
-    uint32_t       goRiceParam      = 0;
-    double     blockUncodedCost = 0;
-    const uint32_t log2BlkSize      = g_convertToBit[width] + 2;
-    int scalingListType = (cu->isIntra(absPartIdx) ? 0 : 3) + g_eTTable[(int)ttype];
+    uint32_t log2TrSize     = g_convertToBit[width] + 2;
+    uint32_t absSum         = 0;
+    int transformShift      = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize; // Represents scaling through forward transform
+    uint32_t goRiceParam    = 0;
+    double blockUncodedCost = 0;
+    int scalingListType     = (cu->isIntra(absPartIdx) ? 0 : 3) + g_eTTable[(int)ttype];
 
     assert(scalingListType < 6);
 
     int qbits = QUANT_SHIFT + m_qpParam.m_per + transformShift; // Right shift of non-RDOQ quantizer;  level = (coeff*Q + offset)>>q_bits
     double *errScaleOrg = getErrScaleCoeff(scalingListType, log2TrSize - 2, m_qpParam.m_rem);
-    int32_t *qCoefOrg = getQuantCoeff(scalingListType, m_qpParam.m_rem, log2TrSize - 2);
-    int32_t *qCoef = qCoefOrg;
-    double *errScale = errScaleOrg;
-    uint32_t scanIdx = cu->getCoefScanIdx(absPartIdx, width, ttype == TEXT_LUMA, cu->isIntra(absPartIdx));
+    int32_t *qCoefOrg   = getQuantCoeff(scalingListType, m_qpParam.m_rem, log2TrSize - 2);
+    int32_t *qCoef      = qCoefOrg;
+    double *errScale    = errScaleOrg;
 
     double costCoeff[32 * 32];
     double costSig[32 * 32];
@@ -530,33 +573,25 @@
     int sigRateDelta[32 * 32];
     int deltaU[32 * 32];
 
-    const uint32_t * scanCG;
-    scanCG = g_sigLastScan[scanIdx][log2BlkSize > 3 ? log2BlkSize - 2 - 1 : 0];
-    if (log2BlkSize == 3)
-    {
-        scanCG = g_sigLastScan8x8[scanIdx];
-    }
-    else if (log2BlkSize == 5)
-    {
-        scanCG = g_sigLastScanCG32x32;
-    }
+    TUEntropyCodingParameters codingParameters;
+    getTUEntropyCodingParameters(cu, codingParameters, absPartIdx,  width, height, ttype);
+
     const uint32_t cgSize = (1 << MLS_CG_SIZE); // 16
     double costCoeffGroupSig[MLS_GRP_NUM];
     uint32_t sigCoeffGroupFlag[MLS_GRP_NUM];
+    const uint32_t log2BlockWidth    = g_convertToBit[ width  ] + 2;
+    const uint32_t log2BlockHeight   = g_convertToBit[ height ] + 2;
 
-    uint32_t   numBlkSide  = width / MLS_CG_SIZE;
-    uint32_t   ctxSet      = 0;
-    int    c1          = 1;
-    int    c2          = 0;
-    double baseCost    = 0;
-    int    lastScanPos = -1;
-    uint32_t   c1Idx       = 0;
-    uint32_t   c2Idx       = 0;
+    uint32_t   ctxSet    = 0;
+    int    c1            = 1;
+    int    c2            = 0;
+    double baseCost      = 0;
+    int    lastScanPos   = -1;
+    uint32_t   c1Idx     = 0;
+    uint32_t   c2Idx     = 0;
     int    cgLastScanPos = -1;
     int    baseLevel;
 
-    const uint32_t *scan = g_sigLastScan[scanIdx][log2BlkSize - 1];
-
     ::memset(sigCoeffGroupFlag, 0, sizeof(uint32_t) * MLS_GRP_NUM);
 
     uint32_t cgNum = width * height >> MLS_CG_SIZE;
@@ -565,17 +600,17 @@
 
     for (int cgScanPos = cgNum - 1; cgScanPos >= 0; cgScanPos--)
     {
-        uint32_t cgBlkPos = scanCG[cgScanPos];
-        uint32_t cgPosY   = cgBlkPos / numBlkSide;
-        uint32_t cgPosX   = cgBlkPos - (cgPosY * numBlkSide);
+        uint32_t cgBlkPos = codingParameters.scanCG[cgScanPos];
+        uint32_t cgPosY   = cgBlkPos / codingParameters.widthInGroups;
+        uint32_t cgPosX   = cgBlkPos - (cgPosY * codingParameters.widthInGroups);
         ::memset(&rdStats, 0, sizeof(coeffGroupRDStats));
 
-        const int patternSigCtx = TComTrQuant::calcPatternSigCtx(sigCoeffGroupFlag, cgPosX, cgPosY, log2BlkSize);
+        const int patternSigCtx = TComTrQuant::calcPatternSigCtx(sigCoeffGroupFlag, cgPosX, cgPosY, codingParameters.widthInGroups, codingParameters.heightInGroups);
         for (int scanPosinCG = cgSize - 1; scanPosinCG >= 0; scanPosinCG--)
         {
             scanPos = cgScanPos * cgSize + scanPosinCG;
             //===== quantization =====
-            uint32_t blkPos = scan[scanPos];
+            uint32_t blkPos = codingParameters.scan[scanPos];
             // set coeff
             int Q = qCoef[blkPos];
             double scaleFactor = errScale[blkPos];
@@ -616,10 +651,8 @@
                 }
                 else
                 {
-                    uint32_t   posY   = blkPos >> log2BlkSize;
-                    uint32_t   posX   = blkPos - (posY << log2BlkSize);
-                    uint16_t ctxSig = getSigCtxInc(patternSigCtx, scanIdx, posX, posY, log2BlkSize, ttype);
-                    level         = xGetCodedLevel(costCoeff[scanPos], costCoeff0[scanPos], costSig[scanPos],
+                    uint16_t ctxSig = getSigCtxInc( patternSigCtx, codingParameters, scanPos, log2BlockWidth, log2BlockHeight, ttype);
+                    level           = xGetCodedLevel(costCoeff[scanPos], costCoeff0[scanPos], costSig[scanPos],
                                                    levelDouble, maxAbsLevel, ctxSig, oneCtx, absCtx, goRiceParam,
                                                    c1Idx, c2Idx, qbits, scaleFactor, 0);
                     sigRateDelta[blkPos] = m_estBitsSbac->significantBits[ctxSig][1] - m_estBitsSbac->significantBits[ctxSig][0];
@@ -627,8 +660,8 @@
                 deltaU[blkPos] = (levelDouble - ((int)level << qbits)) >> (qbits - 8);
                 if (level > 0)
                 {
-                    int rateNow = xGetICRate(level, oneCtx, absCtx, goRiceParam, c1Idx, c2Idx);
-                    rateIncUp[blkPos] = xGetICRate(level + 1, oneCtx, absCtx, goRiceParam, c1Idx, c2Idx) - rateNow;
+                    int rateNow         = xGetICRate(level, oneCtx, absCtx, goRiceParam, c1Idx, c2Idx);
+                    rateIncUp[blkPos]   = xGetICRate(level + 1, oneCtx, absCtx, goRiceParam, c1Idx, c2Idx) - rateNow;
                     rateIncDown[blkPos] = xGetICRate(level - 1, oneCtx, absCtx, goRiceParam, c1Idx, c2Idx) - rateNow;
                 }
                 else // level == 0
@@ -708,7 +741,7 @@
             {
                 if (sigCoeffGroupFlag[cgBlkPos] == 0)
                 {
-                    uint32_t  ctxSig = getSigCoeffGroupCtxInc(sigCoeffGroupFlag, cgPosX, cgPosY, log2BlkSize);
+                    uint32_t  ctxSig = getSigCoeffGroupCtxInc( sigCoeffGroupFlag, cgPosX, cgPosY, codingParameters.widthInGroups, codingParameters.heightInGroups );
                     baseCost += xGetRateSigCoeffGroup(0, ctxSig) - rdStats.sigCost;
                     costCoeffGroupSig[cgScanPos] = xGetRateSigCoeffGroup(0, ctxSig);
                 }
@@ -725,7 +758,7 @@
                         double costZeroCG = baseCost;
 
                         // add SigCoeffGroupFlag cost to total cost
-                        uint32_t  ctxSig = getSigCoeffGroupCtxInc(sigCoeffGroupFlag, cgPosX, cgPosY, log2BlkSize);
+                        uint32_t  ctxSig = getSigCoeffGroupCtxInc( sigCoeffGroupFlag, cgPosX, cgPosY, codingParameters.widthInGroups, codingParameters.heightInGroups );
                         if (cgScanPos < cgLastScanPos)
                         {
                             baseCost  += xGetRateSigCoeffGroup(1, ctxSig);
@@ -751,7 +784,7 @@
                             for (int scanPosinCG = cgSize - 1; scanPosinCG >= 0; scanPosinCG--)
                             {
                                 scanPos      = cgScanPos * cgSize + scanPosinCG;
-                                uint32_t blkPos = scan[scanPos];
+                                uint32_t blkPos = codingParameters.scan[scanPos];
 
                                 if (dstCoeff[blkPos])
                                 {
@@ -797,8 +830,7 @@
     bool foundLast = false;
     for (int cgScanPos = cgLastScanPos; cgScanPos >= 0; cgScanPos--)
     {
-        uint32_t cgBlkPos = scanCG[cgScanPos];
-
+        uint32_t cgBlkPos = codingParameters.scanCG[cgScanPos];
         baseCost -= costCoeffGroupSig[cgScanPos];
         if (sigCoeffGroupFlag[cgBlkPos])
         {
@@ -807,13 +839,13 @@
                 scanPos = cgScanPos * cgSize + scanPosinCG;
                 if (scanPos > lastScanPos) continue;
 
-                uint32_t blkPos = scan[scanPos];
+                uint32_t blkPos = codingParameters.scan[scanPos];
                 if (dstCoeff[blkPos])
                 {
-                    uint32_t posY = blkPos >> log2BlkSize;
-                    uint32_t posX = blkPos - (posY << log2BlkSize);
+                    uint32_t posY = blkPos >> log2BlockWidth;
+                    uint32_t posX = blkPos - (posY << log2BlockWidth);
 
-                    double costLast = scanIdx == SCAN_VER ? xGetRateLast(posY, posX) : xGetRateLast(posX, posY);
+                    double costLast = codingParameters.scanType == SCAN_VER ? xGetRateLast(posY, posX) : xGetRateLast(posX, posY);
                     double totalCost = baseCost + costLast - costSig[scanPos];
 
                     if (totalCost < bestCost)
@@ -844,7 +876,7 @@
 
     for (int pos = 0; pos < bestLastIdxp1; pos++)
     {
-        int blkPos = scan[pos];
+        int blkPos = codingParameters.scan[pos];
         int level  = dstCoeff[blkPos];
         absSum += level;
         if (level)
@@ -855,7 +887,7 @@
     //===== clean uncoded coefficients =====
     for (int pos = bestLastIdxp1; pos <= lastScanPos; pos++)
     {
-        dstCoeff[scan[pos]] = 0;
+        dstCoeff[codingParameters.scan[pos]] = 0;
     }
 
     if (cu->getSlice()->getPPS()->getSignHideFlag() && absSum >= 2)
@@ -876,7 +908,7 @@
 
             for (n = SCAN_SET_SIZE - 1; n >= 0; --n)
             {
-                if (dstCoeff[scan[n + subPos]])
+                if (dstCoeff[codingParameters.scan[n + subPos]])
                 {
                     lastNZPosInCG = n;
                     break;
@@ -885,7 +917,7 @@
 
             for (n = 0; n < SCAN_SET_SIZE; n++)
             {
-                if (dstCoeff[scan[n + subPos]])
+                if (dstCoeff[codingParameters.scan[n + subPos]])
                 {
                     firstNZPosInCG = n;
                     break;
@@ -894,7 +926,7 @@
 
             for (n = firstNZPosInCG; n <= lastNZPosInCG; n++)
             {
-                tmpSum += dstCoeff[scan[n + subPos]];
+                tmpSum += dstCoeff[codingParameters.scan[n + subPos]];
             }
 
             if (lastNZPosInCG >= 0 && lastCG == -1)
@@ -904,7 +936,7 @@
 
             if (lastNZPosInCG - firstNZPosInCG >= SBH_THRESHOLD)
             {
-                uint32_t signbit = (dstCoeff[scan[subPos + firstNZPosInCG]] > 0 ? 0 : 1);
+                uint32_t signbit = (dstCoeff[codingParameters.scan[subPos + firstNZPosInCG]] > 0 ? 0 : 1);
                 if (signbit != (tmpSum & 0x1)) // hide but need tune
                 {
                     // calculate the cost
@@ -913,7 +945,7 @@
 
                     for (n = (lastCG == 1 ? lastNZPosInCG : SCAN_SET_SIZE - 1); n >= 0; --n)
                     {
-                        uint32_t blkPos   = scan[n + subPos];
+                        uint32_t blkPos   = codingParameters.scan[n + subPos];
                         if (dstCoeff[blkPos] != 0)
                         {
                             int64_t costUp   = rdFactor * (-deltaU[blkPos]) + rateIncUp[blkPos];
@@ -1000,29 +1032,20 @@
  * \param height height of the block
  * \returns pattern for current coefficient group
  */
-int TComTrQuant::calcPatternSigCtx(const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, int log2BlockSize)
+int TComTrQuant::calcPatternSigCtx(const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, uint32_t widthInGroups, uint32_t heightInGroups)
 {
-    if (log2BlockSize == 2)
-        return -1;
+    if ((widthInGroups <= 1) && (heightInGroups <= 1)) return 0;
 
-    log2BlockSize -= 2;
+    const bool rightAvailable = posXCG < (widthInGroups  - 1);
+    const bool belowAvailable = posYCG < (heightInGroups - 1);
 
-    const int size = (1 << log2BlockSize);
-    const uint32_t* sigPos = &sigCoeffGroupFlag[(posYCG << log2BlockSize) + posXCG];
+    uint32_t sigRight = 0;
+    uint32_t sigLower = 0;
 
-    if (posXCG < size - 1)
-        assert(sigPos[1] <= 1);
-
-    if (posYCG < size - 1)
-        assert(sigPos[size] <= 1);
-
-    uint32_t sigRight = (sigPos[1]);
-    uint32_t sigLower = (sigPos[size]);
-    int maskRight = ((int)(posXCG - size + 1)) >> 31;
-    int maskLower = ((int)(posYCG - size + 1)) >> 31;
-
-    sigRight &= maskRight;
-    sigLower &= maskLower;
+    if (rightAvailable)
+        sigRight = ((sigCoeffGroupFlag[ (posYCG * widthInGroups) + posXCG + 1 ] != 0) ? 1 : 0);
+    if (belowAvailable)
+        sigLower = ((sigCoeffGroupFlag[ (posYCG + 1) * widthInGroups + posXCG ] != 0) ? 1 : 0);
 
     return sigRight + (sigLower << 1);
 }
@@ -1037,12 +1060,12 @@
  * \param textureType texture type (TEXT_LUMA...)
  * \returns ctxInc for current scan position
  */
-int TComTrQuant::getSigCtxInc(int      patternSigCtx,
-                              uint32_t scanIdx,
-                              int      posX,
-                              int      posY,
-                              int      log2BlockSize,
-                              TextType ttype)
+int TComTrQuant::getSigCtxInc(      int patternSigCtx,
+                                  const TUEntropyCodingParameters &codingParameters,
+                                  const int                        scanPosition,
+                                  const int                        log2BlockWidth,
+                                  const int                        log2BlockHeight,
+                                  const TextType                   ttype)
 {
     static const int ctxIndMap[16] =
     {
@@ -1052,58 +1075,74 @@
         7, 7, 8, 8
     };
 
-    if (posX + posY == 0)
+    const uint32_t rasterPosition = codingParameters.scan[scanPosition];
+    const uint32_t posY           = rasterPosition >> log2BlockWidth;
+    const uint32_t posX           = rasterPosition - (posY << log2BlockWidth);
+
+    if ((posX + posY) == 0) return 0; //special case for the DC context variable
+
+    int offset = MAX_INT;
+
+    if ((log2BlockWidth == 2) && (log2BlockHeight == 2)) //4x4
     {
-        return 0;
+        offset = ctxIndMap[ (4 * posY) + posX ];
+    }
+    else
+    {
+        int cnt = 0;
+
+        switch (patternSigCtx)
+        {
+        case 0: //neither neighbouring group is significant
+        {
+            const int posXinSubset     = posX & ((1 << MLS_CG_LOG2_WIDTH)  - 1);
+            const int posYinSubset     = posY & ((1 << MLS_CG_LOG2_HEIGHT) - 1);
+            const int posTotalInSubset = posXinSubset + posYinSubset;
+
+            //first N coefficients in scan order use 2; the next few use 1; the rest use 0.
+            const uint32_t context1Threshold = NEIGHBOURHOOD_00_CONTEXT_1_THRESHOLD_4x4;
+            const uint32_t context2Threshold = NEIGHBOURHOOD_00_CONTEXT_2_THRESHOLD_4x4;
+
+            cnt = (posTotalInSubset >= context1Threshold) ? 0 : ((posTotalInSubset >= context2Threshold) ? 1 : 2);
+        }
+        break;
+
+        case 1: //right group is significant, below is not
+        {
+            const int posYinSubset = posY & ((1 << MLS_CG_LOG2_HEIGHT) - 1);
+            const int groupHeight  = 1 << MLS_CG_LOG2_HEIGHT;
+
+            cnt = (posYinSubset >= (groupHeight >> 1)) ? 0 : ((posYinSubset >= (groupHeight >> 2)) ? 1 : 2); //top quarter uses 2; second-from-top quarter uses 1; bottom half uses 0
+        }
+        break;
+
+        case 2: //below group is significant, right is not
+        {
+            const int posXinSubset = posX & ((1 << MLS_CG_LOG2_WIDTH)  - 1);
+            const int groupWidth   = 1 << MLS_CG_LOG2_WIDTH;
+
+            cnt = (posXinSubset >= (groupWidth >> 1)) ? 0 : ((posXinSubset >= (groupWidth >> 2)) ? 1 : 2); //left quarter uses 2; second-from-left quarter uses 1; right half uses 0
+        }
+        break;
+
+        case 3: //both neighbouring groups are significant
+        {
+            cnt = 2;
+        }
+        break;
+
+        default:
+            x265_log(NULL, X265_LOG_ERROR, "TComTrQuant: ERROR - Invalid patternSigCtx");
+            exit(1);
+            break;
+        }
+
+        const bool notFirstGroup = ((posX >> MLS_CG_LOG2_WIDTH) + (posY >> MLS_CG_LOG2_HEIGHT)) > 0;
+
+        offset = (notFirstGroup ? notFirstGroupNeighbourhoodContextOffset[ttype] : 0) + cnt;
     }
 
-    if (log2BlockSize == 2)
-    {
-        return ctxIndMap[4 * posY + posX];
-    }
-
-    int posXinSubset = posX & 3;
-    int posYinSubset = posY & 3;
-
-    // NOTE: [patternSigCtx][posXinSubset][posYinSubset]
-    static uint8_t table_cnt[4][4][4] =
-    {
-        // patternSigCtx = 0
-        {
-            { 2, 1, 1, 0 },
-            { 1, 1, 0, 0 },
-            { 1, 0, 0, 0 },
-            { 0, 0, 0, 0 },
-        },
-        // patternSigCtx = 1
-        {
-            { 2, 1, 0, 0 },
-            { 2, 1, 0, 0 },
-            { 2, 1, 0, 0 },
-            { 2, 1, 0, 0 },
-        },
-        // patternSigCtx = 2
-        {
-            { 2, 2, 2, 2 },
-            { 1, 1, 1, 1 },
-            { 0, 0, 0, 0 },
-            { 0, 0, 0, 0 },
-        },
-        // patternSigCtx = 3
-        {
-            { 2, 2, 2, 2 },
-            { 2, 2, 2, 2 },
-            { 2, 2, 2, 2 },
-            { 2, 2, 2, 2 },
-        }
-    };
-
-    int cnt = table_cnt[patternSigCtx][posXinSubset][posYinSubset];
-    int offset = log2BlockSize == 3 ? (scanIdx == SCAN_DIAG ? 9 : 15) : (ttype == TEXT_LUMA ? 21 : 12);
-
-    offset += cnt;
-
-    return (ttype == TEXT_LUMA && (posX | posY) >= 4) ? 3 + offset : offset;
+  return codingParameters.firstSignificanceMapContext + offset;
 }
 
 /** Get the best level in RD sense
@@ -1332,23 +1371,25 @@
  * \param uiLog2BlkSize log2 value of block size
  * \returns ctxInc for current scan position
  */
-uint32_t TComTrQuant::getSigCoeffGroupCtxInc(const uint32_t* sigCoeffGroupFlag, uint32_t cgPosX, uint32_t cgPosY, int log2BlockSize)
+uint32_t TComTrQuant::getSigCoeffGroupCtxInc  (const uint32_t*  sigCoeffGroupFlag,
+                                           const uint32_t   cgPosX,
+                                           const uint32_t   cgPosY,
+                                           const uint32_t   widthInGroups,
+                                           const uint32_t   heightInGroups)
 {
-    log2BlockSize -= 2;
+    uint32_t sigRight = 0;
+    uint32_t sigLower = 0;
 
-    const int size = (1 << log2BlockSize);
-    const uint32_t* sigPos = &sigCoeffGroupFlag[(cgPosY << log2BlockSize) + cgPosX];
+    if (cgPosX < (widthInGroups  - 1))
+    {
+        sigRight = ((sigCoeffGroupFlag[ (cgPosY * widthInGroups) + cgPosX + 1 ] != 0) ? 1 : 0);
+    }
+    if (cgPosY < (heightInGroups - 1))
+    {
+        sigLower = ((sigCoeffGroupFlag[ (cgPosY + 1) * widthInGroups + cgPosX ] != 0) ? 1 : 0);
+    }
 
-    if (cgPosX < size - 1)
-        assert(sigPos[1] <= 1);
-
-    if (cgPosY < size - 1)
-        assert(sigPos[size] <= 1);
-
-    uint32_t sigRight = (cgPosX == size - 1) ? 0 : (sigPos[1]);
-    uint32_t sigLower = (cgPosY == size - 1) ? 0 : (sigPos[size]);
-
-    return sigRight | sigLower;
+    return ((sigRight + sigLower) != 0) ? 1 : 0;
 }
 
 /** set quantized matrix coefficient for encode
@@ -1548,14 +1589,6 @@
             }
         }
     }
-
-    // alias list [1] as [3].
-    for (uint32_t qp = 0; qp < SCALING_LIST_REM_NUM; qp++)
-    {
-        m_quantCoef[SCALING_LIST_32x32][3][qp] = m_quantCoef[SCALING_LIST_32x32][1][qp];
-        m_dequantCoef[SCALING_LIST_32x32][3][qp] = m_dequantCoef[SCALING_LIST_32x32][1][qp];
-        m_errScale[SCALING_LIST_32x32][3][qp] = m_errScale[SCALING_LIST_32x32][1][qp];
-    }
 }
 
 /** destroy quantization matrix array
diff -r 6a602378d31b -r 7e09261ecc4b source/Lib/TLibCommon/TComTrQuant.h
--- a/source/Lib/TLibCommon/TComTrQuant.h	Fri Jan 03 18:23:22 2014 +0530
+++ b/source/Lib/TLibCommon/TComTrQuant.h	Fri Jan 03 18:29:15 2014 +0530
@@ -133,7 +133,7 @@
     void invtransformNxN(bool transQuantBypass, uint32_t mode, int16_t* residual, uint32_t stride, TCoeff* coeff, uint32_t width, uint32_t height, int scalingListType, bool useTransformSkip = false, int lastPos = MAX_INT);
 
     // Misc functions
-    void setQPforQuant(int qpy, TextType ttype, int qpBdOffset, int chromaQPOffset);
+    void setQPforQuant(int qpy, TextType ttype, int qpBdOffset, int chromaQPOffset, int chFmt);
 
     void setLambda(double lambdaLuma, double lambdaChroma) { m_lumaLambda = lambdaLuma; m_chromaLambda = lambdaChroma; }
 
@@ -160,11 +160,12 @@
     void processScalingListEnc(int32_t *coeff, int32_t *quantcoeff, int quantScales, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
     void processScalingListDec(int32_t *coeff, int32_t *dequantcoeff, int invQuantScales, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
 
-    static int  calcPatternSigCtx(const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, int log2BlockSize);
+    static int  calcPatternSigCtx(const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, uint32_t widthInGroups, uint32_t heightInGroups);
 
-    static int  getSigCtxInc(int patternSigCtx, uint32_t scanIdx, int posX, int posY, int log2BlkSize, TextType ttype);
+    static int getSigCtxInc(int patternSigCtx, const TUEntropyCodingParameters &codingParameters, const int scanPosition, const int log2BlockWidth, const int log2BlockHeight, const TextType ttype);
 
-    static uint32_t getSigCoeffGroupCtxInc(const uint32_t* sigCoeffGroupFlag, uint32_t cGPosX, uint32_t cGPosY, int log2BlockSize);
+    static uint32_t getSigCoeffGroupCtxInc(const uint32_t* sigCoeffGroupFlag, uint32_t cGPosX, uint32_t cGPosY, const uint32_t widthInGroups, const uint32_t heightInGroups);
+     static void getTUEntropyCodingParameters(TComDataCU* cu, TUEntropyCodingParameters &result, uint32_t absPartIdx, uint32_t width, uint32_t height, TextType ttype);
 
     estBitsSbacStruct* m_estBitsSbac;
 
@@ -192,7 +193,7 @@
 
     void xTransformSkip(int16_t* resiBlock, uint32_t stride, int32_t* coeff, int width, int height);
 
-    void signBitHidingHDQ(TCoeff* qcoeff, TCoeff* coeff, const uint32_t* scan, int32_t* deltaU, int width, int height);
+    void signBitHidingHDQ(TCoeff* qcoeff, TCoeff* coeff, int32_t* deltaU, const TUEntropyCodingParameters &codingParameters);
 
     uint32_t xQuant(TComDataCU* cu, int32_t* src, TCoeff* dst, int width, int height, TextType ttype, uint32_t absPartIdx, int32_t *lastPos, bool curUseRDOQ = true);
 


More information about the x265-devel mailing list