Skip to content

Instantly share code, notes, and snippets.

@Megawats777
Created April 15, 2020 20:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Megawats777/6113156894fc60df0379de74136339b1 to your computer and use it in GitHub Desktop.
Save Megawats777/6113156894fc60df0379de74136339b1 to your computer and use it in GitHub Desktop.
WelsResidualBlockCavlc function
int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCache, PBitStringAux pBs, int32_t iIndex,
int32_t iMaxNumCoeff,
const uint8_t* kpZigzagTable, int32_t iResidualProperty, int16_t* pTCoeff, uint8_t uiQp,
PWelsDecoderContext pCtx) {
int32_t iLevel[16], iZerosLeft, iCoeffNum;
int32_t iRun[16];
int32_t iCurNonZeroCacheIdx, i;
int32_t iMbResProperty = 0;
GetMbResProperty (&iMbResProperty, &iResidualProperty, 1);
const uint16_t* kpDequantCoeff = pCtx->bUseScalingList ? pCtx->pDequant_coeff4x4[iMbResProperty][uiQp] :
g_kuiDequantCoeff[uiQp];
int8_t nA, nB, nC;
uint8_t uiTotalCoeff, uiTrailingOnes;
int32_t iUsedBits = 0;
intX_t iCurIdx = pBs->iIndex;
uint8_t* pBuf = ((uint8_t*)pBs->pStartBuf) + (iCurIdx >> 3);
bool bChromaDc = (CHROMA_DC == iResidualProperty);
uint8_t bChroma = (bChromaDc || CHROMA_AC == iResidualProperty);
SReadBitsCache sReadBitsCache;
uint32_t uiCache32Bit = (uint32_t) ((((pBuf[0] << 8) | pBuf[1]) << 16) | (pBuf[2] << 8) | pBuf[3]);
sReadBitsCache.uiCache32Bit = uiCache32Bit << (iCurIdx & 0x07);
sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07);
sReadBitsCache.pBuf = pBuf;
//////////////////////////////////////////////////////////////////////////
if (bChroma) {
iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
} else { //luma
iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
}
WELS_NON_ZERO_COUNT_AVERAGE (nC, nA, nB);
iUsedBits += CavlcGetTrailingOnesAndTotalCoeff (uiTotalCoeff, uiTrailingOnes, &sReadBitsCache, pVlcTable, bChromaDc,
nC);
if (iResidualProperty != CHROMA_DC && iResidualProperty != I16_LUMA_DC) {
pNonZeroCountCache[iCurNonZeroCacheIdx] = uiTotalCoeff;
//////////////////////////////////////////////////////////////////////////
}
if (0 == uiTotalCoeff) {
pBs->iIndex += iUsedBits;
return ERR_NONE;
}
if ((uiTrailingOnes > 3) || (uiTotalCoeff > 16)) { /////////////////check uiTrailingOnes and uiTotalCoeff
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES);
}
if ((i = CavlcGetLevelVal (iLevel, &sReadBitsCache, uiTotalCoeff, uiTrailingOnes)) == -1) {
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_LEVEL);
}
iUsedBits += i;
if (uiTotalCoeff < iMaxNumCoeff) {
iUsedBits += CavlcGetTotalZeros (iZerosLeft, &sReadBitsCache, uiTotalCoeff, pVlcTable, bChromaDc);
} else {
iZerosLeft = 0;
}
if ((iZerosLeft < 0) || ((iZerosLeft + uiTotalCoeff) > iMaxNumCoeff)) {
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_ZERO_LEFT);
}
if ((i = CavlcGetRunBefore (iRun, &sReadBitsCache, uiTotalCoeff, pVlcTable, iZerosLeft)) == -1) {
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_RUN_BEFORE);
}
iUsedBits += i;
pBs->iIndex += iUsedBits;
iCoeffNum = -1;
if (iResidualProperty == CHROMA_DC) {
//chroma dc scaling process, is kpDequantCoeff[0]? LevelScale(qPdc%6,0,0))<<(qPdc/6-6), the transform is done at construction.
for (i = uiTotalCoeff - 1; i >= 0; --i) {
//FIXME merge into rundecode?
int32_t j;
iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
j = kpZigzagTable[ iCoeffNum ];
pTCoeff[j] = iLevel[i];
}
WelsChromaDcIdct (pTCoeff);
//scaling
if (!pCtx->bUseScalingList) {
for (int j = 0; j < 4; ++j) {
pTCoeff[kpZigzagTable[j]] = (pTCoeff[kpZigzagTable[j]] * kpDequantCoeff[0]) >> 1;
}
} else {
for (int j = 0; j < 4; ++j) {
pTCoeff[kpZigzagTable[j]] = ((int64_t) pTCoeff[kpZigzagTable[j]] * (int64_t) kpDequantCoeff[0]) >> 5;
}
}
} else if (iResidualProperty == I16_LUMA_DC) { //DC coefficent, only call in Intra_16x16, base_mode_flag = 0
for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
int32_t j;
iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
j = kpZigzagTable[ iCoeffNum ];
pTCoeff[j] = iLevel[i];
}
WelsLumaDcDequantIdct (pTCoeff, uiQp, pCtx);
} else {
for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
int32_t j;
iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
j = kpZigzagTable[ iCoeffNum ];
if (!pCtx->bUseScalingList) {
pTCoeff[j] = (iLevel[i] * kpDequantCoeff[j & 0x07]);
} else {
pTCoeff[j] = (iLevel[i] * kpDequantCoeff[j] + 8) >> 4;
}
}
}
return ERR_NONE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment