Mercurial > libavcodec.hg
annotate opt.c @ 2877:b447caeb6978 libavcodec
convert some options in ffmpeg.c to AVOptions
author | michael |
---|---|
date | Mon, 12 Sep 2005 10:23:52 +0000 |
parents | 8026edf6a349 |
children | 4d91f38477ee |
rev | line source |
---|---|
2862 | 1 /* |
2 * AVOptions | |
3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 * | |
19 */ | |
20 | |
21 /** | |
22 * @file opt.c | |
23 * AVOptions | |
24 * @author Michael Niedermayer <michaelni@gmx.at> | |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 | |
29 static double av_parse_num(const char *name, char **tail){ | |
30 double d; | |
31 d= strtod(name, tail); | |
32 if(*tail>name && (**tail=='/' || **tail==':')) | |
33 d/=strtod((*tail)+1, tail); | |
34 return d; | |
35 } | |
36 | |
37 //FIXME order them and do a bin search | |
2877 | 38 static AVOption *find_opt(void *v, const char *name, const char *unit){ |
2862 | 39 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass |
40 AVOption *o= c->option; | |
41 | |
42 for(;o && o->name; o++){ | |
2877 | 43 if(!strcmp(o->name, name) && (!unit || !strcmp(o->unit, unit)) ) |
2862 | 44 return o; |
45 } | |
46 return NULL; | |
47 } | |
48 | |
2865
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
49 AVOption *av_next_option(void *obj, AVOption *last){ |
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
50 if(last && last[1].name) return ++last; |
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
51 else if(last) return NULL; |
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
52 else return (*(AVClass**)obj)->option; |
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
53 } |
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
54 |
2873 | 55 static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ |
2877 | 56 AVOption *o= find_opt(obj, name, NULL); |
2862 | 57 void *dst; |
58 if(!o || o->offset<=0) | |
2873 | 59 return NULL; |
2862 | 60 |
61 if(o->max*den < num*intnum || o->min*den > num*intnum) | |
2873 | 62 return NULL; |
2862 | 63 |
64 dst= ((uint8_t*)obj) + o->offset; | |
65 | |
66 switch(o->type){ | |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
67 case FF_OPT_TYPE_FLAGS: |
2873 | 68 case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break; |
69 case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break; | |
70 case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; | |
71 case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; | |
2862 | 72 case FF_OPT_TYPE_RATIONAL: |
2873 | 73 if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; |
74 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); | |
2862 | 75 default: |
2873 | 76 return NULL; |
2862 | 77 } |
2873 | 78 return o; |
2862 | 79 } |
80 | |
2877 | 81 static AVOption *set_all_opt(void *v, const char *unit, double d){ |
82 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass | |
83 AVOption *o= c->option; | |
84 AVOption *ret=NULL; | |
85 | |
86 for(;o && o->name; o++){ | |
87 if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){ | |
88 double tmp= d; | |
89 if(o->type == FF_OPT_TYPE_FLAGS) | |
90 tmp= av_get_int(v, o->name, NULL) | (int64_t)d; | |
91 | |
92 av_set_number(v, o->name, tmp, 1, 1); | |
93 ret= o; | |
94 } | |
95 } | |
96 return ret; | |
97 } | |
98 | |
2862 | 99 //FIXME use eval.c maybe? |
2873 | 100 AVOption *av_set_string(void *obj, const char *name, const char *val){ |
2877 | 101 AVOption *o= find_opt(obj, name, NULL); |
102 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ | |
103 return set_all_opt(obj, o->unit, o->default_val); | |
104 } | |
2862 | 105 if(!o || !val || o->offset<=0) |
2873 | 106 return NULL; |
2862 | 107 if(o->type != FF_OPT_TYPE_STRING){ |
108 for(;;){ | |
109 int i; | |
110 char buf[256], *tail; | |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
111 int cmd=0; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
112 double d; |
2862 | 113 |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
114 if(*val == '+' || *val == '-') |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
115 cmd= *(val++); |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
116 |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
117 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) |
2862 | 118 buf[i]= val[i]; |
119 buf[i]=0; | |
120 val+= i; | |
121 | |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
122 d= av_parse_num(buf, &tail); |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
123 if(tail <= buf){ |
2877 | 124 AVOption *o_named= find_opt(obj, buf, o->unit); |
125 if(o_named && o_named->type == FF_OPT_TYPE_CONST) | |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
126 d= o_named->default_val; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
127 else if(!strcmp(buf, "default")) d= o->default_val; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
128 else if(!strcmp(buf, "max" )) d= o->max; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
129 else if(!strcmp(buf, "min" )) d= o->min; |
2873 | 130 else return NULL; |
2862 | 131 } |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
132 if(o->type == FF_OPT_TYPE_FLAGS){ |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
133 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
134 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
135 }else if(cmd=='-') |
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
136 d= -d; |
2862 | 137 |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
138 av_set_number(obj, name, d, 1, 1); |
2862 | 139 if(!*val) |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
140 return o; |
2862 | 141 } |
2873 | 142 return NULL; |
2862 | 143 } |
144 | |
145 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); | |
2873 | 146 return o; |
2862 | 147 } |
148 | |
2873 | 149 AVOption *av_set_double(void *obj, const char *name, double n){ |
2862 | 150 return av_set_number(obj, name, n, 1, 1); |
151 } | |
152 | |
2873 | 153 AVOption *av_set_q(void *obj, const char *name, AVRational n){ |
2862 | 154 return av_set_number(obj, name, n.num, n.den, 1); |
155 } | |
156 | |
2873 | 157 AVOption *av_set_int(void *obj, const char *name, int64_t n){ |
2862 | 158 return av_set_number(obj, name, 1, 1, n); |
159 } | |
160 | |
2873 | 161 /** |
162 * | |
163 * @param buf a buffer which is used for returning non string values as strings, can be NULL | |
164 * @param buf_len allocated length in bytes of buf | |
165 */ | |
166 const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){ | |
2877 | 167 AVOption *o= find_opt(obj, name, NULL); |
2873 | 168 void *dst; |
2862 | 169 if(!o || o->offset<=0) |
170 return NULL; | |
2873 | 171 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) |
2862 | 172 return NULL; |
173 | |
2873 | 174 dst= ((uint8_t*)obj) + o->offset; |
175 if(o_out) *o_out= o; | |
176 | |
177 if(o->type == FF_OPT_TYPE_STRING) | |
178 return dst; | |
179 | |
180 switch(o->type){ | |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
181 case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; |
2873 | 182 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; |
183 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%Ld", *(int64_t*)dst);break; | |
184 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; | |
185 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; | |
186 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; | |
187 default: return NULL; | |
188 } | |
189 return buf; | |
2862 | 190 } |
191 | |
2873 | 192 static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){ |
2877 | 193 AVOption *o= find_opt(obj, name, NULL); |
2862 | 194 void *dst; |
195 if(!o || o->offset<=0) | |
2873 | 196 goto error; |
2862 | 197 |
198 dst= ((uint8_t*)obj) + o->offset; | |
199 | |
2873 | 200 if(o_out) *o_out= o; |
201 | |
2862 | 202 switch(o->type){ |
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
203 case FF_OPT_TYPE_FLAGS: |
2873 | 204 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; |
205 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; | |
206 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; | |
207 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; | |
208 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; | |
209 *den = ((AVRational*)dst)->den; | |
210 return 0; | |
2862 | 211 } |
2873 | 212 error: |
213 *den=*intnum=0; | |
214 return -1; | |
2862 | 215 } |
2873 | 216 |
217 double av_get_double(void *obj, const char *name, AVOption **o_out){ | |
218 int64_t intnum=1; | |
219 double num=1; | |
220 int den=1; | |
221 | |
222 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
223 return num*intnum/den; | |
224 } | |
225 | |
226 AVRational av_get_q(void *obj, const char *name, AVOption **o_out){ | |
227 int64_t intnum=1; | |
228 double num=1; | |
229 int den=1; | |
230 | |
231 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
232 if(num == 1.0 && (int)intnum == intnum) | |
233 return (AVRational){intnum, den}; | |
234 else | |
235 return av_d2q(num*intnum/den, 1<<24); | |
236 } | |
237 | |
238 int64_t av_get_int(void *obj, const char *name, AVOption **o_out){ | |
239 int64_t intnum=1; | |
240 double num=1; | |
241 int den=1; | |
242 | |
243 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
244 return num*intnum/den; | |
245 } | |
246 | |
2876 | 247 int av_opt_show(void *obj, void *av_log_obj){ |
2873 | 248 AVOption *opt=NULL; |
249 | |
250 if(!obj) | |
251 return -1; | |
2876 | 252 |
253 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); | |
2873 | 254 |
255 while((opt= av_next_option(obj, opt))){ | |
256 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) | |
257 continue; | |
258 | |
2876 | 259 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); |
260 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); | |
261 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); | |
262 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); | |
263 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); | |
264 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); | |
2873 | 265 |
2876 | 266 av_log(av_log_obj, AV_LOG_INFO, " %s\n", opt->help); |
2873 | 267 } |
268 return 0; | |
269 } |