Exemplo n.º 1
0
uint32_t
dequant_mpeg_inter_altivec_c(int16_t * data,
					 const int16_t * coeff,
					 const uint32_t quant,
					 const uint16_t * mpeg_quant_matrices)
{
	register uint32_t sum;
	register const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
	
	register vec_sint16_t ox00;
	register vec_sint16_t v2048;
	register vec_sint16_t level;
	register vec_uint16_t vinter;
	register vec_uint32_t hi,lo;
	register vec_uint32_t sw_hi,sw_lo;
	register vec_uint32_t swap;
	register vec_uint32_t t,v16;
	
	vec_uint32_t vsum;
	vec_uint32_t vquant;
	vector bool short zero_eq;
	vector bool short zero_less;
	vector bool short overflow;
	
#ifdef DEBUG
	if((long)data & 0xf)
		fprintf(stderr, "xvidcore: error in dequant_mpeg_inter_altivec_c, incorrect align: %x\n", data);
#endif
	
	/* Initialization */
	ox00 = vec_splat_s16(0);
	v16 = vec_splat_u32(-16);
	v2048 = vec_rl(vec_splat_s16(8),vec_splat_u16(8));
	
	vsum = (vec_uint32_t)ox00;
	
	*((uint32_t*)&vquant) = quant;
	vquant = vec_splat(vquant,0);
	swap = vec_rl(vquant,v16);
	
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	DEQUANT_MPEG_INTER();
	
	sum = ((uint32_t*)&vsum)[0];
	sum ^= ((uint32_t*)&vsum)[1];
	sum ^= ((uint32_t*)&vsum)[2];
	sum ^= ((uint32_t*)&vsum)[3];
	
	/* mismatch control */
	if((sum & 1) == 0) {
		data -= 1;
		*data ^= 1;
	}
	
	return 0;
}
/* Quantize all blocks -- Inter mode */
static __inline uint8_t
MBQuantInter(const MBParam * pParam,
			 const FRAMEINFO * const frame,
			 const MACROBLOCK * pMB,
			 int16_t data[6 * 64],
			 int16_t qcoeff[6 * 64],
			 int bvop,
			 int limit)
{

	int i;
	uint8_t cbp = 0;
	int sum;
	int code_block, mpeg;

	quant_interFuncPtr const quant[2] =
		{
			quant_h263_inter,
			quant_mpeg_inter
		};

	mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);

	for (i = 0; i < 6; i++) {

		/* Quantize the block */
		start_timer();

		sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);

		if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
			const uint16_t *matrix;
			const static uint16_t h263matrix[] =
				{
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16,
					16, 16, 16, 16, 16, 16, 16, 16
				};

			matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
			sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
										 pMB->quant, &scan_tables[0][0],
										 matrix,
										 63,
										 sum,
										 pMB->lambda[i],
										 pMB->rel_var8[i],
										 !!(frame->vop_flags & XVID_VOP_RD_PSNRHVSM));
		}
		stop_quant_timer();

		/*
		 * We code the block if the sum is higher than the limit and if the first
		 * two AC coefficients in zig zag order are not zero.
		 */
		code_block = 0;
		if ((sum >= limit) || (qcoeff[i*64+1] != 0) || (qcoeff[i*64+8] != 0)) {
			code_block = 1;
		} else {

			if (bvop && (pMB->mode == MODE_DIRECT || pMB->mode == MODE_DIRECT_NO4V)) {
				/* dark blocks prevention for direct mode */
				if ((qcoeff[i*64] < -1) || (qcoeff[i*64] > 0))
					code_block = 1;
			} else {
				/* not direct mode */
				if (qcoeff[i*64] != 0)
					code_block = 1;
			}
		}

		/* Set the corresponding cbp bit */
		cbp |= code_block << (5 - i);
	}

	return(cbp);
}