[x265] [PATCH] entropy: modified last coefficient position encoding in codeCoeffNxN()
ashok at multicorewareinc.com
ashok at multicorewareinc.com
Tue Jan 6 12:45:45 CET 2015
# HG changeset patch
# User Ashok Kumar Mishra<ashok at multicorewareinc.com>
# Date 1420538998 -19800
# Tue Jan 06 15:39:58 2015 +0530
# Node ID e8bf703fa06148c38f6a9c976563d7c90825d9bd
# Parent f255e8d06423231cb8c58ab5d3b10de7fb27b424
entropy: modified last coefficient position encoding in codeCoeffNxN()
diff -r f255e8d06423 -r e8bf703fa061 source/common/constants.cpp
--- a/source/common/constants.cpp Fri Jan 02 18:22:38 2015 +0530
+++ b/source/common/constants.cpp Tue Jan 06 15:39:58 2015 +0530
@@ -412,7 +412,16 @@
{ g_scan4x4[2], g_scan2x2[0], g_scan4x4[0], g_scan8x8diag }
};
-const uint8_t g_minInGroup[10] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24 };
+// Table used for encoding the last coefficient position. The index is the position.
+// The low 4 bits are the number of "1" in the prefix and the high 4 bits are the number
+// of bits in the suffix.
+const uint8_t lastCoeffTable[32] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x14, 0x14, 0x15, 0x15,
+ 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
+};
// Rice parameters for absolute transform levels
const uint8_t g_goRiceRange[5] = { 7, 14, 26, 46, 78 };
diff -r f255e8d06423 -r e8bf703fa061 source/common/constants.h
--- a/source/common/constants.h Fri Jan 02 18:22:38 2015 +0530
+++ b/source/common/constants.h Tue Jan 06 15:39:58 2015 +0530
@@ -83,7 +83,7 @@
extern const uint16_t g_scan8x8diag[8 * 8];
extern const uint16_t g_scan4x4[NUM_SCAN_TYPE][4 * 4];
-extern const uint8_t g_minInGroup[10];
+extern const uint8_t lastCoeffTable[32];
extern const uint8_t g_goRiceRange[5]; // maximum value coded with Rice codes
// CABAC tables
diff -r f255e8d06423 -r e8bf703fa061 source/encoder/entropy.cpp
--- a/source/encoder/entropy.cpp Fri Jan 02 18:22:38 2015 +0530
+++ b/source/encoder/entropy.cpp Tue Jan 06 15:39:58 2015 +0530
@@ -1407,58 +1407,6 @@
encodeBin(cu.getCbf(absPartIdx, ttype, lowestTUDepth), m_contextState[OFF_QT_CBF_CTX + ctx]);
}
-/** Encode (X,Y) position of the last significant coefficient
- * \param posx X component of last coefficient
- * \param posy Y component of last coefficient
- * \param log2TrSize
- * \param bIsLuma
- * \param scanIdx scan type (zig-zag, hor, ver)
- * This method encodes the X and Y component within a block of the last significant coefficient.
- */
-void Entropy::codeLastSignificantXY(uint32_t posx, uint32_t posy, uint32_t log2TrSize, bool bIsLuma, uint32_t scanIdx)
-{
- // swap
- if (scanIdx == SCAN_VER)
- std::swap(posx, posy);
-
- uint32_t ctxLast;
- uint32_t groupIdxX = getGroupIdx(posx);
- uint32_t groupIdxY = getGroupIdx(posy);
-
- int blkSizeOffset = bIsLuma ? ((log2TrSize - 2) * 3 + ((log2TrSize - 1) >> 2)) : NUM_CTX_LAST_FLAG_XY_LUMA;
- int ctxShift = bIsLuma ? ((log2TrSize + 1) >> 2) : log2TrSize - 2;
- uint32_t maxGroupIdx = log2TrSize * 2 - 1;
-
- // posX
- uint8_t *ctxX = &m_contextState[OFF_CTX_LAST_FLAG_X];
- for (ctxLast = 0; ctxLast < groupIdxX; ctxLast++)
- encodeBin(1, *(ctxX + blkSizeOffset + (ctxLast >> ctxShift)));
-
- if (groupIdxX < maxGroupIdx)
- encodeBin(0, *(ctxX + blkSizeOffset + (ctxLast >> ctxShift)));
-
- // posY
- uint8_t *ctxY = &m_contextState[OFF_CTX_LAST_FLAG_Y];
- for (ctxLast = 0; ctxLast < groupIdxY; ctxLast++)
- encodeBin(1, *(ctxY + blkSizeOffset + (ctxLast >> ctxShift)));
-
- if (groupIdxY < maxGroupIdx)
- encodeBin(0, *(ctxY + blkSizeOffset + (ctxLast >> ctxShift)));
-
- if (groupIdxX > 3)
- {
- uint32_t count = (groupIdxX - 2) >> 1;
- posx = posx - g_minInGroup[groupIdxX];
- encodeBinsEP(posx, count);
- }
- if (groupIdxY > 3)
- {
- uint32_t count = (groupIdxY - 2) >> 1;
- posy = posy - g_minInGroup[groupIdxY];
- encodeBinsEP(posy, count);
- }
-}
-
void Entropy::codeCoeffNxN(const CUData& cu, const coeff_t* coeff, uint32_t absPartIdx, uint32_t log2TrSize, TextType ttype)
{
uint32_t trSize = 1 << log2TrSize;
@@ -1506,11 +1454,42 @@
scanPosLast--;
// Code position of last coefficient
- int posLastY = posLast >> log2TrSize;
- int posLastX = posLast & (trSize - 1);
- codeLastSignificantXY(posLastX, posLastY, log2TrSize, bIsLuma, codingParameters.scanType);
+ {
+ // The last position is composed of a prefix and suffix.
+ // The prefix is context coded truncated unary bins. The suffix is bypass coded fixed length bins.
+ // The bypass coded bins for both the x and y components are grouped together.
+ int packedSuffixBits = 0, packedSuffixLen = 0;
+ int pos[2] = { (posLast & (trSize - 1)), (posLast >> log2TrSize) };
+ // swap
+ if (codingParameters.scanType == SCAN_VER)
+ std::swap(pos[0], pos[1]);
- //===== code significance flag =====
+ int ctxIdx = bIsLuma ? (3 * (log2TrSize - 2) + ((log2TrSize - 1) >> 2)) : NUM_CTX_LAST_FLAG_XY_LUMA;
+ int ctxShift = bIsLuma ? ((log2TrSize + 1) >> 2) : log2TrSize - 2;
+ uint32_t maxGroupIdx = (log2TrSize << 1) - 1;
+
+ uint8_t *ctx = &m_contextState[OFF_CTX_LAST_FLAG_X];
+ for (uint32_t i = 0; i < 2; i++, ctxIdx += NUM_CTX_LAST_FLAG_XY)
+ {
+ uint32_t temp = lastCoeffTable[pos[i]];
+ uint32_t prefixOnes = temp & 15;
+ uint32_t suffixLen = temp >> 4;
+
+ for (uint32_t ctxLast = 0; ctxLast < prefixOnes; ctxLast++)
+ encodeBin(1, *(ctx + ctxIdx + (ctxLast >> ctxShift)));
+
+ if (prefixOnes < maxGroupIdx)
+ encodeBin(0, *(ctx + ctxIdx + (prefixOnes >> ctxShift)));
+
+ packedSuffixBits <<= suffixLen;
+ packedSuffixBits |= (pos[i] & ((1 << suffixLen) - 1));
+ packedSuffixLen += suffixLen;
+ }
+
+ encodeBinsEP(packedSuffixBits, packedSuffixLen);
+ }
+
+ // code significance flag
uint8_t * const baseCoeffGroupCtx = &m_contextState[OFF_SIG_CG_FLAG_CTX + (bIsLuma ? 0 : NUM_SIG_CG_FLAG_CTX)];
uint8_t * const baseCtx = bIsLuma ? &m_contextState[OFF_SIG_FLAG_CTX] : &m_contextState[OFF_SIG_FLAG_CTX + NUM_SIG_FLAG_CTX_LUMA];
const int lastScanSet = scanPosLast >> MLS_CG_SIZE;
More information about the x265-devel
mailing list