📄 mb.cpp
字号:
/*************************************************************************This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation Bruce Lin (blin@microsoft.com), Microsoft Corporation Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation (date: March, 1996)and edited by Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerin 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 cany, 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 standard> conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1996, 1997.Module Name: MB.hppAbstract: MacroBlock base class Revision History: May. 9 1998: add chroma subsampling and field based MC padding by Hyundai Electronics Cheol-Soo Park (cspark@super5.hyundai.co.kr)*************************************************************************/#include <stdio.h>#include "typeapi.h"#include "codehead.h"#include "mode.hpp"#include "dct.hpp"#include "vopses.hpp"#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_Void CVideoObject::decideTransparencyStatus (CMBMode* pmbmd, const PixelC* ppxlcMBBY){ const PixelC* ppxlcBlkBY1 = ppxlcMBBY; const PixelC* ppxlcBlkBY2 = ppxlcMBBY + BLOCK_SIZE; const PixelC* ppxlcBlkBY3 = ppxlcMBBY + MB_SIZE * BLOCK_SIZE; const PixelC* ppxlcBlkBY4 = ppxlcMBBY + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;// const PixelC* ppxlcBlkBUV = m_ppxlcCurrMBBUV; UInt uiNonTransPixels1 = 0, uiNonTransPixels2 = 0; UInt uiNonTransPixels3 = 0, uiNonTransPixels4 = 0;// UInt uiNonTransPixelsUV = 0; CoordI ix, iy; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix = 0; ix < BLOCK_SIZE; ix++) { uiNonTransPixels1 += ppxlcBlkBY1 [ix]; uiNonTransPixels2 += ppxlcBlkBY2 [ix]; uiNonTransPixels3 += ppxlcBlkBY3 [ix]; uiNonTransPixels4 += ppxlcBlkBY4 [ix];// uiNonTransPixelsUV += ppxlcBlkBUV [ix]; } ppxlcBlkBY1 += MB_SIZE; ppxlcBlkBY2 += MB_SIZE; ppxlcBlkBY3 += MB_SIZE; ppxlcBlkBY4 += MB_SIZE;// ppxlcBlkBUV += BLOCK_SIZE; } uiNonTransPixels1 /= opaqueValue; uiNonTransPixels2 /= opaqueValue; uiNonTransPixels3 /= opaqueValue; uiNonTransPixels4 /= opaqueValue;// uiNonTransPixelsUV /= opaqueValue; pmbmd->m_rgNumNonTranspPixels [0] = uiNonTransPixels1 + uiNonTransPixels2 + uiNonTransPixels3 + uiNonTransPixels4; pmbmd->m_rgNumNonTranspPixels [1] = uiNonTransPixels1; pmbmd->m_rgNumNonTranspPixels [2] = uiNonTransPixels2; pmbmd->m_rgNumNonTranspPixels [3] = uiNonTransPixels3; pmbmd->m_rgNumNonTranspPixels [4] = uiNonTransPixels4;// pmbmd->m_rgNumNonTranspPixels [5] = uiNonTransPixelsUV; if (pmbmd->m_rgNumNonTranspPixels [0] == 0) { pmbmd->m_rgTranspStatus [0] = ALL; pmbmd->m_dctMd = INTER; } else if (pmbmd->m_rgNumNonTranspPixels [0] == MB_SQUARE_SIZE) pmbmd -> m_rgTranspStatus [0] = NONE; else pmbmd -> m_rgTranspStatus [0] = PARTIAL;// for (ix = (UInt) Y_BLOCK1; ix <= (UInt) U_BLOCK; ix++) { for (ix = (UInt) Y_BLOCK1; ix < U_BLOCK; ix++) { if (pmbmd -> m_rgNumNonTranspPixels [ix] == 0) pmbmd -> m_rgTranspStatus [ix] = ALL; else if (pmbmd -> m_rgNumNonTranspPixels [ix] == BLOCK_SQUARE_SIZE) pmbmd -> m_rgTranspStatus [ix] = NONE; else pmbmd -> m_rgTranspStatus [ix] = PARTIAL; }//pmbmd->m_rgTranspStatus [V_BLOCK] = pmbmd->m_rgTranspStatus [U_BLOCK];pmbmd->m_rgTranspStatus [V_BLOCK] = pmbmd->m_rgTranspStatus [U_BLOCK] = pmbmd -> m_rgTranspStatus [0];}Void CVideoObject::decideMBTransparencyStatus (CMBMode* pmbmd){ UInt uiNonTransPixels0 = 0; UInt ix; for (ix = 0; ix < MB_SQUARE_SIZE; ix++) uiNonTransPixels0 += m_ppxlcCurrMBBY [ix]; uiNonTransPixels0 /= opaqueValue; pmbmd -> m_rgNumNonTranspPixels [0] = uiNonTransPixels0; if (uiNonTransPixels0 == 0) { pmbmd -> m_rgTranspStatus [0] = ALL; pmbmd -> m_dctMd = INTER; } else if (uiNonTransPixels0 == MB_SQUARE_SIZE) pmbmd -> m_rgTranspStatus [0] = NONE; else pmbmd -> m_rgTranspStatus [0] = PARTIAL;}// Added for Field Based MC Padding by Hyundai(1998-5-9)Void CVideoObject::decideFieldTransparencyStatus ( CMBMode* pmbmd, const PixelC* ppxlcMBBY, const PixelC* ppxlcMBBUV){ Int *piNonTransPixels = new Int [5]; Int iYFieldSkip = 2*m_iFrameWidthY; Int iCFieldSkip = 2*m_iFrameWidthUV; CoordI ix, iy; // for field based mc-padding memset (piNonTransPixels, 0, sizeof(Int)*5); const PixelC* ppxlcTopFieldBY = ppxlcMBBY; const PixelC* ppxlcBotFieldBY = ppxlcMBBY + m_iFrameWidthY; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix = 0; ix < MB_SIZE; ix++) { piNonTransPixels[1] += ppxlcTopFieldBY [ix]; piNonTransPixels[2] += ppxlcBotFieldBY [ix]; } ppxlcTopFieldBY += iYFieldSkip; ppxlcBotFieldBY += iYFieldSkip; } piNonTransPixels[1] /= opaqueValue; piNonTransPixels[2] /= opaqueValue; for (ix=1; ix<=2; ix++) { if (piNonTransPixels [ix] == 0) pmbmd-> m_rgFieldTranspStatus [ix] = ALL; else if (piNonTransPixels [ix] == MB_SQUARE_SIZE/2) pmbmd -> m_rgFieldTranspStatus [ix] = NONE; else pmbmd -> m_rgFieldTranspStatus [ix] = PARTIAL; } ppxlcTopFieldBY = ppxlcMBBUV; ppxlcBotFieldBY = ppxlcMBBUV + m_iFrameWidthUV; for (iy = 0; iy < BLOCK_SIZE/2; iy++) { for (ix = 0; ix < BLOCK_SIZE; ix++) { piNonTransPixels[3] += ppxlcTopFieldBY [ix]; piNonTransPixels[4] += ppxlcBotFieldBY [ix]; } ppxlcTopFieldBY += iCFieldSkip; ppxlcBotFieldBY += iCFieldSkip; } piNonTransPixels[3] /= opaqueValue; piNonTransPixels[4] /= opaqueValue; for (ix=3; ix<=4; ix++) { if (piNonTransPixels [ix] == 0) pmbmd-> m_rgFieldTranspStatus [ix] = ALL; else if (piNonTransPixels [ix] == BLOCK_SQUARE_SIZE/2) pmbmd -> m_rgFieldTranspStatus [ix] = NONE; else pmbmd -> m_rgFieldTranspStatus [ix] = PARTIAL; } delete piNonTransPixels;}Void CVideoObject::fieldBasedDownSampleBY ( const PixelC* ppxlcMBBY, PixelC* ppxlcMBBUV){ UInt ix, iy, x, iFieldSkip = 4*m_iFrameWidthY; const PixelC* ppxlcTopFieldBY = ppxlcMBBY; const PixelC* ppxlcBotFieldBY = ppxlcMBBY + m_iFrameWidthY; const PixelC* ppxlcTopFieldBYNext = ppxlcTopFieldBY + 2*m_iFrameWidthY; const PixelC* ppxlcBotFieldBYNext = ppxlcBotFieldBY + 2*m_iFrameWidthY; for (iy = 0; iy < BLOCK_SIZE/2; iy++) { for (ix = 0, x = 0; ix < BLOCK_SIZE; ix++, x = 2*ix) ppxlcMBBUV [ix] = (ppxlcTopFieldBY [x] | ppxlcTopFieldBY [x+1] | ppxlcTopFieldBYNext [x] | ppxlcTopFieldBYNext [x+1]); ppxlcMBBUV += m_iFrameWidthUV; for (ix = 0, x = 0; ix < BLOCK_SIZE; ix++, x = 2*ix) ppxlcMBBUV [ix] = (ppxlcBotFieldBY [x] | ppxlcBotFieldBY [x+1] | ppxlcBotFieldBYNext [x] | ppxlcBotFieldBYNext [x+1]); ppxlcMBBUV += m_iFrameWidthUV; ppxlcTopFieldBY += iFieldSkip; ppxlcBotFieldBY += iFieldSkip; ppxlcTopFieldBYNext += iFieldSkip; ppxlcBotFieldBYNext += iFieldSkip; }}// End of Hyundai(1998-5-9)Void CVideoObject::downSampleBY (const PixelC* ppxlcMBBY, PixelC* ppxlcMBBUV){ const PixelC* ppxlcMBBYNextRow = ppxlcMBBY + MB_SIZE; UInt ix, iy; // Added for Chroma Subsampling by Hyundai(1998-5-9) if (m_vopmd.bInterlace) { UInt x, iFieldSkip = 4*MB_SIZE; const PixelC* ppxlcTopFieldBY = ppxlcMBBY; const PixelC* ppxlcBotFieldBY = ppxlcMBBY + MB_SIZE; const PixelC* ppxlcTopFieldBYNext = ppxlcTopFieldBY + 2*MB_SIZE; const PixelC* ppxlcBotFieldBYNext = ppxlcBotFieldBY + 2*MB_SIZE; for (iy = 0; iy < BLOCK_SIZE/2; iy++) { for (ix = 0, x = 0; ix < BLOCK_SIZE; ix++, x = 2*ix) ppxlcMBBUV [ix] = (ppxlcTopFieldBY [x] | ppxlcTopFieldBY [x+1] | ppxlcTopFieldBYNext [x] | ppxlcTopFieldBYNext [x+1]); ppxlcMBBUV += BLOCK_SIZE; for (ix = 0, x = 0; ix < BLOCK_SIZE; ix++, x = 2*ix) ppxlcMBBUV [ix] = (ppxlcBotFieldBY [x] | ppxlcBotFieldBY [x+1] | ppxlcBotFieldBYNext [x] | ppxlcBotFieldBYNext [x+1]); ppxlcMBBUV += BLOCK_SIZE; ppxlcTopFieldBY += iFieldSkip; ppxlcBotFieldBY += iFieldSkip; ppxlcTopFieldBYNext += iFieldSkip; ppxlcBotFieldBYNext += iFieldSkip; } return; } // End of Hyundai(1998-5-9) for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix = 0; ix < BLOCK_SIZE; ix++) { ppxlcMBBUV [ix] = ( (ppxlcMBBY [2 * ix] | ppxlcMBBY [2 * ix + 1]) | (ppxlcMBBYNextRow [2 * ix] | ppxlcMBBYNextRow [2 * ix + 1]) ); } ppxlcMBBUV += BLOCK_SIZE; ppxlcMBBY += 2 * MB_SIZE; ppxlcMBBYNextRow += 2 * MB_SIZE; }}Void CVideoObject::addErrorAndPredToCurrQ ( PixelC* ppxlcQMBY, PixelC* ppxlcQMBU, PixelC* ppxlcQMBV){ CoordI ix, iy, ic = 0; for (iy = 0; iy < MB_SIZE; iy++) { for (ix = 0; ix < MB_SIZE; ix++, ic++) { ppxlcQMBY [ix] = m_rgiClipTab [m_ppxlcPredMBY [ic] + m_ppxliErrorMBY [ic]]; } ppxlcQMBY += m_iFrameWidthY; } ic = 0; for (iy = 0; iy < BLOCK_SIZE; iy++) { for (ix = 0; ix < BLOCK_SIZE; ix++, ic++) { ppxlcQMBU [ix] = m_rgiClipTab [m_ppxlcPredMBU [ic] + m_ppxliErrorMBU [ic]]; ppxlcQMBV [ix] = m_rgiClipTab [m_ppxlcPredMBV [ic] + m_ppxliErrorMBV [ic]]; } ppxlcQMBU += m_iFrameWidthUV; ppxlcQMBV += m_iFrameWidthUV; }}Void CVideoObject::addAlphaErrorAndPredToCurrQ (PixelC* ppxlcQMBA){ CoordI ix, iy, ic = 0; for (iy = 0; iy < MB_SIZE; iy++) { for (ix = 0; ix < MB_SIZE; ix++, ic++) ppxlcQMBA [ix] = m_rgiClipTab [m_ppxlcPredMBA [ic] + m_ppxliErrorMBA [ic]]; ppxlcQMBA += m_iFrameWidthY; }}Void CVideoObject::assignPredToCurrQ ( PixelC* ppxlcQMBY, PixelC* ppxlcQMBU, PixelC* ppxlcQMBV){ CoordI ix; const PixelC* ppxlcPredMBY = m_ppxlcPredMBY; const PixelC* ppxlcPredMBU = m_ppxlcPredMBU; const PixelC* ppxlcPredMBV = m_ppxlcPredMBV; for (ix = 0; ix < BLOCK_SIZE; ix++) { memcpy (ppxlcQMBY, ppxlcPredMBY, MB_SIZE*sizeof(PixelC)); memcpy (ppxlcQMBU, ppxlcPredMBU, BLOCK_SIZE*sizeof(PixelC)); memcpy (ppxlcQMBV, ppxlcPredMBV, BLOCK_SIZE*sizeof(PixelC)); ppxlcPredMBY += MB_SIZE; ppxlcPredMBU += BLOCK_SIZE; ppxlcPredMBV += BLOCK_SIZE; ppxlcQMBY += m_iFrameWidthY; ppxlcQMBU += m_iFrameWidthUV; ppxlcQMBV += m_iFrameWidthUV; memcpy (ppxlcQMBY, ppxlcPredMBY, MB_SIZE*sizeof(PixelC)); ppxlcPredMBY += MB_SIZE; ppxlcQMBY += m_iFrameWidthY; }}Void CVideoObject::assignAlphaPredToCurrQ (PixelC* ppxlcQMBA){ CoordI ix; const PixelC* ppxlcPredMBA = m_ppxlcPredMBA; for (ix = 0; ix < MB_SIZE; ix++) { memcpy (ppxlcQMBA, ppxlcPredMBA, MB_SIZE*sizeof(PixelC)); ppxlcPredMBA += MB_SIZE; ppxlcQMBA += m_iFrameWidthY; }}Void CVideoObject::findColocatedMB (Int iMBX, Int iMBY, const CMBMode*& pmbmdRef, const CMotionVector*& pmvRef){ Bool bColocatedMBExist = FALSE; if(m_bCodedFutureRef!=FALSE) if(iMBX<m_iNumMBXRef && iMBX>=0 && iMBY<m_iNumMBYRef && iMBY>=0) { pmbmdRef = &m_rgmbmdRef [iMBX + iMBY * m_iNumMBXRef]; if(pmbmdRef -> m_rgTranspStatus [0] != ALL) { Int iOffset = min (max (0, iMBX), m_iNumMBXRef - 1) + min (max (0, iMBY), m_iNumMBYRef - 1) * m_iNumMBXRef; pmvRef = m_rgmvRef + iOffset * PVOP_MV_PER_REF_PER_MB; bColocatedMBExist = TRUE; } } if(bColocatedMBExist==FALSE) { pmbmdRef = NULL; pmvRef = NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -