00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031 #include <stdio.h>
00032 #include <math.h>
00033 #include <fenv.h>
00034 #include "global.h"
00035 #include "cpu_accel.h"
00036 #include "simd.h"
00037 #include "fastintfns.h"
00038
00039
00040
00041 int (*pquant_non_intra)(pict_data_s *picture, int16_t *src, int16_t *dst,
00042 int mquant, int *nonsat_mquant);
00043 int (*pquant_weight_coeff_sum)(int16_t *blk, uint16_t*i_quant_mat );
00044
00045
00046
00047 static void (*piquant_non_intra_m1)(int16_t *src, int16_t *dst, uint16_t *quant_mat);
00048
00049
00050 static int quant_weight_coeff_sum( int16_t *blk, uint16_t * i_quant_mat );
00051 static void iquant_non_intra_m1(int16_t *src, int16_t *dst, uint16_t *quant_mat);
00052
00053
00054
00055
00056
00057
00058
00059 void init_quantizer_hv()
00060 {
00061 int flags;
00062 flags = cpu_accel();
00063 #ifdef X86_CPU
00064 if( (flags & ACCEL_X86_MMX) != 0 )
00065 {
00066 if(verbose) fprintf( stderr, "SETTING " );
00067 if( (flags & ACCEL_X86_3DNOW) != 0 )
00068 {
00069 if(verbose) fprintf( stderr, "3DNOW and ");
00070 pquant_non_intra = quant_non_intra_hv_3dnow;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 else
00080 {
00081 pquant_non_intra = quant_non_intra_hv;
00082 }
00083
00084 if ( (flags & ACCEL_X86_MMXEXT) != 0 )
00085 {
00086 if(verbose) fprintf( stderr, "EXTENDED MMX");
00087 pquant_weight_coeff_sum = quant_weight_coeff_sum_mmx;
00088 piquant_non_intra_m1 = iquant_non_intra_m1_sse;
00089 }
00090 else
00091 {
00092 if(verbose) fprintf( stderr, "MMX");
00093 pquant_weight_coeff_sum = quant_weight_coeff_sum_mmx;
00094 piquant_non_intra_m1 = iquant_non_intra_m1_mmx;
00095 }
00096 if(verbose) fprintf( stderr, " for QUANTIZER!\n");
00097 }
00098 else
00099 #endif
00100 {
00101 pquant_non_intra = quant_non_intra_hv;
00102 pquant_weight_coeff_sum = quant_weight_coeff_sum;
00103 piquant_non_intra_m1 = iquant_non_intra_m1;
00104 }
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 int next_larger_quant_hv( pict_data_s *picture, int quant )
00119 {
00120 if( picture->q_scale_type )
00121 {
00122 if( map_non_linear_mquant_hv[quant]+1 > 31 )
00123 return quant;
00124 else
00125 return non_linear_mquant_table_hv[map_non_linear_mquant_hv[quant]+1];
00126 }
00127 else
00128 {
00129 if( quant+2 > 31 )
00130 return quant;
00131 else
00132 return quant+2;
00133 }
00134
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 void quant_intra_hv(
00150 pict_data_s *picture,
00151 int16_t *src,
00152 int16_t *dst,
00153 int mquant,
00154 int *nonsat_mquant
00155 )
00156 {
00157 int16_t *psrc,*pbuf;
00158 int i,comp;
00159 int x, y, d;
00160 int clipping;
00161 int clipvalue = dctsatlim;
00162 uint16_t *quant_mat = intra_q_tbl[mquant] ;
00163
00164
00165
00166
00167
00168 do
00169 {
00170 clipping = 0;
00171 pbuf = dst;
00172 psrc = src;
00173 for( comp = 0; comp<block_count && !clipping; ++comp )
00174 {
00175 x = psrc[0];
00176 d = 8>>picture->dc_prec;
00177 pbuf[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d);
00178
00179
00180 for (i=1; i<64 ; i++)
00181 {
00182 x = psrc[i];
00183 d = quant_mat[i];
00184
00185 y = ((abs(x) << 5)+ ((3 * quant_mat[i]) >> 2)) / (quant_mat[i] << 1);
00186 if ( y > clipvalue )
00187 {
00188 clipping = 1;
00189 mquant = next_larger_quant_hv( picture, mquant );
00190 quant_mat = intra_q_tbl[mquant];
00191 break;
00192 }
00193
00194 pbuf[i] = intsamesign(x,y);
00195 }
00196 pbuf += 64;
00197 psrc += 64;
00198 }
00199
00200 } while( clipping );
00201 *nonsat_mquant = mquant;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int quant_weight_coeff_sum( int16_t *blk, uint16_t * i_quant_mat )
00214 {
00215 int i;
00216 int sum = 0;
00217 for( i = 0; i < 64; i+=2 )
00218 {
00219 sum += abs((int)blk[i]) * (i_quant_mat[i]) + abs((int)blk[i+1]) * (i_quant_mat[i+1]);
00220 }
00221 return sum;
00222
00223
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 int quant_non_intra_hv(
00248 pict_data_s *picture,
00249 int16_t *src, int16_t *dst,
00250 int mquant,
00251 int *nonsat_mquant)
00252 {
00253 int i;
00254 int x, y, d;
00255 int nzflag;
00256 int coeff_count;
00257 int clipvalue = dctsatlim;
00258 int flags = 0;
00259 int saturated = 0;
00260 uint16_t *quant_mat = inter_q_tbl[mquant];
00261
00262 coeff_count = 64*block_count;
00263 flags = 0;
00264 nzflag = 0;
00265 for (i=0; i<coeff_count; ++i)
00266 {
00267 restart:
00268 if( (i%64) == 0 )
00269 {
00270 nzflag = (nzflag<<1) | !!flags;
00271 flags = 0;
00272
00273 }
00274
00275
00276 x = abs( ((int)src[i]) ) ;
00277 d = (int)quant_mat[(i&63)];
00278
00279
00280
00281
00282
00283
00284 y = (x<<4) / (d) ;
00285 if ( y > clipvalue )
00286 {
00287 if( saturated )
00288 {
00289 y = clipvalue;
00290 }
00291 else
00292 {
00293 int new_mquant = next_larger_quant_hv( picture, mquant );
00294 if( new_mquant != mquant )
00295 {
00296 mquant = new_mquant;
00297 quant_mat = inter_q_tbl[mquant];
00298 }
00299 else
00300 {
00301 saturated = 1;
00302 }
00303 i=0;
00304 nzflag =0;
00305 goto restart;
00306 }
00307 }
00308 dst[i] = intsamesign(src[i], y) ;
00309 flags |= dst[i];
00310 }
00311 nzflag = (nzflag<<1) | !!flags;
00312
00313 *nonsat_mquant = mquant;
00314 return nzflag;
00315 }
00316
00317
00318 static void iquant1_intra(int16_t *src, int16_t *dst, int dc_prec, int mquant)
00319 {
00320 int i, val;
00321 uint16_t *quant_mat = intra_q;
00322
00323 dst[0] = src[0] << (3-dc_prec);
00324 for (i=1; i<64; i++)
00325 {
00326 val = (int)(src[i]*quant_mat[i]*mquant)/16;
00327
00328
00329 if ((val&1)==0 && val!=0)
00330 val+= (val>0) ? -1 : 1;
00331
00332
00333 dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
00334 }
00335 }
00336
00337
00338
00339 void iquant_intra(int16_t *src, int16_t *dst, int dc_prec, int mquant)
00340 {
00341 int i, val, sum;
00342
00343 if ( mpeg1 )
00344 iquant1_intra(src,dst,dc_prec, mquant);
00345 else
00346 {
00347 sum = dst[0] = src[0] << (3-dc_prec);
00348 for (i=1; i<64; i++)
00349 {
00350 val = (int)(src[i]*intra_q[i]*mquant)/16;
00351 sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
00352 }
00353
00354
00355 if ((sum&1)==0)
00356 dst[63]^= 1;
00357 }
00358 }
00359
00360
00361 static void iquant_non_intra_m1(int16_t *src, int16_t *dst, uint16_t *quant_mat)
00362 {
00363 int i, val;
00364
00365 #ifndef ORIGINAL_CODE
00366
00367 for (i=0; i<64; i++)
00368 {
00369 val = src[i];
00370 if (val!=0)
00371 {
00372 val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i])/32;
00373
00374
00375 if ((val&1)==0 && val!=0)
00376 val+= (val>0) ? -1 : 1;
00377 }
00378
00379
00380 dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
00381 }
00382 #else
00383
00384 for (i=0; i<64; i++)
00385 {
00386 val = abs(src[i]);
00387 if (val!=0)
00388 {
00389 val = ((val+val+1)*quant_mat[i]) >> 5;
00390
00391 val -= (~(val&1))&(val!=0);
00392 val = fastmin(val, 2047);
00393 }
00394 dst[i] = intsamesign(src[i],val);
00395
00396 }
00397
00398 #endif
00399 }
00400
00401
00402
00403
00404 void iquant_non_intra(int16_t *src, int16_t *dst, int mquant )
00405 {
00406 int i, val, sum;
00407 uint16_t *quant_mat;
00408
00409 if ( mpeg1 )
00410 (*piquant_non_intra_m1)(src,dst,inter_q_tbl[mquant]);
00411 else
00412 {
00413 sum = 0;
00414 #ifdef ORIGINAL_CODE
00415
00416 for (i=0; i<64; i++)
00417 {
00418 val = src[i];
00419 if (val!=0)
00420
00421 val = (int)((2*val+(val>0 ? 1 : -1))*inter_q[i]*mquant)/32;
00422 sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
00423 }
00424 #else
00425 quant_mat = inter_q_tbl[mquant];
00426 for (i=0; i<64; i++)
00427 {
00428 val = src[i];
00429 if( val != 0 )
00430 {
00431 val = abs(val);
00432 val = (int)((val+val+1)*quant_mat[i])>>5;
00433 val = intmin( val, 2047);
00434 sum += val;
00435 }
00436 dst[i] = intsamesign(src[i],val);
00437 }
00438 #endif
00439
00440
00441 if ((sum&1)==0)
00442 dst[63]^= 1;
00443 }
00444 }
00445
00446 void iquantize( pict_data_s *picture )
00447 {
00448 int j,k;
00449 int16_t (*qblocks)[64] = picture->qblocks;
00450 for (k=0; k<mb_per_pict; k++)
00451 {
00452 if (picture->mbinfo[k].mb_type & MB_INTRA)
00453 for (j=0; j<block_count; j++)
00454 iquant_intra(qblocks[k*block_count+j],
00455 qblocks[k*block_count+j],
00456 cur_picture.dc_prec,
00457 cur_picture.mbinfo[k].mquant);
00458 else
00459 for (j=0;j<block_count;j++)
00460 iquant_non_intra(qblocks[k*block_count+j],
00461 qblocks[k*block_count+j],
00462 cur_picture.mbinfo[k].mquant);
00463 }
00464 }