Mercurial > libavcodec.hg
comparison opt.c @ 2862:f4aea2c316cc libavcodec
AVOption first try
author | michael |
---|---|
date | Tue, 06 Sep 2005 12:51:56 +0000 |
parents | |
children | 3b999ce45b37 |
comparison
equal
deleted
inserted
replaced
2861:3b920e274b26 | 2862:f4aea2c316cc |
---|---|
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 | |
38 static AVOption *find_opt(void *v, const char *name){ | |
39 AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass | |
40 AVOption *o= c->option; | |
41 | |
42 for(;o && o->name; o++){ | |
43 if(!strcmp(o->name, name)) | |
44 return o; | |
45 } | |
46 return NULL; | |
47 } | |
48 | |
49 static int av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ | |
50 AVOption *o= find_opt(obj, name); | |
51 void *dst; | |
52 if(!o || o->offset<=0) | |
53 return -1; | |
54 | |
55 if(o->max*den < num*intnum || o->min*den > num*intnum) | |
56 return -1; | |
57 | |
58 dst= ((uint8_t*)obj) + o->offset; | |
59 | |
60 switch(o->type){ | |
61 case FF_OPT_TYPE_INT: | |
62 *(int*)dst= lrintf(num/den)*intnum; | |
63 break; | |
64 case FF_OPT_TYPE_INT64: | |
65 *(int64_t*)dst= lrintf(num/den)*intnum; | |
66 break; | |
67 case FF_OPT_TYPE_FLOAT: | |
68 *(float*)dst= num*intnum/den; | |
69 break; | |
70 case FF_OPT_TYPE_DOUBLE: | |
71 *(double*)dst= num*intnum/den; | |
72 break; | |
73 case FF_OPT_TYPE_RATIONAL: | |
74 if((int)num == num) | |
75 *(AVRational*)dst= (AVRational){num*intnum, den}; | |
76 else | |
77 *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); | |
78 default: | |
79 return -1; | |
80 } | |
81 return 0; | |
82 } | |
83 | |
84 //FIXME use eval.c maybe? | |
85 int av_set_string(void *obj, const char *name, const char *val){ | |
86 AVOption *o= find_opt(obj, name); | |
87 if(!o || !val || o->offset<=0) | |
88 return -1; | |
89 if(o->type != FF_OPT_TYPE_STRING){ | |
90 double d=0, tmp_d; | |
91 for(;;){ | |
92 int i; | |
93 char buf[256], *tail; | |
94 | |
95 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+'; i++) | |
96 buf[i]= val[i]; | |
97 buf[i]=0; | |
98 val+= i; | |
99 | |
100 tmp_d= av_parse_num(buf, &tail); | |
101 if(tail > buf) | |
102 d+= tmp_d; | |
103 else{ | |
104 AVOption *o_named= find_opt(obj, buf); | |
105 if(o_named && o_named->type == FF_OPT_TYPE_CONST) | |
106 d+= o_named->default_val; | |
107 else if(!strcmp(buf, "default")) d+= o->default_val; | |
108 else if(!strcmp(buf, "max" )) d+= o->max; | |
109 else if(!strcmp(buf, "min" )) d+= o->min; | |
110 else return -1; | |
111 } | |
112 | |
113 if(*val == '+') val++; | |
114 if(!*val) | |
115 return av_set_number(obj, name, d, 1, 1); | |
116 } | |
117 return -1; | |
118 } | |
119 | |
120 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); | |
121 return 0; | |
122 } | |
123 | |
124 int av_set_double(void *obj, const char *name, double n){ | |
125 return av_set_number(obj, name, n, 1, 1); | |
126 } | |
127 | |
128 int av_set_q(void *obj, const char *name, AVRational n){ | |
129 return av_set_number(obj, name, n.num, n.den, 1); | |
130 } | |
131 | |
132 int av_set_int(void *obj, const char *name, int64_t n){ | |
133 return av_set_number(obj, name, 1, 1, n); | |
134 } | |
135 | |
136 const char *av_get_string(void *obj, const char *name){ | |
137 AVOption *o= find_opt(obj, name); | |
138 if(!o || o->offset<=0) | |
139 return NULL; | |
140 if(o->type != FF_OPT_TYPE_STRING) //FIXME convert to string? but what about free()? | |
141 return NULL; | |
142 | |
143 return (const char*)(((uint8_t*)obj) + o->offset); | |
144 } | |
145 | |
146 double av_get_double(void *obj, const char *name){ | |
147 AVOption *o= find_opt(obj, name); | |
148 void *dst; | |
149 if(!o || o->offset<=0) | |
150 return NAN; | |
151 | |
152 dst= ((uint8_t*)obj) + o->offset; | |
153 | |
154 switch(o->type){ | |
155 case FF_OPT_TYPE_INT: return *(int*)dst; | |
156 case FF_OPT_TYPE_INT64: return *(int64_t*)dst; //FIXME maybe write a av_get_int64() ? | |
157 case FF_OPT_TYPE_FLOAT: return *(float*)dst; | |
158 case FF_OPT_TYPE_DOUBLE: return *(double*)dst; | |
159 case FF_OPT_TYPE_RATIONAL: return av_q2d(*(AVRational*)dst); //FIXME maybe write a av_get_q() ? | |
160 default: return NAN; | |
161 } | |
162 } |