📄 errenc.cpp
字号:
m_pbitstrmShapeMBOut = m_pbitstrmShape_DP[iMBY * m_iNumMBX + iMBX + 1];
// Added for error resilient mode by Toshiba(1997-11-14)
// The following operation is needed only for OBMC
if( bCodeVPHeaderNext ) {
iTempVPMBnum = m_iVPMBnum;
m_iVPMBnum = VPMBnum(iMBX+1, iMBY);
}
// End Toshiba(1997-11-14)
// code shape 1mb in advance
copyToCurrBuffJustShape (ppxlcOrigMBBY+MB_SIZE,m_iFrameWidthY);
// Modified for error resilient mode by Toshiba(1997-11-14)
if(m_vopmd.bShapeCodingType) {
shpmdColocatedMB = m_rgmbmdRef [
min (max (0, iMBX+1), m_iNumMBXRef-1) +
min (max (0, iMBY), m_iNumMBYRef-1) * m_iNumMBXRef
].m_shpmd;
encodePVOPMBJustShape(
ppxlcRefMBBY+MB_SIZE, pmbmd+1,
shpmdColocatedMB,
pmv+PVOP_MV_PER_REF_PER_MB,
pmvBY+1, x+MB_SIZE, y,
iMBX+1, iMBY
);
}
else {
m_statsMB.nBitsShape
+= codeIntraShape (
ppxlcRefMBBY+MB_SIZE,
pmbmd+1, iMBX+1, iMBY
);
decideTransparencyStatus (pmbmd+1,
m_ppxlcCurrMBBY);
}
// End Toshiba(1997-11-14)
// Added for error resilient mode by Toshiba(1997-11-14)
// The following operation is needed only for OBMC
if( bCodeVPHeaderNext )
m_iVPMBnum = iTempVPMBnum;
// End Toshiba(1997-11-14)
if((pmbmd+1)->m_bhas4MVForward)
padMotionVectors(pmbmd+1, pmv+PVOP_MV_PER_REF_PER_MB);
}
// Set not to output but count bitstream
m_pbitstrmOut->SetDontSendBits(TRUE);
// copy DCT coefficient to buffer
iCoefQ_DP[iVPlastMBnum] = new Int* [6];
Int iBlk;
for (iBlk = 0; iBlk < 6; iBlk++) {
iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];
}
if(m_volmd.bShapeOnly==FALSE)
{
if (pmbmd -> m_rgTranspStatus [0] != ALL) {
// need to copy binary shape too since curr buff is future shape
copyToCurrBuffWithShape(ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV,
ppxlcRefMBBY, ppxlcOrigMBA, m_iFrameWidthY, m_iFrameWidthUV);
downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);
encodePVOPMBTextureWithShape(ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA, pmbmd, pmv, iMBX, iMBY, x, y,
iQPPrev, iQPPrevAlpha, bRestartDelayedQP);
// copy DCT coefficient to buffer
for (iBlk = 0; iBlk < 6; iBlk++) {
for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
}
if (pmbmd -> m_rgTranspStatus [0] == PARTIAL)
mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
padNeighborTranspMBs (
iMBX, iMBY,
pmbmd,
ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
);
}
else {
padCurrAndTopTranspMBFromNeighbor (
iMBX, iMBY,
pmbmd,
ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
);
}
}
// Set to output bitstream
m_pbitstrmOut->SetDontSendBits(FALSE);
pmbmd++;
pmv += PVOP_MV_PER_REF_PER_MB;
pmvBY++;
ppxlcRefMBBY += MB_SIZE;
ppxlcRefMBA += MB_SIZE;
ppxlcRefMBBUV += BLOCK_SIZE;
ppxlcOrigMBBY += MB_SIZE;
ppxlcOrigMBA += MB_SIZE;
#ifdef __TRACE_AND_STATS_
m_statsVOP += m_statsMB;
#endif // __TRACE_AND_STATS_
ppxlcRefMBY += MB_SIZE;
ppxlcRefMBU += BLOCK_SIZE;
ppxlcRefMBV += BLOCK_SIZE;
ppxlcOrigMBY += MB_SIZE;
ppxlcOrigMBU += BLOCK_SIZE;
ppxlcOrigMBV += BLOCK_SIZE;
iVPtotal = (int) m_statsVOP.total() - iVPCounter;
if( bCodeVPHeaderNext || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
// Set to output bitstream
m_pbitstrmOut->SetDontSendBits(FALSE);
// encode video packet
iVPCounter = m_statsVOP.total();
m_statsVP.reset();
if( m_iVPMBnum > 0 )
{
m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
bRestartDelayedQP = TRUE;
}
DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
m_pbitstrmOut -> putBits (MOTION_MARKER, NUMBITS_DP_MOTION_MARKER, "motion_marker");
m_statsVP.nBitsHead += NUMBITS_DP_MOTION_MARKER;
DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
// assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );
m_iVPMBnum = iVPlastMBnum + 1;
}
// The following operation is needed only for OBMC
iCounter = m_statsVOP.total();
bCodeVPHeaderNext = iCounter - iVPCounter > m_volmd.bVPBitTh;
}
MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
m_rgpmbmAbove = m_rgpmbmCurr;
m_rgpmbmCurr = ppmbmTemp;
ppxlcRefY += m_iFrameWidthYxMBSize;
ppxlcRefU += m_iFrameWidthUVxBlkSize;
ppxlcRefV += m_iFrameWidthUVxBlkSize;
ppxlcRefBY += m_iFrameWidthYxMBSize;
ppxlcRefA += m_iFrameWidthYxMBSize;
ppxlcRefBUV += m_iFrameWidthUVxBlkSize;
ppxlcOrigY += m_iFrameWidthYxMBSize;
ppxlcOrigBY += m_iFrameWidthYxMBSize;
ppxlcOrigA += m_iFrameWidthYxMBSize;
ppxlcOrigU += m_iFrameWidthUVxBlkSize;
ppxlcOrigV += m_iFrameWidthUVxBlkSize;
}
// delete CoefQ_DP
for( Int iMB = 0; iMB < m_iNumMB; iMB++ ) {
for (Int iBlk = 0; iBlk < 6; iBlk++) {
delete [] iCoefQ_DP [iMB] [iBlk];
}
delete [] iCoefQ_DP[iMB];
}
delete [] iCoefQ_DP;
// restore normal output stream
m_pbitstrmShapeMBOut = m_pbitstrmOut;
// Set to output bitstream
m_pbitstrmOut->SetDontSendBits(FALSE);
}
//////////////////////////////////////////////////////////
//// The following functions are for Reversible VLC ////
//////////////////////////////////////////////////////////
UInt CVideoObjectEncoder::sendTCOEFIntraRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
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 += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
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 += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
return numBits;
}
UInt CVideoObjectEncoder::putBitsOfTCOEFIntraRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
assert(m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
UInt nBits = 0;
Long lVLCtableIndex;
if (bIsLastRun == FALSE) {
lVLCtableIndex = findVLCtableIndexOfNonLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits); // huffman encode
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");
nBits++;
}
else
escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
}
else {
lVLCtableIndex = findVLCtableIndexOfLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits); // huffman encode
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");
nBits++;
}
else
escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
}
return nBits;
}
Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
assert (uiRun >= 0);
if (uiRun > 19 || (uiLevel > grgIfNotLastNumOfLevelAtRunIntraRVLC [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfNotLastNumOfLevelAtRunIntraRVLC [i];
uiTableIndex += uiLevel;
uiTableIndex--; // make it zero-based; see Table H13/H.263
return uiTableIndex;
}
}
Int CVideoObjectEncoder::findVLCtableIndexOfLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
assert (uiRun >= 0);
if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunIntraRVLC [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfLastNumOfLevelAtRunIntraRVLC [i];
uiTableIndex += uiLevel;
uiTableIndex += 102; // make it zero-based and
return uiTableIndex; //correction of offset; see Table H13/H.263
}
}
UInt CVideoObjectEncoder::sendTCOEFInterRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
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 += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
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 += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
return numBits;
}
UInt CVideoObjectEncoder::putBitsOfTCOEFInterRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
UInt nBits = 0;
Long lVLCtableIndex;
if (bIsLastRun == FALSE) {
lVLCtableIndex = findVLCtableIndexOfNonLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits); // huffman encode
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");
nBits++;
}
else
escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
}
else {
lVLCtableIndex = findVLCtableIndexOfLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
if (lVLCtableIndex != NOT_IN_TABLE) {
nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits); // huffman encode
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");
nBits++;
}
else
escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
}
return nBits;
}
Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
assert (uiRun >= 0);
if (uiRun > 38 || (uiLevel > grgIfNotLastNumOfLevelAtRunInterRVLC [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfNotLastNumOfLevelAtRunInterRVLC [i];
uiTableIndex += uiLevel;
uiTableIndex--; // make it zero-based; see Table H13/H.263
return uiTableIndex;
}
}
Int CVideoObjectEncoder::findVLCtableIndexOfLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
assert (uiRun >= 0);
if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunInterRVLC [uiRun]))
return NOT_IN_TABLE;
else {
UInt uiTableIndex = 0;
for (UInt i = 0; i < uiRun; i++)
uiTableIndex += grgIfLastNumOfLevelAtRunInterRVLC [i];
uiTableIndex += uiLevel;
uiTableIndex += 102; // make it zero-based and
return uiTableIndex; //correction of offset; see Table H13/H.263
}
}
UInt CVideoObjectEncoder::escapeEncodeRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
{
assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
UInt nBits = 0;
Int iLevelAbs = abs (iLevel);
Char iLevelSign = (Char) invSignOf (iLevel);
nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "FEsc_TCOEF_RVLC", bDontSendBits);
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "FEsc1_TCOEF_RVLC");
nBits ++;
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Esc_TCOEF_RVLC");
nBits ++;
assert (uiRun < BLOCK_SQUARE_SIZE);
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (uiRun, NUMBITS_RVLC_ESC_RUN, "Run_Esc_TCOEF_RVLC");
nBits += NUMBITS_RVLC_ESC_RUN;
Int iLevelBits = 12; // = m_volmd.nBits;
Int iMaxAC = (1<<(iLevelBits - 1)) - 1;
assert (iLevelAbs <= iMaxAC && iLevelAbs > 0);
if( !bDontSendBits )
{
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelAbs, iLevelBits - 1, "Level_Esc_TCOEF_RVLC");
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
}
nBits += iLevelBits - 1 + 2;
nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "LEsc_TCOEF_RVLC", bDontSendBits);
if( !bDontSendBits )
m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelSign, 1, "Sign_LEsc_TCOEF_RVLC");
nBits ++;
return nBits;
}
Int CVideoObjectEncoder::dumpCachedShapeBits_DP(Int iMBnum)
{
Int ret;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HERE\n");
m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");
#endif // __TRACE_AND_STATS_
m_pbitstrmOut->putBitStream(*m_pbitstrmShape_DP[iMBnum]);
ret = m_pbitstrmShape_DP[iMBnum]->getCounter();
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");
#endif // __TRACE_AND_STATS_
m_pbitstrmShape_DP[iMBnum]->flush();
m_pbitstrmShape_DP[iMBnum]->resetAll();
return(ret);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -