Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenoptimize.c
Go to the documentation of this file.
00001 /* 00002 optimize: get a grip on the different optimizations 00003 00004 copyright 2006-9 by the mpg123 project - free software under the terms of the LGPL 2.1 00005 see COPYING and AUTHORS files in distribution or http://mpg123.org 00006 initially written by Thomas Orgis, inspired by 3DNow stuff in mpg123.[hc] 00007 00008 Currently, this file contains the struct and function to choose an optimization variant and works only when OPT_MULTI is in effect. 00009 */ 00010 00011 #include "mpg123lib_intern.h" /* includes optimize.h */ 00012 #include "debug.h" 00013 00014 /* Must match the enum dectype! */ 00015 00016 /* 00017 It SUCKS having to define these names that way, but compile-time intialization of string arrays is a bitch. 00018 GCC doesn't see constant stuff when it's wiggling in front of it! 00019 Anyhow: Have a script for that: 00020 names="generic generic_dither i386 i486 i586 i586_dither MMX 3DNow 3DNowExt AltiVec SSE x86-64" 00021 for i in $names; do echo "##define dn_${i/-/_} \"$i\""; done 00022 echo -n "static const char* decname[] = 00023 { 00024 \"auto\" 00025 " 00026 for i in $names; do echo -n ", dn_${i/-/_}"; done 00027 echo " 00028 , \"nodec\" 00029 };" 00030 */ 00031 #define dn_generic "generic" 00032 #define dn_generic_dither "generic_dither" 00033 #define dn_i386 "i386" 00034 #define dn_i486 "i486" 00035 #define dn_i586 "i586" 00036 #define dn_i586_dither "i586_dither" 00037 #define dn_MMX "MMX" 00038 #define dn_3DNow "3DNow" 00039 #define dn_3DNowExt "3DNowExt" 00040 #define dn_AltiVec "AltiVec" 00041 #define dn_SSE "SSE" 00042 #define dn_x86_64 "x86-64" 00043 #define dn_ARM "ARM" 00044 static const char* decname[] = 00045 { 00046 "auto" 00047 , dn_generic, dn_generic_dither, dn_i386, dn_i486, dn_i586, dn_i586_dither, dn_MMX, dn_3DNow, dn_3DNowExt, dn_AltiVec, dn_SSE, dn_x86_64, dn_ARM 00048 , "nodec" 00049 }; 00050 00051 #if (defined OPT_X86) && (defined OPT_MULTI) 00052 #include "getcpuflags.h" 00053 struct cpuflags cpu_flags; 00054 #else 00055 /* Faking stuff for non-multi builds. The same code for synth function choice is used. 00056 Just no runtime dependency of result... */ 00057 char cpu_flags; 00058 #define cpu_i586(s) 1 00059 #define cpu_fpu(s) 1 00060 #define cpu_mmx(s) 1 00061 #define cpu_3dnow(s) 1 00062 #define cpu_3dnowext(s) 1 00063 #define cpu_sse(s) 1 00064 #define cpu_sse2(s) 1 00065 #define cpu_sse3(s) 1 00066 #endif 00067 00068 /* Ugly macros to build conditional synth function array values. */ 00069 00070 #ifndef NO_8BIT 00071 #define IF8(synth) synth, 00072 #else 00073 #define IF8(synth) 00074 #endif 00075 00076 #ifndef NO_REAL 00077 #define IFREAL(synth) synth, 00078 #else 00079 #define IFREAL(synth) 00080 #endif 00081 00082 #ifndef NO_32BIT 00083 #define IF32(synth) synth 00084 #else 00085 #define IF32(synth) 00086 #endif 00087 00088 #ifndef NO_16BIT 00089 # define OUT_SYNTHS(synth_16, synth_8, synth_real, synth_32) { synth_16, IF8(synth_8) IFREAL(synth_real) IF32(synth_32) } 00090 #else 00091 # define OUT_SYNTHS(synth_16, synth_8, synth_real, synth_32) { IF8(synth_8) IFREAL(synth_real) IF32(synth_32) } 00092 #endif 00093 00094 /* The call of left and right plain synth, wrapped. 00095 This may be replaced by a direct stereo optimized synth. */ 00096 int synth_stereo_wrap(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 00097 { 00098 int clip; 00099 clip = (fr->synth)(bandPtr_l, 0, fr, 0); 00100 clip += (fr->synth)(bandPtr_r, 1, fr, 1); 00101 return clip; 00102 } 00103 00104 const struct synth_s synth_base = 00105 { 00106 { /* plain */ 00107 OUT_SYNTHS(synth_1to1, synth_1to1_8bit, synth_1to1_real, synth_1to1_s32) 00108 # ifndef NO_DOWNSAMPLE 00109 ,OUT_SYNTHS(synth_2to1, synth_2to1_8bit, synth_2to1_real, synth_2to1_s32) 00110 ,OUT_SYNTHS(synth_4to1, synth_4to1_8bit, synth_4to1_real, synth_4to1_s32) 00111 # endif 00112 # ifndef NO_NTOM 00113 ,OUT_SYNTHS(synth_ntom, synth_ntom_8bit, synth_ntom_real, synth_ntom_s32) 00114 # endif 00115 }, 00116 { /* stereo, by default only wrappers over plain synth */ 00117 OUT_SYNTHS(synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap) 00118 # ifndef NO_DOWNSAMPLE 00119 ,OUT_SYNTHS(synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap) 00120 ,OUT_SYNTHS(synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap) 00121 # endif 00122 # ifndef NO_NTOM 00123 ,OUT_SYNTHS(synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap, synth_stereo_wrap) 00124 # endif 00125 }, 00126 { /* mono2stereo */ 00127 OUT_SYNTHS(synth_1to1_mono2stereo, synth_1to1_8bit_mono2stereo, synth_1to1_real_mono2stereo, synth_1to1_s32_mono2stereo) 00128 # ifndef NO_DOWNSAMPLE 00129 ,OUT_SYNTHS(synth_2to1_mono2stereo, synth_2to1_8bit_mono2stereo, synth_2to1_real_mono2stereo, synth_2to1_s32_mono2stereo) 00130 ,OUT_SYNTHS(synth_4to1_mono2stereo, synth_4to1_8bit_mono2stereo, synth_4to1_real_mono2stereo, synth_4to1_s32_mono2stereo) 00131 # endif 00132 # ifndef NO_NTOM 00133 ,OUT_SYNTHS(synth_ntom_mono2stereo, synth_ntom_8bit_mono2stereo, synth_ntom_real_mono2stereo, synth_ntom_s32_mono2stereo) 00134 # endif 00135 }, 00136 { /* mono*/ 00137 OUT_SYNTHS(synth_1to1_mono, synth_1to1_8bit_mono, synth_1to1_real_mono, synth_1to1_s32_mono) 00138 # ifndef NO_DOWNSAMPLE 00139 ,OUT_SYNTHS(synth_2to1_mono, synth_2to1_8bit_mono, synth_2to1_real_mono, synth_2to1_s32_mono) 00140 ,OUT_SYNTHS(synth_4to1_mono, synth_4to1_8bit_mono, synth_4to1_real_mono, synth_4to1_s32_mono) 00141 # endif 00142 # ifndef NO_NTOM 00143 ,OUT_SYNTHS(synth_ntom_mono, synth_ntom_8bit_mono, synth_ntom_real_mono, synth_ntom_s32_mono) 00144 #endif 00145 } 00146 }; 00147 00148 #ifdef OPT_X86 00149 /* More plain synths for i386 */ 00150 const func_synth plain_i386[r_limit][f_limit] = 00151 { /* plain */ 00152 OUT_SYNTHS(synth_1to1_i386, synth_1to1_8bit_i386, synth_1to1_real_i386, synth_1to1_s32_i386) 00153 # ifndef NO_DOWNSAMPLE 00154 ,OUT_SYNTHS(synth_2to1_i386, synth_2to1_8bit_i386, synth_2to1_real_i386, synth_2to1_s32_i386) 00155 ,OUT_SYNTHS(synth_4to1_i386, synth_4to1_8bit_i386, synth_4to1_real_i386, synth_4to1_s32_i386) 00156 # endif 00157 # ifndef NO_NTOM 00158 ,OUT_SYNTHS(synth_ntom, synth_ntom_8bit, synth_ntom_real, synth_ntom_s32) 00159 # endif 00160 }; 00161 #endif 00162 00163 00164 enum optdec defdec(void){ return defopt; } 00165 00166 enum optcla decclass(const enum optdec type) 00167 { 00168 return (type == mmx || type == sse || type == dreidnowext || type == x86_64 ) ? mmxsse : normal; 00169 } 00170 00171 00172 static int find_synth(func_synth synth, const func_synth synths[r_limit][f_limit]) 00173 { 00174 enum synth_resample ri; 00175 enum synth_format fi; 00176 for(ri=0; ri<r_limit; ++ri) 00177 for(fi=0; fi<f_limit; ++fi) 00178 if(synth == synths[ri][fi]) 00179 return TRUE; 00180 00181 return FALSE; 00182 } 00183 00184 /* Determine what kind of decoder is actually active 00185 This depends on runtime choices which may cause fallback to i386 or generic code. */ 00186 static int find_dectype(mpg123_handle *fr) 00187 { 00188 enum optdec type = nodec; 00189 /* Direct and indirect usage, 1to1 stereo decoding. 00190 Concentrating on the plain stereo synth should be fine, mono stuff is derived. */ 00191 func_synth basic_synth = fr->synth; 00192 #ifndef NO_8BIT 00193 #ifndef NO_16BIT 00194 if(basic_synth == synth_1to1_8bit_wrap) 00195 basic_synth = fr->synths.plain[r_1to1][f_16]; /* That is what's really below the surface. */ 00196 #endif 00197 #endif 00198 00199 if(FALSE) ; /* Just to initialize the else if ladder. */ 00200 #ifndef NO_16BIT 00201 #ifdef OPT_3DNOWEXT 00202 else if(basic_synth == synth_1to1_3dnowext) type = dreidnowext; 00203 #endif 00204 #ifdef OPT_SSE 00205 else if(basic_synth == synth_1to1_sse) type = sse; 00206 #endif 00207 #ifdef OPT_3DNOW 00208 else if(basic_synth == synth_1to1_3dnow) type = dreidnow; 00209 #endif 00210 #ifdef OPT_MMX 00211 else if(basic_synth == synth_1to1_mmx) type = mmx; 00212 #endif 00213 #ifdef OPT_I586_DITHER 00214 else if(basic_synth == synth_1to1_i586_dither) type = ifuenf_dither; 00215 #endif 00216 #ifdef OPT_I586 00217 else if(basic_synth == synth_1to1_i586) type = ifuenf; 00218 #endif 00219 #ifdef OPT_ALTIVEC 00220 else if(basic_synth == synth_1to1_altivec) type = altivec; 00221 #endif 00222 #ifdef OPT_X86_64 00223 else if(basic_synth == synth_1to1_x86_64) type = x86_64; 00224 #endif 00225 #ifdef OPT_ARM 00226 else if(basic_synth == synth_1to1_arm) type = arm; 00227 #endif 00228 #ifdef OPT_GENERIC_DITHER 00229 else if(basic_synth == synth_1to1_dither) type = generic_dither; 00230 #endif 00231 #ifdef OPT_DITHER /* either i586 or generic! */ 00232 #ifndef NO_DOWNSAMPLE 00233 else if 00234 ( 00235 basic_synth == synth_2to1_dither 00236 || basic_synth == synth_4to1_dither 00237 ) type = generic_dither; 00238 #endif 00239 #endif 00240 #endif /* 16bit */ 00241 00242 #ifndef NO_REAL 00243 #ifdef OPT_SSE 00244 else if(basic_synth == synth_1to1_real_sse) type = sse; 00245 #endif 00246 #ifdef OPT_X86_64 00247 else if(basic_synth == synth_1to1_real_x86_64) type = x86_64; 00248 #endif 00249 #ifdef OPT_ALTIVEC 00250 else if(basic_synth == synth_1to1_real_altivec) type = altivec; 00251 #endif 00252 00253 #endif /* real */ 00254 00255 #ifndef NO_32BIT 00256 #ifdef OPT_SSE 00257 else if(basic_synth == synth_1to1_s32_sse) type = sse; 00258 #endif 00259 #ifdef OPT_X86_64 00260 else if(basic_synth == synth_1to1_s32_x86_64) type = x86_64; 00261 #endif 00262 #ifdef OPT_ALTIVEC 00263 else if(basic_synth == synth_1to1_s32_altivec) type = altivec; 00264 #endif 00265 #endif /* 32bit */ 00266 00267 #ifdef OPT_X86 00268 else if(find_synth(basic_synth, plain_i386)) 00269 type = idrei; 00270 #endif 00271 00272 else if(find_synth(basic_synth, synth_base.plain)) 00273 type = generic; 00274 00275 00276 00277 #ifdef OPT_I486 00278 /* i486 is special ... the specific code is in use for 16bit 1to1 stereo 00279 otherwise we have i386 active... but still, the distinction doesn't matter*/ 00280 type = ivier; 00281 #endif 00282 00283 if(type != nodec) 00284 { 00285 fr->cpu_opts.type = type; 00286 fr->cpu_opts.class = decclass(type); 00287 00288 debug3("determined active decoder type %i (%s) of class %i", type, decname[type], fr->cpu_opts.class); 00289 return MPG123_OK; 00290 } 00291 else 00292 { 00293 if(NOQUIET) error("Unable to determine active decoder type -- this is SERIOUS b0rkage!"); 00294 00295 fr->err = MPG123_BAD_DECODER_SETUP; 00296 return MPG123_ERR; 00297 } 00298 } 00299 00300 /* set synth functions for current frame, optimizations handled by opt_* macros */ 00301 int set_synth_functions(mpg123_handle *fr) 00302 { 00303 enum synth_resample resample = r_none; 00304 enum synth_format basic_format = f_none; /* Default is always 16bit, or whatever. */ 00305 00306 /* Select the basic output format, different from 16bit: 8bit, real. */ 00307 if(FALSE){} 00308 #ifndef NO_16BIT 00309 else if(fr->af.encoding & MPG123_ENC_16) 00310 basic_format = f_16; 00311 #endif 00312 #ifndef NO_8BIT 00313 else if(fr->af.encoding & MPG123_ENC_8) 00314 basic_format = f_8; 00315 #endif 00316 #ifndef NO_REAL 00317 else if(fr->af.encoding & MPG123_ENC_FLOAT) 00318 basic_format = f_real; 00319 #endif 00320 #ifndef NO_32BIT 00321 else if(fr->af.encoding & MPG123_ENC_32) 00322 basic_format = f_32; 00323 #endif 00324 00325 /* Make sure the chosen format is compiled into this lib. */ 00326 if(basic_format == f_none) 00327 { 00328 if(NOQUIET) error("set_synth_functions: This output format is disabled in this build!"); 00329 00330 return -1; 00331 } 00332 00333 /* Be explicit about downsampling variant. */ 00334 switch(fr->down_sample) 00335 { 00336 case 0: resample = r_1to1; break; 00337 #ifndef NO_DOWNSAMPLE 00338 case 1: resample = r_2to1; break; 00339 case 2: resample = r_4to1; break; 00340 #endif 00341 #ifndef NO_NTOM 00342 case 3: resample = r_ntom; break; 00343 #endif 00344 } 00345 00346 if(resample == r_none) 00347 { 00348 if(NOQUIET) error("set_synth_functions: This resampling mode is not supported in this build!"); 00349 00350 return -1; 00351 } 00352 00353 debug2("selecting synth: resample=%i format=%i", resample, basic_format); 00354 /* Finally selecting the synth functions for stereo / mono. */ 00355 fr->synth = fr->synths.plain[resample][basic_format]; 00356 fr->synth_stereo = fr->synths.stereo[resample][basic_format]; 00357 fr->synth_mono = fr->af.channels==2 00358 ? fr->synths.mono2stereo[resample][basic_format] /* Mono MPEG file decoded to stereo. */ 00359 : fr->synths.mono[resample][basic_format]; /* Mono MPEG file decoded to mono. */ 00360 00361 if(find_dectype(fr) != MPG123_OK) /* Actually determine the currently active decoder breed. */ 00362 { 00363 fr->err = MPG123_BAD_DECODER_SETUP; 00364 return MPG123_ERR; 00365 } 00366 00367 if(frame_buffers(fr) != 0) 00368 { 00369 fr->err = MPG123_NO_BUFFERS; 00370 if(NOQUIET) error("Failed to set up decoder buffers!"); 00371 00372 return MPG123_ERR; 00373 } 00374 00375 #ifndef NO_8BIT 00376 if(basic_format == f_8) 00377 { 00378 if(make_conv16to8_table(fr) != 0) 00379 { 00380 if(NOQUIET) error("Failed to set up conv16to8 table!"); 00381 /* it's a bit more work to get proper error propagation up */ 00382 return -1; 00383 } 00384 } 00385 #endif 00386 00387 #ifdef OPT_MMXORSSE 00388 /* Special treatment for MMX, SSE and 3DNowExt stuff. 00389 The real-decoding SSE for x86-64 uses normal tables! */ 00390 if(fr->cpu_opts.class == mmxsse 00391 # ifndef NO_REAL 00392 && basic_format != f_real 00393 # endif 00394 # ifndef NO_32BIT 00395 && basic_format != f_32 00396 # endif 00397 # ifdef ACCURATE_ROUNDING 00398 && fr->cpu_opts.type != sse 00399 && fr->cpu_opts.type != x86_64 00400 # endif 00401 ) 00402 { 00403 #ifndef NO_LAYER3 00404 init_layer3_stuff(fr, init_layer3_gainpow2_mmx); 00405 #endif 00406 #ifndef NO_LAYER12 00407 init_layer12_stuff(fr, init_layer12_table_mmx); 00408 #endif 00409 fr->make_decode_tables = make_decode_tables_mmx; 00410 } 00411 else 00412 #endif 00413 { 00414 #ifndef NO_LAYER3 00415 init_layer3_stuff(fr, init_layer3_gainpow2); 00416 #endif 00417 #ifndef NO_LAYER12 00418 init_layer12_stuff(fr, init_layer12_table); 00419 #endif 00420 fr->make_decode_tables = make_decode_tables; 00421 } 00422 00423 /* We allocated the table buffers just now, so (re)create the tables. */ 00424 fr->make_decode_tables(fr); 00425 00426 return 0; 00427 } 00428 00429 int frame_cpu_opt(mpg123_handle *fr, const char* cpu) 00430 { 00431 const char* chosen = ""; /* the chosen decoder opt as string */ 00432 enum optdec want_dec = nodec; 00433 int done = 0; 00434 int auto_choose = 0; 00435 #ifdef OPT_DITHER 00436 int dithered = FALSE; /* If some dithered decoder is chosen. */ 00437 #endif 00438 00439 want_dec = dectype(cpu); 00440 auto_choose = want_dec == autodec; 00441 /* Fill whole array of synth functions with generic code first. */ 00442 fr->synths = synth_base; 00443 00444 #ifndef OPT_MULTI 00445 { 00446 if(!auto_choose && want_dec != defopt) 00447 { 00448 if(NOQUIET) error2("you wanted decoder type %i, I only have %i", want_dec, defopt); 00449 } 00450 auto_choose = TRUE; /* There will be only one choice anyway. */ 00451 } 00452 #endif 00453 00454 fr->cpu_opts.type = nodec; 00455 /* covers any i386+ cpu; they actually differ only in the synth_1to1 function, mostly... */ 00456 #ifdef OPT_X86 00457 00458 #ifdef OPT_MULTI 00459 #ifndef NO_LAYER3 00460 #if (defined OPT_3DNOW || defined OPT_3DNOWEXT) 00461 fr->cpu_opts.the_dct36 = dct36; 00462 #endif 00463 #endif 00464 #endif 00465 00466 if(cpu_i586(cpu_flags)) 00467 { 00468 # ifdef OPT_MULTI 00469 debug2("standard flags: 0x%08x\textended flags: 0x%08x", cpu_flags.std, cpu_flags.ext); 00470 # endif 00471 #ifdef OPT_SSE 00472 if( !done && (auto_choose || want_dec == sse) 00473 && cpu_sse(cpu_flags) && cpu_mmx(cpu_flags) ) 00474 { 00475 chosen = "SSE"; 00476 fr->cpu_opts.type = sse; 00477 # ifndef NO_16BIT 00478 fr->synths.plain[r_1to1][f_16] = synth_1to1_sse; 00479 # ifdef ACCURATE_ROUNDING 00480 fr->synths.stereo[r_1to1][f_16] = synth_1to1_stereo_sse; 00481 # endif 00482 # endif 00483 # ifndef NO_REAL 00484 fr->synths.plain[r_1to1][f_real] = synth_1to1_real_sse; 00485 fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_sse; 00486 # endif 00487 # ifndef NO_32BIT 00488 fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_sse; 00489 fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32_stereo_sse; 00490 # endif 00491 done = 1; 00492 } 00493 #endif 00494 # ifdef OPT_3DNOWEXT 00495 if( !done && (auto_choose || want_dec == dreidnowext ) 00496 && cpu_3dnow(cpu_flags) 00497 && cpu_3dnowext(cpu_flags) 00498 && cpu_mmx(cpu_flags) ) 00499 { 00500 chosen = "3DNowExt"; 00501 fr->cpu_opts.type = dreidnowext; 00502 #ifdef OPT_MULTI 00503 # ifndef NO_LAYER3 00504 fr->cpu_opts.the_dct36 = dct36_3dnowext; 00505 # endif 00506 #endif 00507 # ifndef NO_16BIT 00508 fr->synths.plain[r_1to1][f_16] = synth_1to1_3dnowext; 00509 # endif 00510 done = 1; 00511 } 00512 #endif 00513 #ifdef OPT_3DNOW 00514 if( !done && (auto_choose || want_dec == dreidnow) 00515 && cpu_3dnow(cpu_flags) && cpu_mmx(cpu_flags) ) 00516 { 00517 chosen = "3DNow"; 00518 fr->cpu_opts.type = dreidnow; 00519 #ifdef OPT_MULTI 00520 # ifndef NO_LAYER3 00521 fr->cpu_opts.the_dct36 = dct36_3dnow; 00522 # endif 00523 #endif 00524 # ifndef NO_16BIT 00525 fr->synths.plain[r_1to1][f_16] = synth_1to1_3dnow; 00526 # endif 00527 done = 1; 00528 } 00529 #endif 00530 #ifdef OPT_MMX 00531 if( !done && (auto_choose || want_dec == mmx) 00532 && cpu_mmx(cpu_flags) ) 00533 { 00534 chosen = "MMX"; 00535 fr->cpu_opts.type = mmx; 00536 # ifndef NO_16BIT 00537 fr->synths.plain[r_1to1][f_16] = synth_1to1_mmx; 00538 # endif 00539 done = 1; 00540 } 00541 #endif 00542 #ifdef OPT_I586 00543 if(!done && (auto_choose || want_dec == ifuenf)) 00544 { 00545 chosen = "i586/pentium"; 00546 fr->cpu_opts.type = ifuenf; 00547 # ifndef NO_16BIT 00548 fr->synths.plain[r_1to1][f_16] = synth_1to1_i586; 00549 # endif 00550 done = 1; 00551 } 00552 #endif 00553 #ifdef OPT_I586_DITHER 00554 if(!done && (auto_choose || want_dec == ifuenf_dither)) 00555 { 00556 chosen = "dithered i586/pentium"; 00557 fr->cpu_opts.type = ifuenf_dither; 00558 dithered = TRUE; 00559 # ifndef NO_16BIT 00560 fr->synths.plain[r_1to1][f_16] = synth_1to1_i586_dither; 00561 # ifndef NO_DOWNSAMPLE 00562 fr->synths.plain[r_2to1][f_16] = synth_2to1_dither; 00563 fr->synths.plain[r_4to1][f_16] = synth_4to1_dither; 00564 # endif 00565 # endif 00566 done = 1; 00567 } 00568 #endif 00569 } 00570 #ifdef OPT_I486 00571 /* That won't cooperate in multi opt mode - forcing i486 in layer3.c 00572 But still... here it is... maybe for real use in future. */ 00573 if(!done && (auto_choose || want_dec == ivier)) 00574 { 00575 chosen = "i486"; 00576 fr->cpu_opts.type = ivier; 00577 done = 1; 00578 } 00579 #endif 00580 #ifdef OPT_I386 00581 if(!done && (auto_choose || want_dec == idrei)) 00582 { 00583 chosen = "i386"; 00584 fr->cpu_opts.type = idrei; 00585 done = 1; 00586 } 00587 #endif 00588 00589 if(done) 00590 { 00591 /* 00592 We have chosen some x86 decoder... fillup some i386 stuff. 00593 There is an open question about using dithered synth_1to1 for 8bit wrappers. 00594 For quality it won't make sense, but wrapped i586_dither wrapped may still be faster... 00595 */ 00596 enum synth_resample ri; 00597 enum synth_format fi; 00598 # ifndef NO_8BIT 00599 # ifndef NO_16BIT /* possibility to use a 16->8 wrapper... */ 00600 if(fr->synths.plain[r_1to1][f_16] != synth_base.plain[r_1to1][f_16]) 00601 { 00602 fr->synths.plain[r_1to1][f_8] = synth_1to1_8bit_wrap; 00603 fr->synths.mono[r_1to1][f_8] = synth_1to1_8bit_wrap_mono; 00604 fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_mono2stereo; 00605 } 00606 # endif 00607 # endif 00608 for(ri=0; ri<r_limit; ++ri) 00609 for(fi=0; fi<f_limit; ++fi) 00610 { 00611 if(fr->synths.plain[ri][fi] == synth_base.plain[ri][fi]) 00612 fr->synths.plain[ri][fi] = plain_i386[ri][fi]; 00613 } 00614 } 00615 00616 #endif /* OPT_X86 */ 00617 00618 #ifdef OPT_X86_64 00619 if(!done && (auto_choose || want_dec == x86_64)) 00620 { 00621 chosen = "x86-64 (SSE)"; 00622 fr->cpu_opts.type = x86_64; 00623 # ifndef NO_16BIT 00624 fr->synths.plain[r_1to1][f_16] = synth_1to1_x86_64; 00625 fr->synths.stereo[r_1to1][f_16] = synth_1to1_stereo_x86_64; 00626 # endif 00627 # ifndef NO_REAL 00628 fr->synths.plain[r_1to1][f_real] = synth_1to1_real_x86_64; 00629 fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_x86_64; 00630 # endif 00631 # ifndef NO_32BIT 00632 fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_x86_64; 00633 fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32_stereo_x86_64; 00634 # endif 00635 done = 1; 00636 } 00637 #endif 00638 00639 #ifdef OPT_GENERIC_DITHER 00640 if(!done && (auto_choose || want_dec == generic_dither)) 00641 { 00642 chosen = "dithered generic"; 00643 fr->cpu_opts.type = generic_dither; 00644 dithered = TRUE; 00645 # ifndef NO_16BIT 00646 fr->synths.plain[r_1to1][f_16] = synth_1to1_dither; 00647 # ifndef NO_DOWNSAMPLE 00648 fr->synths.plain[r_2to1][f_16] = synth_2to1_dither; 00649 fr->synths.plain[r_4to1][f_16] = synth_4to1_dither; 00650 # endif 00651 # endif 00652 done = 1; 00653 } 00654 #endif 00655 00656 # ifdef OPT_ALTIVEC 00657 if(!done && (auto_choose || want_dec == altivec)) 00658 { 00659 chosen = "AltiVec"; 00660 fr->cpu_opts.type = altivec; 00661 # ifndef NO_16BIT 00662 fr->synths.plain[r_1to1][f_16] = synth_1to1_altivec; 00663 fr->synths.stereo[r_1to1][f_16] = synth_1to1_stereo_altivec; 00664 # endif 00665 # ifndef NO_REAL 00666 fr->synths.plain[r_1to1][f_real] = synth_1to1_real_altivec; 00667 fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_altivec; 00668 # endif 00669 # ifndef NO_32BIT 00670 fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_altivec; 00671 fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32_stereo_altivec; 00672 # endif 00673 done = 1; 00674 } 00675 # endif 00676 00677 # ifdef OPT_ARM 00678 if(!done && (auto_choose || want_dec == arm)) 00679 { 00680 chosen = "ARM"; 00681 fr->cpu_opts.type = arm; 00682 # ifndef NO_16BIT 00683 fr->synths.plain[r_1to1][f_16] = synth_1to1_arm; 00684 # endif 00685 done = 1; 00686 } 00687 # endif 00688 00689 # ifdef OPT_GENERIC 00690 if(!done && (auto_choose || want_dec == generic)) 00691 { 00692 chosen = "generic"; 00693 fr->cpu_opts.type = generic; 00694 done = 1; 00695 } 00696 # endif 00697 00698 fr->cpu_opts.class = decclass(fr->cpu_opts.type); 00699 00700 # ifndef NO_8BIT 00701 # ifndef NO_16BIT /* possibility to use a 16->8 wrapper... */ 00702 /* Last chance to use some optimized routine via generic wrappers (for 8bit). */ 00703 if( fr->cpu_opts.type != ifuenf_dither 00704 && fr->cpu_opts.type != generic_dither 00705 && fr->synths.plain[r_1to1][f_16] != synth_base.plain[r_1to1][f_16] ) 00706 { 00707 fr->synths.plain[r_1to1][f_8] = synth_1to1_8bit_wrap; 00708 fr->synths.mono[r_1to1][f_8] = synth_1to1_8bit_wrap_mono; 00709 fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_mono2stereo; 00710 } 00711 # endif 00712 # endif 00713 00714 #ifdef OPT_DITHER 00715 if(done && dithered) 00716 { 00717 /* run-time dither noise table generation */ 00718 if(!frame_dither_init(fr)) 00719 { 00720 if(NOQUIET) error("Dither noise setup failed!"); 00721 return 0; 00722 } 00723 } 00724 #endif 00725 00726 if(done) 00727 { 00728 if(VERBOSE) fprintf(stderr, "Decoder: %s\n", chosen); 00729 return 1; 00730 } 00731 else 00732 { 00733 if(NOQUIET) error("Could not set optimization!"); 00734 return 0; 00735 } 00736 } 00737 00738 enum optdec dectype(const char* decoder) 00739 { 00740 enum optdec dt; 00741 if( (decoder == NULL) 00742 || (decoder[0] == 0) ) 00743 return autodec; 00744 00745 for(dt=autodec; dt<nodec; ++dt) 00746 if(!strcasecmp(decoder, decname[dt])) return dt; 00747 00748 return nodec; /* If we found nothing... */ 00749 } 00750 00751 #ifdef OPT_MULTI 00752 00753 /* same number of entries as full list, but empty at beginning */ 00754 static const char *mpg123_supported_decoder_list[] = 00755 { 00756 #ifdef OPT_SSE 00757 NULL, 00758 #endif 00759 #ifdef OPT_3DNOWEXT 00760 NULL, 00761 #endif 00762 #ifdef OPT_3DNOW 00763 NULL, 00764 #endif 00765 #ifdef OPT_MMX 00766 NULL, 00767 #endif 00768 #ifdef OPT_I586 00769 NULL, 00770 #endif 00771 #ifdef OPT_I586_DITHER 00772 NULL, 00773 #endif 00774 #ifdef OPT_I486 00775 NULL, 00776 #endif 00777 #ifdef OPT_I386 00778 NULL, 00779 #endif 00780 #ifdef OPT_ALTIVEC 00781 NULL, 00782 #endif 00783 #ifdef OPT_X86_64 00784 NULL, 00785 #endif 00786 #ifdef OPT_ARM 00787 NULL, 00788 #endif 00789 #ifdef OPT_GENERIC_FLOAT 00790 NULL, 00791 #endif 00792 # ifdef OPT_GENERIC 00793 NULL, 00794 # endif 00795 # ifdef OPT_GENERIC_DITHER 00796 NULL, 00797 # endif 00798 NULL 00799 }; 00800 #endif 00801 00802 static const char *mpg123_decoder_list[] = 00803 { 00804 #ifdef OPT_SSE 00805 dn_SSE, 00806 #endif 00807 #ifdef OPT_3DNOWEXT 00808 dn_3DNowExt, 00809 #endif 00810 #ifdef OPT_3DNOW 00811 dn_3DNow, 00812 #endif 00813 #ifdef OPT_MMX 00814 dn_MMX, 00815 #endif 00816 #ifdef OPT_I586 00817 dn_i586, 00818 #endif 00819 #ifdef OPT_I586_DITHER 00820 dn_i586_dither, 00821 #endif 00822 #ifdef OPT_I486 00823 dn_i486, 00824 #endif 00825 #ifdef OPT_I386 00826 dn_i386, 00827 #endif 00828 #ifdef OPT_ALTIVEC 00829 dn_AltiVec, 00830 #endif 00831 #ifdef OPT_X86_64 00832 dn_x86_64, 00833 #endif 00834 #ifdef OPT_ARM 00835 dn_ARM, 00836 #endif 00837 #ifdef OPT_GENERIC 00838 dn_generic, 00839 #endif 00840 #ifdef OPT_GENERIC_DITHER 00841 dn_generic_dither, 00842 #endif 00843 NULL 00844 }; 00845 00846 void check_decoders(void ) 00847 { 00848 #ifndef OPT_MULTI 00849 /* In non-multi mode, only the full list (one entry) is used. */ 00850 return; 00851 #else 00852 const char **d = mpg123_supported_decoder_list; 00853 #ifdef OPT_X86 00854 getcpuflags(&cpu_flags); 00855 if(cpu_i586(cpu_flags)) 00856 { 00857 /* not yet: if(cpu_sse2(cpu_flags)) printf(" SSE2"); 00858 if(cpu_sse3(cpu_flags)) printf(" SSE3"); */ 00859 #ifdef OPT_SSE 00860 if(cpu_sse(cpu_flags)) *(d++) = decname[sse]; 00861 #endif 00862 #ifdef OPT_3DNOWEXT 00863 if(cpu_3dnowext(cpu_flags)) *(d++) = decname[dreidnowext]; 00864 #endif 00865 #ifdef OPT_3DNOW 00866 if(cpu_3dnow(cpu_flags)) *(d++) = decname[dreidnow]; 00867 #endif 00868 #ifdef OPT_MMX 00869 if(cpu_mmx(cpu_flags)) *(d++) = decname[mmx]; 00870 #endif 00871 #ifdef OPT_I586 00872 *(d++) = decname[ifuenf]; 00873 #endif 00874 #ifdef OPT_I586_DITHER 00875 *(d++) = decname[ifuenf_dither]; 00876 #endif 00877 } 00878 #endif 00879 /* just assume that the i486 built is run on a i486 cpu... */ 00880 #ifdef OPT_I486 00881 *(d++) = decname[ivier]; 00882 #endif 00883 #ifdef OPT_ALTIVEC 00884 *(d++) = decname[altivec]; 00885 #endif 00886 /* every supported x86 can do i386, any cpu can do generic */ 00887 #ifdef OPT_I386 00888 *(d++) = decname[idrei]; 00889 #endif 00890 #ifdef OPT_X86_64 00891 *(d++) = decname[x86_64]; 00892 #endif 00893 #ifdef OPT_ARM 00894 *(d++) = decname[arm]; 00895 #endif 00896 #ifdef OPT_GENERIC 00897 *(d++) = decname[generic]; 00898 #endif 00899 #ifdef OPT_GENERIC_DITHER 00900 *(d++) = decname[generic_dither]; 00901 #endif 00902 #endif /* ndef OPT_MULTI */ 00903 } 00904 00905 const char* attribute_align_arg mpg123_current_decoder(mpg123_handle *mh) 00906 { 00907 if(mh == NULL) return NULL; 00908 00909 return decname[mh->cpu_opts.type]; 00910 } 00911 00912 const char attribute_align_arg **mpg123_decoders(void){ return mpg123_decoder_list; } 00913 const char attribute_align_arg **mpg123_supported_decoders(void) 00914 { 00915 #ifdef OPT_MULTI 00916 return mpg123_supported_decoder_list; 00917 #else 00918 return mpg123_decoder_list; 00919 #endif 00920 } Generated on Fri May 25 2012 04:32:37 for ReactOS by
1.7.6.1
|