📄 errenc.cpp
字号:
ppxlcRefY += m_iFrameWidthYxMBSize;
ppxlcRefU += m_iFrameWidthUVxBlkSize;
ppxlcRefV += m_iFrameWidthUVxBlkSize;
ppxlcOrigY += 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;
// Set to output bitstream
m_pbitstrmOut->SetDontSendBits(FALSE);
}
Void CVideoObjectEncoder::encodeNSForIVOP_DP ()
{
assert( m_volmd.bDataPartitioning );
assert( m_vopmd.vopPredType==IVOP );
//assert(m_volmd.nBits==8);
// bug fix by toshiba 98-9-24 start
//in case the IVOP is used as an ref for direct mode
memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
// bug fix by toshiba 98-9-24 end
CMBMode* pmbmd = m_rgmbmd;
Int iQPPrev = m_vopmd.intStepI; //initialization
PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
// MB rate control
Int iIndexofQ = 0;
Int rgiQ [4] = {-1, -2, 1, 2};
// -----
Int iMBX, iMBY;
Int iVPCounter = m_statsVOP.total();
Int iVPtotal;
m_iVPMBnum = 0;
CStatistics m_statsVP;
// DCT coefficient buffer for Data Partitioning mode
Int*** iCoefQ_DP = new Int** [m_iNumMB];
// Set not to output but count bitstream
m_pbitstrmOut->SetDontSendBits(TRUE);
Bool bRestartDelayedQP = TRUE;
for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
PixelC* ppxlcRefMBY = ppxlcRefY;
PixelC* ppxlcRefMBU = ppxlcRefU;
PixelC* ppxlcRefMBV = ppxlcRefV;
PixelC* ppxlcOrigMBY = ppxlcOrigY;
PixelC* ppxlcOrigMBU = ppxlcOrigU;
PixelC* ppxlcOrigMBV = ppxlcOrigV;
for (iMBX = 0; iMBX < m_iNumMBX; iMBX++) {
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
#endif // __TRACE_AND_STATS_
m_statsMB.reset ();
// MB rate control
//pmbmd->m_intStepDelta = 0;
//iIndexofQ = (iIndexofQ + 1) % 4;
//pmbmd->m_intStepDelta = rgiQ [iIndexofQ];
// -----
// bug fix by toshiba 98-9-24 start
pmbmd->m_bSkip = FALSE; //reset for direct mode
// bug fix by toshiba 98-9-24 end
pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
if(bRestartDelayedQP)
{
pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
bRestartDelayedQP = FALSE;
}
else
pmbmd->m_stepSizeDelayed = iQPPrev;
iQPPrev = pmbmd->m_stepSize;
if (pmbmd->m_intStepDelta == 0)
pmbmd->m_dctMd = INTRA;
else
pmbmd->m_dctMd = INTRAQ;
copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV);
quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);
codeMBTextureHeadOfIVOP (pmbmd);
sendDCTCoefOfIntraMBTexture (pmbmd);
Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;
// 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];
for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
}
pmbmd++;
#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( iVPtotal > m_volmd.bVPBitTh || 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 (DC_MARKER, NUMBITS_DP_DC_MARKER, "DC_marker");
m_statsVP.nBitsHead += NUMBITS_DP_DC_MARKER;
DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
//assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );
m_iVPMBnum = iVPlastMBnum + 1;
// Set not to output but count bitstream
m_pbitstrmOut->SetDontSendBits(TRUE);
}
}
MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
m_rgpmbmAbove = m_rgpmbmCurr;
m_rgpmbmCurr = ppmbmTemp;
ppxlcRefY += m_iFrameWidthYxMBSize;
ppxlcRefU += m_iFrameWidthUVxBlkSize;
ppxlcRefV += m_iFrameWidthUVxBlkSize;
ppxlcOrigY += 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;
// Set to output bitstream
m_pbitstrmOut->SetDontSendBits(FALSE);
}
Void CVideoObjectEncoder::DataPartitioningMotionCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
{
assert( m_volmd.bDataPartitioning );
Int iMBnum;
CMBMode* pmbmd;
CMotionVector* pmv = m_rgmv;
Int iMBX, iMBY;
for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
iMBX = iMBnum % m_iNumMBX;
iMBY = iMBnum / m_iNumMBX;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (CSite (iMBX, iMBY), "Motion_MB_X_Y");
#endif // __TRACE_AND_STATS_
if( m_volmd.fAUsage != RECTANGLE ) {
m_statsVP->nBitsShape += dumpCachedShapeBits_DP(iMBnum);
}
if (pmbmd -> m_rgTranspStatus [0] != ALL) {
if( m_vopmd.vopPredType==PVOP ) {
m_pbitstrmOut->putBits (pmbmd->m_bSkip, 1, "MB_Skip");
m_statsVP->nBitsCOD++;
}
if (!pmbmd->m_bSkip) {
UInt CBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1)
| pmbmd->getCodedBlockPattern (V_BLOCK);
//per defintion of H.263's CBPC
assert (CBPC >= 0 && CBPC <= 3);
Int iMBtype; //per H.263's MBtype
Int iSymbol;
switch( m_vopmd.vopPredType ) {
case PVOP:
if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)
iMBtype = pmbmd->m_dctMd + 3;
else
iMBtype = (pmbmd -> m_dctMd - 2) | pmbmd -> m_bhas4MVForward << 1;
assert (iMBtype >= 0 && iMBtype <= 4);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iMBtype, "MB_MBtype");
m_pbitstrmOut->trace (CBPC, "MB_CBPC");
#endif // __TRACE_AND_STATS_
m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCinter->encodeSymbol (iMBtype * 4 + CBPC, "MCBPC");
break;
case IVOP:
iSymbol = 4 * pmbmd->m_dctMd + CBPC;
assert (iSymbol >= 0 && iSymbol <= 7); //send MCBPC
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (CBPC, "MB_CBPC");
#endif // __TRACE_AND_STATS_
m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCintra->encodeSymbol (iSymbol, "MB_MCBPC");
break;
default:
assert(FALSE);
}
if ( m_vopmd.vopPredType == IVOP ) {
if( pmbmd->m_dctMd == INTRAQ) {
Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
assert (DQUANT >= -2 && DQUANT <= 2);
if (DQUANT != 0) {
if (sign (DQUANT) == 1)
m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
else
m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
m_statsVP->nBitsDQUANT += 2;
}
}
UInt iBlk = 0;
for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
UInt nBits = 0;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iBlk, "BLK_NO");
#endif // __TRACE_AND_STATS_
if (iBlk < U_BLOCK)
if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
#endif // __TRACE_AND_STATS_
if (pmbmd->m_bCodeDcAsAc != TRUE) {
nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
}
switch (iBlk) {
case U_BLOCK:
m_statsVP->nBitsCr += nBits;
break;
case V_BLOCK:
m_statsVP->nBitsCb += nBits;
break;
default:
m_statsVP->nBitsY += nBits;
}
}
}
if (pmbmd->m_dctMd != INTRA && pmbmd->m_dctMd != INTRAQ) {
if( m_volmd.fAUsage == RECTANGLE )
m_statsVP->nBitsMV += encodeMVVP (pmv, pmbmd, iMBX, iMBY);
else
m_statsVP->nBitsMV += encodeMVWithShape (pmv, pmbmd, iMBX, iMBY);
}
}
}
}
}
Void CVideoObjectEncoder::DataPartitioningTextureCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
{
assert( m_volmd.bDataPartitioning );
Int iMBnum;
CMBMode* pmbmd;
CMotionVector* pmv = m_rgmv;
Int iMBX, iMBY;
for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
if (pmbmd->m_bSkip || pmbmd -> m_rgTranspStatus [0] == ALL)
continue;
iMBX = iMBnum % m_iNumMBX;
iMBY = iMBnum / m_iNumMBX;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (CSite (iMBX, iMBY), "TextureHeader_MB_X_Y");
#endif // __TRACE_AND_STATS_
Int CBPY = 0;
UInt cNonTrnspBlk = 0, iBlk;
for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
if (pmbmd->m_rgTranspStatus [iBlk] != ALL)
cNonTrnspBlk++;
}
UInt iBitPos = 1;
for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
if (pmbmd->m_rgTranspStatus [iBlk] != ALL) {
CBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
iBitPos++;
}
}
assert (CBPY >= 0 && CBPY <= 15); //per defintion of H.263's CBPY
if (m_volmd.fAUsage == RECTANGLE)
assert (cNonTrnspBlk==4); // Only all opaque is only supportedin DP mode at present
if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
m_pbitstrmOut->putBits (pmbmd->m_bACPrediction, 1, "MB_ACPRED");
m_statsVP->nBitsIntraPred++;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
m_pbitstrmOut->trace (CBPY, "MB_CBPY (I-style)");
#endif // __TRACE_AND_STATS_
switch (cNonTrnspBlk) {
case 1:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (CBPY, "MB_CBPY1");
break;
case 2:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (CBPY, "MB_CBPY2");
break;
case 3:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (CBPY, "MB_CBPY3");
break;
case 4:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (CBPY, "MB_CBPY");
break;
default:
assert (FALSE);
}
m_statsVP->nIntraMB++;
}
else {
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
m_pbitstrmOut->trace (CBPY, "MB_CBPY (P-style)");
#endif // __TRACE_AND_STATS_
switch (cNonTrnspBlk) {
case 1:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPY, "MB_CBPY1");
break;
case 2:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPY, "MB_CBPY2");
break;
case 3:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPY, "MB_CBPY3");
break;
case 4:
m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPY, "MB_CBPY");
break;
default:
assert (FALSE);
}
}
if ( m_vopmd.vopPredType != IVOP &&
(pmbmd->m_dctMd == INTERQ || pmbmd->m_dctMd == INTRAQ)) {
Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
assert (DQUANT >= -2 && DQUANT <= 2);
if (DQUANT != 0) {
if (sign (DQUANT) == 1)
m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
else
m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
m_statsVP->nBitsDQUANT += 2;
}
}
if (m_vopmd.vopPredType != IVOP &&
(pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)) {
UInt iBlk = 0;
for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
UInt nBits = 0;
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iBlk, "BLK_NO");
#endif // __TRACE_AND_STATS_
if (iBlk < U_BLOCK)
if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
//// Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
#ifdef __TRACE_AND_STATS_
//// m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
#endif // __TRACE_AND_STATS_
//// Int iCoefStart = 0;
if (pmbmd->m_bCodeDcAsAc != TRUE) {
//// iCoefStart = 1;
nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
}
switch (iBlk) {
case U_BLOCK:
m_statsVP->nBitsCr += nBits;
break;
case V_BLOCK:
m_statsVP->nBitsCb += nBits;
break;
default:
m_statsVP->nBitsY += nBits;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -