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

📄 mbmotionestcomp.c

📁 quicktime linux播放器v1
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (first_pass)    {		best_sdelta2 = best_sdelta;		best_dx2 = best_dx;		best_dy2 = best_dy;		// perform 2nd pass search, center=pmv		first_pass = 0;		center_dx = 0;		center_dy = 0;		goto start;    }	if (best_sdelta2 < best_sdelta)	{		best_sdelta = best_sdelta2;		best_dx = best_dx2;		best_dy = best_dy2;    }	/*	refinement step	(only neccessary when diamond points are multiplied by 2)	*/	center_dx = best_dx;	center_dy = best_dy;	if (!(best_sdelta < MV16_THRESHOLD))	for (dx = center_dx - 1; dx <= center_dx + 1; dx++)	{		for (dy = center_dy - 1; dy <= center_dy + 1; dy++)	    {			int32_t sdelta;					    if ((dx == center_dx && dy == center_dy) ||			    dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy)			{				continue;			}			sdelta = SAD16(cur,					get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, pred_x + dx, pred_y + dy, iEdgedWidth),					iEdgedWidth,					best_sdelta);			sdelta += calc_delta_16(dx, dy, (uint8_t)iFcode) * iQuant;			if (sdelta < best_sdelta)			{				best_sdelta = sdelta;				best_dx = dx;				best_dy = dy;				if (sdelta < MV16_THRESHOLD)				{					break;				}			}		}	}	pmv->x = pred_x + best_dx;	pmv->y = pred_y + best_dy;    return best_sdelta;}static uint32_t MotionSearch8(				const uint8_t * const pRef,				const uint8_t * const pRefH,				const uint8_t * const pRefV,				const uint8_t * const pRefHV,				const Image * const pCur,				const uint32_t x, const uint32_t y,				const int32_t pred_x, const int32_t pred_y,				const int32_t start_x, const int32_t start_y,				const uint32_t iFcode,				const uint32_t iQuant,				MotionVector * const pmv){	const uint32_t iEdgedWidth = pCur->iEdgedWidth;	const uint8_t * cur = pCur->pY + x*8 + y*8*iEdgedWidth;	const uint32_t iEdgeSize = iEdgedWidth - pCur->iWidth;	const DPOINT * diamond;    int32_t min_dx, max_dx;    int32_t min_dy, max_dy;    int32_t dx, dy;    int32_t center_dx, center_dy;	    uint32_t best_sdelta;	int32_t best_dx, best_dy;	    uint32_t point;	uint32_t best_point;    uint32_t count;//	if (pCur->iWidth % 16)//		iEdgeSize += (pCur->iWidth % 16) - 16;//printf("MotionSearch8 1\n");    get_range(			&min_dx, &max_dx,			&min_dy, &max_dy,			x, y, 8,			pCur->iWidth, pCur->iHeight,			pred_x, pred_y,			iEdgeSize,			iFcode);//printf("MotionSearch8 1\n");	min_dx = EVEN(min_dx);	max_dx = EVEN(max_dx);	min_dy = EVEN(min_dy);	max_dy = EVEN(max_dy);	// center search on start_x/y (mv from previous frame)//printf("MotionSearch8 1\n");	center_dx = EVEN(start_x - pred_x);    center_dy = EVEN(start_y - pred_y);//printf("MotionSearch8 1\n");	if (center_dx < min_dx) 		center_dx = min_dx;	else if (center_dx > max_dx) 		center_dx = max_dx;//printf("MotionSearch8 1\n");	if (center_dy < min_dy) 		center_dy = min_dy;	else if (center_dy > max_dy) 		center_dy = max_dy;//printf("MotionSearch8 1\n");	// sad/delta for center		best_sdelta = SAD8(cur,			get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, pred_x + center_dx, pred_y + center_dy, iEdgedWidth),			iEdgedWidth);	best_sdelta += calc_delta_8(center_dx, center_dy, (uint8_t)iFcode) * iQuant;//printf("MotionSearch8 1\n");	if (best_sdelta < MV8_THRESHOLD) {		pmv->x = pred_x + center_dx;		pmv->y = pred_y + center_dy;	    return best_sdelta;	}	best_dx = center_dx;	best_dy = center_dy;//printf("MotionSearch8 1\n");	diamond = diamond_large;    point = 0;    count = 8;    best_point = 99;//printf("MotionSearch8 1\n");    while(1)    {		while(count--)		{			uint32_t sdelta;			uint8_t *tmp;			dx = center_dx + diamond[point].dx;			dy = center_dy + diamond[point].dy;		    if (dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy)		    {				point =  (point + 1) & 7;		// % 8				continue;		    }//printf("MotionSearch8 1 %d\n", iEdgedWidth);			tmp = get_ref(pRef, 						pRefH, 						pRefV, 						pRefHV, 						x, 						y, 						8, 						pred_x + dx, 						pred_y + dy, 						iEdgedWidth);//printf("MotionSearch8 1 %p %p %d\n", cur, tmp, iEdgedWidth); 			sdelta = SAD8(cur,					tmp,					iEdgedWidth);//printf("MotionSearch8 1\n");			sdelta += calc_delta_8(dx, dy, (uint8_t)iFcode) * iQuant;//printf("MotionSearch8 1\n");			if (sdelta < best_sdelta)			{				if (sdelta < MV8_THRESHOLD) {					pmv->x = pred_x + dx;					pmv->y = pred_y + dy;				    return sdelta;				}				best_sdelta = sdelta;				best_dx = dx;				best_dy = dy;				best_point = point;			}//printf("MotionSearch8 2\n"); 			point =  (point + 1) & 7;		// % 8		}		if (diamond == diamond_small)		{			break;		}		if (best_dx == center_dx && best_dy == center_dy)		{			diamond = diamond_small;			point = 0;			count = 4;		}		else		{			if (best_dx == center_dx || best_dy == center_dy)			{				point = (best_point + 6) & 7;   // % 8				count = 5;			}			else			{				point = (best_point + 7) & 7;   // % 8				count = 3;			}						if (best_point == 99)			{				// we're getting cases where min=-30 & max=-34				// under normal circumstances we should never get here!				// likely cause: buggy obtainrange16//				char tmp[1000];//				wsprintf(tmp, "8c:%i,%i  min:%i,%i  max:%i,%i\n", center_dx, center_dy, min_dx, min_dy, max_dx, max_dy);//				OutputDebugString(tmp);				// set point=6 for binary compatibility with latest cvs snapshot				point = 6;			}						center_dx = best_dx;			center_dy = best_dy;	    }    }//printf("MotionSearch8 1\n");	/*	refinement step	(only neccessary when diamond points are multiplied by 2)	center_dx = best_dx;	center_dy = best_dy;//printf("MotionSearch8 1\n");	if (!(best_sdelta < MV8_THRESHOLD))	for (dx = center_dx - 1; dx <= center_dx + 1; dx++)	{		for (dy = center_dy - 1; dy <= center_dy + 1; dy++)	    {			uint32_t sdelta;					    if ((dx == center_dx && dy == center_dy) ||			    dx < min_dx || dx > max_dx || dy < min_dy || dy > max_dy)			{				continue;			}			sdelta = SAD8(cur,					get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, pred_x + dx, pred_y + dy, iEdgedWidth),					iEdgedWidth);			sdelta += calc_delta_8(dx, dy, (uint8_t)iFcode) * iQuant;			if (sdelta < best_sdelta)			{				best_sdelta = sdelta;				best_dx = dx;				best_dy = dy;				if (sdelta < MV8_THRESHOLD)				{					break;				}			}		}	} *///printf("MotionSearch8 2\n");	pmv->x = pred_x + best_dx;	pmv->y = pred_y + best_dy;    return best_sdelta;}static __inline void CompensateBlock(Image * const pVcur,				     const Image * const pRefN,					 const Image * const pRefH,				     const Image * const pRefV,					 const Image * const pRefHV,				     uint32_t x, uint32_t y,					 const int32_t comp,					 const int32_t dx,  const int dy,					 int16_t * const dct_codes){    uint32_t stride = pVcur->iEdgedWidth;  // (comp ? 2 : 1);    uint8_t * pCur;    const uint8_t * pRef;    const Image * pVref;	int32_t ddx;	int32_t ddy;//printf("CompensateBlock 1\n");	switch ( ((dx&1)<<1) + (dy&1) )   // ((dx%2)?2:0)+((dy%2)?1:0)    {    case 0:		pVref = pRefN;		ddx = dx/2;		ddy = dy/2;		break;    case 1:		pVref = pRefV;		ddx = dx/2;		ddy = (dy-1)/2;		break;    case 2:		pVref = pRefH;		ddx = (dx-1)/2;		ddy = dy/2;		break;    case 3:    default:		pVref = pRefHV;		ddx = (dx-1)/2;		ddy = (dy-1)/2;		break;    }//printf("CompensateBlock 1\n");    switch (comp)    {    case 0:		pCur = pVcur->pY;		pRef = pVref->pY;		break;    case 1:		pCur = pVcur->pU;		pRef = pVref->pU;		stride /=2;		break;    case 2:	default:		pCur = pVcur->pV;		pRef = pVref->pV;		stride /=2;		break;    }//printf("CompensateBlock 1 %p %p\n", pRef, pCur);	pCur += (int)(y * stride + x);    pRef += (int)((y + ddy) * stride + x + ddx);//printf("CompensateBlock 2 %p %p\n", pRef, pCur);	COMPENSATE(dct_codes, pCur, pRef, stride);//printf("CompensateBlock 2\n");}#define SEARCH16	MotionSearch16#define SEARCH8		MotionSearch8bool MBMotionEstComp(			const MBParam * const pParam,		    const uint32_t j,			const uint32_t i,		    const Image * const pRef,			const Image * const pRefH,		    const Image * const pRefV,			const Image * const pRefHV,		    Image * const pCurrent,		    int16_t dct_codes[][64],			const int inter4v_mode){    static const uint32_t roundtab[16] =		{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };    const uint32_t iWcount = pCurrent->iMbWcount;	Macroblock * const pMB = pCurrent->pMBs + j + i * iWcount;  	int32_t pred_x;	int32_t pred_y;    MotionVector mv16;    int32_t sad8_result = 0;    int32_t sad16_result;    int32_t deviation;	int32_t sum;    int32_t dx, dy;//printf("MBMotionEstComp 1\n");   	get_pmv(pCurrent->pMBs, j, i, iWcount, 0, &pred_x, &pred_y);    sad16_result = SEARCH16(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY,				pCurrent, 				j, i, pred_x, pred_y,				pParam->fixed_code,				pParam->quant,pParam->quality, 				&mv16); //printf("MBMotionEstComp 1\n");       if (pParam->quality > 3)    {//printf("MBMotionEstComp 1\n");   		sad8_result = SEARCH8(pRef->pY, 				pRefH->pY, 				pRefV->pY, 				pRefHV->pY,			    pCurrent, 				2 * j, 2 * i, 				pred_x, 				pred_y,			    mv16.x, 				mv16.y, 				pParam->fixed_code,			    pParam->quant, 				&pMB->mvs[0]);//printf("MBMotionEstComp 1\n");   		get_pmv(pCurrent->pMBs, j, i, iWcount, 1, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n");   		sad8_result += SEARCH8(pRef->pY, 			pRefH->pY, 			pRefV->pY, 			pRefHV->pY,			pCurrent, 			2 * j + 1, 			2 * i, 			pred_x, 			pred_y,			mv16.x, 			mv16.y, 			pParam->fixed_code,			pParam->quant, 			&pMB->mvs[1]);//printf("MBMotionEstComp 1\n");   		get_pmv(pCurrent->pMBs, j, i, iWcount, 2, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n");   		sad8_result += SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY,			      pCurrent, 2 * j, 2 * i + 1, pred_x, pred_y,			      mv16.x, mv16.y, pParam->fixed_code,			      pParam->quant, &pMB->mvs[2]);//printf("MBMotionEstComp 1\n");   		get_pmv(pCurrent->pMBs, j, i, iWcount, 3, &pred_x, &pred_y);//printf("MBMotionEstComp 1\n");   		sad8_result += SEARCH8(pRef->pY, pRefH->pY, pRefV->pY, pRefHV->pY,			      pCurrent, 2 * j + 1, 2 * i + 1, pred_x,			      pred_y, mv16.x, mv16.y,			      pParam->fixed_code, pParam->quant,			      &pMB->mvs[3]);//printf("MBMotionEstComp 1\n");       }//printf("MBMotionEstComp 1\n");       	/* decide: MODE_INTER or MODE_INTER4V 		mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v	*/	if (inter4v_mode == 1) {		if ((pParam->quality <= 3) || 			(sad16_result < (sad8_result + (IMV16X16 * pParam->quant)))) { 						sad8_result = sad16_result;			pMB->mode = MODE_INTER;			pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;			pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;		}		else			pMB->mode = MODE_INTER4V;	}	else 	{		sad8_result = sad16_result;		pMB->mode = MODE_INTER;		pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;		pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;	}//printf("MBMotionEstComp 1\n");   	/* decide: MODE_INTER/4V or MODE_INTRA 	    if (dev_intra < sad_inter - 2 * nb) use_intra	*/	deviation = DEV16(pCurrent->pY + j*16 + i*16*pCurrent->iEdgedWidth, pCurrent->iEdgedWidth);	    if (deviation < sad8_result - INTER_BIAS)    {		pMB->mode = MODE_INTRA;		pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;		pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;		return 1;    }//printf("MBMotionEstComp 1\n");       /** Motion compensation **/    switch (pMB->mode)    {    case MODE_INTER:    case MODE_INTER_Q:		dx = pMB->mvs[0].x;		dy = pMB->mvs[0].y;		/*if (pParam->quality <= 3)		{		    assert(!(dx % 2));		    assert(!(dy % 2));		} */		CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			16 * j, 16 * i, 0, dx, dy, dct_codes[0]);			CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			16 * j + 8, 16 * i, 0, dx, dy, dct_codes[1]);		CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			16 * j, 16 * i + 8, 0, dx, dy, dct_codes[2]);		CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			16 * j + 8, 16 * i + 8, 0, dx, dy, dct_codes[3]);		if (!(dx & 3))		// % 4		    dx /= 2;		else		    dx = (dx >> 1) | 1;		if (!(dy & 3))		// % 4		    dy /= 2;		else		    dy = (dy >> 1) | 1;		CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			8*j, 8*i, 1, dx, dy, dct_codes[4]);		CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			8*j, 8*i, 2, dx, dy, dct_codes[5]);		break;   		case MODE_INTER4V:		// assert(pParam->quality >= 4);			CompensateBlock(pCurrent,			pRef, pRefH, pRefV, pRefHV,			16 * j, 16 * i, 0, pMB->mvs[0].x, pMB->mvs[0].y,			dct_codes[0]);		CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV,			16 * j + 8, 16 * i, 0, pMB->mvs[1].x,			pMB->mvs[1].y, dct_codes[1]);		CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV,			16 * j, 16 * i + 8, 0, pMB->mvs[2].x,			pMB->mvs[2].y, dct_codes[2]);		CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV,			16 * j + 8, 16 * i + 8, 0, pMB->mvs[3].x,			pMB->mvs[3].y, dct_codes[3]);		sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;			if (sum == 0)		    dx = 0;		else		    dx = SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2);		sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;		if (sum == 0)		    dy = 0;		else		    dy = SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2);		CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV,			8*j, 8*i, 1, dx, dy, dct_codes[4]);		CompensateBlock(pCurrent, pRef, pRefH, pRefV, pRefHV,			8*j, 8*i, 2, dx, dy, dct_codes[5]);			break;    case MODE_INTRA:    case MODE_INTRA_Q:	break;    }						 // switch//printf("MBMotionEstComp 2\n");   	return 0;    // return (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q);}

⌨️ 快捷键说明

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