[x265] [PATCH 2 of 3] improve rdoQuant by more parameters on getSigCoeffGroupCtxInc and calcPatternSigCtx
Min Chen
chenm003 at 163.com
Mon Apr 6 14:18:14 CEST 2015
# HG changeset patch
# User Min Chen <chenm003 at 163.com>
# Date 1428322677 -28800
# Node ID d2469bcb4e81c7e095b5ecbeef5fa956ae28d673
# Parent 67e573d7cb4369898e4e664fbc7e4421b800cc30
improve rdoQuant by more parameters on getSigCoeffGroupCtxInc and calcPatternSigCtx
---
source/common/quant.cpp | 36 ++++--------------------------------
source/common/quant.h | 33 +++++++++++++++++++++++++++++++--
source/encoder/entropy.cpp | 4 ++--
3 files changed, 37 insertions(+), 36 deletions(-)
diff -r 67e573d7cb43 -r d2469bcb4e81 source/common/quant.cpp
--- a/source/common/quant.cpp Mon Apr 06 20:17:52 2015 +0800
+++ b/source/common/quant.cpp Mon Apr 06 20:17:57 2015 +0800
@@ -595,7 +595,7 @@
const uint64_t cgBlkPosMask = ((uint64_t)1 << cgBlkPos);
memset(&cgRdStats, 0, sizeof(coeffGroupRDStats));
- const int patternSigCtx = calcPatternSigCtx(sigCoeffGroupFlag64, cgPosX, cgPosY, codeParams.log2TrSizeCG);
+ const int patternSigCtx = calcPatternSigCtx(sigCoeffGroupFlag64, cgPosX, cgPosY, cgBlkPos, (trSize >> MLS_CG_LOG2_SIZE));
/* iterate over coefficients in each group in reverse scan order */
for (int scanPosinCG = cgSize - 1; scanPosinCG >= 0; scanPosinCG--)
@@ -815,7 +815,7 @@
* of the significant coefficient group flag and evaluate whether the RD cost of the
* coded group is more than the RD cost of the uncoded group */
- uint32_t sigCtx = getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, codeParams.log2TrSizeCG);
+ uint32_t sigCtx = getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, cgBlkPos, (trSize >> MLS_CG_LOG2_SIZE));
int64_t costZeroCG = totalRdCost + SIGCOST(estBitsSbac.significantCoeffGroupBits[sigCtx][0]);
costZeroCG += cgRdStats.uncodedDist; /* add distortion for resetting non-zero levels to zero levels */
@@ -848,7 +848,7 @@
else
{
/* there were no coded coefficients in this coefficient group */
- uint32_t ctxSig = getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, codeParams.log2TrSizeCG);
+ uint32_t ctxSig = getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, cgBlkPos, (trSize >> MLS_CG_LOG2_SIZE));
costCoeffGroupSig[cgScanPos] = SIGCOST(estBitsSbac.significantCoeffGroupBits[ctxSig][0]);
totalRdCost += costCoeffGroupSig[cgScanPos]; /* add cost of 0 bit in significant CG bitmap */
totalRdCost -= cgRdStats.sigCost; /* remove cost of significant coefficient bitmap */
@@ -909,7 +909,7 @@
* cost of signaling it as not-significant */
uint32_t blkPos = codeParams.scan[scanPos];
if (dstCoeff[blkPos])
- {
+ {
// Calculates the cost of signaling the last significant coefficient in the block
uint32_t pos[2] = { (blkPos & (trSize - 1)), (blkPos >> log2TrSize) };
if (codeParams.scanType == SCAN_VER)
@@ -1092,22 +1092,6 @@
return numSig;
}
-/* Pattern decision for context derivation process of significant_coeff_flag */
-uint32_t Quant::calcPatternSigCtx(uint64_t sigCoeffGroupFlag64, uint32_t cgPosX, uint32_t cgPosY, uint32_t log2TrSizeCG)
-{
- if (!log2TrSizeCG)
- return 0;
-
- const uint32_t trSizeCG = 1 << log2TrSizeCG;
- X265_CHECK(trSizeCG <= 8, "transform CG is too large\n");
- const uint32_t shift = (cgPosY << log2TrSizeCG) + cgPosX + 1;
- const uint32_t sigPos = (uint32_t)(shift >= 64 ? 0 : sigCoeffGroupFlag64 >> shift);
- const uint32_t sigRight = ((int32_t)(cgPosX - (trSizeCG - 1)) >> 31) & (sigPos & 1);
- const uint32_t sigLower = ((int32_t)(cgPosY - (trSizeCG - 1)) >> 31) & (sigPos >> (trSizeCG - 2)) & 2;
-
- return sigRight + sigLower;
-}
-
/* Context derivation process of coeff_abs_significant_flag */
uint32_t Quant::getSigCtxInc(uint32_t patternSigCtx, uint32_t log2TrSize, uint32_t trSize, uint32_t blkPos, bool bIsLuma,
uint32_t firstSignificanceMapContext)
@@ -1175,15 +1159,3 @@
return (bIsLuma && (posX | posY) >= 4) ? 3 + offset : offset;
}
-/* Context derivation process of coeff_abs_significant_flag */
-uint32_t Quant::getSigCoeffGroupCtxInc(uint64_t cgGroupMask, uint32_t cgPosX, uint32_t cgPosY, uint32_t log2TrSizeCG)
-{
- const uint32_t trSizeCG = 1 << log2TrSizeCG;
-
- const uint32_t shift = (cgPosY << log2TrSizeCG) + cgPosX + 1;
- const uint32_t sigPos = (uint32_t)(shift >= 64 ? 0 : cgGroupMask >> shift);
- const uint32_t sigRight = ((int32_t)(cgPosX - (trSizeCG - 1)) >> 31) & sigPos;
- const uint32_t sigLower = ((int32_t)(cgPosY - (trSizeCG - 1)) >> 31) & (sigPos >> (trSizeCG - 1));
-
- return (sigRight | sigLower) & 1;
-}
diff -r 67e573d7cb43 -r d2469bcb4e81 source/common/quant.h
--- a/source/common/quant.h Mon Apr 06 20:17:52 2015 +0800
+++ b/source/common/quant.h Mon Apr 06 20:17:57 2015 +0800
@@ -111,10 +111,39 @@
void invtransformNxN(int16_t* residual, uint32_t resiStride, const coeff_t* coeff,
uint32_t log2TrSize, TextType ttype, bool bIntra, bool useTransformSkip, uint32_t numSig);
+ /* Pattern decision for context derivation process of significant_coeff_flag */
+ static uint32_t calcPatternSigCtx(uint64_t sigCoeffGroupFlag64, uint32_t cgPosX, uint32_t cgPosY, uint32_t cgBlkPos, uint32_t trSizeCG)
+ {
+ if (trSizeCG == 1)
+ return 0;
+
+ X265_CHECK(trSizeCG <= 8, "transform CG is too large\n");
+ X265_CHECK(cgBlkPos < 64, "cgBlkPos is too large\n");
+ // NOTE: cgBlkPos+1 may more than 63, it is invalid for shift,
+ // but in this case, both cgPosX and cgPosY equal to (trSizeCG - 1),
+ // the sigRight and sigLower will clear value to zero, the final result will be correct
+ const uint32_t sigPos = (uint32_t)(sigCoeffGroupFlag64 >> (cgBlkPos + 1)); // just need lowest 7-bits valid
+
+ // TODO: instruction BT is faster, but _bittest64 still generate instruction 'BT m, r' in VS2012
+ const uint32_t sigRight = ((int32_t)(cgPosX - (trSizeCG - 1)) >> 31) & (sigPos & 1);
+ const uint32_t sigLower = ((int32_t)(cgPosY - (trSizeCG - 1)) >> 31) & (sigPos >> (trSizeCG - 2)) & 2;
+ return sigRight + sigLower;
+ }
+
+ /* Context derivation process of coeff_abs_significant_flag */
+ static uint32_t getSigCoeffGroupCtxInc(uint64_t cgGroupMask, uint32_t cgPosX, uint32_t cgPosY, uint32_t cgBlkPos, uint32_t trSizeCG)
+ {
+ X265_CHECK(cgBlkPos < 64, "cgBlkPos is too large\n");
+ // NOTE: unsafe shift operator, see NOTE in calcPatternSigCtx
+ const uint32_t sigPos = (uint32_t)(cgGroupMask >> (cgBlkPos + 1)); // just need lowest 8-bits valid
+ const uint32_t sigRight = ((int32_t)(cgPosX - (trSizeCG - 1)) >> 31) & sigPos;
+ const uint32_t sigLower = ((int32_t)(cgPosY - (trSizeCG - 1)) >> 31) & (sigPos >> (trSizeCG - 1));
+
+ return (sigRight | sigLower) & 1;
+ }
+
/* static methods shared with entropy.cpp */
- static uint32_t calcPatternSigCtx(uint64_t sigCoeffGroupFlag64, uint32_t cgPosX, uint32_t cgPosY, uint32_t log2TrSizeCG);
static uint32_t getSigCtxInc(uint32_t patternSigCtx, uint32_t log2TrSize, uint32_t trSize, uint32_t blkPos, bool bIsLuma, uint32_t firstSignificanceMapContext);
- static uint32_t getSigCoeffGroupCtxInc(uint64_t sigCoeffGroupFlag64, uint32_t cgPosX, uint32_t cgPosY, uint32_t log2TrSizeCG);
protected:
diff -r 67e573d7cb43 -r d2469bcb4e81 source/encoder/entropy.cpp
--- a/source/encoder/entropy.cpp Mon Apr 06 20:17:52 2015 +0800
+++ b/source/encoder/entropy.cpp Mon Apr 06 20:17:57 2015 +0800
@@ -1548,7 +1548,7 @@
else
{
uint32_t sigCoeffGroup = ((sigCoeffGroupFlag64 & cgBlkPosMask) != 0);
- uint32_t ctxSig = Quant::getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, codingParameters.log2TrSizeCG);
+ uint32_t ctxSig = Quant::getSigCoeffGroupCtxInc(sigCoeffGroupFlag64, cgPosX, cgPosY, cgBlkPos, (trSize >> MLS_CG_LOG2_SIZE));
encodeBin(sigCoeffGroup, baseCoeffGroupCtx[ctxSig]);
}
@@ -1556,7 +1556,7 @@
if (sigCoeffGroupFlag64 & cgBlkPosMask)
{
X265_CHECK((log2TrSize != 2) || (log2TrSize == 2 && subSet == 0), "log2TrSize and subSet mistake!\n");
- const int patternSigCtx = Quant::calcPatternSigCtx(sigCoeffGroupFlag64, cgPosX, cgPosY, codingParameters.log2TrSizeCG);
+ const int patternSigCtx = Quant::calcPatternSigCtx(sigCoeffGroupFlag64, cgPosX, cgPosY, cgBlkPos, (trSize >> MLS_CG_LOG2_SIZE));
static const uint8_t ctxIndMap4x4[16] =
{
More information about the x265-devel
mailing list