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

📄 motioncompute.c

📁 DM642的mpeg4编码
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -