📄 blkenc.cpp
字号:
iSumErr += abs (rgiCoefQ [i]) - abs (iDiff);
else
return -100000; //arbitrary negative number to turn off ac pred.
}
}
}
}
return iSumErr;
}
Void CVideoObjectEncoder::intraPred (Int blkn, const CMBMode* pmbmd,
Int* rgiCoefQ, Int iQPcurr, Int iDcScaler,
const BlockMemory blkmPred, Int iQPpred)
{
Int iDefVal; // NBIT: start to calculate default value
UInt nBits = m_volmd.nBits;
Int iMaxDC = (1<<nBits) - 1;
Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127
iDefVal = 1<<(nBits + 2);
//do DC prediction
if (blkmPred == NULL)
/* NBIT: change 1024 to iDefVal
rgiCoefQ [0] -= (1024 + (iDcScaler >> 1)) / iDcScaler;
*/
rgiCoefQ [0] -= divroundnearest(iDefVal, iDcScaler);
else {
rgiCoefQ [0] -= divroundnearest(blkmPred [0], iDcScaler);
/* NBIT: change 255 to iMaxVal
assert (rgiCoefQ [0] >= -255 && rgiCoefQ [0] <= 255);
*/
assert (rgiCoefQ [0] >= -iMaxDC && rgiCoefQ [0] <= iMaxDC);
if ((blkn < A_BLOCK1 && pmbmd->m_bACPrediction)
|| (blkn >=A_BLOCK1 && pmbmd->m_pbACPredictionAlpha[(blkn-7)/4]))
{
Int i, j;
//do AC prediction
if (pmbmd->m_preddir [blkn - 1] == HORIZONTAL) {
for (i = 8, j = 8; j < 2 * BLOCK_SIZE - 1; i += 8, j++) {
rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ?
blkmPred [j] : divroundnearest(blkmPred [j] * iQPpred, iQPcurr);
assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i] <= iMaxAC);
}
}
else if (pmbmd->m_preddir [blkn - 1] == VERTICAL) {
//horizontal zigzag scan
for (i = 1; i < BLOCK_SIZE; i++) {
rgiCoefQ [i] -= (blkmPred == NULL) ? 0 : (iQPcurr == iQPpred) ?
blkmPred [i] : divroundnearest(blkmPred [i] * iQPpred, iQPcurr);
assert (rgiCoefQ [i] >= -iMaxAC && rgiCoefQ [i] <= iMaxAC);
}
}
else
assert (FALSE);
}
}
}
// HHI Schueuer: added const PixelC *rgpxlcBlkShape, Int iBlkShapeWidth
Void CVideoObjectEncoder::quantizeTextureInterBlock (PixelI* ppxliCurrQBlock,
Int iWidthCurrQ,
Int* rgiCoefQ,
Int iQP,
Bool bAlphaBlock,
const PixelC *rgpxlcBlkShape,
Int iBlkShapeWidth,
Int iBlk)
{
// m_pentrencSet->m_pentrencDCT->bitstream()->trace (rgiCoefQ, "BLK_TEXTURE");
// HHI Schueuer : rgpxlcBlkShape, iBlkShapeWidth, lx added
Int *lx = new Int [iBlkShapeWidth];
m_pfdct->apply (ppxliCurrQBlock, iWidthCurrQ, m_rgiDCTcoef, BLOCK_SIZE, rgpxlcBlkShape, iBlkShapeWidth, lx);
// end HHI
// RRV insertion
if(m_vopmd.RRVmode.iOnOff == 1)
{
cutoffDCTcoef();
}
// ~RRV
if (m_volmd.fQuantizer == Q_H263) {
quantizeInterDCTcoefH263 (rgiCoefQ, 0, iQP);
// HHI Schueuer
if (rgpxlcBlkShape && !m_volmd.bSadctDisable) {
// assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL);
// brute force method to clean out mispredictions outside the active region
// Int *lx = m_rgiCurrMBCoeffWidth[iBlk];
Int iy, ix;
for (iy = 0; iy < BLOCK_SIZE; iy++) {
for (ix=lx[iy]; ix<BLOCK_SIZE; ix++)
rgiCoefQ[ix + iy * BLOCK_SIZE] = 0;
}
}
// end HHI
inverseQuantizeDCTcoefH263 (rgiCoefQ, 0, iQP);
}
else {
quantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock);
// HHI Schueuer
if (rgpxlcBlkShape && !m_volmd.bSadctDisable) {
// assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL);
// brute force method to clean out mispredictions outside the active region
// Int *lx = m_rgiCurrMBCoeffWidth[iBlk];
Int iy, ix;
for (iy = 0; iy < BLOCK_SIZE; iy++) {
for (ix=lx[iy]; ix<BLOCK_SIZE; ix++)
rgiCoefQ[ix + iy * BLOCK_SIZE] = 0;
}
}
// end HHI
inverseQuantizeInterDCTcoefMPEG (rgiCoefQ, 0, iQP, bAlphaBlock, 0);
}
// m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ);
// HHI Schueuer : added rgpxlcBlkShape, iBlkShapeWidth, lx
m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxliCurrQBlock, iWidthCurrQ, rgpxlcBlkShape, iBlkShapeWidth, lx);
delete lx;
// end HHI
// m_pentrencSet->m_pentrencDCT->bitstream()->trace (ppxliCurrQBlock, "BLK_TEXTURE_Q");
}
UInt CVideoObjectEncoder::sendIntraDC (const Int* rgiCoefQ, Int blkn)
{
UInt nBits = 0;
UInt nBitsPerPixel = m_volmd.nBits; // NBIT
Int iMaxVal = 1<<nBitsPerPixel; // NBIT
assert (rgiCoefQ [0] >= -iMaxVal && rgiCoefQ [0] < iMaxVal);
Int iAbsDiffIntraDC = abs (rgiCoefQ [0]);
Long lSzDiffIntraDC = 0;
for (Int i = nBitsPerPixel; i > 0; i--)
if (iAbsDiffIntraDC & (1 << (i - 1))) {
lSzDiffIntraDC = i;
break;
}
COutBitStream* pobstrmIntraDC;
if (blkn == U_BLOCK || blkn == V_BLOCK) {
nBits = m_pentrencSet->m_pentrencIntraDCc->encodeSymbol(lSzDiffIntraDC, "IntraDClen"); // huffman encode
pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCc -> bitstream ();
}
else {
nBits = m_pentrencSet->m_pentrencIntraDCy->encodeSymbol(lSzDiffIntraDC, "IntraDClen"); // huffman encode
pobstrmIntraDC = m_pentrencSet->m_pentrencIntraDCy -> bitstream ();
}
if (lSzDiffIntraDC<=8) { // NBIT
if (rgiCoefQ [0] > 0)
pobstrmIntraDC->putBits ((Char) rgiCoefQ [0], lSzDiffIntraDC, "IntraDC"); //fix length code
else if (rgiCoefQ [0] < 0)
pobstrmIntraDC->putBits (~iAbsDiffIntraDC, lSzDiffIntraDC, "IntraDC"); //fix length code
nBits += lSzDiffIntraDC;
} else { // NBIT: MARKER bit inserted after first 8 bits
// UInt uiOffset = lSzDiffIntraDC-8;
UInt uiValue = iAbsDiffIntraDC;
if (rgiCoefQ [0] < 0) {
uiValue = ~iAbsDiffIntraDC;
}
/*
uiValue = ( (uiValue>>uiOffset)<<(uiOffset+1) )
+ ( 1<<uiOffset )
+ ( uiValue&((1<<uiOffset)-1) );
pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC+1, "IntraDC");
*/
pobstrmIntraDC->putBits (uiValue, lSzDiffIntraDC, "IntraDC");
pobstrmIntraDC->putBits (1, 1, "Marker");
nBits += lSzDiffIntraDC+1;
}
return nBits;
}
UInt CVideoObjectEncoder::sendTCOEFIntra (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag)
{
Bool bIsFirstRun = TRUE;
Bool bIsLastRun = FALSE;
UInt uiCurrRun = 0;
UInt uiPrevRun = 0;
Int iCurrLevel = 0;
Int iPrevLevel = 0;
UInt uiCoefToStart = 0;
UInt numBits = 0;
for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here
uiCurrRun++; // counting zeros
else {
if (!bIsFirstRun)
numBits += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun);
uiPrevRun = uiCurrRun; // reset for next run
iPrevLevel = rgiCoefQ [rgiZigzag [j]];
uiCurrRun = 0;
bIsFirstRun = FALSE;
}
}
assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1) - 1); // Some AC must be non-zero; at least for inter
bIsLastRun = TRUE;
numBits += putBitsOfTCOEFIntra (uiPrevRun, iPrevLevel, bIsLastRun);
return numBits;
}
UInt CVideoObjectEncoder::sendTCOEFInter (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag)
{
Bool bIsFirstRun = TRUE;
Bool bIsLastRun = FALSE;
UInt uiCurrRun = 0;
UInt uiPrevRun = 0;
Int iCurrLevel = 0;
Int iPrevLevel = 0;
UInt numBits = 0;
for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here
uiCurrRun++; // counting zeros
else {
if (!bIsFirstRun)
numBits += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun);
uiPrevRun = uiCurrRun; // reset for next run
iPrevLevel = rgiCoefQ [rgiZigzag [j]];
uiCurrRun = 0;
bIsFirstRun = FALSE;
}
}
assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1)); // Some AC must be non-zero; at least for inter
bIsLastRun = TRUE;
numBits += putBitsOfTCOEFInter (uiPrevRun, iPrevLevel, bIsLastRun);
return numBits;
}
UInt CVideoObjectEncoder::putBitsOfTCOEFInter (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
UInt nBits = 0;
Long lVLCtableIndex;
if (bIsLastRun == FALSE) {
lVLCtableIndex = findVLCtableIndexOfNonLastEvent (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode
m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
nBits++;
}
else
nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent);
}
else {
lVLCtableIndex = findVLCtableIndexOfLastEvent (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode
m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
nBits++;
}
else
nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter, &CVideoObjectEncoder::findVLCtableIndexOfLastEvent);
}
return nBits;
}
UInt CVideoObjectEncoder::putBitsOfTCOEFIntra (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
//fprintf(stderr,"%d %d %d\n", iLevel,uiRun,bIsLastRun);
Int nBits = 0;
Long lVLCtableIndex;
lVLCtableIndex = findVLCtableIndexOfIntra (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCTIntra->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF"); // huffman encode
m_pentrencSet->m_pentrencDCTIntra->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
nBits++;
}
else
nBits += escapeEncode (uiRun, iLevel, bIsLastRun, g_rgiLMAXintra, g_rgiRMAXintra, &CVideoObjectEncoder::findVLCtableIndexOfIntra);
return nBits;
}
UInt CVideoObjectEncoder::escapeEncode (UInt uiRun, Int iLevel, Bool bIsLastRun, Int* rgiLMAX, Int* rgiRMAX,
FIND_TABLE_INDEX findVLCtableIndex)
{
UInt nBits = 0;
nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(TCOEF_ESCAPE, "Esc_TCOEF");
Int iLevelAbs = abs (iLevel);
Int iLevelPlus = iLevelAbs - rgiLMAX [(uiRun & 0x0000003F) + (bIsLastRun << 6)]; //hashing the table
Int iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, uiRun, abs (iLevelPlus));
if (iVLCtableIndex != NOT_IN_TABLE) {
m_pbitstrmOut->putBits (0, 1, "Esc_0");
nBits++;
nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_1_Vlc_TCOEF"); // huffman encode
m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
nBits++;
}
else {
Int iRunPlus = uiRun - rgiRMAX [(iLevelAbs & 0x0000001F) + (bIsLastRun << 5)]; //RMAX table includes + 1 already
iVLCtableIndex = (this->*findVLCtableIndex) (bIsLastRun, (UInt) iRunPlus, iLevelAbs);
if (iVLCtableIndex != NOT_IN_TABLE) {
m_pbitstrmOut->putBits (2, 2, "Esc_10");
nBits += 2;
nBits += m_pentrencSet->m_pentrencDCT->encodeSymbol(iVLCtableIndex, "Esc_01_Vlc_TCOEF"); // huffman encode
m_pbitstrmOut->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF");
nBits++;
}
else {
m_pbitstrmOut->putBits (3, 2, "Esc_11");
nBits += 2;
nBits += fixLengthCode (uiRun, iLevel, bIsLastRun);
}
}
return nBits;
}
UInt CVideoObjectEncoder::fixLengthCode (UInt uiRun, Int iLevel, Bool bIsLastRun)
{
UInt nBits = 0;
m_pentrencSet->m_pentrencDCT->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Run_TCOEF");
nBits++;
assert (uiRun < BLOCK_SQUARE_SIZE);
m_pentrencSet->m_pentrencDCT->bitstream()->putBits (uiRun, NUMBITS_ESC_RUN, "Run_Esc_TCOEF");
nBits+=NUMBITS_ESC_RUN;
Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT
assert (iLevel >= -iMaxAC && iLevel <= iMaxAC && iLevel != 0);
if (iLevel < 0)
iLevel = (1<<iLevelBits) - abs(iLevel);
m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker");
m_pentrencSet->m_pentrencDCT->bitstream()->putBits (iLevel, iLevelBits, "Level_Esc_TCOEF");
m_pentrencSet->m_pentrencDCT->bitstream()->putBits (1, 1, "Marker");
nBits += iLevelBits + 2;
return nBits;
}
Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert (uiRun >= 0);
if (uiRun > 26 || (uiLevel > grgIfNotLastNumOfLevelAtRun [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfNotLastNumOfLevelAtRun [i];
uiTableIndex += uiLevel;
uiTableIndex--; // make it zero-based; see Table H13/H.263
return uiTableIndex;
}
}
Int CVideoObjectEncoder::findVLCtableIndexOfLastEvent (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert (uiRun >= 0);
if (uiRun > 40 || (uiLevel > grgIfLastNumOfLevelAtRun [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfLastNumOfLevelAtRun [i];
uiTableIndex += uiLevel;
uiTableIndex += 57; // make it zero-based and
return uiTableIndex; //correction of offset; see Table H13/H.263
}
}
Int CVideoObjectEncoder::findVLCtableIndexOfIntra (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
UInt i;
assert (uiRun >= 0);
if (uiRun > 20 || uiLevel > 27)
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (i = 0; i < TCOEF_ESCAPE; i++) {
UInt iHashing = (bIsLastRun << 10) | (uiRun << 5) | uiLevel;
if (iHashing == grgiIntraYAVCLHashingTable [i])
return i;
}
return NOT_IN_TABLE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -