📄 vlc.c
字号:
code = cbpCode[cbp][1]; return vlcuSendUVLC(bitbuf, code);}/* * vlcGetNumCoefsPredLuma: * * Parameters: * mb Macroblock object * blkX Horizontal block index within MB * blkY Vertical block index within MB * * Function: * Get predictor for encoding number of coefficients in a luma block. * In getting the neighboring block information, pre-configured pointers * blkLeft and blkUp are used. In processing luma information, the * buffer "current" is used. * * Returns: * Predictor. */static int vlcGetNumCoefsPredLuma(macroblock_s *mb, int blkX, int blkY){ int leftAvail, numCoefPred; leftAvail = 0; numCoefPred = 0; if ((blkX > 0) || mb->mbAvailMap[0]) { numCoefPred += mb->blkLeft[blkY * 4 + blkX]->numLumaCoefs; leftAvail = 1; } if ((blkY > 0) || mb->mbAvailMap[1]) { numCoefPred += mb->blkUp[blkY * 4 + blkX]->numLumaCoefs; if (leftAvail) numCoefPred = (numCoefPred + 1) >> 1; } return numCoefPred;}/* * vlcGetNumCoefsPredChroma: * * Parameters: * mb Macroblock object * comp 0, Cb, 1, Cr * blkX Horizontal block index within MB * blkY Vertical block index within MB * * Function: * Get predictor for encoding number of coefficients in a chroma block. * * Returns: * Predictor. */static int vlcGetNumCoefsPredChroma(macroblock_s *mb, int comp, int blkX, int blkY){ int leftAvail, numCoefPred; leftAvail = 0; numCoefPred = 0; if ((blkX > 0) || mb->mbAvailMap[0]) { if (blkX > 0) numCoefPred += mb->mbThis->numChromaCoefs[comp][blkY][blkX - 1]; else numCoefPred += mb->mbLeft->numChromaCoefs[comp][blkY][1]; leftAvail = 1; } if ((blkY > 0) || mb->mbAvailMap[1]) { if (blkY > 0) numCoefPred += mb->mbThis->numChromaCoefs[comp][blkY - 1][blkX]; else numCoefPred += mb->mbUp->numChromaCoefs[comp][1][blkX]; if (leftAvail) numCoefPred = (numCoefPred + 1) >> 1; } return numCoefPred;}/* * vlcCollectCoefBlkStat * * Parameters: * coef Coefficient buffer * lastCoefIdx Index of the last coeff in block, either 15 or 3 * dcSkip Whether the first coefficient should be skipped * blkStat Block statistics * * Function: * Encode a block based on statistics collected in streamCollectCoefBlkStat. * * Returns: * Number of bits generated. */void vlcCollectCoefBlkStat(int *coef, int lastCoefIdx, int dcSkip, vlcCoefBlkStat_s *blkStat){ int i, prev, run; /* Trailing zeros are counted outside */ /* * Find trailing ones and runs */ blkStat->numTrailingOnes = 0; blkStat->signs = 0; i = lastCoefIdx - blkStat->numTrailingZeros; // first non-zero coefficient while (i >= dcSkip && blkStat->numTrailingOnes < 3 && abs(coef[i]) == 1) { blkStat->signs <<= 1; if (coef[i] < 0) blkStat->signs |= 1; i --; prev = i; while (i >= dcSkip && coef[i] == 0) i--; run = prev - i; blkStat->runs[blkStat->numTrailingOnes] = (int8) run; blkStat->numTrailingOnes++; } blkStat->totalCoef = blkStat->numTrailingOnes; /* * Find levels and runs */ while (i >= dcSkip) { blkStat->levels[blkStat->totalCoef] = coef[i]; i--; prev = i; while (i >= dcSkip && coef[i] == 0) i--; run = prev - i; blkStat->runs[blkStat->totalCoef] = (int8) run; blkStat->totalCoef ++; } // total number of zeros excluding the trailing zeros blkStat->totalZeros = (int8) (lastCoefIdx + 1 - dcSkip - blkStat->numTrailingZeros - blkStat->totalCoef);}/* * vlcSendCoeffToken * * Parameters: * bitbuf Bitbuffer * numCoefsPred Number of coefficients predictor * numTrailingOnes Number of trailing ones in the 4x4 block * totalCoef Number of non-zero coefficients * * Function: * Encode a coefficient token which consists of number of trailing ones * and total number of coefficients, under the context of numCoefsPred. * numCoefsPred is calculated from the numbers of non-zero coeffcients * of the neighboring blocks. * * Returns: * Number of bits generated. */int vlcSendCoeffToken(bitbuffer_s *bitbuf, macroblock_s *mb, int comp, int blkX, int blkY, int numTrailingOnes, int totalCoef){ int code, len, numCoefsPred; if (comp == COMP_LUMA) numCoefsPred = vlcGetNumCoefsPredLuma(mb, blkX, blkY); else numCoefsPred = vlcGetNumCoefsPredChroma(mb, comp - 1, blkX, blkY); /* Select variable length code or fixed length coding */ if (numCoefsPred < 8) { int tabNum; /* Select table number based on the prediction */ tabNum = vlcNumTab[numCoefsPred]; code = numCoefsTrailTab[tabNum][numTrailingOnes][totalCoef]; len = numCoefsTrailLenTab[tabNum][numTrailingOnes][totalCoef]; } else { code = 3; if (totalCoef != 0) code = ((totalCoef - 1) << 2) | numTrailingOnes; len = 6; } return bibPutBits(bitbuf, code, len);}/* * vlcEncodeCoefBlk * * Parameters: * bitbuf Bitbuffer * blkStat Block statistics * blockSize Size of the block, either 16 or 4 * dcSkip Whether the first coefficient should be skipped * blkType 0, 4x4 block, 1, chroma DC 2x2 block. * * Function: * Encode a block based on statistics collected in vlcCollectCoefBlkStat. * * Returns: * Number of bits generated. */int vlcEncodeCoefBlk(bitbuffer_s *bitbuf, vlcCoefBlkStat_s *blkStat, int blockSize, int dcSkip, int blkType){ int i; int len; int level, run; int levelTabNum; int zerosLeft; int coefNum; const vlcCode_s *pVlc; const vlcCode_s *pNumZerosVlc; if (blkType == 0) pNumZerosVlc = & totZerosTab[blkStat->totalCoef - 1][blkStat->totalZeros]; else pNumZerosVlc = & totZerosTabChroma[blkStat->totalCoef - 1][blkStat->totalZeros]; levelTabNum = (blkStat->totalCoef > 10 && blkStat->numTrailingOnes < 3) ? 1 : 0; // Send signs for trailing ones len = 0; if (blkStat->numTrailingOnes != 0) len += bibPutBits(bitbuf, blkStat->signs, blkStat->numTrailingOnes); // Send the large coefficients if (blkStat->totalCoef > blkStat->numTrailingOnes) { // Encode first level level = blkStat->levels[blkStat->numTrailingOnes]; if (blkStat->numTrailingOnes < 3) level += (level > 0) ? -1 : 1; if (levelTabNum == 0) len += vlcuSendCoefLevelVLC0(bitbuf, level); else len += vlcuSendCoefLevelVLCN(bitbuf, levelTabNum, level); // update VLC table if (abs(blkStat->levels[blkStat->numTrailingOnes]) > incVlc[levelTabNum]) levelTabNum ++; if (abs(blkStat->levels[blkStat->numTrailingOnes]) > 3) levelTabNum = 2; // Encode rest of the levels for (i = blkStat->numTrailingOnes + 1; i < blkStat->totalCoef; i++) { level = blkStat->levels[i]; if (levelTabNum == 0) len += vlcuSendCoefLevelVLC0(bitbuf, level); else len += vlcuSendCoefLevelVLCN(bitbuf, levelTabNum, level); // update VLC table if (abs(level) > incVlc[levelTabNum]) levelTabNum++; } } // Send the number of zero coefficients if (blkStat->totalCoef < blockSize - dcSkip) len += bibPutBits(bitbuf, pNumZerosVlc->code, pNumZerosVlc->len); // Send runs zerosLeft = blkStat->totalZeros; coefNum = 0; while (coefNum < blkStat->totalCoef - 1 && zerosLeft > 0) { run = blkStat->runs[coefNum]; // select VLC for runbefore if (zerosLeft <= 7) pVlc = & runTab[zerosLeft-1][run]; else pVlc = & runTabLong[run]; len += bibPutBits(bitbuf, pVlc->code, pVlc->len); zerosLeft -= run; coefNum++; } return len;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -