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

📄 mcpad.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************

This software module was originally developed by 

	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
	Simon Winder (swinder@microsoft.com), Microsoft Corporation
	(date: June, 1997)
and edited by
        Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center

in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
This software module is an implementation of a part of one or more MPEG-4 Video tools 
as specified by the MPEG-4 Video. 
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, 
the subsequent editors and their companies, 
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Video conforming products. 
Microsoft retains full right to use the code for his/her own purpose, 
assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video conforming products. 
This copyright notice must be included in all copies or derivative works. 

Copyright (c) 1996, 1997.


Module Name:

	mcPad.cpp

Abstract:

	MB Padding (for motion estimation and compensation).

Revision History:
        May. 9   1998:  add field based MC padding  by Hyundai Electronics
                                  Cheol-Soo Park (cspark@super5.hyundai.co.kr)

*************************************************************************/

#include "typeapi.h"
#include "codehead.h"
#include "mode.hpp"
#include "vopses.hpp"

// size of image for ppxlcAlphaBase is (uiBlkSize X uiBlkSize)


#define invalidColour -1

// Added for field based MC padding by Hyundai(1998-5-9)
#define MB_FIELDY       1
#define MB_FIELDC       3
// End of Hyundai(1998-5-9)

Void CVideoObject::mcPadCurrMB (
	PixelC* ppxlcRefMBY, 
	PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV,
	PixelC* ppxlcRefMBA 
)
{
	mcPadCurr (ppxlcRefMBY, m_ppxlcCurrMBBY, MB_SIZE, m_iFrameWidthY);
	mcPadCurr (ppxlcRefMBU, m_ppxlcCurrMBBUV, BLOCK_SIZE, m_iFrameWidthUV);
	mcPadCurr (ppxlcRefMBV, m_ppxlcCurrMBBUV, BLOCK_SIZE, m_iFrameWidthUV);
	if (m_volmd.fAUsage == EIGHT_BIT)
		mcPadCurr (ppxlcRefMBA, m_ppxlcCurrMBBY, MB_SIZE, m_iFrameWidthY);
}

Void CVideoObject::mcPadCurr (
	PixelC *ppxlcTextureBase, // (uiStride X ???)
	const PixelC *ppxlcAlphaBase, // uiBlkSize X uiBlkSize
	UInt uiBlkSize, UInt uiStride
)
{
	Int iUnit = sizeof(PixelC); // NBIT: memcpy
	CoordI iX,iY,iJ,iLeftX = 0;
	Bool bEmptyRow = FALSE;
	Bool bInVop;
	Int iLeftColour;

	PixelC *ppxlcTexture = ppxlcTextureBase;
	const PixelC *ppxlcAlpha = ppxlcAlphaBase;

	for (iY=0; iY < (CoordI) uiBlkSize; iY++, ppxlcTexture+=uiStride)
    {
		bInVop = TRUE;
		iLeftColour = invalidColour;
		m_pbEmptyRowArray[iY]=0;

		for(iX=0;iX<(CoordI)uiBlkSize;iX++,ppxlcAlpha++)
		{
			if(bInVop==TRUE && *ppxlcAlpha==transpValue)
		    {
				// start of stripe or left border 
				bInVop=FALSE;
				iLeftX=iX;
				if(iX>0)
					iLeftColour=ppxlcTexture[iLeftX-1];
		    }
			else if(bInVop==FALSE && *ppxlcAlpha!=transpValue)
		    {
				// end of stripe not right border 
				bInVop=TRUE;
				if(iLeftColour==invalidColour)
					iLeftColour=ppxlcTexture[iX];
				else
					iLeftColour=(iLeftColour+ppxlcTexture[iX]+1)>>1;
				
				// fill stripe 
				for(iJ=iLeftX;iJ<iX;iJ++)
					ppxlcTexture[iJ]=(PixelC)iLeftColour;
		    }
		}

        if(bInVop==FALSE)
		{
			// end of stripe at right border 
			if(iLeftX==0)
			{
				// blank stripe so mark
				m_pbEmptyRowArray[iY]=TRUE;
				bEmptyRow=TRUE;
			}
			else
	        {
				// fill trailing stripe 
	            for(iJ=iLeftX;iJ<iX;iJ++)
					ppxlcTexture[iJ]=(PixelC)iLeftColour;	      
	        }
 	    }
    }

	// fill remaining holes 
	if(bEmptyRow)
	{
		ppxlcTexture=ppxlcTextureBase;
		PixelC *ppxlcUpperRow = NULL;
		for(iY=0;iY<(CoordI)uiBlkSize;iY++,ppxlcTexture+=uiStride)
			if(!m_pbEmptyRowArray[iY])
				ppxlcUpperRow = ppxlcTexture;
			else
			{
				// empty row, find lower row
				PixelC *ppxlcLowerRow = ppxlcTexture+uiStride;
				CoordI iYY;
				for(iYY=iY+1;iYY<(CoordI)uiBlkSize;iYY++,ppxlcLowerRow+=uiStride)
					if(!m_pbEmptyRowArray[iYY])
						break;
				if(iYY<(CoordI)uiBlkSize)
				{
					if(ppxlcUpperRow==NULL)
					{
						// just lower row
						for(;ppxlcTexture<ppxlcLowerRow;ppxlcTexture+=uiStride)
							memcpy(ppxlcTexture,ppxlcLowerRow,uiBlkSize*iUnit);
					}
					else
					{
						// lower row, upper row
						for(;ppxlcTexture<ppxlcLowerRow;ppxlcTexture+=uiStride)
							for(iX=0;iX<(CoordI)uiBlkSize;iX++)
								ppxlcTexture[iX]=
									(ppxlcUpperRow[iX]+ppxlcLowerRow[iX]+1)>>1;
					}
				}
				else
				{
					// just upper row
					assert(ppxlcUpperRow!=NULL);
					for(iYY=iY;iYY<(CoordI)uiBlkSize;iYY++,ppxlcTexture+=uiStride)
						memcpy(ppxlcTexture,ppxlcUpperRow,uiBlkSize*iUnit);
				}
				iY=iYY-1;
				ppxlcTexture -= uiStride;
			}	
	}
}

Void CVideoObject::padNeighborTranspMBs (
	CoordI xb, CoordI yb,
	CMBMode* pmbmd,
	PixelC* ppxlcY, PixelC* ppxlcU, PixelC* ppxlcV, PixelC *ppxlcA
)
{
	if (xb > 0) {
		if ((pmbmd - 1)->m_rgTranspStatus [0] == ALL) {
			if (!((pmbmd - 1)->m_bPadded)) {
				mcPadLeftMB (ppxlcY, ppxlcU, ppxlcV, ppxlcA);
				(pmbmd - 1)->m_bPadded = TRUE;
			}
		}
	}
	if (yb > 0) {
		if ((pmbmd - m_iNumMBX)->m_rgTranspStatus [0] == ALL) {
			if (!((pmbmd - m_iNumMBX)->m_bPadded)) {
				mcPadTopMB (ppxlcY, ppxlcU, ppxlcV, ppxlcA);
				(pmbmd - m_iNumMBX)->m_bPadded = TRUE;
			}
		}
	}
}

Void CVideoObject::padCurrAndTopTranspMBFromNeighbor (
	CoordI xb, CoordI yb,
	CMBMode* pmbmd,
	PixelC* ppxlcY, PixelC* ppxlcU, PixelC* ppxlcV, PixelC* ppxlcA
)
{
	if (xb > 0) {
		if ((pmbmd - 1)->m_rgTranspStatus [0] != ALL) {
			mcPadCurrMBFromLeft (ppxlcY, ppxlcU, ppxlcV, ppxlcA);
			pmbmd->m_bPadded = TRUE;
		}
	}
	if (yb > 0) {
		if ((pmbmd - m_iNumMBX)->m_rgTranspStatus [0] != ALL) {
			if (!(pmbmd->m_bPadded)) {
				mcPadCurrMBFromTop (ppxlcY, ppxlcU, ppxlcV, ppxlcA);
				pmbmd->m_bPadded = TRUE;
			}
		}
		else
			if (!(pmbmd - m_iNumMBX)->m_bPadded)
				mcSetTopMBGray (ppxlcY, ppxlcU, ppxlcV, ppxlcA);
	}
	if(yb == m_iNumMBY-1)
	{
		if(xb > 0 && (pmbmd-1)->m_rgTranspStatus [0] == ALL && !((pmbmd-1)->m_bPadded))
			mcSetLeftMBGray(ppxlcY, ppxlcU, ppxlcV, ppxlcA);
		if(xb == m_iNumMBX-1 && !(pmbmd->m_bPadded))
			mcSetCurrMBGray(ppxlcY, ppxlcU, ppxlcV, ppxlcA);
	}
}


Void CVideoObject::mcPadLeftMB (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	UInt iy;
	for (iy = 0; iy < BLOCK_SIZE; iy++) {
		pxlcmemset (ppxlcMBY - MB_SIZE, *ppxlcMBY, MB_SIZE);
		pxlcmemset (ppxlcMBU - BLOCK_SIZE, *ppxlcMBU, BLOCK_SIZE);
		pxlcmemset (ppxlcMBV - BLOCK_SIZE, *ppxlcMBV, BLOCK_SIZE);
		ppxlcMBY += m_iFrameWidthY;
		ppxlcMBU += m_iFrameWidthUV;
		ppxlcMBV += m_iFrameWidthUV;
	
		pxlcmemset (ppxlcMBY - MB_SIZE, *ppxlcMBY, MB_SIZE);
		ppxlcMBY += m_iFrameWidthY;
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			pxlcmemset (ppxlcMBA - MB_SIZE, *ppxlcMBA, MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
			pxlcmemset (ppxlcMBA - MB_SIZE, *ppxlcMBA, MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
		}
}

Void CVideoObject::mcPadTopMB (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	UInt ix, iy;
	for (ix = 0; ix < MB_SIZE; ix++) {
		PixelC* ppxlcYCol = ppxlcMBY;
		for (iy = 0; iy < MB_SIZE; iy++) {
			ppxlcYCol -= m_iFrameWidthY;
			*ppxlcYCol = *ppxlcMBY;
		}
		ppxlcMBY++;
	}

	for (ix = 0; ix < BLOCK_SIZE; ix++) {
		PixelC* ppxlcUCol = ppxlcMBU;
		PixelC* ppxlcVCol = ppxlcMBV;
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			ppxlcUCol -= m_iFrameWidthUV;
			ppxlcVCol -= m_iFrameWidthUV;
			*ppxlcUCol = *ppxlcMBU;
			*ppxlcVCol = *ppxlcMBV;
		}
		ppxlcMBU++;
		ppxlcMBV++;
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (ix = 0; ix < MB_SIZE; ix++) {
			PixelC* ppxlcACol = ppxlcMBA;
			for (iy = 0; iy < MB_SIZE; iy++) {
				ppxlcACol -= m_iFrameWidthY;
				*ppxlcACol = *ppxlcMBA;
			}
			ppxlcMBA++;
		}
}

Void CVideoObject::mcPadCurrMBFromLeft (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	UInt iy;
	for (iy = 0; iy < BLOCK_SIZE; iy++) {
		pxlcmemset (ppxlcMBY, *(ppxlcMBY - 1), MB_SIZE);
		pxlcmemset (ppxlcMBU, *(ppxlcMBU - 1), BLOCK_SIZE);
		pxlcmemset (ppxlcMBV, *(ppxlcMBV - 1), BLOCK_SIZE);
		ppxlcMBY += m_iFrameWidthY;
		ppxlcMBU += m_iFrameWidthUV;
		ppxlcMBV += m_iFrameWidthUV;
	
		pxlcmemset (ppxlcMBY, *(ppxlcMBY - 1), MB_SIZE);
		ppxlcMBY += m_iFrameWidthY;
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			pxlcmemset (ppxlcMBA, *(ppxlcMBA - 1), MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
			pxlcmemset (ppxlcMBA, *(ppxlcMBA - 1), MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
		}
}

Void CVideoObject::mcPadCurrMBFromTop (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	UInt ix, iy;
	for (ix = 0; ix < MB_SIZE; ix++) {
		PixelC* ppxlcYCol = ppxlcMBY;
		PixelC pxlcY = *(ppxlcMBY - m_iFrameWidthY);
		for (iy = 0; iy < MB_SIZE; iy++) {
			*ppxlcYCol = pxlcY;
			ppxlcYCol += m_iFrameWidthY;
		}
		ppxlcMBY++;
	}

	for (ix = 0; ix < BLOCK_SIZE; ix++) {
		PixelC* ppxlcUCol = ppxlcMBU;
		PixelC* ppxlcVCol = ppxlcMBV;
		PixelC pxlcU = *(ppxlcMBU - m_iFrameWidthUV);
		PixelC pxlcV = *(ppxlcMBV - m_iFrameWidthUV);
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			*ppxlcUCol = pxlcU;
			*ppxlcVCol = pxlcV;
			ppxlcUCol += m_iFrameWidthUV;
			ppxlcVCol += m_iFrameWidthUV;
		}
		ppxlcMBU++;
		ppxlcMBV++;
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (ix = 0; ix < MB_SIZE; ix++) {
			PixelC* ppxlcACol = ppxlcMBA;
			PixelC pxlcA = *(ppxlcMBA - m_iFrameWidthY);
			for (iy = 0; iy < MB_SIZE; iy++) {
				*ppxlcACol = pxlcA;
				ppxlcACol += m_iFrameWidthY;
			}
			ppxlcMBA++;
		}
}

Void CVideoObject::mcSetTopMBGray (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	PixelC pxlcGrayVal = 128;
	if(m_volmd.bNot8Bit)
		pxlcGrayVal = 1<<(m_volmd.nBits-1);

	UInt iy;
	for (iy = 0; iy < BLOCK_SIZE; iy++) {
		ppxlcMBY -= m_iFrameWidthY;
		ppxlcMBU -= m_iFrameWidthUV;
		ppxlcMBV -= m_iFrameWidthUV;
		pxlcmemset (ppxlcMBY, pxlcGrayVal, MB_SIZE);
		pxlcmemset (ppxlcMBU, pxlcGrayVal, BLOCK_SIZE);
		pxlcmemset (ppxlcMBV, pxlcGrayVal, BLOCK_SIZE);

		ppxlcMBY -= m_iFrameWidthY;
		pxlcmemset (ppxlcMBY, pxlcGrayVal, MB_SIZE);
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			ppxlcMBA -= m_iFrameWidthY;
			pxlcmemset (ppxlcMBA, pxlcGrayVal, MB_SIZE);
			ppxlcMBA -= m_iFrameWidthY;
			pxlcmemset (ppxlcMBA, pxlcGrayVal, MB_SIZE);
		}
}

Void CVideoObject::mcSetLeftMBGray (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	mcSetCurrMBGray(
		ppxlcMBY-MB_SIZE,
		ppxlcMBU-BLOCK_SIZE,
		ppxlcMBV-BLOCK_SIZE,
		(m_volmd.fAUsage == EIGHT_BIT) ? ppxlcMBA-MB_SIZE : (PixelC *)NULL
	);
}

Void CVideoObject::mcSetCurrMBGray (PixelC* ppxlcMBY, PixelC* ppxlcMBU, PixelC* ppxlcMBV, PixelC* ppxlcMBA)
{
	PixelC pxlcGrayVal = 128;
	if(m_volmd.bNot8Bit)
		pxlcGrayVal = 1<<(m_volmd.nBits-1);
	UInt iy;
	for (iy = 0; iy < BLOCK_SIZE; iy++) {
		pxlcmemset (ppxlcMBY, pxlcGrayVal, MB_SIZE);
		pxlcmemset (ppxlcMBU, pxlcGrayVal, BLOCK_SIZE);
		pxlcmemset (ppxlcMBV, pxlcGrayVal, BLOCK_SIZE);
		ppxlcMBY += m_iFrameWidthY;
		ppxlcMBU += m_iFrameWidthUV;
		ppxlcMBV += m_iFrameWidthUV;

		pxlcmemset (ppxlcMBY, pxlcGrayVal, MB_SIZE);
		ppxlcMBY += m_iFrameWidthY;
	}
	if(m_volmd.fAUsage == EIGHT_BIT)
		for (iy = 0; iy < BLOCK_SIZE; iy++) {
			pxlcmemset (ppxlcMBA, pxlcGrayVal, MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
			pxlcmemset (ppxlcMBA, pxlcGrayVal, MB_SIZE);
			ppxlcMBA += m_iFrameWidthY;
		}
}

// Added for field based MC padding by Hyundai(1998-5-9)

Void CVideoObject::fieldBasedMCPadding (CMBMode* pmbmd, CVOPU8YUVBA* pvopcCurrQ)
{
        Int     iMBX, iMBY;

        PixelC* ppxlcCurrY  = (PixelC*) pvopcCurrQ->pixelsY () + m_iStartInRefToCurrRctY;
        PixelC* ppxlcCurrU  = (PixelC*) pvopcCurrQ->pixelsU () + m_iStartInRefToCurrRctUV;
        PixelC* ppxlcCurrV  = (PixelC*) pvopcCurrQ->pixelsV () + m_iStartInRefToCurrRctUV;

⌨️ 快捷键说明

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