[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);
}