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

📄 motioncompute.c

📁 DM642的mpeg4编码
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <time.h>

#include "motioncompute.h"
#include "../global.h"
#include "../initial/initial.h"
#include "../quant/mpeg4quant.h"
#include "../mempry/block.h"
#include "../mempry/mem.h"

#include "../mpeg4/writempegheader.h"

#define SkipThesh 6
#define SearchSize 2

#define ErrorOfMv	(4096 * 256)

#define MBlockInterBias	450

#define IMV				2
#define MBPara		    0.6
#define BlockPara			0.6

#define SkipThresh2		50
#define SadSkip		20
#define ChroSkip	22

#define IEXTMBWIDTH  26

//extern clock_t sc,ec;

extern	unsigned char curentPingBuffer[6*64*IEXTMBWIDTH];
extern	unsigned char curentPongBuffer[6*64*IEXTMBWIDTH];
	
extern	unsigned char refPingBuffer[3*6*64*IEXTMBWIDTH];
extern	unsigned char refPongBuffer[3*6*64*IEXTMBWIDTH];

extern unsigned char curentRecPingBuffer[6*64*IEXTMBWIDTH];
extern unsigned char curentRecPongBuffer[6*64*IEXTMBWIDTH];

static const VECTOR ZeroMV = {0,0};

#define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )

#define EVEN(A)		(((A)<0?(A)+1:(A)) & ~1)

static const int ReverMvTable[64] = 
{
	12, 12, 12, 12, 12, 12, 12, 12,
	12, 12, 12, 12, 12, 12, 12, 12,
	12, 12, 12, 12, 12, 12, 12, 12,
	12, 12, 12, 12, 12, 12, 12, 12,
	12, 11, 11, 11, 11, 11, 11, 10,
	10, 10, 10, 10, 10, 10, 10, 10,
	10, 10, 10, 10, 10, 9, 9, 9,
	7, 7, 7, 6, 4, 3, 2, 1
};


static const int VectorBlock[32] =
	{     0    ,(int)(1.0 * BlockPara + 0.5),
	(int)(2.0*BlockPara + 0.5), (int)(3.0*BlockPara + 0.5),
	(int)(4.0*BlockPara + 0.5), (int)(5.0*BlockPara + 0.5),
	(int)(6.0*BlockPara + 0.5), (int)(7.0*BlockPara + 0.5),
	(int)(8.0*BlockPara + 0.5), (int)(9.0*BlockPara + 0.5),
	(int)(10.0*BlockPara + 0.5), (int)(11.0*BlockPara + 0.5),
	(int)(12.0*BlockPara + 0.5), (int)(13.0*BlockPara + 0.5),
	(int)(14.0*BlockPara + 0.5), (int)(15.0*BlockPara + 0.5),
	(int)(16.0*BlockPara + 0.5), (int)(17.0*BlockPara + 0.5),
	(int)(18.0*BlockPara + 0.5), (int)(19.0*BlockPara + 0.5),
	(int)(20.0*BlockPara + 0.5), (int)(21.0*BlockPara + 0.5),
	(int)(22.0*BlockPara + 0.5), (int)(23.0*BlockPara + 0.5),
	(int)(24.0*BlockPara + 0.5), (int)(25.0*BlockPara + 0.5),
	(int)(26.0*BlockPara + 0.5), (int)(27.0*BlockPara + 0.5),
	(int)(28.0*BlockPara + 0.5), (int)(29.0*BlockPara + 0.5),
	(int)(30.0*BlockPara + 0.5), (int)(31.0*BlockPara + 0.5)
};


const int VectorMacroBlock[32] =
	{     0    ,(int)(0.5 * MBPara + 0.5),
	(int)(1.0*MBPara + 0.5), (int)(1.5*MBPara + 0.5),
	(int)(2.0*MBPara + 0.5), (int)(2.5*MBPara + 0.5),
	(int)(5.0*MBPara + 0.5), (int)(7.0*MBPara + 0.5),
	(int)(8.0*MBPara + 0.5), (int)(9.0*MBPara + 0.5),
	(int)(10.0*MBPara + 0.5), (int)(11.0*MBPara + 0.5),
	(int)(12.0*MBPara + 0.5), (int)(13.0*MBPara + 0.5),
	(int)(14.0*MBPara + 0.5), (int)(15.0*MBPara + 0.5),
	(int)(16.0*MBPara + 0.5), (int)(17.0*MBPara + 0.5),
	(int)(18.0*MBPara + 0.5), (int)(19.0*MBPara + 0.5),
	(int)(20.0*MBPara + 0.5), (int)(21.0*MBPara + 0.5),
	(int)(22.0*MBPara + 0.5), (int)(23.0*MBPara + 0.5),
	(int)(24.0*MBPara + 0.5), (int)(25.0*MBPara + 0.5),
	(int)(26.0*MBPara + 0.5), (int)(27.0*MBPara + 0.5),
	(int)(28.0*MBPara + 0.5), (int)(29.0*MBPara + 0.5),
	(int)(30.0*MBPara + 0.5), (int)(31.0*MBPara + 0.5)
};

static __inline unsigned char* GetRefImage(int x, int y, MvSearchData* pData)
{
	const int image = ((x&1)*2) | (y&1);
	const int offset = (x>>1) + (y>>1)*pData->iExtWidth;
	return pData->RefP[image] + offset;
}

static __inline void SetPframeZeroMB(MacroBlock *pMB, const int sad)
{
	pMB->mb_type = MB_INTER;
	pMB->Mv[0].x = pMB->Mv[1].x = pMB->Mv[2].x = pMB->Mv[3].x = 0;
	pMB->Mv[0].y = pMB->Mv[1].y = pMB->Mv[2].y = pMB->Mv[3].y = 0;

	pMB->LumMBlockSad = pMB->LumBlockSad[0] = pMB->LumBlockSad[1] = pMB->LumBlockSad[2] = pMB->LumBlockSad[3] = sad;
	pMB->cbp = 0;
}

static __inline int VectorCheck(const VECTOR * const pmv, const unsigned int i)
{
	unsigned int j;
	for (j = 0; j < i; j++)
	{
		if (MVequal(pmv[i], pmv[j])) 
		{
			return 1; 
		}
	}
	return 0;
}

static __inline void motionStatsPVOP(int* MVmax, int* mvCount, int* mvSum, MacroBlock* pCurMB)
{
	VECTOR* mv = pCurMB->Mv;
	int i;
	int max = *MVmax;

	switch (pCurMB->mb_type) 
	{
	case MB_INTER_4V:
		*mvCount += 3;
		for(i = 3; i; i--) 
		{
			if (mv[i].x > max) 
			{
				max = mv[i].x;
			}
			else if (-mv[i].x - 1 > max) 
			{
				max = -mv[i].x - 1;
			}
			*mvSum += mv[i].x * mv[i].x;

			if (mv[i].y > max) 
			{
				max = mv[i].y;
			}
			else if (-mv[i].y - 1 > max) 
			{
				max = -mv[i].y - 1;
			}
			*mvSum += mv[i].y * mv[i].y;
		}
	case MB_INTER:
		(*mvCount)++;
		*mvSum += mv[0].x * mv[0].x;
		*mvSum += mv[0].y * mv[0].y;
		if (mv[0].x > max)
		{
			max = mv[0].x;
		}
		else if (-mv[0].x - 1 > max) 
		{
			max = -mv[0].x - 1;
		}
		if (mv[0].y > max)
		{
			max = mv[0].y;
		}
		else if (-mv[0].y - 1 > max) 
		{
			max = -mv[0].y - 1;
		}
		*MVmax = max;
	default:
		break;
	}
}
//***********************************************************************************************
//函 数 名:ComputeMvBits()
//函数功能:计算运动矢量编码比特
//形式参数:x, y   运动矢量
//          PreMv 预测运动矢量

//返 回 值:void
//***********************************************************************************************

static __inline unsigned char ComputeMvBits(int x , int y, VECTOR PreMv, short iFcode)
{
    unsigned int TotalBits;
     
	x -= PreMv.x;
	//TotalBits = (x != 0 ? iFcode:0);
	TotalBits = (x&&1)*iFcode;
	x = -abs(x);
	x >>= (iFcode - 1);
	TotalBits += ReverMvTable[x+63];

	y -= PreMv.y;
	//TotalBits += (y != 0 ? iFcode:0);
	TotalBits += (y&&1)*iFcode;
	y = -abs(y);
	y >>= (iFcode - 1);
	TotalBits += ReverMvTable[y+63];

	return TotalBits;
}

static __inline int GetMask(const VECTOR * const pmv, const unsigned int i, const unsigned int current)
{
	unsigned int mask = 255, j;

	for (j = 0; j < i; j++)
	{
		if (pmv[current].x == pmv[j].x) 
		{
			if (pmv[current].y == pmv[j].y + SearchSize) 
			{ 
				mask &= ~4;
			}
			else if (pmv[current].y == pmv[j].y - SearchSize) 
			{
				mask &= ~8;
			}
		}
		else
		{
			if (pmv[current].y == pmv[j].y)
			{
				if (pmv[current].x == pmv[j].x + SearchSize) 
				{
					mask &= ~1;
				}
				else if (pmv[current].x == pmv[j].x - SearchSize) 
				{
					mask &= ~2;
				}
			}
		}
	}
	return mask;
}
//***********************************************************************************************
//函 数 名:ComputBlockSad
//函数功能:计算当前8*8块的SAD值,并返回计算得到的SAD值
//形式参数:pCur:当前块的首地址
//			pRef:参考块的首地址
//			iStride:
//返 回 值:SAD值
//***********************************************************************************************
/*   compute block sad  */
//#pragma CODE_SECTION(ComputBlockSad,".internal_code1");
/*
static unsigned int ComputBlockSad(unsigned char * pCur, unsigned char* pRef, int iStride)
{
	unsigned int total = 0;
	
	short i;

	for (i = 0; i < 8; i++)
	{
		total += abs(pCur[0] - pRef[0]);
		total += abs(pCur[1] - pRef[1]);
		total += abs(pCur[2] - pRef[2]);
		total += abs(pCur[3] - pRef[3]);
		total += abs(pCur[4] - pRef[4]);
		total += abs(pCur[5] - pRef[5]);
		total += abs(pCur[6] - pRef[6]);
		total += abs(pCur[7] - pRef[7]);

		pCur += iStride;
		pRef += iStride;
	}
	return total;
}
*/
unsigned int SearchMacroBlock_C(unsigned char* cur, unsigned char* ref,unsigned int stride, unsigned int best_sad)
{

	unsigned int sad = 0;
	unsigned int j;
	unsigned char* ptr_cur = cur;
	unsigned char* ptr_ref = ref;

	for (j = 0; j < 16; j++) 
	{
			sad += abs(ptr_cur[0] - ptr_ref[0]);
			sad += abs(ptr_cur[1] - ptr_ref[1]);
			sad += abs(ptr_cur[2] - ptr_ref[2]);
			sad += abs(ptr_cur[3] - ptr_ref[3]);
			sad += abs(ptr_cur[4] - ptr_ref[4]);
			sad += abs(ptr_cur[5] - ptr_ref[5]);
			sad += abs(ptr_cur[6] - ptr_ref[6]);
			sad += abs(ptr_cur[7] - ptr_ref[7]);
			sad += abs(ptr_cur[8] - ptr_ref[8]);
			sad += abs(ptr_cur[9] - ptr_ref[9]);
			sad += abs(ptr_cur[10] - ptr_ref[10]);
			sad += abs(ptr_cur[11] - ptr_ref[11]);
			sad += abs(ptr_cur[12] - ptr_ref[12]);
			sad += abs(ptr_cur[13] - ptr_ref[13]);
			sad += abs(ptr_cur[14] - ptr_ref[14]);
			sad += abs(ptr_cur[15] - ptr_ref[15]);

			if (sad >= best_sad)
			{
				return sad;
			}

			ptr_cur += stride;
			ptr_ref += stride;

	}

	return sad;
}
//***********************************************************************************************
//函 数 名:ComputMBlockSad()
//函数功能:计算当前传入宏块的SAD值,并将各个亮度块的SAD值,放入到相应的位置,然后将四个8*8块的SAD的和返回
//形式参数:pCur:当前宏块亮度值的首地址
//			pRef:参考宏块亮度值的首地址
//			iSride:步长,扩边后的图象宽度
//			iSad:存放各个SAD值的首地址
//返 回 值:void
//备注:注意宏块中四个块的起始地址(图象中的顺序)
//***********************************************************************************************
static unsigned int ComputMBlockSad(unsigned char* pCur, unsigned char * pRef, short iStride, int* iSad)
{
//sc = clock();
	iSad[0] = ComputBlockSad(pCur, pRef, iStride);
//ec = clock();
//printf("block sad cycles is %d\n",ec-sc);
	iSad[1] = ComputBlockSad(pCur+8, pRef+8, iStride);
	iSad[2] = ComputBlockSad(pCur+8*iStride, pRef+8*iStride, iStride);
	iSad[3] = ComputBlockSad(pCur+8*iStride+8, pRef+8*iStride+8, iStride);

    return (iSad[0] + iSad[1] + iSad[2] + iSad[3]);
}
//***********************************************************************************************
//函 数 名:GetMvSearchRange()
//函数功能:确定运动搜索的范围,并记录在pData
//形式参数:
//			pData:
//			x,y  :当前宏块的坐标值
//			iBlock_size:
//			iWidth:
//			iHeight:
//			iFcode:
//返 回 值:void
//***********************************************************************************************
static __inline void GetMvSearchRange(MvSearchData* pData, int x, int y, unsigned int iBlock_size, short iWidth, short iHeight, short iFcode)
{
	short iTemp;

	short iHighRange, iLowRange;

#ifdef SEARCH_WINDOW32X32
    short MvRange = 1 << (4+iFcode);	//搜索窗口为64
#else
	 short MvRange = 1 << (3+iFcode);	//搜索窗口为64
#endif

	iHighRange = MvRange - 1;
	iLowRange = -MvRange;
	
	iTemp = (int)(iWidth - (x<<iBlock_size))<<1;
	pData->max_rangeX = MIN(iHighRange, iTemp);
	iTemp = (int)(iHeight -  (y<<iBlock_size))<<1;
	pData->max_rangeY = MIN(iHighRange, iTemp);

	iTemp = (-(int)((x+1)<<iBlock_size))<<1;
	pData->min_rangeX = MAX(iLowRange, iTemp);
	iTemp = (-(int)((y+1)<<iBlock_size))<<1;
	pData->min_rangeY = MAX(iLowRange, iTemp); 
}
//***********************************************************************************************
//函 数 名:GetPredictMv()
//函数功能:得到预测的MV值,
//形式参数:
//返 回 值:void
//***********************************************************************************************
static __inline void GetPredictMv(MacroBlock* Mbs, short iMBWidth, short x, short y, VECTOR* pMv, int* LumTempBlockSad)
{
    int lx, ly, lz;		
	int tx, ty, tz;		
	int rx, ry, rz;		
	int lpos, tpos, rpos;
	int num = 0, last = 1;

	lx = x - 1;	ly = y;		lz = 1;		//左边宏块
	tx = x;		ty = y - 1;	tz = 2;		//上面的宏块
	rx = x + 1;	ry = y - 1;	rz = 2;		//右边的宏块

	lpos = lx + ly * iMBWidth;
	rpos = rx + ry * iMBWidth;
	tpos = tx + ty * iMBWidth;

	if (lpos >= 0 && lx >= 0)
	{
		num++;
		last = 1;
		pMv[1] = Mbs[lpos].Mv[lz];
		LumTempBlockSad[1] = Mbs[lpos].LumBlockSad[lz];
	} 
	else 
	{
		pMv[1] = ZeroMV;
		LumTempBlockSad[1] = ErrorOfMv;
	}

	if (tpos >= 0)
	{
		num++;
		last = 2;
		pMv[2]= Mbs[tpos].Mv[tz];
		LumTempBlockSad[2] = Mbs[tpos].LumBlockSad[tz];
	} else 
	{
		pMv[2] = ZeroMV;
		LumTempBlockSad[2] = ErrorOfMv;
	}

⌨️ 快捷键说明

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