📄 motioncompute.c
字号:
#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 + -