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

📄 mb.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 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 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 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.hpp

Abstract:

	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_FILE
static 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 + -