]> git.sesse.net Git - ffmpeg/blob - libavcodec/opt.c
Pull out the ff_eval* from the mpegvideo header, as it doesn't belong there and
[ffmpeg] / libavcodec / opt.c
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 #include "opt.h"
29 #include "eval.h"
30
31 //FIXME order them and do a bin search
32 static AVOption *find_opt(void *v, const char *name, const char *unit){
33     AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
34     AVOption *o= c->option;
35
36     for(;o && o->name; o++){
37         if(!strcmp(o->name, name) && (!unit || !strcmp(o->unit, unit)) )
38             return o;
39     }
40     return NULL;
41 }
42
43 AVOption *av_next_option(void *obj, AVOption *last){
44     if(last && last[1].name) return ++last;
45     else if(last)            return NULL;
46     else                     return (*(AVClass**)obj)->option;
47 }
48
49 static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
50     AVOption *o= find_opt(obj, name, NULL);
51     void *dst;
52     if(!o || o->offset<=0)
53         return NULL;
54
55     if(o->max*den < num*intnum || o->min*den > num*intnum) {
56         av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name);
57         return NULL;
58     }
59
60     dst= ((uint8_t*)obj) + o->offset;
61
62     switch(o->type){
63     case FF_OPT_TYPE_FLAGS:
64     case FF_OPT_TYPE_INT:   *(int       *)dst= lrintf(num/den)*intnum; break;
65     case FF_OPT_TYPE_INT64: *(int64_t   *)dst= lrintf(num/den)*intnum; break;
66     case FF_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
67     case FF_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
68     case FF_OPT_TYPE_RATIONAL:
69         if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
70         else                *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
71     default:
72         return NULL;
73     }
74     return o;
75 }
76
77 static AVOption *set_all_opt(void *v, const char *unit, double d){
78     AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
79     AVOption *o= c->option;
80     AVOption *ret=NULL;
81
82     for(;o && o->name; o++){
83         if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){
84             double tmp= d;
85             if(o->type == FF_OPT_TYPE_FLAGS)
86                 tmp= av_get_int(v, o->name, NULL) | (int64_t)d;
87
88             av_set_number(v, o->name, tmp, 1, 1);
89             ret= o;
90         }
91     }
92     return ret;
93 }
94
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
109 AVOption *av_set_string(void *obj, const char *name, const char *val){
110     AVOption *o= find_opt(obj, name, NULL);
111     if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
112         return set_all_opt(obj, o->unit, o->default_val);
113     }
114     if(!o || !val || o->offset<=0)
115         return NULL;
116     if(o->type != FF_OPT_TYPE_STRING){
117         for(;;){
118             int i;
119             char buf[256];
120             int cmd=0;
121             double d;
122             char *error = NULL;
123
124             if(*val == '+' || *val == '-')
125                 cmd= *(val++);
126
127             for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
128                 buf[i]= val[i];
129             buf[i]=0;
130             val+= i;
131
132             d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error);
133             if(isnan(d)) {
134                 AVOption *o_named= find_opt(obj, buf, o->unit);
135                 if(o_named && o_named->type == FF_OPT_TYPE_CONST)
136                     d= o_named->default_val;
137                 else if(!strcmp(buf, "default")) d= o->default_val;
138                 else if(!strcmp(buf, "max"    )) d= o->max;
139                 else if(!strcmp(buf, "min"    )) d= o->min;
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                 }
145             }
146             if(o->type == FF_OPT_TYPE_FLAGS){
147                 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;
149             }else if(cmd=='-')
150                 d= -d;
151
152             av_set_number(obj, name, d, 1, 1);
153             if(!*val)
154                 return o;
155         }
156         return NULL;
157     }
158
159     memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val));
160     return o;
161 }
162
163 AVOption *av_set_double(void *obj, const char *name, double n){
164     return av_set_number(obj, name, n, 1, 1);
165 }
166
167 AVOption *av_set_q(void *obj, const char *name, AVRational n){
168     return av_set_number(obj, name, n.num, n.den, 1);
169 }
170
171 AVOption *av_set_int(void *obj, const char *name, int64_t n){
172     return av_set_number(obj, name, 1, 1, n);
173 }
174
175 /**
176  *
177  * @param buf a buffer which is used for returning non string values as strings, can be NULL
178  * @param buf_len allocated length in bytes of buf
179  */
180 const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){
181     AVOption *o= find_opt(obj, name, NULL);
182     void *dst;
183     if(!o || o->offset<=0)
184         return NULL;
185     if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
186         return NULL;
187
188     dst= ((uint8_t*)obj) + o->offset;
189     if(o_out) *o_out= o;
190
191     if(o->type == FF_OPT_TYPE_STRING)
192         return dst;
193
194     switch(o->type){
195     case FF_OPT_TYPE_FLAGS:     snprintf(buf, buf_len, "0x%08X",*(int    *)dst);break;
196     case FF_OPT_TYPE_INT:       snprintf(buf, buf_len, "%d" , *(int    *)dst);break;
197     case FF_OPT_TYPE_INT64:     snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
198     case FF_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
199     case FF_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
200     case FF_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
201     default: return NULL;
202     }
203     return buf;
204 }
205
206 static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){
207     AVOption *o= find_opt(obj, name, NULL);
208     void *dst;
209     if(!o || o->offset<=0)
210         goto error;
211
212     dst= ((uint8_t*)obj) + o->offset;
213
214     if(o_out) *o_out= o;
215
216     switch(o->type){
217     case FF_OPT_TYPE_FLAGS:
218     case FF_OPT_TYPE_INT:       *intnum= *(int    *)dst;return 0;
219     case FF_OPT_TYPE_INT64:     *intnum= *(int64_t*)dst;return 0;
220     case FF_OPT_TYPE_FLOAT:     *num=    *(float  *)dst;return 0;
221     case FF_OPT_TYPE_DOUBLE:    *num=    *(double *)dst;return 0;
222     case FF_OPT_TYPE_RATIONAL:  *intnum= ((AVRational*)dst)->num;
223                                 *den   = ((AVRational*)dst)->den;
224                                                         return 0;
225     }
226 error:
227     *den=*intnum=0;
228     return -1;
229 }
230
231 double av_get_double(void *obj, const char *name, AVOption **o_out){
232     int64_t intnum=1;
233     double num=1;
234     int den=1;
235
236     av_get_number(obj, name, o_out, &num, &den, &intnum);
237     return num*intnum/den;
238 }
239
240 AVRational av_get_q(void *obj, const char *name, AVOption **o_out){
241     int64_t intnum=1;
242     double num=1;
243     int den=1;
244
245     av_get_number(obj, name, o_out, &num, &den, &intnum);
246     if(num == 1.0 && (int)intnum == intnum)
247         return (AVRational){intnum, den};
248     else
249         return av_d2q(num*intnum/den, 1<<24);
250 }
251
252 int64_t av_get_int(void *obj, const char *name, AVOption **o_out){
253     int64_t intnum=1;
254     double num=1;
255     int den=1;
256
257     av_get_number(obj, name, o_out, &num, &den, &intnum);
258     return num*intnum/den;
259 }
260
261 int av_opt_show(void *obj, void *av_log_obj){
262     AVOption *opt=NULL;
263
264     if(!obj)
265         return -1;
266
267     av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
268
269     while((opt= av_next_option(obj, opt))){
270         if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
271             continue;
272
273         av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
274
275         switch( opt->type )
276         {
277             case FF_OPT_TYPE_FLAGS:
278                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" );
279                 break;
280             case FF_OPT_TYPE_INT:
281                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" );
282                 break;
283             case FF_OPT_TYPE_INT64:
284                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" );
285                 break;
286             case FF_OPT_TYPE_DOUBLE:
287                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" );
288                 break;
289             case FF_OPT_TYPE_FLOAT:
290                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" );
291                 break;
292             case FF_OPT_TYPE_STRING:
293                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" );
294                 break;
295             case FF_OPT_TYPE_RATIONAL:
296                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
297                 break;
298             case FF_OPT_TYPE_CONST:
299             default:
300                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
301                 break;
302         }
303         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
304         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
305         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
306         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
307         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
308
309         if(opt->help)
310             av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
311         av_log(av_log_obj, AV_LOG_INFO, "\n");
312     }
313     return 0;
314 }
315
316 /** Set the values of the AVCodecContext or AVFormatContext structure.
317  * They are set to the defaults specified in the according AVOption options
318  * array default_val field.
319  *
320  * @param s AVCodecContext or AVFormatContext for which the defaults will be set
321  */
322 void av_opt_set_defaults(void *s)
323 {
324     AVOption *opt = NULL;
325     while ((opt = av_next_option(s, opt)) != NULL) {
326         switch(opt->type) {
327             case FF_OPT_TYPE_CONST:
328                 /* Nothing to be done here */
329             break;
330             case FF_OPT_TYPE_FLAGS:
331             case FF_OPT_TYPE_INT: {
332                 int val;
333                 val = opt->default_val;
334                 av_set_int(s, opt->name, val);
335             }
336             break;
337             case FF_OPT_TYPE_FLOAT: {
338                 double val;
339                 val = opt->default_val;
340                 av_set_double(s, opt->name, val);
341             }
342             break;
343             case FF_OPT_TYPE_RATIONAL: {
344                 AVRational val;
345                 val = av_d2q(opt->default_val, INT_MAX);
346                 av_set_q(s, opt->name, val);
347             }
348             break;
349             case FF_OPT_TYPE_STRING:
350                 /* Cannot set default for string as default_val is of type * double */
351             break;
352             default:
353                 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
354         }
355     }
356 }
357