📄 blkdec.cpp
字号:
}
else
{ // MPEG-4
decodeIntraVLCtableIndex (lIndex, iLevel, iRun, bIsLastRun);
}
}
else {
decodeEscape (iLevel, iRun, bIsLastRun, g_rgiLMAXintra, g_rgiRMAXintra,
m_pentrdecSet->m_pentrdecDCTIntra, CVideoObjectDecoder::decodeIntraVLCtableIndex);
}
//fprintf(stderr,"%d %d %d %d\n", lIndex,iLevel,iRun,bIsLastRun);
for (Int i = 0; i < iRun; i++) {
rgiCoefQ [rgiZigzag [iCoef]] = 0;
iCoef++;
}
rgiCoefQ [rgiZigzag [iCoef]] = iLevel;
iCoef++;
}
for (Int i = iCoef; i < BLOCK_SQUARE_SIZE; i++) // fill the rest w/ zero
rgiCoefQ [rgiZigzag [i]] = 0;
}
Void CVideoObjectDecoder::decodeEscape (Int& iLevel, Int& iRun, Int& bIsLastRun, const Int* rgiLMAX, const Int* rgiRMAX,
CEntropyDecoder* pentrdec, DECODE_TABLE_INDEX decodeVLCtableIndex)
{
// Modified by Toshiba(1997-11-14)
if (!short_video_header) { // Added bij KPN [FDS]
if (m_pbitstrmIn->getBits (1) == 0) { //vlc; Level+
//if (m_pbitstrmIn->getBits (1) == 1) { //vlc; Level+
// End Toshiba(1997-11-14)
Int iIndex = pentrdec->decodeSymbol();
(this->*decodeVLCtableIndex) (iIndex, iLevel, iRun, bIsLastRun);
//get level back
Int iLevelPlusAbs = abs (iLevel);
Int iLevelAbs = iLevelPlusAbs + rgiLMAX [(iRun & 0x0000003F) + (bIsLastRun << 6)]; //hashing the table
iLevel = sign(iLevel) * iLevelAbs;
}
// Modified Toshiba(1997-11-14)
else if (m_pbitstrmIn->getBits (1) == 0) { //vlc; Run+
//else if (m_pbitstrmIn->getBits (1) == 1) { //vlc; Run+
// End Toshiba(1997-11-14)
Int iIndex = pentrdec->decodeSymbol();
(this->*decodeVLCtableIndex) (iIndex, iLevel, iRun, bIsLastRun);
iRun = iRun + rgiRMAX [(abs(iLevel) & 0x0000001F) + (bIsLastRun << 5)]; //get run back; RMAX tabl incl. + 1 already
}
else { //flc
bIsLastRun = (Bool) m_pbitstrmIn->getBits (1);
iRun = (Int) m_pbitstrmIn->getBits (NUMBITS_ESC_RUN);
assert (iRun < BLOCK_SQUARE_SIZE);\
Int iLevelBits = 12; // = m_volmd.nBits;
Int iMarker = m_pbitstrmIn->getBits (1);
assert(iMarker == 1);
iLevel = (Int) m_pbitstrmIn->getBits (iLevelBits);
iMarker = m_pbitstrmIn->getBits (1);
assert(iMarker == 1);
Int iMaxAC = (1<<(iLevelBits-1)) - 1;
assert(iLevel!=iMaxAC+1);
if (iLevel > iMaxAC)
iLevel -= (1<<iLevelBits);
assert(iLevel != 0);
}
} // Escape coding short headers. Added by KPN
else
{
bIsLastRun = (Bool) m_pbitstrmIn->getBits (1);
iRun = (Int) m_pbitstrmIn->getBits (6);
int iLevelIndex = (Int) m_pbitstrmIn->getBits(8);
if (iLevelIndex==0||iLevelIndex==128)
{
fprintf(stderr,"Short header mode. Levels 0 and 128 are not allowed\n");
exit(2);
}
if (iLevelIndex >=0 && iLevelIndex <128)
{
iLevel=iLevelIndex;
} else
{
iLevel=iLevelIndex-256;
}
}
}
Void CVideoObjectDecoder::decodeInterTCOEF (Int* rgiCoefQ, Int iCoefStart, Int* rgiZigzag)
{
Bool bIsLastRun = FALSE;
Int iRun = 0;
Int iLevel = 0;
Int iCoef = iCoefStart;
Long lIndex;
while (!bIsLastRun) {
lIndex = m_pentrdecSet->m_pentrdecDCT->decodeSymbol();
if (lIndex != TCOEF_ESCAPE) { // if Huffman
decodeInterVLCtableIndex (lIndex, iLevel, iRun, bIsLastRun);
assert (iRun < BLOCK_SQUARE_SIZE);
}
else
decodeEscape (iLevel, iRun, bIsLastRun, g_rgiLMAXinter, g_rgiRMAXinter,
m_pentrdecSet->m_pentrdecDCT, CVideoObjectDecoder::decodeInterVLCtableIndex);
for (Int i = 0; i < iRun; i++) {
rgiCoefQ [rgiZigzag [iCoef]] = 0;
iCoef++;
}
rgiCoefQ [rgiZigzag [iCoef]] = iLevel;
iCoef++;
}
for (Int i = iCoef; i < BLOCK_SQUARE_SIZE; i++) // fill the rest w/ zero
rgiCoefQ [rgiZigzag [i]] = 0;
}
Void CVideoObjectDecoder::decodeIntraVLCtableIndex (Int iIndex, Int& iLevel, Int& iRun, Int& bIsLastRun)
{
static Int iLevelMask = 0x0000001F;
static Int iRunMask = 0x000003E0;
static Int iLastRunMask = 0x00000400;
iLevel = iLevelMask & grgiIntraYAVCLHashingTable [iIndex];
iRun = (iRunMask & grgiIntraYAVCLHashingTable [iIndex]) >> 5;
bIsLastRun = (iLastRunMask & grgiIntraYAVCLHashingTable [iIndex]) >> 10;
if (m_pentrdecSet->m_pentrdecDCT->bitstream()->getBits (1) == TRUE) // get signbit
iLevel = -iLevel;
assert (iRun < BLOCK_SQUARE_SIZE);
}
Void CVideoObjectDecoder::decodeInterVLCtableIndex (Int iIndex, Int& iLevel, // return islastrun, run and level
Int& iRun, Bool& bIsLastRun)
{
assert (iIndex >= 0 && iIndex < 102);
bIsLastRun = FALSE;
Int iIndexLeft = (Int) iIndex;
if (iIndex >= 58) {
iIndexLeft -= 58;
bIsLastRun = TRUE;
}
iRun = 0;
while (iIndexLeft >= 0) {
if (!bIsLastRun)
iIndexLeft -= grgIfNotLastNumOfLevelAtRun [iRun];
else
iIndexLeft -= grgIfLastNumOfLevelAtRun [iRun];
iRun++;
}
assert (iRun > 0);
iRun--;
if (!bIsLastRun)
iLevel = iIndexLeft + grgIfNotLastNumOfLevelAtRun [iRun] + 1;
else
iLevel = iIndexLeft + grgIfLastNumOfLevelAtRun [iRun] + 1;
assert (iRun >= 0);
if (m_pentrdecSet->m_pentrdecDCT->bitstream()->getBits (1) == TRUE) // get signbit
iLevel = -iLevel;
}
Int CVideoObjectDecoder::decodeIntraDCmpeg (Bool bIsYBlk)
{
Long lSzDiffIntraDC;
if (bIsYBlk)
lSzDiffIntraDC = m_pentrdecSet->m_pentrdecIntraDCy->decodeSymbol();
else
lSzDiffIntraDC = m_pentrdecSet->m_pentrdecIntraDCc->decodeSymbol();
Int iDiffIntraDC = 0;
if (lSzDiffIntraDC !=0 ) {
if (lSzDiffIntraDC<=8) { // NBIT
U8 chDiffIntraDC =
(U8) m_pentrdecSet->m_pentrdecIntraDCy->bitstream()->getBits (lSzDiffIntraDC);
if (!((1 << (lSzDiffIntraDC - 1)) & chDiffIntraDC))
iDiffIntraDC = -1 * ((0x00FF >> (8 - lSzDiffIntraDC)) & (~chDiffIntraDC));
else
iDiffIntraDC = (Int) chDiffIntraDC;
} else { // NBIT - marker bit inserted after 8 bits
/*
UInt uiDiffIntraDC =
(UInt) m_pentrdecSet->m_pentrdecIntraDCy->bitstream()->getBits (lSzDiffIntraDC+1);
Int iOffset = lSzDiffIntraDC-8;
uiDiffIntraDC = ( uiDiffIntraDC>>(iOffset+1)<<iOffset )
+ ( uiDiffIntraDC & ((1<<iOffset)-1) );
*/
UInt uiDiffIntraDC =
(UInt) m_pentrdecSet->m_pentrdecIntraDCy->bitstream()->getBits (lSzDiffIntraDC);
if (!((1 << (lSzDiffIntraDC - 1)) & uiDiffIntraDC))
iDiffIntraDC = -1 * ((0xFFFF >> (16 - lSzDiffIntraDC)) & (~uiDiffIntraDC));
else
iDiffIntraDC = (Int) uiDiffIntraDC;
m_pentrdecSet->m_pentrdecIntraDCy->bitstream()->getBits (1);
}
}
return iDiffIntraDC;
}
Void CVideoObjectDecoder::inverseDCACPred (const CMBMode* pmbmd, Int iBlkIdx,
Int* rgiCoefQ, Int iQP,
Int iDcScaler,
const BlockMemory blkmPred,
Int iQpPred)
{
UInt nBits = m_volmd.nBits; // NBIT
Int iDefVal = 1<<(nBits+2); // NBIT
//do DC prediction
if (!short_video_header)
{ // Added by KPN for short video headers
if (blkmPred == NULL)
rgiCoefQ [0] += divroundnearest(iDefVal, iDcScaler);
else {
rgiCoefQ [0] += divroundnearest(blkmPred [0], iDcScaler);
// clip range after inverse pred
rgiCoefQ [0] = rgiCoefQ[0] < -2048 ? -2048 : (rgiCoefQ[0] > 2047 ? 2047 : rgiCoefQ[0]);
if (iBlkIdx<(A_BLOCK1 - 1) && pmbmd->m_bACPrediction
|| iBlkIdx>=(A_BLOCK1 - 1) && pmbmd->m_bACPredictionAlpha) {
Int i, j;
//do AC prediction
if (pmbmd->m_preddir [iBlkIdx] == HORIZONTAL) {
for (i = 8, j = 8; j < 2 * BLOCK_SIZE - 1; i += 8, j++)
{
rgiCoefQ [i] += (blkmPred == NULL) ? 0 : (iQP == iQpPred) ?
blkmPred [j] : divroundnearest(blkmPred [j] * iQpPred, iQP);
// clip range after inverse pred
rgiCoefQ [i] = rgiCoefQ[i] < -2048 ? -2048 : (rgiCoefQ[i] > 2047 ? 2047 : rgiCoefQ[i]);
}
}
else if (pmbmd->m_preddir [iBlkIdx] == VERTICAL) {
//horizontal zigzag scan
for (i = 1; i < BLOCK_SIZE; i++)
{
rgiCoefQ [i] += (blkmPred == NULL) ? 0 : (iQP == iQpPred) ?
blkmPred [i] : divroundnearest(blkmPred [i] * iQpPred, iQP);
// clip range after inverse pred
rgiCoefQ [i] = rgiCoefQ[i] < -2048 ? -2048 : (rgiCoefQ[i] > 2047 ? 2047 : rgiCoefQ[i]);
}
}
else
assert (FALSE);
}
}
}// End short video headers
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -