Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavcodec/opt.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
| author | nenolod |
|---|---|
| date | Mon, 12 Mar 2007 11:18:54 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 807:0f9c8d4d3ac4 | 808:e8776388b02a |
|---|---|
| 1 /* | |
| 2 * AVOptions | |
| 3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> | |
| 4 * | |
| 5 * This file is part of FFmpeg. | |
| 6 * | |
| 7 * FFmpeg is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Lesser General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2.1 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * FFmpeg is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Lesser General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Lesser General Public | |
| 18 * License along with FFmpeg; if not, write to the Free Software | |
| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 * | |
| 21 */ | |
| 22 | |
| 23 /** | |
| 24 * @file opt.c | |
| 25 * AVOptions | |
| 26 * @author Michael Niedermayer <michaelni@gmx.at> | |
| 27 */ | |
| 28 | |
| 29 #include "avcodec.h" | |
| 30 #include "opt.h" | |
| 31 #include "eval.h" | |
| 32 | |
| 33 //FIXME order them and do a bin search | |
| 34 static AVOption *find_opt(void *v, const char *name, const char *unit){ | |
| 35 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass | |
| 36 AVOption *o= c->option; | |
| 37 | |
| 38 for(;o && o->name; o++){ | |
| 39 if(!strcmp(o->name, name) && (!unit || !strcmp(o->unit, unit)) ) | |
| 40 return o; | |
| 41 } | |
| 42 return NULL; | |
| 43 } | |
| 44 | |
| 45 AVOption *av_next_option(void *obj, AVOption *last){ | |
| 46 if(last && last[1].name) return ++last; | |
| 47 else if(last) return NULL; | |
| 48 else return (*(AVClass**)obj)->option; | |
| 49 } | |
| 50 | |
| 51 static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ | |
| 52 AVOption *o= find_opt(obj, name, NULL); | |
| 53 void *dst; | |
| 54 if(!o || o->offset<=0) | |
| 55 return NULL; | |
| 56 | |
| 57 if(o->max*den < num*intnum || o->min*den > num*intnum) { | |
| 58 av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name); | |
| 59 return NULL; | |
| 60 } | |
| 61 | |
| 62 dst= ((uint8_t*)obj) + o->offset; | |
| 63 | |
| 64 switch(o->type){ | |
| 65 case FF_OPT_TYPE_FLAGS: | |
| 66 case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break; | |
| 67 case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break; | |
| 68 case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; | |
| 69 case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; | |
| 70 case FF_OPT_TYPE_RATIONAL: | |
| 71 if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; | |
| 72 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); | |
| 73 default: | |
| 74 return NULL; | |
| 75 } | |
| 76 return o; | |
| 77 } | |
| 78 | |
| 79 static AVOption *set_all_opt(void *v, const char *unit, double d){ | |
| 80 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass | |
| 81 AVOption *o= c->option; | |
| 82 AVOption *ret=NULL; | |
| 83 | |
| 84 for(;o && o->name; o++){ | |
| 85 if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){ | |
| 86 double tmp= d; | |
| 87 if(o->type == FF_OPT_TYPE_FLAGS) | |
| 88 tmp= av_get_int(v, o->name, NULL) | (int64_t)d; | |
| 89 | |
| 90 av_set_number(v, o->name, tmp, 1, 1); | |
| 91 ret= o; | |
| 92 } | |
| 93 } | |
| 94 return ret; | |
| 95 } | |
| 96 | |
| 97 static double const_values[]={ | |
| 98 M_PI, | |
| 99 M_E, | |
| 100 FF_QP2LAMBDA, | |
| 101 0 | |
| 102 }; | |
| 103 | |
| 104 static const char *const_names[]={ | |
| 105 "PI", | |
| 106 "E", | |
| 107 "QP2LAMBDA", | |
| 108 0 | |
| 109 }; | |
| 110 | |
| 111 AVOption *av_set_string(void *obj, const char *name, const char *val){ | |
| 112 AVOption *o= find_opt(obj, name, NULL); | |
| 113 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ | |
| 114 return set_all_opt(obj, o->unit, o->default_val); | |
| 115 } | |
| 116 if(!o || !val || o->offset<=0) | |
| 117 return NULL; | |
| 118 if(o->type != FF_OPT_TYPE_STRING){ | |
| 119 for(;;){ | |
| 120 int i; | |
| 121 char buf[256]; | |
| 122 int cmd=0; | |
| 123 double d; | |
| 124 char *error = NULL; | |
| 125 | |
| 126 if(*val == '+' || *val == '-') | |
| 127 cmd= *(val++); | |
| 128 | |
| 129 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) | |
| 130 buf[i]= val[i]; | |
| 131 buf[i]=0; | |
| 132 val+= i; | |
| 133 | |
| 134 d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error); | |
| 135 if(isnan(d)) { | |
| 136 AVOption *o_named= find_opt(obj, buf, o->unit); | |
| 137 if(o_named && o_named->type == FF_OPT_TYPE_CONST) | |
| 138 d= o_named->default_val; | |
| 139 else if(!strcmp(buf, "default")) d= o->default_val; | |
| 140 else if(!strcmp(buf, "max" )) d= o->max; | |
| 141 else if(!strcmp(buf, "min" )) d= o->min; | |
| 142 else { | |
| 143 if (!error) | |
| 144 av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); | |
| 145 return NULL; | |
| 146 } | |
| 147 } | |
| 148 if(o->type == FF_OPT_TYPE_FLAGS){ | |
| 149 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; | |
| 150 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; | |
| 151 }else if(cmd=='-') | |
| 152 d= -d; | |
| 153 | |
| 154 av_set_number(obj, name, d, 1, 1); | |
| 155 if(!*val) | |
| 156 return o; | |
| 157 } | |
| 158 return NULL; | |
| 159 } | |
| 160 | |
| 161 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); | |
| 162 return o; | |
| 163 } | |
| 164 | |
| 165 AVOption *av_set_double(void *obj, const char *name, double n){ | |
| 166 return av_set_number(obj, name, n, 1, 1); | |
| 167 } | |
| 168 | |
| 169 AVOption *av_set_q(void *obj, const char *name, AVRational n){ | |
| 170 return av_set_number(obj, name, n.num, n.den, 1); | |
| 171 } | |
| 172 | |
| 173 AVOption *av_set_int(void *obj, const char *name, int64_t n){ | |
| 174 return av_set_number(obj, name, 1, 1, n); | |
| 175 } | |
| 176 | |
| 177 /** | |
| 178 * | |
| 179 * @param buf a buffer which is used for returning non string values as strings, can be NULL | |
| 180 * @param buf_len allocated length in bytes of buf | |
| 181 */ | |
| 182 const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){ | |
| 183 AVOption *o= find_opt(obj, name, NULL); | |
| 184 void *dst; | |
| 185 if(!o || o->offset<=0) | |
| 186 return NULL; | |
| 187 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) | |
| 188 return NULL; | |
| 189 | |
| 190 dst= ((uint8_t*)obj) + o->offset; | |
| 191 if(o_out) *o_out= o; | |
| 192 | |
| 193 if(o->type == FF_OPT_TYPE_STRING) | |
| 194 return dst; | |
| 195 | |
| 196 switch(o->type){ | |
| 197 case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; | |
| 198 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; | |
| 199 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break; | |
| 200 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; | |
| 201 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; | |
| 202 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; | |
| 203 default: return NULL; | |
| 204 } | |
| 205 return buf; | |
| 206 } | |
| 207 | |
| 208 static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){ | |
| 209 AVOption *o= find_opt(obj, name, NULL); | |
| 210 void *dst; | |
| 211 if(!o || o->offset<=0) | |
| 212 goto error; | |
| 213 | |
| 214 dst= ((uint8_t*)obj) + o->offset; | |
| 215 | |
| 216 if(o_out) *o_out= o; | |
| 217 | |
| 218 switch(o->type){ | |
| 219 case FF_OPT_TYPE_FLAGS: | |
| 220 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; | |
| 221 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; | |
| 222 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; | |
| 223 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; | |
| 224 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; | |
| 225 *den = ((AVRational*)dst)->den; | |
| 226 return 0; | |
| 227 } | |
| 228 error: | |
| 229 *den=*intnum=0; | |
| 230 return -1; | |
| 231 } | |
| 232 | |
| 233 double av_get_double(void *obj, const char *name, AVOption **o_out){ | |
| 234 int64_t intnum=1; | |
| 235 double num=1; | |
| 236 int den=1; | |
| 237 | |
| 238 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 239 return num*intnum/den; | |
| 240 } | |
| 241 | |
| 242 AVRational av_get_q(void *obj, const char *name, AVOption **o_out){ | |
| 243 int64_t intnum=1; | |
| 244 double num=1; | |
| 245 int den=1; | |
| 246 | |
| 247 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 248 if(num == 1.0 && (int)intnum == intnum) | |
| 249 return (AVRational){intnum, den}; | |
| 250 else | |
| 251 return av_d2q(num*intnum/den, 1<<24); | |
| 252 } | |
| 253 | |
| 254 int64_t av_get_int(void *obj, const char *name, AVOption **o_out){ | |
| 255 int64_t intnum=1; | |
| 256 double num=1; | |
| 257 int den=1; | |
| 258 | |
| 259 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
| 260 return num*intnum/den; | |
| 261 } | |
| 262 | |
| 263 static void opt_list(void *obj, void *av_log_obj, char *unit) | |
| 264 { | |
| 265 AVOption *opt=NULL; | |
| 266 | |
| 267 while((opt= av_next_option(obj, opt))){ | |
| 268 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) | |
| 269 continue; | |
| 270 | |
| 271 /* Don't print CONST's on level one. | |
| 272 * Don't print anything but CONST's on level two. | |
| 273 * Only print items from the requested unit. | |
| 274 */ | |
| 275 if (!unit && opt->type==FF_OPT_TYPE_CONST) | |
| 276 continue; | |
| 277 else if (unit && opt->type!=FF_OPT_TYPE_CONST) | |
| 278 continue; | |
| 279 else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit)) | |
| 280 continue; | |
| 281 else if (unit && opt->type == FF_OPT_TYPE_CONST) | |
| 282 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); | |
| 283 else | |
| 284 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); | |
| 285 | |
| 286 switch( opt->type ) | |
| 287 { | |
| 288 case FF_OPT_TYPE_FLAGS: | |
| 289 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" ); | |
| 290 break; | |
| 291 case FF_OPT_TYPE_INT: | |
| 292 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" ); | |
| 293 break; | |
| 294 case FF_OPT_TYPE_INT64: | |
| 295 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" ); | |
| 296 break; | |
| 297 case FF_OPT_TYPE_DOUBLE: | |
| 298 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" ); | |
| 299 break; | |
| 300 case FF_OPT_TYPE_FLOAT: | |
| 301 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" ); | |
| 302 break; | |
| 303 case FF_OPT_TYPE_STRING: | |
| 304 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" ); | |
| 305 break; | |
| 306 case FF_OPT_TYPE_RATIONAL: | |
| 307 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" ); | |
| 308 break; | |
| 309 case FF_OPT_TYPE_CONST: | |
| 310 default: | |
| 311 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); | |
| 312 break; | |
| 313 } | |
| 314 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); | |
| 315 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); | |
| 316 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); | |
| 317 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); | |
| 318 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); | |
| 319 | |
| 320 if(opt->help) | |
| 321 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); | |
| 322 av_log(av_log_obj, AV_LOG_INFO, "\n"); | |
| 323 if (opt->unit && opt->type != FF_OPT_TYPE_CONST) { | |
| 324 opt_list(obj, av_log_obj, opt->unit); | |
| 325 } | |
| 326 } | |
| 327 } | |
| 328 | |
| 329 int av_opt_show(void *obj, void *av_log_obj){ | |
| 330 if(!obj) | |
| 331 return -1; | |
| 332 | |
| 333 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); | |
| 334 | |
| 335 opt_list(obj, av_log_obj, NULL); | |
| 336 | |
| 337 return 0; | |
| 338 } | |
| 339 | |
| 340 /** Set the values of the AVCodecContext or AVFormatContext structure. | |
| 341 * They are set to the defaults specified in the according AVOption options | |
| 342 * array default_val field. | |
| 343 * | |
| 344 * @param s AVCodecContext or AVFormatContext for which the defaults will be set | |
| 345 */ | |
| 346 void av_opt_set_defaults(void *s) | |
| 347 { | |
| 348 AVOption *opt = NULL; | |
| 349 while ((opt = av_next_option(s, opt)) != NULL) { | |
| 350 switch(opt->type) { | |
| 351 case FF_OPT_TYPE_CONST: | |
| 352 /* Nothing to be done here */ | |
| 353 break; | |
| 354 case FF_OPT_TYPE_FLAGS: | |
| 355 case FF_OPT_TYPE_INT: { | |
| 356 int val; | |
| 357 val = opt->default_val; | |
| 358 av_set_int(s, opt->name, val); | |
| 359 } | |
| 360 break; | |
| 361 case FF_OPT_TYPE_FLOAT: { | |
| 362 double val; | |
| 363 val = opt->default_val; | |
| 364 av_set_double(s, opt->name, val); | |
| 365 } | |
| 366 break; | |
| 367 case FF_OPT_TYPE_RATIONAL: { | |
| 368 AVRational val; | |
| 369 val = av_d2q(opt->default_val, INT_MAX); | |
| 370 av_set_q(s, opt->name, val); | |
| 371 } | |
| 372 break; | |
| 373 case FF_OPT_TYPE_STRING: | |
| 374 /* Cannot set default for string as default_val is of type * double */ | |
| 375 break; | |
| 376 default: | |
| 377 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); | |
| 378 } | |
| 379 } | |
| 380 } | |
| 381 |
