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
35 #include "cpu_accel.h"
37 #include "fastintfns.h"
40 /* Global function pointers for SIMD-dependent functions */
41 int (*pquant_non_intra
)(pict_data_s
*picture
, int16_t *src
, int16_t *dst
,
42 int mquant
, int *nonsat_mquant
);
43 int (*pquant_weight_coeff_sum
)(int16_t *blk
, uint16_t*i_quant_mat
);
45 /* Local functions pointers for SIMD-dependent functions */
47 static void (*piquant_non_intra_m1
)(int16_t *src
, int16_t *dst
, uint16_t *quant_mat
);
50 static int quant_weight_coeff_sum( int16_t *blk
, uint16_t * i_quant_mat
);
51 static void iquant_non_intra_m1(int16_t *src
, int16_t *dst
, uint16_t *quant_mat
);
55 Initialise quantization routines.
56 Currently just setting up MMX routines if available...
64 if( (flags
& ACCEL_X86_MMX
) != 0 ) /* MMX CPU */
66 if(verbose
) fprintf( stderr
, "SETTING " );
67 if( (flags
& ACCEL_X86_3DNOW
) != 0 )
69 if(verbose
) fprintf( stderr
, "3DNOW and ");
70 pquant_non_intra
= quant_non_intra_3dnow
;
72 else if ( (flags
& ACCEL_X86_MMXEXT
) != 0 )
74 if(verbose
) fprintf( stderr
, "SSE and ");
75 pquant_non_intra
= quant_non_intra_sse
;
79 pquant_non_intra
= quant_non_intra
;
82 if ( (flags
& ACCEL_X86_MMXEXT
) != 0 )
84 if(verbose
) fprintf( stderr
, "EXTENDED MMX");
85 pquant_weight_coeff_sum
= quant_weight_coeff_sum_mmx
;
86 piquant_non_intra_m1
= iquant_non_intra_m1_sse
;
90 if(verbose
) fprintf( stderr
, "MMX");
91 pquant_weight_coeff_sum
= quant_weight_coeff_sum_mmx
;
92 piquant_non_intra_m1
= iquant_non_intra_m1_mmx
;
94 if(verbose
) fprintf( stderr
, " for QUANTIZER!\n");
99 pquant_non_intra
= quant_non_intra
;
100 pquant_weight_coeff_sum
= quant_weight_coeff_sum
;
101 piquant_non_intra_m1
= iquant_non_intra_m1
;
107 * Computes the next quantisation up. Used to avoid saturation
108 * in macroblock coefficients - common in MPEG-1 - which causes
111 * NOTE: Does no range checking...
116 int next_larger_quant( pict_data_s
*picture
, int quant
)
118 if( picture
->q_scale_type
)
120 if( map_non_linear_mquant
[quant
]+1 > 31 )
123 return non_linear_mquant_table
[map_non_linear_mquant
[quant
]+1];
136 * Quantisation for intra blocks using Test Model 5 quantization
138 * this quantizer has a bias of 1/8 stepsize towards zero
139 * (except for the DC coefficient)
141 PRECONDITION: src dst point to *disinct* memory buffers...
142 of block_count *adjact* int16_t[64] arrays...
144 * RETURN: 1 If non-zero coefficients left after quantisaiont 0 otherwise
148 pict_data_s
*picture
,
159 int clipvalue
= dctsatlim
;
160 uint16_t *quant_mat
= intra_q_tbl
[mquant
] /* intra_q */;
163 /* Inspired by suggestion by Juan. Quantize a little harder if we clip...
171 for( comp
= 0; comp
<block_count
&& !clipping
; ++comp
)
174 d
= 8>>picture
->dc_prec
; /* intra_dc_mult */
175 pbuf
[0] = (x
>=0) ? (x
+(d
>>1))/d
: -((-x
+(d
>>1))/d
); /* round(x/d) */
178 for (i
=1; i
<64 ; i
++)
182 /* RJ: save one divide operation */
183 y
= ((abs(x
) << 5)+ ((3 * quant_mat
[i
]) >> 2)) / (quant_mat
[i
] << 1);
187 mquant
= next_larger_quant( picture
, mquant
);
188 quant_mat
= intra_q_tbl
[mquant
];
192 pbuf
[i
] = intsamesign(x
,y
);
199 *nonsat_mquant
= mquant
;
204 * Quantisation matrix weighted Coefficient sum fixed-point
205 * integer with low 16 bits fractional...
206 * To be used for rate control as a measure of dct block
211 int quant_weight_coeff_sum( int16_t *blk
, uint16_t * i_quant_mat
)
215 for( i
= 0; i
< 64; i
+=2 )
217 sum
+= abs((int)blk
[i
]) * (i_quant_mat
[i
]) + abs((int)blk
[i
+1]) * (i_quant_mat
[i
+1]);
220 /* In case you're wondering typical average coeff_sum's for a rather
221 noisy video are around 20.0. */
227 * Quantisation for non-intra blocks using Test Model 5 quantization
229 * this quantizer has a bias of 1/8 stepsize towards zero
230 * (except for the DC coefficient)
232 * A.Stevens 2000: The above comment is nonsense. Only the intra quantiser does
233 * this. This one just truncates with a modest bias of 1/(4*quant_matrix_scale)
236 * PRECONDITION: src dst point to *disinct* memory buffers...
237 * of block_count *adjacent* int16_t[64] arrays...
239 * RETURN: A bit-mask of block_count bits indicating non-zero blocks (a 1).
241 * TODO: A candidate for use of efficient abs and "intsamesign". If only gcc understood
242 * PPro conditional moves...
246 pict_data_s
*picture
,
247 int16_t *src
, int16_t *dst
,
255 int clipvalue
= dctsatlim
;
258 uint16_t *quant_mat
= inter_q_tbl
[mquant
]/* inter_q */;
260 coeff_count
= 64*block_count
;
263 for (i
=0; i
<coeff_count
; ++i
)
268 nzflag
= (nzflag
<<1) | !!flags
;
272 /* RJ: save one divide operation */
274 x
= abs( ((int)src
[i
]) ) /*(src[i] >= 0 ? src[i] : -src[i])*/ ;
275 d
= (int)quant_mat
[(i
&63)];
276 /* A.Stevens 2000: Given the math of non-intra frame
277 quantisation / inverse quantisation I always though the
278 funny little foudning factor was bogus. It seems to be
279 the encoder needs less bits if you simply divide!
282 y
= (x
<<4) / (d
) /* (32*x + (d>>1))/(d*2*mquant)*/ ;
291 int new_mquant
= next_larger_quant( picture
, mquant
);
292 if( new_mquant
!= mquant
)
295 quant_mat
= inter_q_tbl
[mquant
];
306 dst
[i
] = intsamesign(src
[i
], y
) /* (src[i] >= 0 ? y : -y) */;
309 nzflag
= (nzflag
<<1) | !!flags
;
311 *nonsat_mquant
= mquant
;
315 /* MPEG-1 inverse quantization */
316 static void iquant1_intra(int16_t *src
, int16_t *dst
, int dc_prec
, int mquant
)
319 uint16_t *quant_mat
= intra_q
;
321 dst
[0] = src
[0] << (3-dc_prec
);
324 val
= (int)(src
[i
]*quant_mat
[i
]*mquant
)/16;
326 /* mismatch control */
327 if ((val
&1)==0 && val
!=0)
328 val
+= (val
>0) ? -1 : 1;
331 dst
[i
] = (val
>2047) ? 2047 : ((val
<-2048) ? -2048 : val
);
336 /* MPEG-2 inverse quantization */
337 void iquant_intra(int16_t *src
, int16_t *dst
, int dc_prec
, int mquant
)
342 iquant1_intra(src
,dst
,dc_prec
, mquant
);
345 sum
= dst
[0] = src
[0] << (3-dc_prec
);
348 val
= (int)(src
[i
]*intra_q
[i
]*mquant
)/16;
349 sum
+= dst
[i
] = (val
>2047) ? 2047 : ((val
<-2048) ? -2048 : val
);
352 /* mismatch control */
359 static void iquant_non_intra_m1(int16_t *src
, int16_t *dst
, uint16_t *quant_mat
)
363 #ifndef ORIGINAL_CODE
370 val
= (int)((2*val
+(val
>0 ? 1 : -1))*quant_mat
[i
])/32;
372 /* mismatch control */
373 if ((val
&1)==0 && val
!=0)
374 val
+= (val
>0) ? -1 : 1;
378 dst
[i
] = (val
>2047) ? 2047 : ((val
<-2048) ? -2048 : val
);
387 val
= ((val
+val
+1)*quant_mat
[i
]) >> 5;
388 /* mismatch control */
389 val
-= (~(val
&1))&(val
!=0);
390 val
= fastmin(val
, 2047); /* Saturation */
392 dst
[i
] = intsamesign(src
[i
],val
);
402 void iquant_non_intra(int16_t *src
, int16_t *dst
, int mquant
)
408 (*piquant_non_intra_m1
)(src
,dst
,inter_q_tbl
[mquant
]);
419 val
= (int)((2*val
+(val
>0 ? 1 : -1))*inter_q
[i
]*mquant
)/32;
420 sum
+= dst
[i
] = (val
>2047) ? 2047 : ((val
<-2048) ? -2048 : val
);
423 quant_mat
= inter_q_tbl
[mquant
];
430 val
= (int)((val
+val
+1)*quant_mat
[i
])>>5;
431 val
= intmin( val
, 2047);
434 dst
[i
] = intsamesign(src
[i
],val
);
438 /* mismatch control */
444 void iquantize( pict_data_s
*picture
)
447 int16_t (*qblocks
)[64] = picture
->qblocks
;
448 for (k
=0; k
<mb_per_pict
; k
++)
450 if (picture
->mbinfo
[k
].mb_type
& MB_INTRA
)
451 for (j
=0; j
<block_count
; j
++)
452 iquant_intra(qblocks
[k
*block_count
+j
],
453 qblocks
[k
*block_count
+j
],
455 cur_picture
.mbinfo
[k
].mquant
);
457 for (j
=0;j
<block_count
;j
++)
458 iquant_non_intra(qblocks
[k
*block_count
+j
],
459 qblocks
[k
*block_count
+j
],
460 cur_picture
.mbinfo
[k
].mquant
);