📄 motioncompute.c
字号:
if (rpos >= 0 && rx < iMBWidth)
{
num++;
last = 3;
pMv[3] = Mbs[rpos].Mv[rz];
LumTempBlockSad[3] = Mbs[rpos].LumBlockSad[rz];
}
else
{
pMv[3] = ZeroMV;
LumTempBlockSad[3] = ErrorOfMv;
}
if (x == 0 && y == 0)
{
pMv[0] = pMv[1] = pMv[2] = pMv[3] = ZeroMV;
LumTempBlockSad[0] = 0;
LumTempBlockSad[1] = LumTempBlockSad[2] = LumTempBlockSad[3] = ErrorOfMv;
return;
}
if (num == 1)
{
pMv[0] = pMv[last];
LumTempBlockSad[0] = LumTempBlockSad[last];
return;
}
if ((MVequal(pMv[1], pMv[2])) && (MVequal(pMv[1], pMv[3])))
{
pMv[0] = pMv[1];
LumTempBlockSad[0] = MIN(MIN(LumTempBlockSad[1], LumTempBlockSad[2]), LumTempBlockSad[3]);
return;
}
pMv[0].x =
MIN(MAX(pMv[1].x, pMv[2].x),
MIN(MAX(pMv[2].x, pMv[3].x), MAX(pMv[1].x, pMv[3].x)));
pMv[0].y =
MIN(MAX(pMv[1].y, pMv[2].y),
MIN(MAX(pMv[2].y, pMv[3].y), MAX(pMv[1].y, pMv[3].y)));
LumTempBlockSad[0] = MIN(MIN(LumTempBlockSad[1], LumTempBlockSad[2]), LumTempBlockSad[3]);
}
static VECTOR Get_pmv(MacroBlock* mbs,
short mb_width,
short bound,
int x,
int y,
short block)
{
int lx, ly, lz;
int tx, ty, tz;
int rx, ry, rz;
int lpos, tpos, rpos;
int num_cand = 0, last_cand = 1;
VECTOR pmv[4];
switch (block)
{
case 0:
lx = x - 1; ly = y; lz = 1;
tx = x; ty = y - 1; tz = 2;
rx = x + 1; ry = y - 1; rz = 2;
break;
case 1:
lx = x; ly = y; lz = 0;
tx = x; ty = y - 1; tz = 3;
rx = x + 1; ry = y - 1; rz = 2;
break;
case 2:
lx = x - 1; ly = y; lz = 3;
tx = x; ty = y; tz = 0;
rx = x; ry = y; rz = 1;
break;
default:
lx = x; ly = y; lz = 2;
tx = x; ty = y; tz = 0;
rx = x; ry = y; rz = 1;
}
lpos = lx + ly * mb_width;
rpos = rx + ry * mb_width;
tpos = tx + ty * mb_width;
if (lpos >= bound && lx >= 0)
{
num_cand++;
pmv[1] = mbs[lpos].Mv[lz];
}
else
{
pmv[1] = ZeroMV;
}
if (tpos >= bound)
{
num_cand++;
last_cand = 2;
pmv[2] = mbs[tpos].Mv[tz];
}
else
{
pmv[2] = ZeroMV;
}
if (rpos >= bound && rx < mb_width)
{
num_cand++;
last_cand = 3;
pmv[3] = mbs[rpos].Mv[rz];
}
else
{
pmv[3] = ZeroMV;
}
if (num_cand > 1)
{
pmv[0].x =
MIN(MAX(pmv[1].x, pmv[2].x),
MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
pmv[0].y =
MIN(MAX(pmv[1].y, pmv[2].y),
MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
return pmv[0];
}
return pmv[last_cand];
}
//***********************************************************************************************
//函 数 名:CheckMemberMB()
//函数功能:以宏块为单位搜索
//形式参数:
//返 回 值:void
//***********************************************************************************************
static void CheckMemberMB(int x, int y, MvSearchData* pData, short Direction)
{
unsigned char * Reference;
int sad, xc, yc;
unsigned int t;
VECTOR * current;
/* K = 1 */
const unsigned int TabK1[4] =
{ 0, 1, 0, 0 };
if ( (x > pData->max_rangeX) || (x < pData->min_rangeX) || (y > pData->max_rangeY) || (y < pData->min_rangeY) )
{
return;
}
Reference = GetRefImage(x, y, pData);
current = pData->CurrentMv;
xc = x; yc = y;
sad = ComputMBlockSad(pData->CurY, Reference, pData->iExtWidth, pData->LumTempBlockSad);
t = ComputeMvBits(x, y, pData->PredMV, pData->iFcode);
sad += (pData->onemvbit * t);
pData->LumTempBlockSad[0] += (pData->fourmvbit * t);
if (sad >= pData->iMinSad[0])
{
goto not16;
}
sad += ComputeChromaSAD((xc >> 1) + TabK1[xc & 0x3], (yc >> 1) + TabK1[yc & 0x3], pData);
if (sad < pData->iMinSad[0])
{
pData->iMinSad[0] = sad;
current[0].x = x; current[0].y = y;
pData->dir = Direction;
}
not16:
if (pData->LumTempBlockSad[0] < pData->iMinSad[1])
{
pData->iMinSad[1] = pData->LumTempBlockSad[0];
current[1].x = x;
current[1].y = y;
}
if (pData->LumTempBlockSad[1] < pData->iMinSad[2])
{
pData->iMinSad[2] = pData->LumTempBlockSad[1];
current[2].x = x;
current[2].y = y;
}
if (pData->LumTempBlockSad[2] < pData->iMinSad[3])
{
pData->iMinSad[3] = pData->LumTempBlockSad[2];
current[3].x = x;
current[3].y = y;
}
if (pData->LumTempBlockSad[3] < pData->iMinSad[4])
{
pData->iMinSad[4] = pData->LumTempBlockSad[3];
current[4].x = x;
current[4].y = y;
}
}
static void CheckMemberBlock(int x, int y, MvSearchData* pData, short Direction)
{
int sad;
unsigned int t;
unsigned char* Reference;
VECTOR * current;
if ( (x > pData->max_rangeX) || (x < pData->min_rangeX)
|| (y > pData->max_rangeY) || (y < pData->min_rangeY) )
{
return;
}
Reference = GetRefImage(x, y, pData);
current = pData->CurrentMv;
sad = ComputBlockSad(pData->CurY, Reference, pData->iExtWidth);
t = ComputeMvBits(x, y, pData->PredMV, pData->iFcode);
sad += (pData->fourmvbit * t);
if (sad < *(pData->iMinSad))
{
*(pData->iMinSad) = sad;
current->x = x;
current->y = y;
pData->dir = Direction;
}
}
static int DevMBlockChro(unsigned char* cur, short stride)
{
unsigned int mean = 0;
unsigned int dev = 0;
unsigned int i, j;
unsigned char *ptr_cur = cur;
for (j = 0; j < 16; j++)
{
for (i = 0; i < 16; i++)
{
mean += *(ptr_cur + i);
}
ptr_cur += stride;
}
mean /= (16 * 16);
ptr_cur = cur;
for (j = 0; j < 16; j++)
{
for (i = 0; i < 16; i++)
{
dev += abs(*(ptr_cur + i) - (int) mean);
}
ptr_cur += stride;
}
return dev;
}
int SearchBlockBi_C(unsigned char* cur, unsigned char* ref1, unsigned char* ref2, short stride)
{
int sad = 0;
unsigned int i, j;
unsigned char* ptr_cur = cur;
unsigned char* ptr_ref1 = ref1;
unsigned char* ptr_ref2 = ref2;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
int pixel = (ptr_ref1[i] + ptr_ref2[i] + 1) / 2;
sad += abs(ptr_cur[i] - pixel);
}
ptr_cur += stride;
ptr_ref1 += stride;
ptr_ref2 += stride;
}
return sad;
}
unsigned int SearchMacroBlockBi_C(unsigned char* cur,
unsigned char* ref1,
unsigned char* ref2,
unsigned int stride)
{
unsigned int sad = 0;
unsigned int i, j;
unsigned char *ptr_cur = cur;
unsigned char *ptr_ref1 = ref1;
unsigned char *ptr_ref2 = ref2;
for (j = 0; j < 16; j++)
{
for (i = 0; i < 16; i++)
{
int pixel = (ptr_ref1[i] + ptr_ref2[i] + 1) / 2;
sad += abs(ptr_cur[i] - pixel);
}
ptr_cur += stride;
ptr_ref1 += stride;
ptr_ref2 += stride;
}
return sad;
}
//***********************************************************************************************
//函 数 名:MEPre()
//函数功能:对pmv作进一步的设置,做运算前的准备
//形式参数:v
//返 回 值:void
//***********************************************************************************************
void MEPre(VECTOR* pMv, short x, short y, short iMBWidth, short iMBHeight, MacroBlock* pRefMBs)
{
if ( (y != 0) && (x < (iMBWidth-1)) )
{
pMv[5].x = EVEN(pMv[3].x);
pMv[5].y = EVEN(pMv[3].y);
}
else
{
pMv[5].x = pMv[5].y = 0;
}
if (x != 0)
{
pMv[3].x = EVEN(pMv[1].x);
pMv[3].y = EVEN(pMv[1].y);
}
else
{
pMv[3].x = pMv[3].y = 0;
}
if (y != 0)
{
pMv[4].x = EVEN(pMv[2].x);
pMv[4].y = EVEN(pMv[2].y);
}
else
{
pMv[4].x = pMv[4].y = 0;
}
pMv[1].x = EVEN(pMv[0].x);
pMv[1].y = EVEN(pMv[0].y);
pMv[0].x = pMv[0].y = 0;
pMv[2].x = EVEN(pRefMBs->Mv[0].x);
pMv[2].y = EVEN(pRefMBs->Mv[0].y);
if ((x < iMBWidth-1) && (y < iMBHeight-1))
{
pMv[6].x = EVEN((pRefMBs+1+iMBWidth)->Mv[0].x);
pMv[6].y = EVEN((pRefMBs+1+iMBWidth)->Mv[0].y);
}
else
{
pMv[6].x = pMv[6].y = 0;
}
}
int ComputeChromaSAD(int dx, int dy, MvSearchData* pData)
{
int sad;
short iStride = pData->iExtWidth/2;
int offset = (dx>>1) + (dy>>1)*iStride;
int next = 1;
if (dx == pData->chromaX && dy == pData->chromaY)
{
return pData->chromaSAD;
}
pData->chromaX = dx; pData->chromaY = dy;
switch (((dx & 1) << 1) | (dy & 1)) {
case 0: //整像素
sad = ComputBlockSad(pData->CurU, pData->RefP[4] + offset, iStride);
sad += ComputBlockSad(pData->CurV, pData->RefP[5] + offset, iStride);
break;
case 1: //y为半像素
next = iStride;
case 2: //x为半像素时,next=1,Y为半像素时,next=iStride
sad = SearchBlockBi_C(pData->CurU, pData->RefP[4] + offset, pData->RefP[4] + offset + next, iStride);
sad += SearchBlockBi_C(pData->CurV, pData->RefP[5] + offset, pData->RefP[5] + offset + next, iStride);
break;
default:
Transfer8_ImageToImage_Interpolate_HV(pData->RefQuarl, pData->RefP[4] + offset, iStride, pData->rounding);
sad = ComputBlockSad(pData->CurU, pData->RefQuarl, iStride);
Transfer8_ImageToImage_Interpolate_HV(pData->RefQuarl, pData->RefP[5] + offset, iStride, pData->rounding);
sad += ComputBlockSad(pData->CurV, pData->RefQuarl, iStride);
break;
}
pData->chromaSAD = sad;
return sad;
}
void DiaSearch1(short x, short y, MvSearchData* pData, short bDirection, CheckFunc* CheckMember)
{
unsigned int * const iDirection = &pData->dir;
for (;;)
{
*iDirection = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -