Mercurial > libavcodec.hg
annotate opt.c @ 3270:d6a5ed01acdf libavcodec
Vorbis specs requires blocksize_1 >= blocksize_0, error if it's false.
Predict buffer size from blocksize_1 and number of channels and make
sure this does not exceed AVCODEC_MAX_AUDIO_FRAME_SIZE
Patch by Uoti Urpala >>> uoti |.| urpala |@| pp1 |.| inet |.| fi <<<
| author | rtognimp |
|---|---|
| date | Sun, 23 Apr 2006 21:11:31 +0000 |
| parents | 25493c849d70 |
| children | 7e7d8a3fe080 |
| 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 | |
|
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 2862 | 18 * |
| 19 */ | |
| 2967 | 20 |
| 2862 | 21 /** |
| 22 * @file opt.c | |
| 23 * AVOptions | |
| 24 * @author Michael Niedermayer <michaelni@gmx.at> | |
| 25 */ | |
| 2967 | 26 |
| 2862 | 27 #include "avcodec.h" |
| 2880 | 28 #include "opt.h" |
| 2967 | 29 |
| 2862 | 30 static double av_parse_num(const char *name, char **tail){ |
| 31 double d; | |
| 32 d= strtod(name, tail); | |
| 33 if(*tail>name && (**tail=='/' || **tail==':')) | |
| 34 d/=strtod((*tail)+1, tail); | |
| 35 return d; | |
| 36 } | |
| 37 | |
| 38 //FIXME order them and do a bin search | |
| 2877 | 39 static AVOption *find_opt(void *v, const char *name, const char *unit){ |
| 2862 | 40 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass |
| 41 AVOption *o= c->option; | |
| 2967 | 42 |
| 2862 | 43 for(;o && o->name; o++){ |
| 2877 | 44 if(!strcmp(o->name, name) && (!unit || !strcmp(o->unit, unit)) ) |
| 2862 | 45 return o; |
| 46 } | |
| 47 return NULL; | |
| 48 } | |
| 49 | |
|
2865
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
50 AVOption *av_next_option(void *obj, AVOption *last){ |
|
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
51 if(last && last[1].name) return ++last; |
|
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
52 else if(last) return NULL; |
|
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
53 else return (*(AVClass**)obj)->option; |
|
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
54 } |
|
3b999ce45b37
AVOption enumeration support and some flags to classify AVOptions
michael
parents:
2862
diff
changeset
|
55 |
| 2873 | 56 static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ |
| 2877 | 57 AVOption *o= find_opt(obj, name, NULL); |
| 2862 | 58 void *dst; |
| 2967 | 59 if(!o || o->offset<=0) |
| 2873 | 60 return NULL; |
| 2967 | 61 |
| 2862 | 62 if(o->max*den < num*intnum || o->min*den > num*intnum) |
| 2873 | 63 return NULL; |
| 2967 | 64 |
| 2862 | 65 dst= ((uint8_t*)obj) + o->offset; |
| 66 | |
| 67 switch(o->type){ | |
| 2967 | 68 case FF_OPT_TYPE_FLAGS: |
| 2873 | 69 case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break; |
| 70 case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break; | |
| 71 case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; | |
| 72 case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; | |
| 2862 | 73 case FF_OPT_TYPE_RATIONAL: |
| 2873 | 74 if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; |
| 75 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); | |
| 2862 | 76 default: |
| 2873 | 77 return NULL; |
| 2862 | 78 } |
| 2873 | 79 return o; |
| 2862 | 80 } |
| 81 | |
| 2877 | 82 static AVOption *set_all_opt(void *v, const char *unit, double d){ |
| 83 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass | |
| 84 AVOption *o= c->option; | |
| 85 AVOption *ret=NULL; | |
| 2967 | 86 |
| 2877 | 87 for(;o && o->name; o++){ |
| 88 if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){ | |
| 89 double tmp= d; | |
| 90 if(o->type == FF_OPT_TYPE_FLAGS) | |
| 91 tmp= av_get_int(v, o->name, NULL) | (int64_t)d; | |
| 92 | |
| 93 av_set_number(v, o->name, tmp, 1, 1); | |
| 94 ret= o; | |
| 95 } | |
| 96 } | |
| 97 return ret; | |
| 98 } | |
| 99 | |
| 2862 | 100 //FIXME use eval.c maybe? |
| 2873 | 101 AVOption *av_set_string(void *obj, const char *name, const char *val){ |
| 2877 | 102 AVOption *o= find_opt(obj, name, NULL); |
| 103 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ | |
| 104 return set_all_opt(obj, o->unit, o->default_val); | |
| 105 } | |
| 2967 | 106 if(!o || !val || o->offset<=0) |
| 2873 | 107 return NULL; |
| 2862 | 108 if(o->type != FF_OPT_TYPE_STRING){ |
| 109 for(;;){ | |
| 110 int i; | |
| 111 char buf[256], *tail; | |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
112 int cmd=0; |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
113 double d; |
| 2862 | 114 |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
115 if(*val == '+' || *val == '-') |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
116 cmd= *(val++); |
| 2967 | 117 |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
118 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) |
| 2862 | 119 buf[i]= val[i]; |
| 120 buf[i]=0; | |
| 121 val+= i; | |
| 2967 | 122 |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
123 d= av_parse_num(buf, &tail); |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
124 if(tail <= buf){ |
| 2877 | 125 AVOption *o_named= find_opt(obj, buf, o->unit); |
| 2967 | 126 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
|
127 d= o_named->default_val; |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
128 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
|
129 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
|
130 else if(!strcmp(buf, "min" )) d= o->min; |
| 2873 | 131 else return NULL; |
| 2862 | 132 } |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
133 if(o->type == FF_OPT_TYPE_FLAGS){ |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
134 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=='-') 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
|
136 }else if(cmd=='-') |
|
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
137 d= -d; |
| 2862 | 138 |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
139 av_set_number(obj, name, d, 1, 1); |
| 2862 | 140 if(!*val) |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
141 return o; |
| 2862 | 142 } |
| 2873 | 143 return NULL; |
| 2862 | 144 } |
| 2967 | 145 |
| 2862 | 146 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); |
| 2873 | 147 return o; |
| 2862 | 148 } |
| 149 | |
| 2873 | 150 AVOption *av_set_double(void *obj, const char *name, double n){ |
| 2862 | 151 return av_set_number(obj, name, n, 1, 1); |
| 152 } | |
| 153 | |
| 2873 | 154 AVOption *av_set_q(void *obj, const char *name, AVRational n){ |
| 2862 | 155 return av_set_number(obj, name, n.num, n.den, 1); |
| 156 } | |
| 157 | |
| 2873 | 158 AVOption *av_set_int(void *obj, const char *name, int64_t n){ |
| 2862 | 159 return av_set_number(obj, name, 1, 1, n); |
| 160 } | |
| 161 | |
| 2873 | 162 /** |
| 2967 | 163 * |
| 2873 | 164 * @param buf a buffer which is used for returning non string values as strings, can be NULL |
| 165 * @param buf_len allocated length in bytes of buf | |
| 166 */ | |
| 167 const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){ | |
| 2877 | 168 AVOption *o= find_opt(obj, name, NULL); |
| 2873 | 169 void *dst; |
| 2862 | 170 if(!o || o->offset<=0) |
| 171 return NULL; | |
| 2873 | 172 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) |
| 2862 | 173 return NULL; |
| 174 | |
| 2873 | 175 dst= ((uint8_t*)obj) + o->offset; |
| 176 if(o_out) *o_out= o; | |
| 2967 | 177 |
| 2873 | 178 if(o->type == FF_OPT_TYPE_STRING) |
| 179 return dst; | |
| 2967 | 180 |
| 2873 | 181 switch(o->type){ |
|
2874
b6def74f5811
flags and named constants with type checking of course for AVOption
michael
parents:
2873
diff
changeset
|
182 case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; |
| 2873 | 183 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; |
| 2962 | 184 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break; |
| 2873 | 185 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; |
| 186 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; | |
| 187 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; | |
| 188 default: return NULL; | |
| 189 } | |
| 190 return buf; | |
| 2862 | 191 } |
| 192 | |
| 2873 | 193 static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){ |
| 2877 | 194 AVOption *o= find_opt(obj, name, NULL); |
| 2862 | 195 void *dst; |
| 196 if(!o || o->offset<=0) | |
| 2873 | 197 goto error; |
| 2862 | 198 |
| 199 dst= ((uint8_t*)obj) + o->offset; | |
| 200 | |
| 2873 | 201 if(o_out) *o_out= o; |
| 202 | |
| 2862 | 203 switch(o->type){ |
| 2967 | 204 case FF_OPT_TYPE_FLAGS: |
| 2873 | 205 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; |
| 206 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; | |
| 207 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; | |
| 208 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; | |
| 2967 | 209 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; |
| 2873 | 210 *den = ((AVRational*)dst)->den; |
| 211 return 0; | |
| 2862 | 212 } |
| 2873 | 213 error: |
| 214 *den=*intnum=0; | |
| 215 return -1; | |
| 2862 | 216 } |
| 2873 | 217 |
| 218 double av_get_double(void *obj, const char *name, AVOption **o_out){ | |
| 219 int64_t intnum=1; | |
| 220 double num=1; | |
| 221 int den=1; | |
| 222 | |
| 223 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 224 return num*intnum/den; | |
| 225 } | |
| 226 | |
| 227 AVRational av_get_q(void *obj, const char *name, AVOption **o_out){ | |
| 228 int64_t intnum=1; | |
| 229 double num=1; | |
| 230 int den=1; | |
| 231 | |
| 232 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 233 if(num == 1.0 && (int)intnum == intnum) | |
| 234 return (AVRational){intnum, den}; | |
| 235 else | |
| 236 return av_d2q(num*intnum/den, 1<<24); | |
| 237 } | |
| 238 | |
| 239 int64_t av_get_int(void *obj, const char *name, AVOption **o_out){ | |
| 240 int64_t intnum=1; | |
| 241 double num=1; | |
| 242 int den=1; | |
| 243 | |
| 244 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 245 return num*intnum/den; | |
| 246 } | |
| 247 | |
| 2876 | 248 int av_opt_show(void *obj, void *av_log_obj){ |
| 2873 | 249 AVOption *opt=NULL; |
| 2967 | 250 |
| 2873 | 251 if(!obj) |
| 252 return -1; | |
| 2876 | 253 |
| 254 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); | |
| 2873 | 255 |
| 256 while((opt= av_next_option(obj, opt))){ | |
| 257 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) | |
| 258 continue; | |
| 2967 | 259 |
| 2876 | 260 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); |
|
3141
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
261 |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
262 switch( opt->type ) |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
263 { |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
264 case FF_OPT_TYPE_FLAGS: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
265 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
266 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
267 case FF_OPT_TYPE_INT: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
268 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
269 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
270 case FF_OPT_TYPE_INT64: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
271 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
272 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
273 case FF_OPT_TYPE_DOUBLE: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
274 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
275 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
276 case FF_OPT_TYPE_FLOAT: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
277 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
278 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
279 case FF_OPT_TYPE_STRING: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
280 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
281 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
282 case FF_OPT_TYPE_RATIONAL: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
283 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
284 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
285 case FF_OPT_TYPE_CONST: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
286 default: |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
287 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
288 break; |
|
25493c849d70
Give a hint about what is the expected the data type of command line options.
gpoirier
parents:
3036
diff
changeset
|
289 } |
| 2876 | 290 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); |
| 291 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); | |
| 292 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); | |
| 293 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); | |
| 294 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); | |
| 2967 | 295 |
| 2888 | 296 if(opt->help) |
| 297 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); | |
| 298 av_log(av_log_obj, AV_LOG_INFO, "\n"); | |
| 2873 | 299 } |
| 300 return 0; | |
| 301 } |
