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

📄 omxvcm4p10_motionestimationmb.c

📁 The OpenMAX DL (Development Layer) APIs contain a comprehensive set of audio, video, signal processi
💻 C
📖 第 1 页 / 共 4 页
字号:
/**                                                                            x *  * File Name:  omxVCM4P10_MotionEstimationMB.c * OpenMAX DL: v1.0.2 * Revision:   10586 * Date:       Wednesday, March 5, 2008 *  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. *  *  * Description: * This function perform MB level motion estimation *  */#include "omxtypes.h"#include "armOMX.h"#include "omxVC.h"#include "armCOMM.h"#include "armVC.h"#define  ARM_VCM4P10_MAX_FRAMES     (15)#define  ARM_VCM4P10_MAX_4x4_SAD		(0xffff)#define  ARM_VCM4P10_MAX_MODE_VALUE     (0xffffffff)#define  ARM_VCM4P10_MAX_MODES          (16)#define  ARM_VCM4P10_MB_BLOCK_SIZE      (16)#define  ARM_VCM4P10_MEDIAN(a,b,c)      (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)#define  ARM_VCM4P10_SHIFT_QP           (12)#define  ARM_VCM4P10_MVPRED_MEDIAN      (0)#define  ARM_VCM4P10_MVPRED_L           (1)#define  ARM_VCM4P10_MVPRED_U           (2)#define  ARM_VCM4P10_MVPRED_UR          (3)#define ARM_VCM4P10_MB_BLOCK_SIZE       (16)#define ARM_VCM4P10_BLOCK_SIZE          (4)#define ARM_VCM4P10_MAX_COST            (1 << 30)#define  ARM_VCM4P10_INVALID_BLOCK      (-2)/** * Function: armVCM4P10_CalculateBlockSAD * * Description: *    Calculate SAD value for the selected MB encoding mode and update  * pDstBlockSAD parameter. These SAD values are calculated 4x4 blocks at * a time and in the scan order. * * Remarks: * * Parameters: * [in] pSrcMBInfo    -  * [in] pSrcCurrBuf   -  * [in] SrcCurrStep   -  * [in] pSrcRefBufList-  * [in] SrcRefStep    -  * [in] pSrcRecBuf    -  * [in] SrcRecStep    -  * [in] pRefRect      -  * [in] pCurrPointPos -  * [in] Lambda        -  * [in] pMESpec       -  * [in] pMBInter      -  * [in] pMBIntra      -  * [out] pDstBlockSAD - pointer to 16 element array for SAD corresponding to 4x4 blocks * Return Value: * None * */static OMXResult armVCM4P10_CalculateBlockSAD(	OMXVCM4P10MBInfo *pSrcMBInfo,     const OMX_U8 *pSrcCurrBuf,                                  	OMX_S32 SrcCurrStep, 	const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],	OMX_S32 SrcRefStep,	const OMX_U8 *pSrcRecBuf, 	OMX_S32 SrcRecStep,	const OMXRect *pRefRect,	const OMXVCM4P2Coordinate *pCurrPointPos,	const OMXVCM4P10MBInfoPtr *pMBInter, 	const OMXVCM4P10MBInfoPtr *pMBIntra,	OMX_U16 *pDstBlockSAD){	OMX_INT		InvalidSAD = 0;	OMX_INT		i;	OMX_U8		Buffer [16*16 + 15];	OMX_U8		*pTempDstBuf;	OMX_S32		TempDstStep;	OMX_U8		*pTempRefBuf;	OMX_S32		TempRefStep; 	/* Temporary buffer to store the predicted mb coefficients */	pTempDstBuf = armAlignTo16Bytes(Buffer);	TempDstStep = 16;	/* Update pDstBlockSAD if MB is a valid type */	if (pSrcMBInfo)	{	    OMX_U32     Width=0, Height=0, MaxXPart, MaxYPart,MaxSubXPart,MaxSubYPart;	    		/* Depending on type of MB, do prediction and fill temp buffer */		switch (pSrcMBInfo->mbType)		{		case OMX_VC_P_16x16:				Width = 16;				Height = 16;				break;		case OMX_VC_P_16x8:				Width = 16;				Height = 8;				break;		case OMX_VC_P_8x16:				Width = 8;				Height = 16;				break;		case OMX_VC_P_8x8:				Width = 8;				Height = 8;				break;		case OMX_VC_INTRA_4x4:			{				/* Create predicted MB Intra4x4 mode */				OMX_S32     PredIntra4x4Mode [5][9];				OMX_S32		x, y, Block8x8, Block4x4, BlockX, BlockY;				OMX_U8      pSrcYBuff [(16*3)*(16*2)];				OMX_U8		*pSrcY;				OMX_S32     StepSrcY;				OMX_S32		availability;				for (y = 0; y < 5; y++)				{					for (x = 0; x < 9; x++)					{						/* 						 * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this 						 * 4x4 block is not available 						 */						PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK;					}				}				/* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/				for (x = 0; x < 4; x++)				{					/* Store values of b0, b1, b2, b3 */					if (pMBIntra[1] != NULL)					{						PredIntra4x4Mode [0][x + 1] = 							pMBIntra[1]->pIntra4x4PredMode[3*4 + x];            					}			        					/* Store values of d0, d1, d2, d3 */					if (pMBIntra[3] != NULL)					{						PredIntra4x4Mode [0][x + 5] = 							pMBIntra[3]->pIntra4x4PredMode[3*4 + x];					}				}		    				/* Store values of c3 */				if (pMBIntra[2] != NULL)				{					PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15];				}		    				for (y = 0; y < 4; y++)				{					/* Store values of a0, a1, a2, a3 */					if (pMBIntra[0] != NULL)					{						PredIntra4x4Mode [y + 1][0] = 							pMBIntra[0]->pIntra4x4PredMode[y*4 + 3];					}				}		        				/*				 * Update neighbouring Pred mode array which will be used for				 * prediction of Intra4x4 modes.				 */			    				pSrcY = pSrcYBuff;				StepSrcY = 16 * 3;				for (y = 0; y < (16 * 2); y++)				{					for (x = 0; x < (16 * 3); x++)					{						pSrcY [StepSrcY * y + x] = 							pSrcRecBuf [SrcRecStep * (y - 16) + x - 16];					}				}		    				/* for each 8x8 block */				for (Block8x8 = 0; Block8x8 < 4; Block8x8++)				{					/* for each 4x4 block inside 8x8 block */					for (Block4x4 = 0; Block4x4 < 4; Block4x4++)					{						/* Get block cordinates from 8x8 block index and 4x4 block index */						BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1);						BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1);					    						/* Add offset to point to start of current MB in the array pIntra4x4PredMode */						x = BlockX + 1;						y = BlockY + 1;						availability = 0;						/* Check for availability of LEFT Block */						if (PredIntra4x4Mode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK)						{							availability |= OMX_VC_LEFT;        						}						/* Check for availability of UPPER Block */						if (PredIntra4x4Mode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK)						{							availability |= OMX_VC_UPPER;        						}						/* Check for availability of UPPER LEFT Block */						if (PredIntra4x4Mode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK)						{							availability |= OMX_VC_UPPER_LEFT;        						}												PredIntra4x4Mode [y][x] = pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX];						x = BlockX * 4;						y = BlockY * 4;						pSrcY = pSrcYBuff + 16 * StepSrcY + 16 + y * StepSrcY + x;						omxVCM4P10_PredictIntra_4x4(							 pSrcY - 1,							 pSrcY - StepSrcY,							 pSrcY - StepSrcY - 1,							 pTempDstBuf + x + y * TempDstStep,							 StepSrcY,							 TempDstStep,							 pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX],							 availability);						for (BlockY=0;BlockY<4;BlockY++)						{							for(BlockX=0;BlockX<4;BlockX++)							{								pSrcY [BlockY * StepSrcY + BlockX] = 									(OMX_U8)(*(pTempDstBuf + x + y * TempDstStep + BlockY * TempDstStep + BlockX));							}						}					}				}				break;			}		case OMX_VC_INTRA_16x16:			{				OMX_U32     MBPosX = pCurrPointPos->x >> 4;        				OMX_U32     MBPosY = pCurrPointPos->y >> 4;        				OMX_U32		availability = 0;				/* Check for availability of LEFT MB */				if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0))				{					availability |= OMX_VC_LEFT;        				}				/* Check for availability of UP MB */				if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0))				{					availability |= OMX_VC_UPPER;        				}				/* Check for availability of UP-LEFT MB */				if ((MBPosX > 0) && (MBPosY > 0) && 					(pMBIntra [2] != 0 || pMBInter [2] != 0))				{					availability |= OMX_VC_UPPER_LEFT;        				}				omxVCM4P10_PredictIntra_16x16(						pSrcRecBuf - 1, 						pSrcRecBuf - SrcRecStep, 						pSrcRecBuf - SrcRecStep - 1, 						pTempDstBuf, 						SrcRecStep, 						TempDstStep, 						pSrcMBInfo->Intra16x16PredMode, 						availability);								break;			}		case OMX_VC_INTER_SKIP:		case OMX_VC_PREF0_8x8:		case OMX_VC_INTRA_PCM:		default:			/* These cases will update pDstBlockSAD with MAX value */			InvalidSAD = 1;			break;		}		/* INTER MB */		if ((pSrcMBInfo->mbType == OMX_VC_P_16x16) ||			(pSrcMBInfo->mbType == OMX_VC_P_8x16) ||			(pSrcMBInfo->mbType == OMX_VC_P_16x8) ||			(pSrcMBInfo->mbType == OMX_VC_P_8x8))		{        	const OMX_U8		*pTempSrcBuf;        	OMX_S32		TempSrcStep;        	OMX_S32		mvx,mvy;        	OMX_U32		PartX, PartY, SubPartX, SubPartY;        				TempSrcStep = SrcRefStep;			MaxXPart = 16/Width;			MaxYPart = 16/Height;			for (PartY = 0; PartY < MaxYPart; PartY++)			{				for (PartX = 0; PartX < MaxXPart; PartX++)				{					pTempSrcBuf = pSrcRefBufList[pSrcMBInfo->pRefL0Idx[PartY * 2 + PartX]];					if (MaxXPart == 2 && MaxYPart == 2)					{        				switch (pSrcMBInfo->subMBType[PartY*2+PartX])        				{        				    case OMX_VC_SUB_P_8x8:								Width = 8;								Height = 8;            				    break;        				    case OMX_VC_SUB_P_8x4:								Width = 8;								Height = 4;            				    break;        				    case OMX_VC_SUB_P_4x8:								Width = 4;								Height = 8;            				    break;        				    case OMX_VC_SUB_P_4x4:								Width = 4;								Height = 4;            				    break;        				    default:								/* Default */								Width = 4;								Height = 4;        				    break;        				}					    				    MaxSubXPart = 8/Width;    				    MaxSubYPart = 8/Height;						for (SubPartY = 0; SubPartY < MaxSubYPart; SubPartY++)						{							for (SubPartX = 0; SubPartX < MaxSubXPart; SubPartX++)							{								mvx = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dx;								mvy = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dy;								armVCM4P10_Interpolate_Luma(									pTempSrcBuf + (8*PartX + 4*SubPartX + (mvx/4)) + (8*PartY + 4*SubPartY + (mvy/4)) * TempSrcStep,									TempSrcStep,									pTempDstBuf + (8*PartX + 4*SubPartX) + (8*PartY + 4*SubPartY) * TempDstStep,									TempDstStep,									Width,									Height,									mvx & 3,									mvy & 3									);							}						}					}					else					{						mvx = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dx;						mvy = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dy;						armVCM4P10_Interpolate_Luma(							pTempSrcBuf + (8*PartX + (mvx/4)) + (8*PartY + (mvy/4)) * TempSrcStep,							TempSrcStep,							pTempDstBuf + (8*PartX) + (8*PartY) * TempDstStep,							TempDstStep,							Width,							Height,							mvx & 3,							mvy & 3							);					}				}			}		}	}	else	{		InvalidSAD = 1;	}	/* Calculate SAD from predicted buffer */	if (!InvalidSAD)	{	    OMX_U32     x8x8, y8x8, x4x4, y4x4, Block8x8, Block4x4;	    OMX_S32     SAD;	    		pTempRefBuf = pTempDstBuf;		TempRefStep = 16;		/* SAD for each 4x4 block in scan order */		for (Block8x8 = 0; Block8x8 < 4; Block8x8++)		{			x8x8 = 8*(Block8x8 & 1);			y8x8 = 8*(Block8x8 >> 1);			for (Block4x4 = 0; Block4x4 < 4; Block4x4++)			{				x4x4 = 4*(Block4x4 & 1);				y4x4 = 4*(Block4x4 >> 1);				armVCCOMM_SAD(						pSrcCurrBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * SrcCurrStep, 					SrcCurrStep,					pTempRefBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * TempRefStep,					TempRefStep,    				&SAD,    				4, /* Height */    				4); /* Width */                *(pDstBlockSAD + 4 * Block8x8 + Block4x4) = (SAD < 0x7fff) ? (OMX_U16) SAD : ARM_VCM4P10_MAX_MODE_VALUE;   			     			}		}	}	else	{		/* Fill SADs with max values and return*/		for (i = 0; i < 16; i++)		{			pDstBlockSAD [i] = ARM_VCM4P10_MAX_4x4_SAD;		}	}	return OMX_Sts_NoErr;}/** * Function: armVCM4P10_Mode4x4Decision * * Description: *    Intra 4x4 Mode decision by calculating cost for all possible modes and * choosing the best mode * * Remarks: * * Parameters: * [in] pSrcCurrBuf    - Pointer to the start of current Macroblock * [in] SrcCurrStep - Step size of the pointer pSrcCurrBuf * [in/out] pSrcDstMBCurr - Pointer to the OMXVCM4P10MBInfo which will be updated for *                    field pIntra4x4PredMode of the current block. * [in] Block8x8    - Index 8x8 block in which current 4x4 block belongs * [in] Block4x4    - Index of current 4x4 block * [in/out] pPredIntra4x4SrcY - Pointer to current block location in buffer  *                    with reconstructed values. This will be modified by this *                    function with best mode predicted values  * [in] StepPredIntra4x4SrcY  - Step size of the pointer pPredIntra4x4SrcY * [in] pIntra4x4PredMode     - Array of Intra 4x4 prediction mode for the MB. *                              Current MB modes starts at [1,1]. * [in] pBestCost   - Cost for the Best Intra 4x4 mode * Return Value: * None *

⌨️ 快捷键说明

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