annotate eval.c @ 3990:746a60ba3177 libavcodec

enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author michael
date Wed, 11 Oct 2006 12:23:40 +0000
parents c8c591fe26f8
children 5160e1bdeff2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
1 /*
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
2 * simple arithmetic expression evaluator
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
3 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
4 * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
5 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
6 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
7 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
12 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
16 * Lesser General Public License for more details.
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
17 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3920
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2967
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
21 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
22 */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
23
1106
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
24 /**
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
25 * @file eval.c
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
26 * simple arithmetic expression evaluator.
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
27 *
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
28 * see http://joe.hotchkiss.com/programming/eval/eval.html
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
29 */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
30
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
31 #include "avcodec.h"
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
32 #include "mpegvideo.h"
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
33
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
34 #include <stdio.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
35 #include <stdlib.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
36 #include <string.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
37 #include <math.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
38
614
b786f15df503 NAN doesnt exist on FreeBSD patch by (Rmi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
39 #ifndef NAN
3753
82ceab4ada49 Define NAN -if not already defined- as 0.0/0.0
takis
parents: 3731
diff changeset
40 #define NAN 0.0/0.0
614
b786f15df503 NAN doesnt exist on FreeBSD patch by (Rmi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
41 #endif
b786f15df503 NAN doesnt exist on FreeBSD patch by (Rmi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
42
627
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
43 #ifndef M_PI
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
44 #define M_PI 3.14159265358979323846
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
45 #endif
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
46
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
47 typedef struct Parser{
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
48 int stack_index;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
49 char *s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
50 double *const_value;
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
51 const char **const_name; // NULL terminated
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
52 double (**func1)(void *, double a); // NULL terminated
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
53 const char **func1_name; // NULL terminated
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
54 double (**func2)(void *, double a, double b); // NULL terminated
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
55 char **func2_name; // NULL terminated
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
56 void *opaque;
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
57 char **error;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
58 } Parser;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
59
3778
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
60 static double evalExpression(Parser *p);
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
61
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
62 static int8_t si_prefixes['z' - 'E' + 1]={
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
63 ['y'-'E']= -24,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
64 ['z'-'E']= -21,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
65 ['a'-'E']= -18,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
66 ['f'-'E']= -15,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
67 ['p'-'E']= -12,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
68 ['n'-'E']= - 9,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
69 ['u'-'E']= - 6,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
70 ['m'-'E']= - 3,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
71 ['c'-'E']= - 2,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
72 ['d'-'E']= - 1,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
73 ['h'-'E']= 2,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
74 ['k'-'E']= 3,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
75 ['K'-'E']= 3,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
76 ['M'-'E']= 6,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
77 ['G'-'E']= 9,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
78 ['T'-'E']= 12,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
79 ['P'-'E']= 15,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
80 ['E'-'E']= 18,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
81 ['Z'-'E']= 21,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
82 ['Y'-'E']= 24,
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
83 };
3756
9813c594dac5 Missing extern declaration for av_strtod.
takis
parents: 3755
diff changeset
84
3778
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
85 /** strtod() function extended with 'k', 'M', 'G', 'ki', 'Mi', 'Gi' and 'B'
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
86 * postfixes. This allows using f.e. kB, MiB, G and B as a postfix. This
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
87 * function assumes that the unit of numbers is bits not bytes.
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
88 */
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
89 static double av_strtod(const char *name, char **tail) {
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
90 double d;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
91 char *next;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
92 d = strtod(name, &next);
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
93 /* if parsing succeeded, check for and interpret postfixes */
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
94 if (next!=name) {
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
95
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
96 if(*next >= 'E' && *next <= 'z'){
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
97 int e= si_prefixes[*next - 'E'];
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
98 if(e){
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
99 if(next[1] == 'i'){
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
100 d*= pow( 2, e/0.3);
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
101 next+=2;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
102 }else{
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
103 d*= pow(10, e);
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
104 next++;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
105 }
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
106 }
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
107 }
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
108
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
109 if(*next=='B') {
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
110 d*=8;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
111 *next++;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
112 }
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
113 }
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
114 /* if requested, fill in tail with the position after the last parsed
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
115 character */
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
116 if (tail)
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
117 *tail = next;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
118 return d;
67a63fa775a7 Make AVOption parsign code use ff_eval2()
takis
parents: 3774
diff changeset
119 }
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
120
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
121 static int strmatch(const char *s, const char *prefix){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
122 int i;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
123 for(i=0; prefix[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
124 if(prefix[i] != s[i]) return 0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
125 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
126 return 1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
127 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
128
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
129 static double evalPrimary(Parser *p){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
130 double d, d2=NAN;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
131 char *next= p->s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
132 int i;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
133
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
134 /* number */
3731
8b8773577dd9 Add support for SI (k, M, ...) and IEC/IEEE (Ki, Mi, ...) units.
takis
parents: 3730
diff changeset
135 d= av_strtod(p->s, &next);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
136 if(next != p->s){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
137 p->s= next;
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
138 return d;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
139 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
140
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
141 /* named constants */
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
142 for(i=0; p->const_name && p->const_name[i]; i++){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
143 if(strmatch(p->s, p->const_name[i])){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
144 p->s+= strlen(p->const_name[i]);
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
145 return p->const_value[i];
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
146 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
147 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
148
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
149 p->s= strchr(p->s, '(');
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
150 if(p->s==NULL){
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
151 *p->error = "missing (";
3754
6f219b6839ba segfault fix
michael
parents: 3753
diff changeset
152 p->s= next;
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
153 return NAN;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
154 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
155 p->s++; // "("
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
156 d= evalExpression(p);
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
157 if(p->s[0]== ','){
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
158 p->s++; // ","
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
159 d2= evalExpression(p);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
160 }
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
161 if(p->s[0] != ')'){
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
162 *p->error = "missing )";
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
163 return NAN;
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
164 }
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
165 p->s++; // ")"
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
166
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
167 if( strmatch(next, "sinh" ) ) d= sinh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
168 else if( strmatch(next, "cosh" ) ) d= cosh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
169 else if( strmatch(next, "tanh" ) ) d= tanh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
170 else if( strmatch(next, "sin" ) ) d= sin(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
171 else if( strmatch(next, "cos" ) ) d= cos(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
172 else if( strmatch(next, "tan" ) ) d= tan(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
173 else if( strmatch(next, "exp" ) ) d= exp(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
174 else if( strmatch(next, "log" ) ) d= log(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
175 else if( strmatch(next, "squish") ) d= 1/(1+exp(4*d));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
176 else if( strmatch(next, "gauss" ) ) d= exp(-d*d/2)/sqrt(2*M_PI);
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
177 else if( strmatch(next, "abs" ) ) d= fabs(d);
3755
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
178 else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2;
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
179 else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2;
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
180 else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0;
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
181 else if( strmatch(next, "gte" ) ) d= d >= d2 ? 1.0 : 0.0;
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
182 else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
882cf925ff7a cosmetic
michael
parents: 3754
diff changeset
183 else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
184 else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0;
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
185 else if( strmatch(next, "(" ) ) d= d;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
186 // else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
187 // else if( strmatch(next, "sq01" ) ) d= (d >= 0.0 && d <=1.0) ? 1.0 : 0.0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
188 else{
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
189 for(i=0; p->func1_name && p->func1_name[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
190 if(strmatch(next, p->func1_name[i])){
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
191 return p->func1[i](p->opaque, d);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
192 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
193 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
194
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
195 for(i=0; p->func2_name && p->func2_name[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
196 if(strmatch(next, p->func2_name[i])){
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
197 return p->func2[i](p->opaque, d, d2);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
198 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
199 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
200
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
201 *p->error = "unknown function";
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
202 return NAN;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
203 }
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
204
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
205 return d;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
206 }
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
207
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
208 static double evalPow(Parser *p){
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
209 int sign= (*p->s == '+') - (*p->s == '-');
86d14aebd527 simplify
michael
parents: 2434
diff changeset
210 p->s += sign&1;
86d14aebd527 simplify
michael
parents: 2434
diff changeset
211 return (sign|1) * evalPrimary(p);
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
212 }
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
213
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
214 static double evalFactor(Parser *p){
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
215 double ret= evalPow(p);
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
216 while(p->s[0]=='^'){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
217 p->s++;
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
218 ret= pow(ret, evalPow(p));
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
219 }
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
220 return ret;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
221 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
222
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
223 static double evalTerm(Parser *p){
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
224 double ret= evalFactor(p);
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
225 while(p->s[0]=='*' || p->s[0]=='/'){
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
226 if(*p->s++ == '*') ret*= evalFactor(p);
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
227 else ret/= evalFactor(p);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
228 }
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
229 return ret;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
230 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
231
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
232 static double evalExpression(Parser *p){
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
233 double ret= 0;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
234
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
235 if(p->stack_index <= 0) //protect against stack overflows
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
236 return NAN;
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
237 p->stack_index--;
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
238
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
239 do{
86d14aebd527 simplify
michael
parents: 2434
diff changeset
240 ret += evalTerm(p);
86d14aebd527 simplify
michael
parents: 2434
diff changeset
241 }while(*p->s == '+' || *p->s == '-');
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
242
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
243 p->stack_index++;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
244
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
245 return ret;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
246 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
247
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
248 double ff_eval2(char *s, double *const_value, const char **const_name,
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
249 double (**func1)(void *, double), const char **func1_name,
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
250 double (**func2)(void *, double, double), char **func2_name,
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
251 void *opaque, char **error){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
252 Parser p;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
253
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
254 p.stack_index=100;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
255 p.s= s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
256 p.const_value= const_value;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
257 p.const_name = const_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
258 p.func1 = func1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
259 p.func1_name = func1_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
260 p.func2 = func2;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
261 p.func2_name = func2_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
262 p.opaque = opaque;
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
263 p.error= error;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
264
2434
24aa9209e8b0 simplify
michael
parents: 2433
diff changeset
265 return evalExpression(&p);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
266 }
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
267
3779
3f7aa9fa5c98 Break compatibility only when first part of version number changes, in this
takis
parents: 3778
diff changeset
268 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
3770
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
269 attribute_deprecated double ff_eval(char *s, double *const_value, const char **const_name,
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
270 double (**func1)(void *, double), const char **func1_name,
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
271 double (**func2)(void *, double, double), char **func2_name,
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
272 void *opaque){
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
273 char *error=NULL;
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
274 double ret;
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
275 ret = ff_eval2(s, const_value, const_name, func1, func1_name, func2, func2_name, opaque, &error);
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
276 if (error)
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
277 av_log(NULL, AV_LOG_ERROR, "Error evaluating \"%s\": %s\n", s, error);
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
278 return ret;
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
279 }
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
280 #endif
ea345e1e440f Introduce ff_eval2 which is equivalent to ff_eval but does not log anything.
takis
parents: 3756
diff changeset
281
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
282 #ifdef TEST
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
283 #undef printf
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
284 static double const_values[]={
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
285 M_PI,
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
286 M_E,
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
287 0
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
288 };
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
289 static const char *const_names[]={
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
290 "PI",
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
291 "E",
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
292 0
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
293 };
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
294 main(){
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
295 int i;
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
296 printf("%f == 12.7\n", ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL));
3730
aae4aed137ea K prefix
michael
parents: 3729
diff changeset
297 printf("%f == 0.931322575\n", ff_eval("80G/80Gi", const_values, const_names, NULL, NULL, NULL, NULL, NULL));
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2436
diff changeset
298
2436
86d14aebd527 simplify
michael
parents: 2434
diff changeset
299 for(i=0; i<1050; i++){
86d14aebd527 simplify
michael
parents: 2434
diff changeset
300 START_TIMER
86d14aebd527 simplify
michael
parents: 2434
diff changeset
301 ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL);
86d14aebd527 simplify
michael
parents: 2434
diff changeset
302 STOP_TIMER("ff_eval")
86d14aebd527 simplify
michael
parents: 2434
diff changeset
303 }
2433
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
304 }
0934621b6453 simplify, null pointer, selftest
michael
parents: 1815
diff changeset
305 #endif