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

📄 mot_est.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{
		for(j = 0, k = 0; j < blocksize; j+=4, k+=8)
		{
			sad+=absm(p1[j] - p2[k]);
			sad+=absm(p1[j+1] - p2[k+2]);
			sad+=absm(p1[j+2] - p2[k+4]);
			sad+=absm(p1[j+3] - p2[k+6]);
			if (sad > sad_last)
				return MAX_SAD;
		}
		p1+=lx1;
		p2+=lx2*2;
	}
	return sad;
}

/*!
*******************************************************************************
*
*   Name:          Choose_mode     
*   Description:   Choose INTRA or INTER
*   Input:         Position of current MB, sad value derived from motion estimation
*   Output:        
*   Side effect:   If the mode is INTRA, set current mv zero
*   Author:        Modified from tmn1.7 by lcl
*   Last modified: 2002/11/23 by lcl
*
*******************************************************************************/
void choose_mode(H263VencStatus *encoder, MCParam *MC, int x_pos, int y_pos)
{
	int i,j;
	int MB_mean = 0, A = 0;
	int y_off;
	unsigned char *curr = encoder->frameToEncode.pLum;
	int mb_size = 16;
	int lines = y_pos/mb_size;
	int pels = x_pos/mb_size;
	int sad16, sad8;
	int min_sad;
	
	sad16 = MC->mv_frame[0][lines+1][pels+1]->min_sad;
	sad8  = !encoder->use4mv ? MAX_SAD :
	MC->mv_frame[1][lines+1][pels+1]->min_sad+
		MC->mv_frame[2][lines+1][pels+1]->min_sad+
		MC->mv_frame[3][lines+1][pels+1]->min_sad+
		MC->mv_frame[4][lines+1][pels+1]->min_sad+ PREF_16_VEC;
	
	if (sad8 < sad16)
	{
		MC->mv_frame[0][lines+1][pels+1]->Mode = MODE_INTER4V;
	}
	else
	{
		MC->mv_frame[0][lines+1][pels+1]->Mode = MODE_INTER;
	}
	min_sad = sad8 < sad16 ? sad8 : sad16;
	
	for (j = 0; j < mb_size; j++) 
	{
		y_off = (y_pos + j) * encoder->pels;
		for (i = 0; i < mb_size; i++) 
		{  
			MB_mean += *(curr + x_pos + i + y_off);
		}
	}
	MB_mean /= (mb_size * mb_size);
	
	for (j = 0; j < mb_size; j++) 
	{
		y_off = (y_pos + j) * encoder->pels;
		for (i = 0; i < mb_size; i++) 
		{
			A += abs( *(curr + x_pos + i + y_off) - MB_mean );
		}
	}
	if (A < (min_sad - 500)) 
	{
		zeroVec(MC->mv_frame[0][lines+1][pels+1]);
		(MC->mv_frame[0][lines+1][pels+1])->Mode = MODE_INTRA;
	}
}

/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
int ZeroVector(MotionVector *mv)
{
	if(0 == mv->x && 0 == mv->y && 0 == mv->x_half && 0 == mv->y_half)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/

void FindNbrMV(MotionVector *MV[6][MBR+1][MBC+2], int block, int index, 
			   int mb_x, int mb_y, int *vec_x, int *vec_y, int BACKWARD)
{
	int p[3];
	int xin1, xin2, xin3;
	int yin1, yin2, yin3;
	int vec1, vec2, vec3;
	int l8, o8, or8;
	

	if (!BACKWARD)
	{
		l8 = o8 = or8 = 0;
		if (MV[0][mb_y+1][mb_x]->Mode == MODE_INTER4V)
		{
			l8 = 1;
		}
		
		if (MV[0][mb_y][mb_x+1]->Mode == MODE_INTER4V)
		{
			o8 = 1;
		}
		
		if (MV[0][mb_y][mb_x+2]->Mode == MODE_INTER4V)
		{
			or8 = 1;
		}
		
		
		switch (block) 
		{
		case 0: 
			vec1 = (l8 ? 2 : 0) ; yin1 = mb_y  ; xin1 = mb_x-1;
			vec2 = (o8 ? 3 : 0) ; yin2 = mb_y-1; xin2 = mb_x;
			vec3 = (or8? 3 : 0) ; yin3 = mb_y-1; xin3 = mb_x+1;
			break;
		case 1:
			vec1 = (l8 ? 2 : 0) ; yin1 = mb_y  ; xin1 = mb_x-1;
			vec2 = (o8 ? 3 : 0) ; yin2 = mb_y-1; xin2 = mb_x;
			vec3 = (or8? 3 : 0) ; yin3 = mb_y-1; xin3 = mb_x+1;
			break;
		case 2:
			vec1 = 1            ; yin1 = mb_y  ; xin1 = mb_x;
			vec2 = (o8 ? 4 : 0) ; yin2 = mb_y-1; xin2 = mb_x;
			vec3 = (or8? 3 : 0) ; yin3 = mb_y-1; xin3 = mb_x+1;
			break;
		case 3:
			vec1 = (l8 ? 4 : 0) ; yin1 = mb_y  ; xin1 = mb_x-1;
			vec2 = 1            ; yin2 = mb_y  ; xin2 = mb_x;
			vec3 = 2            ; yin3 = mb_y  ; xin3 = mb_x;
			break;
		case 4:
			vec1 = 3            ; yin1 = mb_y  ; xin1 = mb_x;
			vec2 = 1            ; yin2 = mb_y  ; xin2 = mb_x;
			vec3 = 2            ; yin3 = mb_y  ; xin3 = mb_x;
			break;
		}
	}
	else
	{
		vec1 = vec2 = vec3 = 5;
		yin1 = mb_y  ; xin1 = mb_x-1;
		yin2 = mb_y-1; xin2 = mb_x;
		yin3 = mb_y-1; xin3 = mb_x+1;
	}

	p[0] = MV[vec1][yin1+1][xin1+1]->x;
	p[1] = mb_y > 0 ? MV[vec2][yin2+1][xin2+1]->x : 0;
	p[2] = mb_y > 0 ? MV[vec3][yin3+1][xin3+1]->x : 0;
	*vec_x = p[index];
	p[0] = MV[vec1][yin1+1][xin1+1]->y;
	p[1] = mb_y > 0 ? MV[vec2][yin2+1][xin2+1]->y : 0;
	p[2] = mb_y > 0 ? MV[vec3][yin3+1][xin3+1]->y : 0;
    *vec_y = p[index];	
} 

/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
void printmv(H263VencStatus *encoder, MCParam *MC, int r, int c, int BACKWARD)
{
	if (!BACKWARD)
	{
		printf("(%d, %d)", MC->mv_frame[0][r+1][c+1]->x, MC->mv_frame[0][r+1][c+1]->y);
		printf("(%d, %d)", MC->mv_frame[0][r+1][c+1]->x_half, MC->mv_frame[0][r+1][c+1]->y_half);
		printf("%d", MC->mv_frame[0][r+1][c+1]->min_sad);
		if(encoder->use4mv)
		{
			printf("-");
			printf("(%d, %d)", MC->mv_frame[1][r+1][c+1]->x, MC->mv_frame[1][r+1][c+1]->y);
			printf("(%d, %d)", MC->mv_frame[1][r+1][c+1]->x_half, MC->mv_frame[1][r+1][c+1]->y_half);
			printf("&");
			printf("(%d, %d)", MC->mv_frame[2][r+1][c+1]->x, MC->mv_frame[2][r+1][c+1]->y);
			printf("(%d, %d)", MC->mv_frame[2][r+1][c+1]->x_half, MC->mv_frame[2][r+1][c+1]->y_half);
			printf("&");
			printf("(%d, %d)", MC->mv_frame[3][r+1][c+1]->x, MC->mv_frame[3][r+1][c+1]->y);
			printf("(%d, %d)", MC->mv_frame[3][r+1][c+1]->x_half, MC->mv_frame[3][r+1][c+1]->y_half);
			printf("&");
			printf("(%d, %d)", MC->mv_frame[4][r+1][c+1]->x, MC->mv_frame[4][r+1][c+1]->y);
			printf("(%d, %d)", MC->mv_frame[4][r+1][c+1]->x_half, MC->mv_frame[4][r+1][c+1]->y_half);
			printf("%d",  MC->mv_frame[1][r+1][c+1]->min_sad+MC->mv_frame[2][r+1][c+1]->min_sad+
				MC->mv_frame[3][r+1][c+1]->min_sad+MC->mv_frame[4][r+1][c+1]->min_sad);
		}
		printf("\n");
	}
	else 
	{
		printf("Backward MV: ");
		printf("(%d, %d)", MC->mv_frame[5][r+1][c+1]->x, MC->mv_frame[5][r+1][c+1]->y);
		printf("(%d, %d)", MC->mv_frame[5][r+1][c+1]->x_half, MC->mv_frame[5][r+1][c+1]->y_half);
		printf("%d", MC->mv_frame[5][r+1][c+1]->min_sad);
		printf("\n");
	}
}
/*!
*******************************************************************************
*
*   Name:          findchromMV
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 2002/12/21
*
*******************************************************************************/
void findchromMV(H263VencStatus *encoder, MCParam *MC, int x, int y, int *dx, int *dy, int BACKWARD)
{
	int r = y/16+1;
	int c = x/16+1;
	int vec = BACKWARD ? 5 : 0;
    int roundtab[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
	int sum;
	
	if (((MC->mv_frame[0][r][c]->Mode == MODE_INTER4V)||(MC->mv_frame[0][r][c]->Mode == MODE_INTER4V_Q))
		&& encoder->use4mv && (encoder->PTYPE != B_IMG))
	{
		
		sum = MC->mv_frame[1][r][c]->x*2+MC->mv_frame[1][r][c]->x_half+
			MC->mv_frame[2][r][c]->x*2+MC->mv_frame[2][r][c]->x_half+
			MC->mv_frame[3][r][c]->x*2+MC->mv_frame[3][r][c]->x_half+
			MC->mv_frame[4][r][c]->x*2+MC->mv_frame[4][r][c]->x_half;
		*dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
		sum = MC->mv_frame[1][r][c]->y*2+MC->mv_frame[1][r][c]->y_half+
			MC->mv_frame[2][r][c]->y*2+MC->mv_frame[2][r][c]->y_half+
			MC->mv_frame[3][r][c]->y*2+MC->mv_frame[3][r][c]->y_half+
			MC->mv_frame[4][r][c]->y*2+MC->mv_frame[4][r][c]->y_half;
		*dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
	}
	else
	{
		*dx = 2*MC->mv_frame[vec][r][c]->x + MC->mv_frame[vec][r][c]->x_half;
		*dy = 2*MC->mv_frame[vec][r][c]->y + MC->mv_frame[vec][r][c]->y_half;
		*dx = ( *dx % 4 == 0 ? *dx >> 1 : (*dx>>1)|1 );
		*dy = ( *dy % 4 == 0 ? *dy >> 1 : (*dy>>1)|1 );
	}
}

/*!
*******************************************************************************
*
*   Name:          findchromMV_dir
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 2003/1/9
*
*******************************************************************************/
void findchromMV_dir(H263VencStatus *encoder, MCParam *MC, int x, int y, 
					 int *dx1, int *dy1, int *dx2, int *dy2)
{
	int r = y/16;
	int c = x/16;
	int trb;
	int trd;
	int dxf, dyf, dxb, dyb;
    int roundtab[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
	int sum1, sum2, sum3, sum4;
	int i;

	trb = encoder->TRB - encoder->TRP[encoder->ref_index];
	if (trb < 0)
	{
		trb += 256;
	}
	trd = encoder->TRP[encoder->zero_index] - encoder->TRP[encoder->ref_index];
	if (trd < 0)
	{
		trd += 256;
	}

	if (((MC->mv_lastframe[0][r][c]->Mode == MODE_INTER4V)||(MC->mv_lastframe[0][r][c]->Mode == MODE_INTER4V_Q))
		&& encoder->use4mv )
	{	
		sum1 = sum2 = sum3 = sum4 = 0;
		for (i = 1; i < 5; i++)
		{
			dxf = (MC->mv_lastframe[i][r][c]->x*2 + MC->mv_lastframe[i][r][c]->x_half) * trb / trd;
			dyf = (MC->mv_lastframe[i][r][c]->y*2 + MC->mv_lastframe[i][r][c]->y_half) * trb / trd;
			dxb = (MC->mv_lastframe[i][r][c]->x*2 + MC->mv_lastframe[i][r][c]->x_half) * (trb - trd) / trd;
			dyb = (MC->mv_lastframe[i][r][c]->y*2 + MC->mv_lastframe[i][r][c]->y_half) * (trb - trd) / trd;
			sum1 += dxf;
			sum2 += dyf;
			sum3 += dxb;
			sum4 += dyb;
		}
		*dx1 = sign(sum1)*(roundtab[abs(sum1)%16] + (abs(sum1)/16)*2);
		*dy1 = sign(sum2)*(roundtab[abs(sum2)%16] + (abs(sum2)/16)*2);
		*dx2 = sign(sum3)*(roundtab[abs(sum3)%16] + (abs(sum3)/16)*2);
		*dy2 = sign(sum4)*(roundtab[abs(sum4)%16] + (abs(sum4)/16)*2);
	}
	else
	{
		dxf = (MC->mv_lastframe[0][r][c]->x*2 + MC->mv_lastframe[0][r][c]->x_half) * trb / trd;
		dyf = (MC->mv_lastframe[0][r][c]->y*2 + MC->mv_lastframe[0][r][c]->y_half) * trb / trd;
		dxb = (MC->mv_lastframe[0][r][c]->x*2 + MC->mv_lastframe[0][r][c]->x_half) * (trb - trd) / trd;
		dyb = (MC->mv_lastframe[0][r][c]->y*2 + MC->mv_lastframe[0][r][c]->y_half) * (trb - trd) / trd;

		*dx1 = (dxf % 4 == 0 ? dxf >> 1 : (dxf>>1)|1);
		*dy1 = (dyf % 4 == 0 ? dyf >> 1 : (dyf>>1)|1);
		*dx2 = (dxb % 4 == 0 ? dxb >> 1 : (dxb>>1)|1);
		*dy2 = (dyb % 4 == 0 ? dyb >> 1 : (dyb>>1)|1);
	}
}
/*!
*******************************************************************************
*
*   Name:          saveVec
*   Description:   Save vectors for B frames to compute MVs in direct mode
*   Input:         
*   Output:        
*   Last modified: 2003/1/8
*
*******************************************************************************/
void saveVec(MCParam *MC, int lines, int pels)
{
	int i, j, k;

	for (i = 0; i < lines; i++)
	{
		for (j = 0; j < pels; j++)
		{
			if (MC->mv_frame[0][i+1][j+1]->Mode == MODE_INTER4V)
			{
				MC->mv_lastframe[0][i][j]->Mode = MC->mv_frame[0][i+1][j+1]->Mode;
				for (k = 0; k < 5; k++)
				{
					MC->mv_lastframe[k][i][j]->x = MC->mv_frame[k][i+1][j+1]->x;
					MC->mv_lastframe[k][i][j]->y = MC->mv_frame[k][i+1][j+1]->y;
					MC->mv_lastframe[k][i][j]->x_half = MC->mv_frame[k][i+1][j+1]->x_half;
					MC->mv_lastframe[k][i][j]->y_half = MC->mv_frame[k][i+1][j+1]->y_half;
					MC->mv_lastframe[k][i][j]->Mode = MC->mv_frame[k][i+1][j+1]->Mode;
					MC->mv_lastframe[k][i][j]->min_sad = MC->mv_frame[k][i+1][j+1]->min_sad;
				}
			}
			else
			{
				MC->mv_lastframe[0][i][j]->x = MC->mv_frame[0][i+1][j+1]->x;
				MC->mv_lastframe[0][i][j]->y = MC->mv_frame[0][i+1][j+1]->y;
				MC->mv_lastframe[0][i][j]->x_half = MC->mv_frame[0][i+1][j+1]->x_half;
				MC->mv_lastframe[0][i][j]->y_half = MC->mv_frame[0][i+1][j+1]->y_half;
				MC->mv_lastframe[0][i][j]->Mode = MC->mv_frame[0][i+1][j+1]->Mode;
				MC->mv_lastframe[0][i][j]->min_sad = MC->mv_frame[0][i+1][j+1]->min_sad;
			}
		}
	}
}

⌨️ 快捷键说明

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