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

📄 mvdec.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
字号:
/*************************************************************************This software module was originally developed by 	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation	(date: July, 1997)and edited by Xuemin Chen (xchen@gi.com), General Instrument Corp.and also edited by    Mathias Wien (wien@ient.rwth-aachen.de) RWTH Aachen / Robert BOSCH GmbHand also edited by    Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)    Sehoon Son (shson@unitel.co.kr) Samsung AITin 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:	mvdec.cAbstract:	motion vector decoderRevision History:	Dec 20, 1997:	Interlaced tools added by General Instrument Corp.    Feb.16, 1999:   add Quarter Sample                     Mathias Wien (wien@ient.rwth-aachen.de) 	Sep.06	1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) *************************************************************************/#include "typeapi.h"#include "codehead.h"#include "mode.h"#include "global.h"#ifdef UNDER_CE#include "bitstrm.h"#include "huffman.h"#else#include "entropy/bitstrm.h"#include "entropy/huffman.h"#endif#include "vopses.h"#include "vopsedec.h"INLINE Void getDiffMV (CVector *, MVInfo);INLINE Int  deScaleMV (Int, Int, Int);INLINE Void fitMvInRange (CVector*, MVInfo);INLINE Void computeDirectForwardMV (CVector, CMotionVector*, CMotionVector*, CMBMode*);INLINE Void decodeMV (CMBMode* pmbmd, CMotionVector* pmv, Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry, Bool bZeroMV, Int iMBX, Int iMBY){#ifdef ENABLE_INTERLACING  CVector vctDecode;#endif  CVector vctDiff, vctPred;  Int iBlk, i;  if (pmbmd->m_bSkip || pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ || bZeroMV)	  {		memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));		return;	}	if (pmbmd->m_bhas4MVForward)   	{		for (iBlk = Y_BLOCK1; iBlk < U_BLOCK; iBlk++)      	{			if (bLeftBndry || bRightBndry || bTopBndry)                if(!main_short_video_header)					findMVpredGeneric (&vctPred, pmv, pmbmd, iBlk, iMBX, iMBY);                else                    find8x8MVpredAtBoundary(&vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry, iBlk);			else 				find8x8MVpredInterior (&vctPred, pmv, iBlk);			getDiffMV (&vctDiff, g_pVOP->mvInfoForward);            ADD_VECT (vctDiff, vctPred);			fitMvInRange ((&g_CAddVect), g_pVOP->mvInfoForward);            CMOTIONVECTOR_INIT1((&pmv[iBlk]), g_CAddVect);		}	}#ifdef ENABLE_INTERLACING// INTERLACE	else if ((m_vopmd.bInterlace)&&(pmbmd->m_bFieldMV))	{		Int iTempX1, iTempY1, iTempX2, iTempY2;		find16x16MVpred (&vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry);		getDiffMV (&vctDiff, m_vopmd.mvInfoForward);		vctDiff.y *= 2;		vctPred.y = 2*(vctPred.y / 2);		vctDecode = vctDiff + vctPred;																//fit in range		fitMvInRange ((&vctDecode), m_vopmd.mvInfoForward);		CMotionVector* pmv16x8 = pmv +5;		if(pmbmd->m_bForwardTop) {			pmv16x8++;			*pmv16x8 = CMotionVector (vctDecode);		//convert to full pel now			iTempX1 = pmv16x8->m_vctTrueHalfPel.x;			iTempY1 = pmv16x8->m_vctTrueHalfPel.y;			pmv16x8++;		} 		else		{			*pmv16x8 = CMotionVector (vctDecode);		//convert to full pel now			iTempX1 = pmv16x8->m_vctTrueHalfPel.x;			iTempY1 = pmv16x8->m_vctTrueHalfPel.y;			pmv16x8++;			pmv16x8++;		}		getDiffMV (&vctDiff, m_vopmd.mvInfoForward);		vctDiff.y *= 2;		vctPred.y = 2*(vctPred.y / 2);		vctDecode = vctDiff + vctPred;																//fit in range		fitMvInRange ((&vctDecode), m_vopmd.mvInfoForward);		if(pmbmd->m_bForwardBottom) {			pmv16x8++;			*pmv16x8 = CMotionVector (vctDecode);		//convert to full pel now			iTempX2 = pmv16x8->m_vctTrueHalfPel.x;			iTempY2 = pmv16x8->m_vctTrueHalfPel.y;		}		else		{			*pmv16x8 = CMotionVector (vctDecode);		//convert to full pel now			iTempX2 = pmv16x8->m_vctTrueHalfPel.x;			iTempY2 = pmv16x8->m_vctTrueHalfPel.y;		}		Int iTemp;		for (UInt i = 1; i < 5; i++) {			iTemp = iTempX1 + iTempX2;			pmv [i].m_vctTrueHalfPel.x = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);			iTemp = iTempY1 + iTempY2;			pmv [i].m_vctTrueHalfPel.y = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);			pmv [i] = pmv [i].m_vctTrueHalfPel;        //convert to full pel now //added mwi            pmv[i].computeMV (); 		}	}// ~INTERLACE#endif	else // 1 mv    {        if(!main_short_video_header)			findMVpredGeneric (&vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);        else            find16x16MVpred(&vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry);		getDiffMV (&vctDiff, g_pVOP->mvInfoForward);        ADD_VECT (vctDiff, vctPred);		fitMvInRange ((&g_CAddVect), g_pVOP->mvInfoForward);        CMOTIONVECTOR_INIT1(pmv, g_CAddVect);        pmv++;		for (i = 0; i < 4; i++)         {			*pmv = *(pmv - 1);			pmv++;		}	}}INLINE Void decodeMVofBVOP (CMotionVector* pmvForward, CMotionVector* pmvBackward, CMBMode* pmbmd, CMotionVector* pmvRef, CMBMode* pmbmdRef){	CVector vctDiff;    Int i;#ifdef DUAL_MODE	if(pmbmd->m_bSkip == TRUE && m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0)		return;#endif	if (pmbmd->m_mbType == FORWARD || pmbmd->m_mbType == INTERPOLATE)	{		assert (pmbmd->m_bSkip != TRUE);		assert (pmbmd->m_bhas4MVForward != TRUE);		getDiffMV (&vctDiff, g_pVOP->mvInfoForward);#ifdef ENABLE_INTERLACING		// TPS FIX		if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER) 		{			vctDecode.x = vctDiff.x + m_vctForwardMvPredBVOP[0].x;			vctDecode.y = (vctDiff.y + m_vctForwardMvPredBVOP[0].y / 2);			fitMvInRange ((&vctDecode), m_vopmd.mvInfoForward);            vctDecode.y *= 2;			m_vctForwardMvPredBVOP[0] = vctDecode;			pmvForward[0] = CMotionVector(vctDecode);			pmvForward[1] = pmvForward[0];			pmvForward[2] = pmvForward[0];			getDiffMV(&vctDiff, m_vopmd.mvInfoForward);			vctDecode.x = vctDiff.x + m_vctForwardMvPredBVOP[1].x;			vctDecode.y = (vctDiff.y + m_vctForwardMvPredBVOP[1].y / 2);			fitMvInRange ((&vctDecode), m_vopmd.mvInfoForward);            vctDecode.y *= 2;			m_vctForwardMvPredBVOP[1] = vctDecode;			pmvForward[3] = CMotionVector(vctDecode);			pmvForward[4] = pmvForward[3];		}	   else#endif	   {            ADD_VECT (vctDiff, g_pVO->m_vctForwardMvPredBVOP[0]);			fitMvInRange ((&g_CAddVect), g_pVOP->mvInfoForward);			g_pVO->m_vctForwardMvPredBVOP[0] = g_CAddVect;			g_pVO->m_vctForwardMvPredBVOP[1] = g_CAddVect;            CMOTIONVECTOR_INIT1(pmvForward, g_CAddVect);            *pmvForward++;			for (i = 0; i < 4; i++)             {				*pmvForward = *(pmvForward - 1);				pmvForward++;			}		}	}	if (pmbmd->m_mbType == BACKWARD || pmbmd->m_mbType == INTERPOLATE)    {		assert (pmbmd->m_bSkip != TRUE);		assert (pmbmd->m_bhas4MVBackward != TRUE);		getDiffMV (&vctDiff, g_pVOP->mvInfoBackward);#ifdef ENABLE_INTERLACING		if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER)         {			vctDecode.x = vctDiff.x + m_vctBackwardMvPredBVOP[0].x;			vctDecode.y = (vctDiff.y + m_vctBackwardMvPredBVOP[0].y / 2);			fitMvInRange ((&vctDecode), m_vopmd.mvInfoBackward);            vctDecode.y *= 2;			m_vctBackwardMvPredBVOP[0] = vctDecode;            CMOTIONVECTOR_INIT1((&pmvBackward[0]), vctDecode);			pmvBackward[1] = pmvBackward[0];			pmvBackward[2] = pmvBackward[0];			getDiffMV(&vctDiff, m_vopmd.mvInfoBackward);			vctDecode.x = vctDiff.x + m_vctBackwardMvPredBVOP[1].x;			vctDecode.y = (vctDiff.y + m_vctBackwardMvPredBVOP[1].y / 2);			fitMvInRange ((&vctDecode), m_vopmd.mvInfoBackward);            vctDecode.y *= 2;			m_vctBackwardMvPredBVOP[1] = vctDecode;            CMOTIONVECTOR_INIT1((&pmvBackward[3]), vctDecode);			pmvBackward[4] = pmvBackward[3];		}        else #endif        {            ADD_VECT (vctDiff, g_pVO->m_vctBackwardMvPredBVOP[0]);			fitMvInRange ((&g_CAddVect), g_pVOP->mvInfoBackward);			g_pVO->m_vctBackwardMvPredBVOP[0] = g_CAddVect;			g_pVO->m_vctBackwardMvPredBVOP[1] = g_CAddVect;            CMOTIONVECTOR_INIT1(pmvBackward, g_CAddVect);            *pmvBackward++;			for (i = 0; i < 4; i++)             {				*pmvBackward = *(pmvBackward - 1);				pmvBackward++;			}		}	}	if (pmbmd->m_mbType == DIRECT)    {	      assert (pmbmd->m_bhas4MVForward != TRUE);      #ifdef ENABLE_INTERLACING      static MVInfo directInfo = { 32, 1, 1};       if (m_vopmd.bInterlace)       {        if (!pmbmd->m_bSkip) {          if (!m_volmd.bQuarterSample) {// Quarterpel, added by mwi                      getDiffMV (&pmbmd->m_vctDirectDeltaMV, directInfo);          }          else {            Long lSymbol = decodeSymbol (m_pentrdecMV);            pmbmd->m_vctDirectDeltaMV.x  = deScaleMV (lSymbol - 32, 0, 1);            lSymbol = decodeSymbol (m_pentrdecMV);            pmbmd->m_vctDirectDeltaMV.y  = deScaleMV (lSymbol - 32, 0, 1);          }          vctDiff.x = pmbmd->m_vctDirectDeltaMV.x;          vctDiff.y = pmbmd->m_vctDirectDeltaMV.y;        }        else          vctDiff.x = vctDiff.y = 0;      }      else#endif      {        if (pmbmd->m_bSkip)          vctDiff.x = vctDiff.y = 0;        else          {          Long lSymbol = decodeSymbol (m_pentrdecMV);          vctDiff.x  = deScaleMV (lSymbol - 32, 0, 1);          lSymbol = decodeSymbol (m_pentrdecMV);          vctDiff.y  = deScaleMV (lSymbol - 32, 0, 1);        }      }            computeDirectForwardMV (vctDiff, pmvForward, pmvRef, pmbmdRef);	//compute forward mv from diff      if(pmbmdRef==NULL)      {          CMotionVector mvRef; // zero motion vector          // transparent reference macroblock          if (!g_pVOL->bQuarterSample) // added by mwi                                pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = FALSE;          else            pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = TRUE;          backwardMVFromForwardMV (pmvBackward, pmvForward, &mvRef, vctDiff);          for (i = 0; i < 4; i++)           {            pmvForward++;            pmvBackward++;            backwardMVFromForwardMV(pmvBackward, pmvForward, &mvRef, vctDiff);				            }      }      else      {          pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = pmbmdRef->m_bhas4MVForward;			//reset 4mv mode//          if (pmbmd->m_bhas4MVBackward || pmbmd->m_mbType == DIRECT)	          {            for (i = 0; i < 4; i++)             {              pmvForward++;              pmvBackward++;              pmvRef++;              backwardMVFromForwardMV (pmvBackward, pmvForward, pmvRef, vctDiff);            }          }//          else//            backwardMVFromForwardMV (pmvBackward, pmvForward, pmvRef, vctDiff);       }    }}INLINE Void computeDirectForwardMV (CVector vctDiff, CMotionVector* pmv, CMotionVector* pmvRef, CMBMode* pmbmdRef){    Int i;	if(pmvRef==NULL)	{		// colocated macroblock is transparent, use zero reference MV        CMOTIONVECTOR_INIT1(pmv, vctDiff);        *pmv++;		for (i = 0; i < 4; i++)         {			*pmv = *(pmv - 1);			pmv++;		}	}	else	{		Int iPartInterval = g_pVO->m_t - g_pVO->m_tPastRef;		Int iFullInterval = g_pVO->m_tFutureRef - g_pVO->m_tPastRef;		if (pmbmdRef->m_bhas4MVForward == FALSE)	        {            MUL_VECT (TRUEMVHALFPEL(pmvRef), iPartInterval);            if (iFullInterval)            {			        g_CMulVect.x /= iFullInterval;			//truncation as per vm			         g_CMulVect.y /= iFullInterval;			//truncation as per vm            }            ADD_VECT (vctDiff, g_CMulVect);            CMOTIONVECTOR_INIT1(pmv, g_CAddVect);            *pmv++;			for (i = 0; i < 4; i++)             {				*pmv = *(pmv - 1);				pmv++;			}		}		else         {			for (i = 0; i < 4; i++)            {				pmv++;				pmvRef++;                MUL_VECT (TRUEMVHALFPEL(pmvRef), iPartInterval);				g_CMulVect.x /= iFullInterval;			//truncation as per vm				g_CMulVect.y /= iFullInterval;			//truncation as per vm                ADD_VECT (vctDiff, g_CMulVect);                CMOTIONVECTOR_INIT1(pmv, g_CAddVect);			}		}	}}INLINE Void getDiffMV (CVector *vctDiffMV, MVInfo mvinfo)		//get half pel{	Int iResidual;	Long lSymbol = decodeSymbol (m_pentrdecMV);	Int iVLC = lSymbol - 32;	if (iVLC != 0)			iResidual = getBits (mvinfo.uiFCode - 1);	else		iResidual = 0;	vctDiffMV->x  = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);    lSymbol = decodeSymbol (m_pentrdecMV);	iVLC = lSymbol - 32;	if (iVLC != 0)		iResidual = getBits (mvinfo.uiFCode - 1);	else		iResidual = 0;	vctDiffMV->y  = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);}INLINE Int deScaleMV (Int iVLC, Int iResidual, Int iScaleFactor){	if (iVLC == 0 && iResidual == 0)		return 0;	else if (iScaleFactor == 1)		return (iVLC);	else     {		Int iAbsDiffMVcomponent = abs (iVLC) * iScaleFactor + iResidual - iScaleFactor + 1;	//changed a'c to enc		return (sign (iVLC) * iAbsDiffMVcomponent);	}}INLINE Void fitMvInRange (CVector *vctSrc, MVInfo mvinfo){    Int iMvRange = mvinfo.uiRange;	//in half pel unit	if (vctSrc->x < -1 * iMvRange)					//* 2 to get length of [-range, range]		vctSrc->x += 2 * iMvRange;					else if (vctSrc->x >= iMvRange)		vctSrc->x  -= 2 * iMvRange;	if (vctSrc->y < -1 * iMvRange)		vctSrc->y += 2 * iMvRange;	else if (vctSrc->y >= iMvRange)		vctSrc->y  -= 2 * iMvRange;}

⌨️ 快捷键说明

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