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

📄 mc.cpp

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

This software module was originally developed by 

	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
	Bruce Lin (blin@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 standard> conforming products. 
This copyright notice must be included in all copies or derivative works. 

Copyright (c) 1996, 1997.

Module Name:

	mc.cpp

Abstract:

	Motion compensation routines (common for encoder and decoder).

Revision History:
    December 20, 1997   Interlaced tools added by NextLevel Systems (GI)
                        X. Chen (xchen@nlvl.com) B. Eifrig (beifrig@nlvl.com)
`
*************************************************************************/

#include <stdio.h>

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

#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW				   
#endif // __MFC_

Void CVideoObject::limitMVRangeToExtendedBBFullPel (CoordI &x,CoordI &y,CRct *prct,Int iBlkSize)
{
	if(prct==NULL)
		return;

	if(x < prct->left)
		x=prct->left;
	else if(x > (prct->right-iBlkSize))
		x=(prct->right-iBlkSize);
	if(y < prct->top)
		y=prct->top;
	else if(y > (prct->bottom-iBlkSize))
		y=(prct->bottom-iBlkSize);
}

Void CVideoObject::limitMVRangeToExtendedBBHalfPel (CoordI &x,CoordI &y,CRct *prct,Int iBlkSize)
{
	if(prct==NULL)
		return;

	if(x < prct->left*2)
		x=prct->left*2;
	else if(x > (prct->right-iBlkSize)*2)
		x=(prct->right-iBlkSize)*2;
	if(y < prct->top*2)
		y=prct->top*2;
	else if(y > (prct->bottom-iBlkSize)*2)
		y=(prct->bottom-iBlkSize)*2;
}

Void CVideoObject::motionCompMB (
	PixelC* ppxlcPredMB,
	const PixelC* ppxlcRefLeftTop,
	const CMotionVector* pmv, const CMBMode* pmbmd, 
	Int imbX, Int imbY,
	CoordI x, CoordI y,
	Bool bSkipNonOBMC,
	Bool bAlphaMB,
	CRct *prctMVLimit
)
{
	if (!bAlphaMB && !m_volmd.bAdvPredDisable && !pmbmd->m_bFieldMV) {
		motionCompOverLap (
			ppxlcPredMB, ppxlcRefLeftTop,
			pmv, pmbmd,
			imbX, imbY,
			x, y,
			prctMVLimit
		);
	}
	else {
		if (bSkipNonOBMC)
			return;
		if (!pmbmd -> m_bhas4MVForward && !pmbmd -> m_bFieldMV)
			motionComp (
				ppxlcPredMB, ppxlcRefLeftTop,
				MB_SIZE, 
				x * 2 + pmv->trueMVHalfPel ().x, 
				y * 2 + pmv->trueMVHalfPel ().y ,
				m_vopmd.iRoundingControl,
				prctMVLimit
			);
		else if (pmbmd -> m_bFieldMV) {
			const CMotionVector* pmv16x8 = pmv+5;
			if(pmbmd->m_bForwardTop) {
				pmv16x8++;
				motionCompYField (
					ppxlcPredMB,
					ppxlcRefLeftTop+m_iFrameWidthY,
					x * 2 + pmv16x8->trueMVHalfPel ().x, 
					y * 2 + pmv16x8->trueMVHalfPel ().y 
				);
				pmv16x8++;
			}
			else {
				motionCompYField (
					ppxlcPredMB,
					ppxlcRefLeftTop,
					x * 2 + pmv16x8->trueMVHalfPel ().x, 
					y * 2 + pmv16x8->trueMVHalfPel ().y 
				);
				pmv16x8++;
				pmv16x8++;
			}
			if(pmbmd->m_bForwardBottom) {
				pmv16x8++;
				motionCompYField (
					ppxlcPredMB+MB_SIZE,
					ppxlcRefLeftTop+m_iFrameWidthY,
					x * 2 + pmv16x8->trueMVHalfPel ().x, 
					y * 2 + pmv16x8->trueMVHalfPel ().y 
				);
			}
			else {
				motionCompYField (
					ppxlcPredMB+MB_SIZE,
					ppxlcRefLeftTop,
					x * 2 + pmv16x8->trueMVHalfPel ().x, 
					y * 2 + pmv16x8->trueMVHalfPel ().y 
				);
			}
		}
		else {
			const CMotionVector* pmv8 = pmv;
			pmv8++;
			CoordI blkX = x + BLOCK_SIZE;
			CoordI blkY = y + BLOCK_SIZE;
			if (pmbmd->m_rgTranspStatus [Y_BLOCK1] != ALL)
				motionComp (
					ppxlcPredMB, ppxlcRefLeftTop,
					BLOCK_SIZE, 
					x * 2 + pmv8->trueMVHalfPel ().x, 
					y * 2 + pmv8->trueMVHalfPel ().y,
					m_vopmd.iRoundingControl,
					prctMVLimit
				);
			pmv8++;
			if (pmbmd->m_rgTranspStatus [Y_BLOCK2] != ALL)
				motionComp (
					ppxlcPredMB + OFFSET_BLK1, ppxlcRefLeftTop,
					BLOCK_SIZE, 
					blkX * 2 + pmv8->trueMVHalfPel ().x, 
					y * 2 + pmv8->trueMVHalfPel ().y,
					m_vopmd.iRoundingControl,
					prctMVLimit
				);
			pmv8++;
			if (pmbmd->m_rgTranspStatus [Y_BLOCK3] != ALL)
				motionComp (
					ppxlcPredMB + OFFSET_BLK2, ppxlcRefLeftTop,
					BLOCK_SIZE, 
					x * 2 + pmv8->trueMVHalfPel ().x, 
					blkY * 2 + pmv8->trueMVHalfPel ().y,
					m_vopmd.iRoundingControl,
					prctMVLimit
				);
			pmv8++;
			if (pmbmd->m_rgTranspStatus [Y_BLOCK4] != ALL)
				motionComp (
					ppxlcPredMB + OFFSET_BLK3, ppxlcRefLeftTop,
					BLOCK_SIZE, 
					blkX * 2 + pmv8->trueMVHalfPel ().x, 
					blkY * 2 + pmv8->trueMVHalfPel ().y,
					m_vopmd.iRoundingControl,
					prctMVLimit
				);
		}
	}
}

Void CVideoObject::motionComp (
	PixelC* ppxlcPred, // can be either Y or A
	const PixelC* ppxlcRefLeftTop, // point to left-top of the frame
	Int iSize, // either MB or BLOCK size
	CoordI xRef, CoordI yRef, // x + mvX, in half pel unit
	Int iRoundingControl,
	CRct *prctMVLimit // extended bounding box
)
{
	CoordI ix, iy;

	limitMVRangeToExtendedBBHalfPel(xRef,yRef,prctMVLimit,iSize);

	const PixelC* ppxlcRef = 
		ppxlcRefLeftTop + 
		((yRef >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRef >> 1) + EXPANDY_REF_FRAME;

	if(iSize==8 || iSize==16)
	{
		// optimisation
		if (!(yRef & 1)) {
			if (!(xRef & 1)) {
				Int iSz = iSize * sizeof(PixelC);
				for(iy = 0; iy < iSize; iy+=8)
				{
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
					memcpy (ppxlcPred, ppxlcRef, iSz);
					ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
				}
			}
			else {
				PixelC pxlcT1,pxlcT2, *ppxlcDst;
				const PixelC *ppxlcSrc;
				Int iRndCtrl = 1 - iRoundingControl;
				for (iy = 0; iy < iSize; iy++){
					ppxlcDst = ppxlcPred;
					ppxlcSrc = ppxlcRef;
					for (ix = 0; ix < iSize; ix+=8) {
						ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + iRndCtrl) >> 1;
						ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + iRndCtrl) >> 1;
						ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + iRndCtrl) >> 1;
						ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + iRndCtrl) >> 1;
						ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + iRndCtrl) >> 1;
						ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + iRndCtrl) >> 1;
						ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + iRndCtrl) >> 1;
						ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + iRndCtrl) >> 1;
						ppxlcDst += 8;
						ppxlcSrc += 8;
					}
					ppxlcRef += m_iFrameWidthY;
					ppxlcPred += MB_SIZE;
				}
			}
		}
		else {
			if (!(xRef & 1)) {
				Int iRndCtrl = 1 - iRoundingControl;
				const PixelC *ppxlcSrc, *ppxlcSrc2;
				PixelC *ppxlcDst;
				for (iy = 0; iy < iSize; iy++) {
					ppxlcDst = ppxlcPred;
					ppxlcSrc = ppxlcRef;
					ppxlcSrc2 = ppxlcRef + m_iFrameWidthY;
					for (ix = 0; ix < iSize; ix+=8) {
						ppxlcDst [0] = (ppxlcSrc [0] + ppxlcSrc2 [0] + iRndCtrl) >> 1;
						ppxlcDst [1] = (ppxlcSrc [1] + ppxlcSrc2 [1] + iRndCtrl) >> 1;
						ppxlcDst [2] = (ppxlcSrc [2] + ppxlcSrc2 [2] + iRndCtrl) >> 1;
						ppxlcDst [3] = (ppxlcSrc [3] + ppxlcSrc2 [3] + iRndCtrl) >> 1;
						ppxlcDst [4] = (ppxlcSrc [4] + ppxlcSrc2 [4] + iRndCtrl) >> 1;
						ppxlcDst [5] = (ppxlcSrc [5] + ppxlcSrc2 [5] + iRndCtrl) >> 1;
						ppxlcDst [6] = (ppxlcSrc [6] + ppxlcSrc2 [6] + iRndCtrl) >> 1;
						ppxlcDst [7] = (ppxlcSrc [7] + ppxlcSrc2 [7] + iRndCtrl) >> 1;
						ppxlcDst += 8;
						ppxlcSrc += 8;
						ppxlcSrc2 += 8;
					}
					ppxlcRef += m_iFrameWidthY;
					ppxlcPred += MB_SIZE;
				}
			}
			else {
				Int iRndCtrl = 2 - iRoundingControl;
				PixelC pxlcT1, pxlcT2, pxlcT3, pxlcT4, *ppxlcDst;
				const PixelC *ppxlcSrc, *ppxlcSrc2;
				for (iy = 0; iy < iSize; iy++) {
					ppxlcDst = ppxlcPred;
					ppxlcSrc = ppxlcRef;
					ppxlcSrc2 = ppxlcRef + m_iFrameWidthY;
					for (ix = 0; ix < iSize; ix+=8) {
						ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + ppxlcSrc2[0] + (pxlcT3=ppxlcSrc2[1]) + iRndCtrl) >> 2;
						ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + pxlcT3 + (pxlcT4=ppxlcSrc2[2]) + iRndCtrl) >> 2;
						ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + pxlcT4 + (pxlcT3=ppxlcSrc2[3]) + iRndCtrl) >> 2;
						ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + pxlcT3 + (pxlcT4=ppxlcSrc2[4]) + iRndCtrl) >> 2;
						ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + pxlcT4 + (pxlcT3=ppxlcSrc2[5]) + iRndCtrl) >> 2;
						ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + pxlcT3 + (pxlcT4=ppxlcSrc2[6]) + iRndCtrl) >> 2;
						ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + pxlcT4 + (pxlcT3=ppxlcSrc2[7]) + iRndCtrl) >> 2;
						ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + pxlcT3 + ppxlcSrc2[8] + iRndCtrl) >> 2;
						ppxlcDst += 8;
						ppxlcSrc += 8;
						ppxlcSrc2 += 8;
					}
					ppxlcRef += m_iFrameWidthY;
					ppxlcPred += MB_SIZE;
				}
			}
		}
	}
	else {
		if (!(yRef & 1)) {
			if (!(xRef & 1)) {  //!bXSubPxl && !bYSubPxl
				for (iy = 0; iy < iSize; iy++) {
					memcpy (ppxlcPred, ppxlcRef, iSize*sizeof(PixelC));
					ppxlcRef += m_iFrameWidthY;
					ppxlcPred += MB_SIZE;
				}
			}
			else {  //bXSubPxl && !bYSubPxl
				for (iy = 0; iy < iSize; iy++){
					for (ix = 0; ix < iSize; ix++)
						ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRef [ix + 1] + 1 - iRoundingControl) >> 1;
					ppxlcRef += m_iFrameWidthY;
					ppxlcPred += MB_SIZE;
				}
			}
		}
		else {
			const PixelC* ppxlcRefBot;
			if (!(xRef & 1)) {  //!bXSubPxl&& bYSubPxl
				for (iy = 0; iy < iSize; iy++) {

⌨️ 快捷键说明

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