[XviD-devel] adaptive quant improvement

Marco "elcabesa" Belli xvid-devel@xvid.org
Wed, 29 Jan 2003 15:28:49 +0100


p.s. i use to put this line of code inside if{ }
 to see which mb quantizer  were changed by my code

ptr[7 * stride + 7]=255;
ptr[7 * stride + 8]=255;
ptr[8 * stride + 7]=255;
ptr[8 * stride + 8]=255;

this is the code that only replace adaptive quant code
changing  the min_level, medium_level mhlevel and huighleve you can change 
threshold


int
adaptive_quantization(unsigned char *buf,
					  int stride,
					  int *intquant,
					  int framequant,
					  int min_quant,
					  int max_quant,
					  int mb_width,
					  int mb_height)	// no qstride because normalization
{
	int i, j, k, l;

	float *quant;
	unsigned char *ptr;
	float *val;
	float *quad;
	float global = 0.;
	float media=0.;

	float min_level=0.0001;  //3
	float medium_level=0.0003; // 4
	float mh_level=0.003;
	float high_level=0.009;  // 5

	float result;



	if (!(quant = (float *) malloc(mb_width * mb_height * sizeof(float))))
		return(-1);

	if (!(quad = (float *) malloc(mb_width * mb_height * sizeof(float))))
		return(-1);

	if(!(val = (float *) malloc(mb_width * mb_height * sizeof(float))))
		return(-1);
	for (k = 0; k < mb_height; k++) {
		for (l = 0; l < mb_width; l++)	// do this for all macroblocks individually
		{
			quant[k * mb_width + l] = (float) framequant;

			// calculate luminance-masking
			ptr = &buf[16 * k * stride + 16 * l];	// address of MB

			val[k * mb_width + l] = 0.;
			quad[k * mb_width + l] = 0.;


			for (i = 0; i < 16; i++)
				for (j = 0; j < 16; j++)
					val[k * mb_width + l] += ptr[i * stride + j];
			val[k * mb_width + l] /= 256.;
			media=val[k * mb_width + l];

			for (i = 0; i < 16; i++)
				for (j = 0; j < 16; j++)
					quad[k * mb_width + l]+=(ptr[i * stride + j]-media)*(ptr[i * stride + 
j]-media);
			quad[k * mb_width + l]/=65536.;
			result=quad[k * mb_width + l]/media;

			if(result<min_level)
			{

				quant[k * mb_width + l]+=4;
			}
			else if(result<medium_level)
			{

				quant[k * mb_width + l]+=2;

			}
			else if(result<mh_level)
			{

			}
			else if(result<high_level)
			{

				quant[k * mb_width + l]-=2;
			}
			else
			{


				quant[k * mb_width + l]-=4;
			}
			if(quant[k * mb_width + l]<min_quant)
					quant[k * mb_width + l]=min_quant;
			if(quant[k * mb_width + l]>max_quant)
					quant[k * mb_width + l]=max_quant;

		}
	}




	i = normalize_quantizer_field(quant, intquant,
								  mb_width * mb_height,
								  min_quant, max_quant);

	free(val);
	free(quant);
	free(quad);

	return(i);

}