comparison opt.c @ 3778:67a63fa775a7 libavcodec

Make AVOption parsign code use ff_eval2()
author takis
date Wed, 27 Sep 2006 20:01:39 +0000
parents 6c407dc6ab4a
children 616a81d04758
comparison
equal deleted inserted replaced
3777:20545fbb6f7c 3778:67a63fa775a7
24 * @author Michael Niedermayer <michaelni@gmx.at> 24 * @author Michael Niedermayer <michaelni@gmx.at>
25 */ 25 */
26 26
27 #include "avcodec.h" 27 #include "avcodec.h"
28 #include "opt.h" 28 #include "opt.h"
29 29 #include "mpegvideo.h"
30 static int8_t si_prefixes['z' - 'E' + 1]={
31 ['y'-'E']= -24,
32 ['z'-'E']= -21,
33 ['a'-'E']= -18,
34 ['f'-'E']= -15,
35 ['p'-'E']= -12,
36 ['n'-'E']= - 9,
37 ['u'-'E']= - 6,
38 ['m'-'E']= - 3,
39 ['c'-'E']= - 2,
40 ['d'-'E']= - 1,
41 ['h'-'E']= 2,
42 ['k'-'E']= 3,
43 ['K'-'E']= 3,
44 ['M'-'E']= 6,
45 ['G'-'E']= 9,
46 ['T'-'E']= 12,
47 ['P'-'E']= 15,
48 ['E'-'E']= 18,
49 ['Z'-'E']= 21,
50 ['Y'-'E']= 24,
51 };
52
53 /** strtod() function extended with 'k', 'M', 'G', 'ki', 'Mi', 'Gi' and 'B'
54 * postfixes. This allows using f.e. kB, MiB, G and B as a postfix. This
55 * function assumes that the unit of numbers is bits not bytes.
56 */
57 double av_strtod(const char *name, char **tail) {
58 double d;
59 int p = 0;
60 char *next;
61 d = strtod(name, &next);
62 /* if parsing succeeded, check for and interpret postfixes */
63 if (next!=name) {
64
65 if(*next >= 'E' && *next <= 'z'){
66 int e= si_prefixes[*next - 'E'];
67 if(e){
68 if(next[1] == 'i'){
69 d*= pow( 2, e/0.3);
70 next+=2;
71 }else{
72 d*= pow(10, e);
73 next++;
74 }
75 }
76 }
77
78 if(*next=='B') {
79 d*=8;
80 *next++;
81 }
82 }
83 /* if requested, fill in tail with the position after the last parsed
84 character */
85 if (tail)
86 *tail = next;
87 return d;
88 }
89
90 static double av_parse_num(const char *name, char **tail){
91 double d;
92 d= av_strtod(name, tail);
93 if(*tail>name && (**tail=='/' || **tail==':'))
94 d/=av_strtod((*tail)+1, tail);
95 return d;
96 }
97 30
98 //FIXME order them and do a bin search 31 //FIXME order them and do a bin search
99 static AVOption *find_opt(void *v, const char *name, const char *unit){ 32 static AVOption *find_opt(void *v, const char *name, const char *unit){
100 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass 33 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
101 AVOption *o= c->option; 34 AVOption *o= c->option;
157 } 90 }
158 } 91 }
159 return ret; 92 return ret;
160 } 93 }
161 94
162 //FIXME use eval.c maybe? 95 static double const_values[]={
96 M_PI,
97 M_E,
98 FF_QP2LAMBDA,
99 0
100 };
101
102 static const char *const_names[]={
103 "PI",
104 "E",
105 "QP2LAMBDA",
106 0
107 };
108
163 AVOption *av_set_string(void *obj, const char *name, const char *val){ 109 AVOption *av_set_string(void *obj, const char *name, const char *val){
164 AVOption *o= find_opt(obj, name, NULL); 110 AVOption *o= find_opt(obj, name, NULL);
165 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ 111 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
166 return set_all_opt(obj, o->unit, o->default_val); 112 return set_all_opt(obj, o->unit, o->default_val);
167 } 113 }
168 if(!o || !val || o->offset<=0) 114 if(!o || !val || o->offset<=0)
169 return NULL; 115 return NULL;
170 if(o->type != FF_OPT_TYPE_STRING){ 116 if(o->type != FF_OPT_TYPE_STRING){
171 for(;;){ 117 for(;;){
172 int i; 118 int i;
173 char buf[256], *tail; 119 char buf[256];
174 int cmd=0; 120 int cmd=0;
175 double d; 121 double d;
122 char *error = NULL;
176 123
177 if(*val == '+' || *val == '-') 124 if(*val == '+' || *val == '-')
178 cmd= *(val++); 125 cmd= *(val++);
179 126
180 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) 127 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
181 buf[i]= val[i]; 128 buf[i]= val[i];
182 buf[i]=0; 129 buf[i]=0;
183 val+= i; 130 val+= i;
184 131
185 d= av_parse_num(buf, &tail); 132 d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error);
186 if(tail <= buf){ 133 if(isnan(d)) {
187 AVOption *o_named= find_opt(obj, buf, o->unit); 134 AVOption *o_named= find_opt(obj, buf, o->unit);
188 if(o_named && o_named->type == FF_OPT_TYPE_CONST) 135 if(o_named && o_named->type == FF_OPT_TYPE_CONST)
189 d= o_named->default_val; 136 d= o_named->default_val;
190 else if(!strcmp(buf, "default")) d= o->default_val; 137 else if(!strcmp(buf, "default")) d= o->default_val;
191 else if(!strcmp(buf, "max" )) d= o->max; 138 else if(!strcmp(buf, "max" )) d= o->max;
192 else if(!strcmp(buf, "min" )) d= o->min; 139 else if(!strcmp(buf, "min" )) d= o->min;
193 else return NULL; 140 else {
141 if (!error)
142 av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
143 return NULL;
144 }
194 } 145 }
195 if(o->type == FF_OPT_TYPE_FLAGS){ 146 if(o->type == FF_OPT_TYPE_FLAGS){
196 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; 147 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
197 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; 148 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
198 }else if(cmd=='-') 149 }else if(cmd=='-')