📄 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 + -