Mercurial > libavcodec.hg
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=='-') |