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

📄 aic.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
字号:
#include "HEnc.h"
#include <memory.h>
#include "block.h"

static int Matrix1[64] = {
  0, 1, 2, 3, 10, 11, 12, 13,
  4, 5, 8, 9, 17, 16, 15, 14,
  6, 7, 19, 18, 26, 27, 28, 29,
  20, 21, 24, 25, 30, 31, 32, 33,
  22, 23, 34, 35, 42, 43, 44, 45,
  36, 37, 40, 41, 46, 47, 48, 49,
  38, 39, 50, 51, 56, 57, 58, 59,
  52, 53, 54, 55, 60, 61, 62, 63,
};
static int Matrix2[64] = {
  0, 4, 6, 20, 22, 36, 38, 52,
  1, 5, 7, 21, 23, 37, 39, 53,
  2, 8, 19, 24, 34, 40, 50, 54,
  3, 9, 18, 25, 35, 41, 51, 55,
  10, 17, 26, 30, 42, 46, 56, 60,
  11, 16, 27, 31, 43, 47, 57, 61,
  12, 15, 28, 32, 44, 48, 58, 62,
  13, 14, 29, 33, 45, 49, 59, 63,
};


int clipAC (int x)
{
	int clipped;
	
	if (x > 2047)
		clipped = 2047;
	else if (x < -2048)
		clipped = -2048;
	else
		clipped = x;
	return clipped;	
}


int clipDC (int x)
{
	int clipped;
	if (x > 2047)
		clipped = 2047;
	else if (x < 0)
		clipped = 0;
	else
		clipped = x;
	return clipped;
}


int oddifyclipDC (int x)
{
	
	int result;
	
	(x % 2) ? (result = clipDC (x)) : (result = clipDC (x + 1));
	return result;
}
int fill_pred(int block, int mb_x, int mb_y, INT16 top_rcoeff[][8], INT16 left_rcoeff[][8],
			   INT16 A[8], INT16 B[8])
{
	switch (block)
	{
	case 0:
		memcpy(A, (void*)top_rcoeff[2*mb_x], sizeof(INT16)*8);
		memcpy(B, (void*)left_rcoeff[0], sizeof(INT16)*8);
		break;
	case 1:
		memcpy(A, (void*)top_rcoeff[2*mb_x+1], sizeof(INT16)*8);
		memcpy(B, (void*)left_rcoeff[0], sizeof(INT16)*8);
		break;
	case 2:
		memcpy(A, (void*)top_rcoeff[2*mb_x], sizeof(INT16)*8);
		memcpy(B, (void*)left_rcoeff[1], sizeof(INT16)*8);
		break;
	case 3:
		memcpy(A, (void*)top_rcoeff[2*mb_x+1], sizeof(INT16)*8);
		memcpy(B, (void*)left_rcoeff[1], sizeof(INT16)*8);
		break;
	case 4:
	case 5:
		memcpy(A, (void*)top_rcoeff[mb_x], sizeof(INT16)*8);
		memcpy(B, (void*)left_rcoeff[0], sizeof(INT16)*8);
		break;
	default:
		break;
	}
	return 0;
}

void acc_SAD(INT16 A[8], INT16 B[8], INT16 coeff[64], int *pSAD0, int *pSAD1, int *pSAD2)
{
	int Pred_DC;

	if (A[0] == 1024 && B[0] == 1024)
	{
		Pred_DC = 1024;
	}
	else if (A[0] == 1024 && B[0] != 1024)
	{
		Pred_DC = B[0];
	}
	else if (A[0] != 1024 && B[0] == 1024)
	{
		Pred_DC = A[0];
	}
	else
	{
		Pred_DC = (A[0] + B[0] + 1)/2;
	}

	*pSAD0 = *pSAD0 +
		     (coeff[0] - Pred_DC) +
		     (absm(coeff[1]) + absm(coeff[2]) + absm(coeff[3]) + absm(coeff[4]) + absm(coeff[5]) + absm(coeff[6]) +absm(coeff[7]) + 
		      absm(coeff[8]) + absm(coeff[16]) + absm(coeff[24]) + absm(coeff[32]) + absm(coeff[40]) + absm(coeff[48]) +absm(coeff[56]))*32;
	*pSAD1 = *pSAD1 +
		     (coeff[0] - A[0]) +
		     (absm(coeff[1] - A[1]) + absm(coeff[2] - A[2]) + absm(coeff[3] - A[3]) + absm(coeff[4] - A[4]) + absm(coeff[5] - A[5]) + absm(coeff[6] - A[6]) + absm(coeff[7] - A[7]) + 
		      absm(coeff[8]) + absm(coeff[16]) + absm(coeff[24]) + absm(coeff[32]) + absm(coeff[40]) + absm(coeff[48]) +absm(coeff[56]))*32;
	*pSAD2 = *pSAD2 + 
		     (coeff[0] - B[0]) +
	         (absm(coeff[1]) + absm(coeff[2]) + absm(coeff[3]) + absm(coeff[4]) + absm(coeff[5]) + absm(coeff[6]) +absm(coeff[7]) + 
	          absm(coeff[8] - B[1]) + absm(coeff[16] - B[2]) + absm(coeff[24] - B[3]) + absm(coeff[32] - B[4]) + absm(coeff[40] - B[5]) + absm(coeff[48] - B[6]) + absm(coeff[56] - B[7]))*32;

}

void save_coeff(int block, int mb_x, int mb_y, INT16 top_rcoeff[][8], INT16 left_rcoeff[][8], INT16 *tmpblk)
{
	switch(block)
	{
	case 0:
		memcpy((void*)top_rcoeff[mb_x*2], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	case 1:
		memcpy((void*)top_rcoeff[mb_x*2+1], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	case 2:
		memcpy((void*)top_rcoeff[mb_x*2], tmpblk, sizeof(INT16)*8);
		left_rcoeff[1][0] = tmpblk[0];
		left_rcoeff[1][1] = tmpblk[8];
		left_rcoeff[1][2] = tmpblk[16];
		left_rcoeff[1][3] = tmpblk[24];
		left_rcoeff[1][4] = tmpblk[32];
		left_rcoeff[1][5] = tmpblk[40];
		left_rcoeff[1][6] = tmpblk[48];
		left_rcoeff[1][7] = tmpblk[56];
		break;
	case 3:
		memcpy((void*)top_rcoeff[mb_x*2+1], tmpblk, sizeof(INT16)*8);
		left_rcoeff[1][0] = tmpblk[0];
		left_rcoeff[1][1] = tmpblk[8];
		left_rcoeff[1][2] = tmpblk[16];
		left_rcoeff[1][3] = tmpblk[24];
		left_rcoeff[1][4] = tmpblk[32];
		left_rcoeff[1][5] = tmpblk[40];
		left_rcoeff[1][6] = tmpblk[48];
		left_rcoeff[1][7] = tmpblk[56];
		break;
	case 4:
	case 5:
		memcpy((void*)top_rcoeff[mb_x], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	default:
		break;
	}
}

int choose_intra_mode(int SAD0, int SAD1, int SAD2)
{
    // mode0: DC predicton only
	if (SAD0 <= SAD1 && SAD0 <= SAD2)
	{
		return INTRA_MODE_DC;
	}
	// mode1: vertical DC && AC prediction
	if (SAD1 <= SAD0 && SAD1 <= SAD2)
	{
		return INTRA_MODE_VERT_AC;
	}
	// mode2: horizontal DC && AC prediction
	if (SAD2 <= SAD0 && SAD2 <= SAD1)
	{
		return INTRA_MODE_HORI_AC;
	}
	return -1;
}

int  coeff_pred(int block, int mode, int mb_x, int mb_y, INT16 top_rcoeff[][8], INT16 left_rcoeff[][8], INT16 A[8], INT16 B[8])
{
	int top_dim, left_dim;
	
	switch(block)
	{
	case 0:
		top_dim = mb_x*2;
		left_dim = 0;
		break;
	case 1:
		top_dim = mb_x*2+1;
		left_dim = 0;
		break;
	case 2:
		top_dim = mb_x*2;
		left_dim = 1;
		break;
	case 3:
		top_dim = mb_x*2+1;
		left_dim = 1;
		break;
	case 4:
	case 5:
		top_dim = mb_x;
		left_dim = 0;
		break;
	default:
		break;

	}
	switch(mode)
	{
	case INTRA_MODE_DC:
		if (top_rcoeff[top_dim][0] == 1024 && left_rcoeff[left_dim][0] == 1024)
		{
			A[0] = 1024;
		}
		else if (top_rcoeff[top_dim][0] != 1024 && left_rcoeff[left_dim][0] == 1024)
		{
			A[0] = top_rcoeff[top_dim][0];
		}
		else if (top_rcoeff[top_dim][0] == 1024 && left_rcoeff[left_dim][0] != 1024)
		{
			A[0] = left_rcoeff[left_dim][0];
		}
		else
		{
			A[0] = (top_rcoeff[top_dim][0] + left_rcoeff[left_dim][0] + 1)/2;
		}
		break;
	case INTRA_MODE_VERT_AC:
		memcpy(A, top_rcoeff[top_dim], sizeof(INT16)*8);
		break;
	case INTRA_MODE_HORI_AC:
		memcpy(B, left_rcoeff[left_dim], sizeof(INT16)*8);
		break;
	default:
		break;
	}
	return 0;
}
int coeff_diff(int mode, INT16 A[8], INT16 B[8], INT16 coeff[64])
{
	switch(mode)
	{
	case INTRA_MODE_DC:
		coeff[0] -= A[0];
		break;
	case INTRA_MODE_VERT_AC:
		coeff[0] -= A[0];
		coeff[1] -= A[1];
		coeff[2] -= A[2];
		coeff[3] -= A[3];
		coeff[4] -= A[4];
		coeff[5] -= A[5];
		coeff[6] -= A[6];
		coeff[7] -= A[7];
		break;
	case INTRA_MODE_HORI_AC:
		coeff[0] -= B[0];
		coeff[8] -= B[1];
		coeff[16] -= B[2];
		coeff[24] -= B[3];
		coeff[32] -= B[4];
		coeff[40] -= B[5];
		coeff[48] -= B[6];
		coeff[56] -= B[7];
		break;
	default:
		break;
	}
	return 0;
}
int Quant_AIC(INT16 *coeff, INT16 *qcoeff, int Q, int mode)
{
	int i;
	int qpp = Q/2;
	float qp = (float) 1/(2*Q);
	int nonezero = 0;
	int *Matrix;
	int q_value;

	switch(mode)
	{
	case INTRA_MODE_DC:
		Matrix = MixZig;
		break;
	case INTRA_MODE_VERT_AC:
		Matrix = Matrix1;
		break;
	case INTRA_MODE_HORI_AC:
		Matrix = Matrix2;
		break;
	default:
		break;
	}

	for (i = 0; i < 64; i++)
	{
		qcoeff[Matrix[i]] =	q_value = mmin(127, mmax(-127, (coeff[i]+sign(coeff[i])*qpp)*qp));
		if (q_value)
		{
			nonezero = 1;
		}
	}
	return nonezero;
}
int DeQuant_AIC(INT16 *qcoeff, INT16 *rcoeff, int Q, int mode)
{
	int i;
	int q_value;
	int qp = Q*2;
	int *Matrix;

	switch(mode)
	{
	case INTRA_MODE_DC:
		Matrix = MixZig;
		break;
	case INTRA_MODE_VERT_AC:
		Matrix = Matrix1;
		break;
	case INTRA_MODE_HORI_AC:
		Matrix = Matrix2;
		break;
	default:
		break;
	}
    for ( i = 0; i < 64; i++)
	{
		if(q_value = qcoeff[Matrix[i]])
		{
			rcoeff[i] = qp * q_value;
		}
		else
		{
			rcoeff[i] = 0;
		}
	}

	return 0;
}
int coeff_recon(int block, int mode, int mb_x, int mb_y, INT16 top_rcoeff[][8], INT16 left_rcoeff[][8],
				INT16 *tmpblk, INT16 A[8], INT16 B[8])
{
	int i, j;

	switch(mode)
	{
	case INTRA_MODE_DC:
		tmpblk[0] = oddifyclipDC(tmpblk[0] + A[0]);
		for (i = 1; i < 64; i++)
		{
			tmpblk[i] = clipAC(tmpblk[i]);
		}
		break;
	case INTRA_MODE_VERT_AC:
		tmpblk[0] = oddifyclipDC(tmpblk[0] + A[0]);
		for (i = 1; i < 8; i++)
		{
			tmpblk[i] = clipAC(tmpblk[i] + A[i]);
		}
		for (j = 1; j < 8; j++)
		{
			for (i = 0; i < 8; i++)
			{
				tmpblk[j*8+i] = clipAC(tmpblk[j*8+i]);
			}
		}
		break;
	case INTRA_MODE_HORI_AC:
		tmpblk[0] = oddifyclipDC(tmpblk[0] + B[0]);
		for (i = 1; i < 8; i++)
		{
			tmpblk[i*8] = clipAC(tmpblk[i*8] + B[i]);
		}
		for (j = 0; j < 8; j++)
		{
			for (i = 1; i < 8; i++)
			{
				tmpblk[j*8+i] = clipAC(tmpblk[j*8+i]);
			}
		}
		break;
	default:
		break;
	}

	switch(block)
	{
	case 0:
		memcpy((void*)top_rcoeff[mb_x*2], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	case 1:
		memcpy((void*)top_rcoeff[mb_x*2+1], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	case 2:
		memcpy((void*)top_rcoeff[mb_x*2], tmpblk, sizeof(INT16)*8);
		left_rcoeff[1][0] = tmpblk[0];
		left_rcoeff[1][1] = tmpblk[8];
		left_rcoeff[1][2] = tmpblk[16];
		left_rcoeff[1][3] = tmpblk[24];
		left_rcoeff[1][4] = tmpblk[32];
		left_rcoeff[1][5] = tmpblk[40];
		left_rcoeff[1][6] = tmpblk[48];
		left_rcoeff[1][7] = tmpblk[56];
		break;
	case 3:
		memcpy((void*)top_rcoeff[mb_x*2+1], tmpblk, sizeof(INT16)*8);
		left_rcoeff[1][0] = tmpblk[0];
		left_rcoeff[1][1] = tmpblk[8];
		left_rcoeff[1][2] = tmpblk[16];
		left_rcoeff[1][3] = tmpblk[24];
		left_rcoeff[1][4] = tmpblk[32];
		left_rcoeff[1][5] = tmpblk[40];
		left_rcoeff[1][6] = tmpblk[48];
		left_rcoeff[1][7] = tmpblk[56];
		break;
	case 4:
	case 5:
		memcpy((void*)top_rcoeff[mb_x], tmpblk, sizeof(INT16)*8);
		left_rcoeff[0][0] = tmpblk[0];
		left_rcoeff[0][1] = tmpblk[8];
		left_rcoeff[0][2] = tmpblk[16];
		left_rcoeff[0][3] = tmpblk[24];
		left_rcoeff[0][4] = tmpblk[32];
		left_rcoeff[0][5] = tmpblk[40];
		left_rcoeff[0][6] = tmpblk[48];
		left_rcoeff[0][7] = tmpblk[56];
		break;
	default:
		break;
	}

	return 0;
}


⌨️ 快捷键说明

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