📄 mcpad.cpp
字号:
/*************************************************************************
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 + -