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

📄 block.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*!
********************************************************
*\file
*    block.cpp
*\brief
*    implementation for 8x8 block level functions.
*\date
*    12/6/2002
*
********************************************************/
#include "HEnc.h"
#include "block.h"
#include <stdio.h>
#include <stdlib.h>


/*!
*******************************************************************************
*
*   Name:          pred_lum
*   Description:   lum prediction for the data of one 8x8 block
*   Input:         interpolated lum image, the position of current block, MV
*   Output:        prediction data
*   Optimization:  no
*   Last modified: 2002/12/21 
*
*******************************************************************************/
void pred_lum_c(int pix_x, int pix_y, MotionVector *MV, unsigned char *ipol, 
			  int lx, unsigned char *pred_block)
{
	int pred_x, pred_y;
	int i, j, k, l;
	int h_space = 2;
	int v_space = lx * 2;
	unsigned char *tmp1;
	unsigned char *tmp2 = pred_block;

	pred_x = 2*pix_x + 2*MV->x + MV->x_half;
	pred_y = 2*pix_y + 2*MV->y + MV->y_half;
	tmp1 = ipol + lx*pred_y + pred_x;

	for (i = 0, k = 0; i < 8; i++, k+=v_space)
	{
		for (j = 0, l = 0; j < 8; j++, l+=h_space)
		{
			*tmp2 = *(tmp1 + k + l);
			tmp2++;
		}
	}

}
/*!
*******************************************************************************
*
*   Name:          pred_lum_bid
*   Description:   bi-direction lum prediction for the data of one 8x8 block(B frames only)
*   Input:         interpolated lum images, the position of current block, displacement
*   Output:        prediction data
*   Optimization:  no
*   Last modified: 2003/1/9 
*
*******************************************************************************/
void pred_lum_bid_c(int pix_x, int pix_y, int dxf, int dyf, int dxb, int dyb, 
					unsigned char *prev_ipol, unsigned char *next_ipol, int lx, 
					unsigned char *pred_block)
{
	int fw_pred_x, fw_pred_y;
	int bw_pred_x, bw_pred_y;
	int i, j, k, l;
	int h_space = 2;
	int v_space = lx * 2;
	unsigned char *tmp1;
	unsigned char *tmp2;
	unsigned char *tmp3 = pred_block;

	fw_pred_x = 2*pix_x + dxf;
	fw_pred_y = 2*pix_y + dyf;
	bw_pred_x = 2*pix_x + dxb;
	bw_pred_y = 2*pix_y + dyb;

	tmp1 = prev_ipol + lx*fw_pred_y + fw_pred_x;
	tmp2 = next_ipol + lx*bw_pred_y + bw_pred_x;

	for (i = 0, k = 0; i < 8; i++, k+=v_space)
	{
		for (j = 0, l = 0; j < 8; j++, l+=h_space)
		{
			*tmp3 = (*(tmp1 + k + l) + *(tmp2 + k + l) + 1) / 2;
			tmp3++;
		}
	}
}

/*!
*******************************************************************************
*
*   Name:          pred_obmc
*   Description:   overlaped motion compensation prediction for lum
*   Input:         
*   Output:        
*   Optimization:  no
*   Last modified: 2002/12/25
*
*******************************************************************************/

void pred_obmc_c(int x, int y, MotionVector *MV[6][MBR+1][MBC+2], int pic_width, 
			   unsigned char *prev_ipol, int lx, int block, unsigned char *pred_block)
{
	int r = y/16+1;
	int c = x/16+1;
	int use4mv_c = (MV[0][r][c]->Mode == MODE_INTER4V ? 1 : 0);
	int	use4mv_t = (MV[0][r-1][c]->Mode == MODE_INTER4V ? 1 : 0);
	int use4mv_l = (MV[0][r][c-1]->Mode == MODE_INTER4V ? 1 : 0);
	int use4mv_r = (MV[0][r][c+1]->Mode == MODE_INTER4V ? 1 : 0);
	int intra_t, intra_l, intra_r;
	int vecc, vect, vecb, vecl, vecr;
	int x_curr, y_curr, x_top, y_top, x_btm, y_btm, x_left, y_left, x_right, y_right;
	int pred_x_c, pred_x_t, pred_x_b, pred_x_l, pred_x_r;
	int pred_y_c, pred_y_t, pred_y_b, pred_y_l, pred_y_r;
	int val_c, val_t, val_b, val_l, val_r;
	int m, n;

	intra_t = (MV[0][r-1][c]->Mode == MODE_INTRA ? 1 : 0);
	intra_t = (MV[0][r-1][c]->Mode == MODE_INTRA_Q ? 1 : intra_t); 
	intra_l = (MV[0][r][c-1]->Mode == MODE_INTRA ? 1 : 0);
	intra_l = (MV[0][r][c-1]->Mode == MODE_INTRA_Q ? 1 : intra_l); 
	intra_r = (MV[0][r][c+1]->Mode == MODE_INTRA ? 1 : 0);
	intra_r = (MV[0][r][c+1]->Mode == MODE_INTRA_Q ? 1 : intra_r); 

	switch (block)
	{
	case 1:
		vecc = use4mv_c ? 1 : 0;
		x_curr = c;
		y_curr = r;

		vect  = intra_t ? vecc : (use4mv_t ? 3 : 0);
		x_top = c;
		y_top = intra_t ? r : r-1;

		vecb = use4mv_c ? 3 : 0;
		x_btm = c;
		y_btm = r;

		vecl = intra_l ? vecc: (use4mv_l ? 2 : 0);
		x_left = intra_l ? c : c-1;
		y_left = r;

		vecr = use4mv_c ? 2 : 0;
		x_right = c;
		y_right = r;

		if (1 == c)
		{
			vecl = vecc;
			x_left = 1;
		}
		if (1 == r)
		{
			vect = vecc;
			y_top = 1;
		}

		break;
	case 2:
		vecc = use4mv_c ? 2 : 0;
		x_curr = c;
		y_curr = r;

		vect = intra_t ? vecc : (use4mv_t ? 4 : 0);
		x_top = c;
		y_top = intra_t ? r : r-1;

		vecb = use4mv_c ? 4 : 0;
		x_btm = c;
		y_btm = r;

		vecl = use4mv_c ? 1 : 0;
		x_left = c;
		y_left = r;

		vecr = intra_r ? vecc : (use4mv_r ? 1 : 0);
		x_right = intra_r ? c : c+1;
		y_right = r;

		if (1 == r)
		{
			vect = vecc;
			y_top = 1;
		}
		if (c == pic_width/16)
		{
			vecr = vecc;
			x_right = c;
		}
		break;
	case 3:
		vecc = use4mv_c ? 3 : 0;
		x_curr = c;
		y_curr = r;

		vect = use4mv_c ? 1 : 0;
		x_top = c;
		y_top = r;

		vecb = vecc;
		x_btm = c;
		y_btm = r;

		vecl = intra_l ? vecc : (use4mv_l ? 4 : 0);
		x_left = intra_l ? c : c-1;
		y_left = r;

		vecr = use4mv_c ? 4 : 0;
		x_right = c;
		y_right = r;

		if (1 == c)
		{
			vecl = vecc;
			x_left = 1;
		}
		break;
	case 4:
		vecc = use4mv_c ? 4 : 0;
		x_curr = c;
		y_curr = r;

		vect = use4mv_c ? 2 : 0;
		x_top = c;
		y_top = r;

		vecb = vecc;
		x_btm = c;
		y_btm = r;

		vecl = use4mv_c ? 3 : 0;
		x_left = c;
		y_left = r;

		vecr = intra_r ? vecc : (use4mv_r ? 3 : 0);
		x_right = intra_r ? c : c+1;
		y_right = r;

		if (c == pic_width/16)
		{
			vecr = vecc;
			x_right = c;
		}
		break;
	default:
		printf("obmc error, block type not exist.\n");
		exit(-1);
	}

	pred_x_c = 2*x + (((block-1)&1)<<4) + MV[vecc][y_curr][x_curr]->x*2 + MV[vecc][y_curr][x_curr]->x_half;
	pred_x_t = 2*x + (((block-1)&1)<<4) + MV[vect][y_top][x_top]->x*2 + MV[vect][y_top][x_top]->x_half;
	pred_x_b = 2*x + (((block-1)&1)<<4) + MV[vecb][y_btm][x_btm]->x*2 + MV[vecb][y_btm][x_btm]->x_half;
	pred_x_l = 2*x + (((block-1)&1)<<4) + MV[vecl][y_left][x_left]->x*2 + MV[vecl][y_left][x_left]->x_half;
	pred_x_r = 2*x + (((block-1)&1)<<4) + MV[vecr][y_right][x_right]->x*2 + MV[vecr][y_right][x_right]->x_half;

	pred_y_c = 2*y + (((block-1)&2)<<3) + MV[vecc][y_curr][x_curr]->y*2 + MV[vecc][y_curr][x_curr]->y_half;
	pred_y_t = 2*y + (((block-1)&2)<<3) + MV[vect][y_top][x_top]->y*2 + MV[vect][y_top][x_top]->y_half;
	pred_y_b = 2*y + (((block-1)&2)<<3) + MV[vecb][y_btm][x_btm]->y*2 + MV[vecb][y_btm][x_btm]->y_half;
	pred_y_l = 2*y + (((block-1)&2)<<3) + MV[vecl][y_left][x_left]->y*2 + MV[vecl][y_left][x_left]->y_half;
	pred_y_r = 2*y + (((block-1)&2)<<3) + MV[vecr][y_right][x_right]->y*2 + MV[vecr][y_right][x_right]->y_half;
	for (n = 0; n < 8; n++)
	{
		for (m = 0; m < 8; m++)
		{
			val_c = *(prev_ipol + (pred_y_c + n*2)*lx + pred_x_c+m*2) * Mc[n][m];
			val_t = *(prev_ipol + (pred_y_t + n*2)*lx + pred_x_t+m*2) * Mt[n][m];
			val_b = *(prev_ipol + (pred_y_b + n*2)*lx + pred_x_b+m*2) * Mb[n][m];
			val_l = *(prev_ipol + (pred_y_l + n*2)*lx + pred_x_l+m*2) * Ml[n][m];
			val_r = *(prev_ipol + (pred_y_r + n*2)*lx + pred_x_r+m*2) * Mr[n][m];

			*(pred_block + n*8 +m) = (val_c + val_t + val_b + val_l + val_r + 4)>>3;
		}
	}
}

/*!
*******************************************************************************
*
*   Name:          pred_chrom
*   Description:   chrom prediction for the data of one 8x8 block
*   Input:         reference picture, the position of current block.
*   Output:        prediction data
*   Optimization:  no
*   Last modified: 2002/11/21 
*   Note:          the chrom data is interpolated online
*
*******************************************************************************/
void pred_chrom_c(int pix_x, int pix_y, unsigned char *prev, 	int lx, 
				int dx, int dy, unsigned char *pred_block)
{
	int xint, yint;
	int xh, yh;
	int i, j;
	int x_off, y_off;
	unsigned char *tmp = pred_block;

    xint = dx>>1;
    xh = dx & 1;
    yint = dy>>1;
    yh = dy & 1;

	if (!xh && !yh)  //!< xh and yh are both zero
	{
		x_off = pix_x + xint;
		y_off = pix_y + yint;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = *(prev + (y_off+i)*lx + x_off+j);
				tmp++;
			}
		}
	}
	else if (!xh && yh) //!< yh is not zero
	{
		x_off = pix_x + xint;
		y_off = pix_y + yint;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					    *(prev + (y_off+i+yh)*lx + x_off+j) + 1)>>1;
				tmp++;
			}
		}
	}
	else if (xh && !yh)  //!< xh is not zero
	{
		x_off = pix_x + xint;
		y_off = pix_y + yint;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					    *(prev + (y_off+i)*lx + x_off+j+xh) + 1)>>1;
				tmp++;
			}
		}
	}
	else   //! neither xh nor yh is zero
	{
		x_off = pix_x + xint;
		y_off = pix_y + yint;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					   *(prev + (y_off+i)*lx + x_off+j+xh) +
						*(prev + (y_off+i+yh)*lx + x_off+j) +
						*(prev + (y_off+i+yh)*lx + x_off+j+xh) + 
						2)>>2;
				tmp++;
			}
		}
	}
}
/*!
*******************************************************************************
*
*   Name:          pred_chrom_bid
*   Description:   bi-direction chrom prediction for the data of one 8x8 block
*                  (only used in B frames) 
*   Input:         the pointer to previous picture and next picture,
*                  the position of current block, forward and backward displacement
*   Output:        prediction data
*   Optimization:  NO
*   Last modified: 2002/11/21 
*   Note:          the chrom data is interpolated online
*
*******************************************************************************/
void pred_chrom_bid_c(int pix_x, int pix_y, unsigned char *prev, 	unsigned char *next, int lx, 
				int dxf, int dyf, int dxb, int dyb, unsigned char *pred_block)
{
	int xint1, yint1, xint2, yint2;
	int xh1, yh1, xh2, yh2;
	int i, j;
	int x_off, y_off;
	unsigned char *tmp = pred_block;

    xint1 = dxf>>1;
    xh1 = dxf & 1;
    yint1 = dyf>>1;
    yh1 = dyf & 1;


	if (!xh1 && !yh1)  //!< xh and yh are both zero
	{
		x_off = pix_x + xint1;
		y_off = pix_y + yint1;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = *(prev + (y_off+i)*lx + x_off+j);
				tmp++;
			}
		}
	}
	else if (!xh1 && yh1) //!< yh is not zero
	{
		x_off = pix_x + xint1;
		y_off = pix_y + yint1;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					    *(prev + (y_off+i+yh1)*lx + x_off+j) + 1)>>1;
				tmp++;
			}
		}
	}
	else if (xh1 && !yh1)  //!< xh is not zero
	{
		x_off = pix_x + xint1;
		y_off = pix_y + yint1;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					    *(prev + (y_off+i)*lx + x_off+j+xh1) + 1)>>1;
				tmp++;
			}
		}
	}
	else   //! neither xh nor yh is zero
	{
		x_off = pix_x + xint1;
		y_off = pix_y + yint1;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*(prev + (y_off+i)*lx + x_off+j) +
					   *(prev + (y_off+i)*lx + x_off+j+xh1) +
						*(prev + (y_off+i+yh1)*lx + x_off+j) +
						*(prev + (y_off+i+yh1)*lx + x_off+j+xh1) + 
						2)>>2;
				tmp++;
			}
		}
	}

	tmp = pred_block;
	xint2 = dxb>>1;
	xh2 = dxb & 1;
	yint2 = dyb>>1;
	yh2 = dyb & 1;

	if (!xh2 && !yh2)  //!< xh and yh are both zero
	{
		x_off = pix_x + xint2;
		y_off = pix_y + yint2;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*tmp)/2 + (*(next + (y_off+i)*lx + x_off+j))/2;
				tmp++;
			}
		}
	}
	else if (!xh2 && yh2) //!< yh is not zero
	{
		x_off = pix_x + xint2;
		y_off = pix_y + yint2;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*tmp)/2 + 
					    (*(next + (y_off+i)*lx + x_off+j) +
					     *(next + (y_off+i+yh2)*lx + x_off+j) + 1)/4;				       			
				tmp++;
			}
		}
	}
	else if (xh2 && !yh2)  //!< xh is not zero
	{
		x_off = pix_x + xint2;
		y_off = pix_y + yint2;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*tmp)/2 + 
					   (*(next + (y_off+i)*lx + x_off+j) +
					    *(next + (y_off+i)*lx + x_off+j+xh2) + 1)/4;
				tmp++;
			}
		}
	}
	else   //! neither xh nor yh is zero
	{
		x_off = pix_x + xint2;
		y_off = pix_y + yint2;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				*tmp = (*tmp)/2 +
					   (*(next + (y_off+i)*lx + x_off+j) +
					    *(next + (y_off+i)*lx + x_off+j+xh2) +
					    *(next + (y_off+i+yh2)*lx + x_off+j) +
						*(next + (y_off+i+yh2)*lx + x_off+j+xh2) + 
						2)/8;
				tmp++;
			}
		}
	}
}
/*!
*******************************************************************************
*
*   Name:          make_diff
*   Description:   compute difference value of one 8x8 block during inter-frame coding 
*   Input:         the pointer of current block, the pointer of predictive block
*   Output:        
*   Effect:        Fill difference block
*   Optimization:  NO
*   Last modified: 2002/11/22
*
*******************************************************************************/
void make_diff_c(unsigned char* curr_block, int pic_width, unsigned char *pred_block, INT16 *diff_block)
{
	unsigned char *tmp1 = curr_block;
	unsigned char *tmp2 = pred_block;
	INT16       *tmp3 = diff_block;
	int i, j, k;

	for (i = 0, k = 0; i < 8; i++, k+=pic_width)
	{
		for (j = 0; j < 8; j++)
		{
			*tmp3 = (INT16)( *(tmp1 + k + j) - *tmp2 );
			tmp2++;
			tmp3++;
		}
	}
}

/*!
*******************************************************************************
*
*   Name:          recon_pic
*   Description:   reconstruct one 8x8 block during inter-frame coding
*   Input:         pred_block, diff_block
*   Output:        
*   Effect:        Fill corresponding area of recon image
*   Optimization:  NO
*   Last modified: 2002/11/22
*
*******************************************************************************/
void recon_pic_c(unsigned char* recon_block, int pic_width, unsigned char *pred_block, INT16 *diff_block)
{
	unsigned char *tmp1 = recon_block;
	unsigned char *tmp2 = pred_block;
	INT16       *tmp3 = diff_block;
	int           i, j, k;

	for (i = 0, k = 0; i < 8; i++, k+=pic_width)
	{
		for (j = 0; j < 8; j ++)
		{
			*(tmp1 + k + j) = (unsigned char)mmin(255, mmax(0, (INT16)(*tmp3 + *tmp2)));
			tmp2++;
			tmp3++;
		}
	}

}

/* removed temporarily, may be utilized in future
   

⌨️ 快捷键说明

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