#endif
}
- static void dct_error(const char *name, int is_idct,
- void (*fdct_func)(DCTELEM *block),
- void (*fdct_ref)(DCTELEM *block), int form, int test, const int bits)
-static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
++
++static int dct_error(const struct algo *dct, int test, int is_idct, int speed, const int bits)
{
+ void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
int it, i, scale;
int err_inf, v;
- int64_t err2, ti, ti1, it1;
- int64_t sysErr[64], sysErrMax=0;
- int maxout=0;
- int blockSumErrMax=0, blockSumErr;
+ int64_t err2, ti, ti1, it1, err_sum = 0;
+ int64_t sysErr[64], sysErrMax = 0;
+ int maxout = 0;
+ int blockSumErrMax = 0, blockSumErr;
AVLFG prng;
+ const int vals=1<<bits;
+ double omse, ome;
+ int spec_err;
av_lfg_init(&prng, 1);
err_inf = 0;
err2 = 0;
- for(i=0; i<64; i++) sysErr[i]=0;
- for(it=0;it<NB_ITS;it++) {
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
+ sysErr[i] = 0;
+ for (it = 0; it < NB_ITS; it++) {
+ for (i = 0; i < 64; i++)
block1[i] = 0;
- switch(test){
+ switch (test) {
case 0:
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
- block1[i] = (av_lfg_get(&prng) % 512) - 256;
+ block1[i] = (av_lfg_get(&prng) % (2*vals)) -vals;
- if (is_idct){
+ if (is_idct) {
ff_ref_fdct(block1);
-
- for(i=0;i<64;i++)
- block1[i]>>=3;
+ for (i = 0; i < 64; i++)
+ block1[i] >>= 3;
}
- break;
- case 1:{
- int num = av_lfg_get(&prng) % 10 + 1;
- for(i=0;i<num;i++)
- block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % (2*vals) -vals;
- }break;
+ break;
+ case 1: {
+ int num = av_lfg_get(&prng) % 10 + 1;
+ for (i = 0; i < num; i++)
- block1[av_lfg_get(&prng) % 64] =
- av_lfg_get(&prng) % 512 - 256;
++ block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % (2*vals) -vals;
+ }
+ break;
case 2:
- block1[0] = av_lfg_get(&prng) % 4096 - 2048;
+ block1[0] = av_lfg_get(&prng) % (16*vals) - (8*vals);
- block1[63]= (block1[0]&1)^1;
- break;
+ block1[63] = (block1[0] & 1) ^ 1;
+ break;
}
- #if 0 // simulate mismatch control
- { int sum=0;
- for(i=0;i<64;i++)
- sum+=block1[i];
-
- if((sum&1)==0) block1[63]^=1;
- }
- #endif
+ for (i = 0; i < 64; i++)
+ block_org[i] = block1[i];
- for(i=0; i<64; i++)
- block_org[i]= block1[i];
-
- if (form == MMX_PERM) {
- for(i=0;i<64;i++)
+ if (dct->format == MMX_PERM) {
+ for (i = 0; i < 64; i++)
block[idct_mmx_perm[i]] = block1[i];
- } else if (form == MMX_SIMPLE_PERM) {
- for(i=0;i<64;i++)
+ } else if (dct->format == MMX_SIMPLE_PERM) {
+ for (i = 0; i < 64; i++)
block[idct_simple_mmx_perm[i]] = block1[i];
-
- } else if (form == SSE2_PERM) {
- for(i=0; i<64; i++)
- block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
- } else if (form == PARTTRANS_PERM) {
- for(i=0; i<64; i++)
- block[(i&0x24) | ((i&3)<<3) | ((i>>3)&3)] = block1[i];
+ } else if (dct->format == SSE2_PERM) {
+ for (i = 0; i < 64; i++)
+ block[(i & 0x38) | idct_sse2_row_perm[i & 7]] = block1[i];
+ } else if (dct->format == PARTTRANS_PERM) {
+ for (i = 0; i < 64; i++)
+ block[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = block1[i];
} else {
- for(i=0; i<64; i++)
- block[i]= block1[i];
+ for (i = 0; i < 64; i++)
+ block[i] = block1[i];
}
- #if 0 // simulate mismatch control for tested IDCT but not the ref
- { int sum=0;
- for(i=0;i<64;i++)
- sum+=block[i];
-
- if((sum&1)==0) block[63]^=1;
- }
- #endif
- fdct_func(block);
+ dct->func(block);
mmx_emms();
- if (form == SCALE_PERM) {
- for(i=0; i<64; i++) {
- scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
- block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
+ if (dct->format == SCALE_PERM) {
+ for (i = 0; i < 64; i++) {
+ scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
+ block[i] = (block[i] * scale) >> AANSCALE_BITS;
}
}
}
printf("\n");
- printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
- is_idct ? "IDCT" : "DCT",
- name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
+ omse = (double) err2 / NB_ITS / 64;
+ ome = (double) err_sum / NB_ITS / 64;
+
+ spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
+
+ printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
+ is_idct ? "IDCT" : "DCT", dct->name, err_inf,
+ omse, ome, (double) sysErrMax / NB_ITS,
+ maxout, blockSumErrMax);
+
+ if (spec_err && !dct->nonspec)
+ return 1;
+
+ if (!speed)
+ return 0;
/* speed test */
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
block1[i] = 0;
- switch(test){
+
+ switch (test) {
case 0:
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
- block1[i] = av_lfg_get(&prng) % 512 - 256;
+ block1[i] = av_lfg_get(&prng) % (2*vals) -vals;
- if (is_idct){
+ if (is_idct) {
ff_ref_fdct(block1);
-
- for(i=0;i<64;i++)
- block1[i]>>=3;
+ for (i = 0; i < 64; i++)
+ block1[i] >>= 3;
}
- break;
- case 1:{
+ break;
+ case 1:
case 2:
- block1[0] = av_lfg_get(&prng) % 512 - 256;
- block1[1] = av_lfg_get(&prng) % 512 - 256;
- block1[2] = av_lfg_get(&prng) % 512 - 256;
- block1[3] = av_lfg_get(&prng) % 512 - 256;
+ block1[0] = av_lfg_get(&prng) % (2*vals) -vals;
+ block1[1] = av_lfg_get(&prng) % (2*vals) -vals;
+ block1[2] = av_lfg_get(&prng) % (2*vals) -vals;
+ block1[3] = av_lfg_get(&prng) % (2*vals) -vals;
- }break;
+ break;
}
- if (form == MMX_PERM) {
- for(i=0;i<64;i++)
+ if (dct->format == MMX_PERM) {
+ for (i = 0; i < 64; i++)
block[idct_mmx_perm[i]] = block1[i];
- } else if(form == MMX_SIMPLE_PERM) {
- for(i=0;i<64;i++)
+ } else if (dct->format == MMX_SIMPLE_PERM) {
+ for (i = 0; i < 64; i++)
block[idct_simple_mmx_perm[i]] = block1[i];
} else {
- for(i=0; i<64; i++)
- block[i]= block1[i];
+ for (i = 0; i < 64; i++)
+ block[i] = block1[i];
}
ti = gettime();
if (v > err_max)
err_max = v;
}
+#if 0
+ printf("ref=\n");
+ for(i=0;i<8;i++) {
+ int j;
+ for(j=0;j<8;j++) {
+ printf(" %3d", img_dest1[i*8+j]);
+ }
+ printf("\n");
+ }
+
+ printf("out=\n");
+ for(i=0;i<8;i++) {
+ int j;
+ for(j=0;j<8;j++) {
+ printf(" %3d", img_dest[i*8+j]);
+ }
+ printf("\n");
+ }
+#endif
}
- printf("%s %s: err_inf=%d\n",
- 1 ? "IDCT248" : "DCT248",
- name, err_max);
+ printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
+
+ if (!speed)
+ return;
ti = gettime();
it1 = 0;
int main(int argc, char **argv)
{
int test_idct = 0, test_248_dct = 0;
- int c,i;
- int test=1;
+ int c, i;
+ int test = 1;
+ int speed = 0;
+ int err = 0;
+ int bits=8;
+
cpu_flags = av_get_cpu_flags();
ff_ref_dct_init();
}
}
- if(optind <argc) test= atoi(argv[optind]);
+ if (optind < argc)
+ test = atoi(argv[optind]);
+ if(optind+1 < argc) bits= atoi(argv[optind+1]);
printf("ffmpeg DCT/IDCT test\n");
if (test_248_dct) {
- idct248_error("SIMPLE-C", ff_simple_idct248_put);
+ idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
} else {
- for (i=0;algos[i].name;i++)
- if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
- dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test, bits);
- }
+ const struct algo *algos = test_idct ? idct_tab : fdct_tab;
+ for (i = 0; algos[i].name; i++)
+ if (!(~cpu_flags & algos[i].mm_support)) {
- err |= dct_error(&algos[i], test, test_idct, speed);
++ err |= dct_error(&algos[i], test, test_idct, speed, bits);
+ }
}
- return 0;
+
+ return err;
}
/*
- * This file is part of Libav.
+ * Copyright (C) 2009 Loren Merritt <lorenm@u.washignton.edu>
+ *
+ * This file is part of FFmpeg.
*
- * FFmpeg is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * Libav is free software; you can redistribute it and/or
++ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
++ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/cpu.h"
return isnan(*d) ? AVERROR(EINVAL) : 0;
}
+#if FF_API_OLD_EVAL_NAMES
+int av_parse_expr(AVExpr **expr, const char *s,
+ const char * const *const_names,
+ const char * const *func1_names, double (* const *funcs1)(void *, double),
+ const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+ int log_offset, void *log_ctx)
+{
+ return av_expr_parse(expr, s, const_names, func1_names, funcs1, func2_names, funcs2,
+ log_offset, log_ctx);
+}
+
+double av_eval_expr(AVExpr *e, const double *const_values, void *opaque)
+{
+ return av_expr_eval(e, const_values, opaque);
+}
+
+int av_parse_and_eval_expr(double *res, const char *s,
+ const char * const *const_names, const double *const_values,
+ const char * const *func1_names, double (* const *funcs1)(void *, double),
+ const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+ void *opaque, int log_offset, void *log_ctx)
+{
+ return av_expr_parse_and_eval(res, s, const_names, const_values, func1_names, funcs1, func2_names, funcs2,
+ opaque, log_offset, log_ctx);
+}
+
+void av_free_expr(AVExpr *e)
+{
+ av_expr_free(e);
+}
+#endif /* FF_API_OLD_EVAL_NAMES */
+
#ifdef TEST
#undef printf
+ #include <string.h>
+
static double const_values[] = {
M_PI,
M_E,
--- /dev/null
+ Evaluating ''
+ '' -> nan
+
+ Evaluating '1;2'
+ '1;2' -> 2.000000
+
+ Evaluating '-20'
+ '-20' -> -20.000000
+
+ Evaluating '-PI'
+ '-PI' -> -3.141593
+
+ Evaluating '+PI'
+ '+PI' -> 3.141593
+
+ Evaluating '1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)'
+ '1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)' -> 12.700000
+
+ Evaluating '80G/80Gi1k'
+ '80G/80Gi1k' -> nan
+
+ Evaluating '1Gi'
+ '1Gi' -> 1073741824.000000
+
+ Evaluating '1gi'
+ '1gi' -> nan
+
+ Evaluating '1GiFoo'
+ '1GiFoo' -> nan
+
+ Evaluating '1k+1k'
+ '1k+1k' -> 2000.000000
+
+ Evaluating '1Gi*3foo'
+ '1Gi*3foo' -> nan
+
+ Evaluating 'foo'
+ 'foo' -> nan
+
+ Evaluating 'foo('
+ 'foo(' -> nan
+
+ Evaluating 'foo()'
+ 'foo()' -> nan
+
+ Evaluating 'foo)'
+ 'foo)' -> nan
+
+ Evaluating 'sin'
+ 'sin' -> nan
+
+ Evaluating 'sin('
+ 'sin(' -> nan
+
+ Evaluating 'sin()'
+ 'sin()' -> nan
+
+ Evaluating 'sin)'
+ 'sin)' -> nan
+
+ Evaluating 'sin 10'
+ 'sin 10' -> nan
+
+ Evaluating 'sin(1,2,3)'
+ 'sin(1,2,3)' -> nan
+
+ Evaluating 'sin(1 )'
+ 'sin(1 )' -> 0.841471
+
+ Evaluating '1'
+ '1' -> 1.000000
+
+ Evaluating '1foo'
+ '1foo' -> nan
+
+ Evaluating 'bar + PI + E + 100f*2 + foo'
+ 'bar + PI + E + 100f*2 + foo' -> nan
+
+ Evaluating '13k + 12f - foo(1, 2)'
+ '13k + 12f - foo(1, 2)' -> nan
+
+ Evaluating '1gi'
+ '1gi' -> nan
+
+ Evaluating '1Gi'
+ '1Gi' -> 1073741824.000000
+
+ Evaluating 'st(0, 123)'
+ 'st(0, 123)' -> 123.000000
+
+ Evaluating 'st(1, 123); ld(1)'
+ 'st(1, 123); ld(1)' -> 123.000000
+
+ Evaluating 'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)'
+ 'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)' -> 4950.000000
+
+ Evaluating 'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)'
+ 'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)' -> 144.000000
+
+ Evaluating 'while(0, 10)'
+ 'while(0, 10)' -> nan
+
+ Evaluating 'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))'
+ 'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))' -> 100.000000
+
+ Evaluating 'isnan(1)'
+ 'isnan(1)' -> 0.000000
+
+ Evaluating 'isnan(NAN)'
+ 'isnan(NAN)' -> 1.000000
+
+ Evaluating 'floor(NAN)'
+ 'floor(NAN)' -> nan
+
+ Evaluating 'floor(123.123)'
+ 'floor(123.123)' -> 123.000000
+
+ Evaluating 'floor(-123.123)'
+ 'floor(-123.123)' -> -124.000000
+
+ Evaluating 'trunc(123.123)'
+ 'trunc(123.123)' -> 123.000000
+
+ Evaluating 'trunc(-123.123)'
+ 'trunc(-123.123)' -> -123.000000
+
+ Evaluating 'ceil(123.123)'
+ 'ceil(123.123)' -> 124.000000
+
+ Evaluating 'ceil(-123.123)'
+ 'ceil(-123.123)' -> -123.000000
+
++Evaluating 'sqrt(1764)'
++'sqrt(1764)' -> 42.000000
++
++Evaluating 'sqrt(-1)'
++'sqrt(-1)' -> -nan
++
++Evaluating 'not(1)'
++'not(1)' -> 0.000000
++
++Evaluating 'not(NAN)'
++'not(NAN)' -> 0.000000
++
++Evaluating 'not(0)'
++'not(0)' -> 1.000000
++
++Evaluating 'pow(0,1.23)'
++'pow(0,1.23)' -> 0.000000
++
++Evaluating 'pow(PI,1.23)'
++'pow(PI,1.23)' -> 4.087844
++
++Evaluating 'PI^1.23'
++'PI^1.23' -> 4.087844
++
++Evaluating 'pow(-1,1.23)'
++'pow(-1,1.23)' -> -nan
++
+ 12.700000 == 12.7
+ 0.931323 == 0.931322575