1 /* quantize.c, quantization / inverse quantization */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
36 #include "cpu_accel.h"
38 #include "fastintfns.h"
41 /* Global function pointers for SIMD-dependent functions */
42 int (*pquant_non_intra)(pict_data_s *picture, int16_t *src, int16_t *dst,
43 int mquant, int *nonsat_mquant);
44 int (*pquant_weight_coeff_sum)(int16_t *blk, uint16_t*i_quant_mat );
46 /* Local functions pointers for SIMD-dependent functions */
48 static void (*piquant_non_intra_m1)(int16_t *src, int16_t *dst, uint16_t *quant_mat);
51 static int quant_weight_coeff_sum( int16_t *blk, uint16_t * i_quant_mat );
52 static void iquant_non_intra_m1(int16_t *src, int16_t *dst, uint16_t *quant_mat);
56 Initialise quantization routines.
57 Currently just setting up MMX routines if available...
60 void init_quantizer_hv(int use_sse)
65 if( (flags & ACCEL_X86_MMX) != 0 ) /* MMX CPU */
67 if(verbose) fprintf( stderr, "SETTING " );
68 if( (flags & ACCEL_X86_3DNOW) != 0 )
70 if(verbose) fprintf( stderr, "3DNOW and ");
71 pquant_non_intra = quant_non_intra_hv_3dnow;
74 * else if ( (flags & ACCEL_X86_MMXEXT) != 0 )
76 * if(verbose) fprintf( stderr, "SSE and ");
77 * pquant_non_intra = quant_non_intra_hv_sse;
82 pquant_non_intra = quant_non_intra_hv;
85 if ( (flags & ACCEL_X86_MMXEXT) != 0 )
87 if(verbose) fprintf( stderr, "EXTENDED MMX");
88 pquant_weight_coeff_sum = quant_weight_coeff_sum_mmx;
90 piquant_non_intra_m1 = iquant_non_intra_m1_sse;
94 if(verbose) fprintf( stderr, "MMX");
95 pquant_weight_coeff_sum = quant_weight_coeff_sum_mmx;
96 piquant_non_intra_m1 = iquant_non_intra_m1_mmx;
98 if(verbose) fprintf( stderr, " for QUANTIZER!\n");
103 pquant_non_intra = quant_non_intra_hv;
104 pquant_weight_coeff_sum = quant_weight_coeff_sum;
105 piquant_non_intra_m1 = iquant_non_intra_m1;
111 * Computes the next quantisation up. Used to avoid saturation
112 * in macroblock coefficients - common in MPEG-1 - which causes
115 * NOTE: Does no range checking...
120 int next_larger_quant_hv( pict_data_s *picture, int quant )
122 if( picture->q_scale_type )
124 if( map_non_linear_mquant_hv[quant]+1 > 31 )
127 return non_linear_mquant_table_hv[map_non_linear_mquant_hv[quant]+1];
140 * Quantisation for intra blocks using Test Model 5 quantization
142 * this quantizer has a bias of 1/8 stepsize towards zero
143 * (except for the DC coefficient)
145 PRECONDITION: src dst point to *disinct* memory buffers...
146 of block_count *adjact* int16_t[64] arrays...
148 * RETURN: 1 If non-zero coefficients left after quantisaiont 0 otherwise
152 pict_data_s *picture,
163 int clipvalue = dctsatlim;
164 uint16_t *quant_mat = intra_q_tbl[mquant] /* intra_q */;
167 /* Inspired by suggestion by Juan. Quantize a little harder if we clip...
175 for( comp = 0; comp<block_count && !clipping; ++comp )
178 d = 8>>picture->dc_prec; /* intra_dc_mult */
179 pbuf[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d); /* round(x/d) */
182 for (i=1; i<64 ; i++)
186 /* RJ: save one divide operation */
187 y = ((abs(x) << 5)+ ((3 * quant_mat[i]) >> 2)) / (quant_mat[i] << 1);
191 mquant = next_larger_quant_hv( picture, mquant );
192 quant_mat = intra_q_tbl[mquant];
196 pbuf[i] = intsamesign(x,y);
203 *nonsat_mquant = mquant;
208 * Quantisation matrix weighted Coefficient sum fixed-point
209 * integer with low 16 bits fractional...
210 * To be used for rate control as a measure of dct block
215 int quant_weight_coeff_sum( int16_t *blk, uint16_t * i_quant_mat )
219 for( i = 0; i < 64; i+=2 )
221 sum += abs((int)blk[i]) * (i_quant_mat[i]) + abs((int)blk[i+1]) * (i_quant_mat[i+1]);
224 /* In case you're wondering typical average coeff_sum's for a rather
225 noisy video are around 20.0. */
231 * Quantisation for non-intra blocks using Test Model 5 quantization
233 * this quantizer has a bias of 1/8 stepsize towards zero
234 * (except for the DC coefficient)
236 * A.Stevens 2000: The above comment is nonsense. Only the intra quantiser does
237 * this. This one just truncates with a modest bias of 1/(4*quant_matrix_scale)
240 * PRECONDITION: src dst point to *disinct* memory buffers...
241 * of block_count *adjacent* int16_t[64] arrays...
243 * RETURN: A bit-mask of block_count bits indicating non-zero blocks (a 1).
245 * TODO: A candidate for use of efficient abs and "intsamesign". If only gcc understood
246 * PPro conditional moves...
249 int quant_non_intra_hv(
250 pict_data_s *picture,
251 int16_t *src, int16_t *dst,
259 int clipvalue = dctsatlim;
262 uint16_t *quant_mat = inter_q_tbl[mquant]/* inter_q */;
264 coeff_count = 64*block_count;
267 for (i=0; i<coeff_count; ++i)
272 nzflag = (nzflag<<1) | !!flags;
276 /* RJ: save one divide operation */
278 x = abs( ((int)src[i]) ) /*(src[i] >= 0 ? src[i] : -src[i])*/ ;
279 d = (int)quant_mat[(i&63)];
280 /* A.Stevens 2000: Given the math of non-intra frame
281 quantisation / inverse quantisation I always though the
282 funny little foudning factor was bogus. It seems to be
283 the encoder needs less bits if you simply divide!
286 y = (x<<4) / (d) /* (32*x + (d>>1))/(d*2*mquant)*/ ;
295 int new_mquant = next_larger_quant_hv( picture, mquant );
296 if( new_mquant != mquant )
299 quant_mat = inter_q_tbl[mquant];
310 dst[i] = intsamesign(src[i], y) /* (src[i] >= 0 ? y : -y) */;
313 nzflag = (nzflag<<1) | !!flags;
315 *nonsat_mquant = mquant;
319 /* MPEG-1 inverse quantization */
320 static void iquant1_intra(int16_t *src, int16_t *dst, int dc_prec, int mquant)
323 uint16_t *quant_mat = intra_q;
325 dst[0] = src[0] << (3-dc_prec);
328 val = (int)(src[i]*quant_mat[i]*mquant)/16;
330 /* mismatch control */
331 if ((val&1)==0 && val!=0)
332 val+= (val>0) ? -1 : 1;
335 dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
340 /* MPEG-2 inverse quantization */
341 void iquant_intra(int16_t *src, int16_t *dst, int dc_prec, int mquant)
346 iquant1_intra(src,dst,dc_prec, mquant);
349 sum = dst[0] = src[0] << (3-dc_prec);
352 val = (int)(src[i]*intra_q[i]*mquant)/16;
353 sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
356 /* mismatch control */
363 static void iquant_non_intra_m1(int16_t *src, int16_t *dst, uint16_t *quant_mat)
367 #ifndef ORIGINAL_CODE
374 val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i])/32;
376 /* mismatch control */
377 if ((val&1)==0 && val!=0)
378 val+= (val>0) ? -1 : 1;
382 dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
391 val = ((val+val+1)*quant_mat[i]) >> 5;
392 /* mismatch control */
393 val -= (~(val&1))&(val!=0);
394 val = fastmin(val, 2047); /* Saturation */
396 dst[i] = intsamesign(src[i],val);
406 void iquant_non_intra(int16_t *src, int16_t *dst, int mquant )
412 (*piquant_non_intra_m1)(src,dst,inter_q_tbl[mquant]);
423 val = (int)((2*val+(val>0 ? 1 : -1))*inter_q[i]*mquant)/32;
424 sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
427 quant_mat = inter_q_tbl[mquant];
434 val = (int)((val+val+1)*quant_mat[i])>>5;
435 val = intmin( val, 2047);
438 dst[i] = intsamesign(src[i],val);
442 /* mismatch control */
448 void iquantize( pict_data_s *picture )
451 int16_t (*qblocks)[64] = picture->qblocks;
452 for (k=0; k<mb_per_pict; k++)
454 if (picture->mbinfo[k].mb_type & MB_INTRA)
455 for (j=0; j<block_count; j++)
456 iquant_intra(qblocks[k*block_count+j],
457 qblocks[k*block_count+j],
459 cur_picture.mbinfo[k].mquant);
461 for (j=0;j<block_count;j++)
462 iquant_non_intra(qblocks[k*block_count+j],
463 qblocks[k*block_count+j],
464 cur_picture.mbinfo[k].mquant);