[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