⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shpenc.cpp

📁 《Visual C++小波变换技术与工程实践》靳济芳编著的光盘程序。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	PixelC* ppxlcDst = m_ppxlcReconCurrBAB + BAB_BORDER + BAB_BORDER * TOTAL_BAB_SIZE;
	PixelC* ppxlcSrc = m_ppxlcCurrMBBY;
	Int iUnit = sizeof(PixelC); // NBIT: for memcpy
	Int i;
	for (i = 0; i < MB_SIZE; i++) {
		memcpy (ppxlcDst, ppxlcSrc, MB_SIZE*iUnit);
		ppxlcSrc += MB_SIZE;
		ppxlcDst += BAB_SIZE;
	}

	// make borders
	copyLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcReconCurrBAB);
	makeRightBottomBorder (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE);	

	// assign encoding buffer
	m_rgpxlcCaeSymbol = m_ppxlcReconCurrBAB;
	return shpmd;
}


Int CVideoObjectEncoder::downSampleShape (const PixelC* ppxlcSrc, 
								   Int* rgiSrcSubBlk,
								   PixelC* ppxlcDst, 
								   Int* piDstPxl, 
								   Int iRate,
								   Int iThreshold,
								   Int nSubBlk)
{
	Int nOpaquePixel = 0, iSum = 0;
	Int iSubBlk;
	for (iSubBlk = 0; iSubBlk < nSubBlk; iSubBlk++)	{
		Int i = rgiSrcSubBlk [iSubBlk];
		iSum = 0;
		for (CoordI iY = 0; iY < iRate; iY++)	{
			for (CoordI iX = 0; iX < iRate; iX++)  {
				iSum += abs (ppxlcSrc [i++]);  //abs???
			}
			i += MB_SIZE - iRate;
		}
		ppxlcDst [*piDstPxl] = (iSum > iThreshold) ? OPAQUE : TRANSPARENT;
		nOpaquePixel += ppxlcDst [*piDstPxl];
		piDstPxl++;
	}		
	return (nOpaquePixel /= OPAQUE);
}

Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndx, Int iWidthSrc, PixelC pxlcRecon, const CMBMode* pmbmd)
{
	if (pmbmd->m_bhas4MVForward == TRUE)	{
		if (!sameBlockTranspStatus (pmbmd, pxlcRecon))	
			return TRUE;
	} 

	//check error in each 4x4 subblock
	Int iSubBlk;
	Int iError = 0;
	for (iSubBlk = 0; iSubBlk < 16; iSubBlk++)	{
		Int i = rgiSubBlkIndx [iSubBlk];
		for (CoordI iY = 0; iY < 4; iY++)	{
			for (CoordI iX = 0; iX < 4; iX++)  {
				iError += abs (rgppxlcSrc [i++] - pxlcRecon);
			}
			if (iError > m_volmd.iBinaryAlphaTH) 
				return TRUE;
			i += iWidthSrc - 4;
		}
	}		
	return FALSE;
}

Bool CVideoObjectEncoder::isErrorLarge (const PixelC* rgppxlcSrc, const Int* rgiSubBlkIndxSrc, const Int iSizeSrc,
								const PixelC* rgppxlcDst, const Int* rgiSubBlkIndxDst, const Int iSizeDst, const CMBMode* pmbmd)
{
	if (pmbmd->m_bhas4MVForward == TRUE)	{
		if (!sameBlockTranspStatus (pmbmd, rgppxlcDst, iSizeDst))	
			return TRUE;
	} 

	//check error in each 4x4 subblock
	Int iSubBlk;
	Int iError = 0;
	for (iSubBlk = 0; iSubBlk < 16; iSubBlk++)	{
		Int iSrc = rgiSubBlkIndxSrc [iSubBlk];
		Int iDst = rgiSubBlkIndxDst [iSubBlk];
		for (CoordI iY = 0; iY < 4; iY++)	{
			for (CoordI iX = 0; iX < 4; iX++)  {
				iError += abs (rgppxlcSrc [iSrc] - rgppxlcDst [iDst]);
				iSrc++;
				iDst++;
			}
			if (iError > m_volmd.iBinaryAlphaTH)
				return TRUE;
			iSrc += iSizeSrc - 4;				
			iDst += iSizeDst - 4;
		}
	}		
	return FALSE;
}

UInt CVideoObjectEncoder::encodeCAEIntra (ShapeMode shpmd, CAEScanDirection shpdir)
{
	assert (shpmd == INTRA_CAE);
//	m_pbitstrmOut->trace (m_rgiCurrShp, TOTAL_BAB_SQUARE_SIZE, "MB_BAB");
	UInt nBits = 0;
	nBits += codeCrAndSt (shpdir, m_iInverseCR);
	//the real arithmatic encoding
	StartArCoder (m_parcodec);
	if (shpdir == HORIZONTAL)	{
		const PixelC* ppxlcSrcRow = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER;
		for (Int iRow = BAB_BORDER; iRow < m_iWidthCurrBAB - BAB_BORDER; iRow++)	{
			const PixelC* ppxlcSrc = ppxlcSrcRow;
			for (Int iCol = BAB_BORDER; iCol < m_iWidthCurrBAB - BAB_BORDER; iCol++)	{
				Int iContext = contextIntra (ppxlcSrc);
#ifdef __TRACE_AND_STATS_
			//	m_pbitstrmOut->trace (iContext, "MB_CAE_Context");
#endif // __TRACE_AND_STATS_
				ArCodeSymbol ((*ppxlcSrc == OPAQUE), gCAEintraProb [iContext], m_parcodec, m_pbitstrmShapeMBOut);	
				ppxlcSrc++;
			}
			ppxlcSrcRow += m_iWidthCurrBAB;
		}
	}
	else {
		const PixelC* ppxlcSrcCol = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER;
		for (Int iCol = BAB_BORDER; iCol < m_iWidthCurrBAB - BAB_BORDER; iCol++)	{
			const PixelC* ppxlcSrc = ppxlcSrcCol;
			for (Int iRow = BAB_BORDER; iRow < m_iWidthCurrBAB - BAB_BORDER; iRow++)	{
				Int iContext = contextIntraTranspose (ppxlcSrc);
#ifdef __TRACE_AND_STATS_
				//m_pbitstrmOut->trace (iContext, "MB_CAE_Context");
#endif // __TRACE_AND_STATS_
				ArCodeSymbol ((*ppxlcSrc == OPAQUE), gCAEintraProb [iContext], m_parcodec, m_pbitstrmShapeMBOut);	
				ppxlcSrc += m_iWidthCurrBAB ;
			}
			ppxlcSrcCol++;
		}
	}
	StopArCoder (m_parcodec, m_pbitstrmShapeMBOut);
	nBits += m_parcodec->nBits;
	return nBits;
}

UInt CVideoObjectEncoder::encodeCAEInter (ShapeMode shpmd, CAEScanDirection shpdir)
{
	assert (shpmd == INTER_CAE_MVDNZ || shpmd == INTER_CAE_MVDZ);	
//	m_pbitstrmOut->trace (m_rgiCurrShp, TOTAL_BAB_SQUARE_SIZE, "MB_BAB");

	UInt nBits = 0;
	nBits += codeCrAndSt (shpdir, m_iInverseCR);
	const PixelC *ppxlcPredBAB = m_puciPredBAB->pixels();
	Int iSizeMB = m_iWidthCurrBAB-BAB_BORDER*2;
	Int iSizePredBAB = iSizeMB+MC_BAB_BORDER*2;
	if(m_iInverseCR==2)
	{
		downSampleShapeMCPred(ppxlcPredBAB,m_ppxlcPredBABDown2,2);
		ppxlcPredBAB = m_ppxlcPredBABDown2;
	}
	else if(m_iInverseCR==4)
	{
		downSampleShapeMCPred(ppxlcPredBAB,m_ppxlcPredBABDown4,4);
		ppxlcPredBAB = m_ppxlcPredBABDown4;
	}

	//the real arithmatic encoding
	StartArCoder (m_parcodec);
	if (shpdir == HORIZONTAL)	{
		const PixelC* ppxlcSrcRow  = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER;
		const PixelC* ppxlcPredRow = ppxlcPredBAB + iSizePredBAB * MC_BAB_BORDER + MC_BAB_BORDER;
		for (Int iRow = 0; iRow < iSizeMB; iRow++)	{
			const PixelC* ppxlcSrc = ppxlcSrcRow;
			const PixelC* ppxlcPred = ppxlcPredRow;
			for (Int iCol = 0; iCol < iSizeMB; iCol++)	{
				Int iContext = contextInter (ppxlcSrc, ppxlcPred);
#ifdef __TRACE_AND_STATS_
				//m_pbitstrmOut->trace (iContext, "MB_CAE_Context");
#endif // __TRACE_AND_STATS_
				ArCodeSymbol ((*ppxlcSrc == OPAQUE), gCAEinterProb [iContext], m_parcodec, m_pbitstrmShapeMBOut);	
				ppxlcSrc++;
				ppxlcPred++;
			}
			ppxlcSrcRow += m_iWidthCurrBAB;
			ppxlcPredRow += iSizePredBAB;
		}
	}
	else {
		const PixelC* ppxlcSrcCol  = m_rgpxlcCaeSymbol + m_iWidthCurrBAB * BAB_BORDER + BAB_BORDER;
		const PixelC* ppxlcPredCol = ppxlcPredBAB + iSizePredBAB * MC_BAB_BORDER + MC_BAB_BORDER;		
		for (Int iCol = 0; iCol < iSizeMB; iCol++)	{
			const PixelC* ppxlcSrc = ppxlcSrcCol;
			const PixelC* ppxlcPred = ppxlcPredCol;
			for (Int iRow = 0; iRow < iSizeMB; iRow++)	{
				Int iContext = contextInterTranspose (ppxlcSrc, ppxlcPred);
#ifdef __TRACE_AND_STATS_
				//m_pbitstrmOut->trace (iContext, "MB_CAE_Context");
#endif // __TRACE_AND_STATS_
				ArCodeSymbol ((*ppxlcSrc == OPAQUE), gCAEinterProb [iContext], m_parcodec, m_pbitstrmShapeMBOut);	
				ppxlcSrc += m_iWidthCurrBAB;
				ppxlcPred += iSizePredBAB;
			}
			ppxlcSrcCol++;
			ppxlcPredCol++;
		}
	}
	StopArCoder (m_parcodec, m_pbitstrmShapeMBOut);
	nBits += m_parcodec->nBits;
	return nBits;
}


UInt CVideoObjectEncoder::encodeMVDS (CMotionVector mvBYD)
{
	assert (!mvBYD.isZero());

	m_pentrencSet->m_pentrencShapeMV1->attachStream(*m_pbitstrmShapeMBOut);
	m_pentrencSet->m_pentrencShapeMV2->attachStream(*m_pbitstrmShapeMBOut);
	UInt nBits = 0;
	nBits += m_pentrencSet->m_pentrencShapeMV1->encodeSymbol (abs (mvBYD.iMVX), "MB_SHP_MVDX");			
	if (mvBYD.iMVX != 0)	{
		m_pbitstrmShapeMBOut->putBits (signOf(mvBYD.iMVX), (UInt) 1, "MB_SHP_MVDX_Sign");
		nBits++;
		nBits += m_pentrencSet->m_pentrencShapeMV1->encodeSymbol (abs (mvBYD.iMVY), "MB_SHP_MVDY");
	}
	else 
		nBits += m_pentrencSet->m_pentrencShapeMV2->encodeSymbol (abs (mvBYD.iMVY) - 1, "MB_SHP_MVDY");
	if (mvBYD.iMVY != 0)	{		
		m_pbitstrmShapeMBOut->putBits (signOf(mvBYD.iMVY), (UInt) 1, "MB_SHP_MVDY_Sign");
		nBits++;
	}
	
	m_pentrencSet->m_pentrencShapeMV1->attachStream(*m_pbitstrmOut);
	m_pentrencSet->m_pentrencShapeMV2->attachStream(*m_pbitstrmOut);
	return nBits;
}

Bool CVideoObjectEncoder::sameBlockTranspStatus (const CMBMode* pmbmd, PixelC pxlcRecon)	//assume src is 16 x 16 buffer
{
	if (pxlcRecon == opaqueValue)
		return ((pmbmd->m_rgTranspStatus [Y_BLOCK1] != ALL) &&		//if recon is all opaque
				(pmbmd->m_rgTranspStatus [Y_BLOCK2] != ALL) &&		//then each orig. blk has to be not all transp
				(pmbmd->m_rgTranspStatus [Y_BLOCK3] != ALL) &&
				(pmbmd->m_rgTranspStatus [Y_BLOCK4] != ALL));
	return TRUE;
}

Bool CVideoObjectEncoder::sameBlockTranspStatus (const CMBMode* pmbmd, const PixelC* pxlcRecon, Int iSizeRecon) //src: 16x16 Recon: 18 x 18 || 20 x 20
{
	Int iBorder = (iSizeRecon == 18) ? 1 : 2;
	const PixelC* ppxlcBlk1 = pxlcRecon + iBorder + iBorder * iSizeRecon;
	const PixelC* ppxlcBlk2 = ppxlcBlk1 + BLOCK_SIZE;
	const PixelC* ppxlcBlk3 = pxlcRecon + iSizeRecon * iSizeRecon / 2 + iBorder;
	const PixelC* ppxlcBlk4 = ppxlcBlk3 + BLOCK_SIZE;
	static rgnOpaquePixels [4];
	rgnOpaquePixels [0] = rgnOpaquePixels [1] = rgnOpaquePixels [2] = rgnOpaquePixels [3] = 0;
	CoordI ix, iy;
	for (iy = 0; iy < BLOCK_SIZE; iy++) {
		for (ix = 0; ix < BLOCK_SIZE; ix++) {
			rgnOpaquePixels [0] += ppxlcBlk1 [ix];
			rgnOpaquePixels [1] += ppxlcBlk2 [ix];
			rgnOpaquePixels [2] += ppxlcBlk3 [ix];
			rgnOpaquePixels [3] += ppxlcBlk4 [ix];
		}
		ppxlcBlk1 += iSizeRecon;
		ppxlcBlk2 += iSizeRecon;
		ppxlcBlk3 += iSizeRecon;
		ppxlcBlk4 += iSizeRecon;
	}

	Int iBlk;
	for (iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++)
		if (pmbmd->m_rgTranspStatus [iBlk] == ALL)			//if org. blk is all transp, the recon can be otherwise
			if (rgnOpaquePixels [iBlk - 1] != 0)
				return FALSE;
	return TRUE;
}


UInt CVideoObjectEncoder::codeCrAndSt (CAEScanDirection shpdir, Int iInverseCR)
{
	UInt nBits = 0;
	if (m_volmd.bNoCrChange == FALSE)	{
		UInt nBitsCR = (iInverseCR == 1) ? 1 : 2;
		Int iCode = (iInverseCR == 1) ? 0 : (iInverseCR == 2) ? 2 : 3;
		m_pbitstrmShapeMBOut->putBits (iCode, nBitsCR, "MB_CR");
		nBits += nBitsCR;
	}
	//Scan direction
	m_pbitstrmShapeMBOut->putBits ((shpdir == HORIZONTAL) ? 1 : 0, (UInt) 1, "MB_ST");
	nBits++;
	return nBits;
}

Void CVideoObjectEncoder::copyReconShapeToRef (PixelC* ppxlcRefFrm, PixelC pxlcSrc)		//no need to reset MB buffer
{
	for (Int i = 0; i < MB_SIZE; i++)	{
		pxlcmemset (ppxlcRefFrm, pxlcSrc, MB_SIZE);
		ppxlcRefFrm+= m_iFrameWidthY;
	}
}

Void CVideoObjectEncoder::copyReconShapeToRef (PixelC* ppxlcRefFrm, 
											   const PixelC* ppxlcSrc, Int iSrcWidth, Int iBorder)
{
	ppxlcSrc += iSrcWidth * iBorder + iBorder;
	Int iUnit = sizeof(PixelC); // NBIT: for memcpy
	for (Int i = 0; i < MB_SIZE; i++)	{
		memcpy (ppxlcRefFrm, ppxlcSrc, MB_SIZE*iUnit);
		ppxlcRefFrm += m_iFrameWidthY;
		ppxlcSrc += iSrcWidth;
	}
}

Int CVideoObjectEncoder::sadForShape (const PixelC* ppxlcRefBY) const
{
	Int iInitSAD = 0;
	CoordI ix, iy;
	const PixelC* ppxlcCurrBY = m_ppxlcCurrMBBY;
	for (iy = 0; iy < MB_SIZE; iy++) {
		for (ix = 0; ix < MB_SIZE; ix++)
			iInitSAD += abs (ppxlcCurrBY [ix] - ppxlcRefBY [ix]);
		ppxlcCurrBY += MB_SIZE;
		ppxlcRefBY += m_iFrameWidthY;
	}
	return iInitSAD;
}

Void CVideoObjectEncoder::blkmatchForShape (
	CVOPU8YUVBA* pvopcRefQ,
	CMotionVector* pmv,
	const CVector& mvPredHalfPel,
	CoordI iX, CoordI iY
)
{
	Int mbDiff;
	CoordI x = iX + (mvPredHalfPel.x >> 1), y = iY + (mvPredHalfPel.y >> 1); 
	Int iXDest = x, iYDest = y;
	CoordI ix, iy;
	const PixelC* ppxlcRefMBY = pvopcRefQ->pixelsBY () + m_rctRefFrameY.offset (x, y);
	Int iMinSAD = sadForShape (ppxlcRefMBY);
	pmv->iMVX = pmv->iMVY = 0;
	Int uiPosInLoop, iLoop;
	// Spiral Search for the rest
	for (iLoop = 1; iLoop <= 16; iLoop++) {
		x++;
		y++;
		ppxlcRefMBY += m_iFrameWidthY + 1;
		for (uiPosInLoop = 0; uiPosInLoop < (iLoop << 3); uiPosInLoop++) {
			// inside each spiral loop 
			if (
				x >= m_rctRefVOPY0.left && y >= m_rctRefVOPY0.top && 
				x <= m_rctRefVOPY0.right - MB_SIZE && y <= m_rctRefVOPY0.bottom - MB_SIZE
			) {
				const PixelC* ppxlcTmpC = m_ppxlcCurrMBBY;
				const PixelC* ppxlcRefMB = ppxlcRefMBY;
				mbDiff = 0;
				for (iy = 0; iy < MB_SIZE; iy++) {
					for (ix = 0; ix < MB_SIZE; ix++)
						mbDiff += abs (ppxlcTmpC [ix] - ppxlcRefMB [ix]);
					if (mbDiff >= iMinSAD)
						goto NEXT_POSITION; // skip the current position
					ppxlcRefMB += m_iFrameWidthY;
					ppxlcTmpC += MB_SIZE;
				}
				iMinSAD = mbDiff;
				iXDest = x;
				iYDest = y;
			}
NEXT_POSITION:	
			if (uiPosInLoop < (iLoop << 1)) {
				ppxlcRefMBY--;
				x--;
			}
			else if (uiPosInLoop < (iLoop << 2)) {
				ppxlcRefMBY -= m_iFrameWidthY;
				y--;
			}
			else if (uiPosInLoop < (iLoop * 6)) {
				ppxlcRefMBY++;					  
				x++;
			}
			else {
				ppxlcRefMBY += m_iFrameWidthY;
				y++;
			}
		}
	}
	*pmv = CMotionVector (iXDest - iX, iYDest - iY);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -