]> git.sesse.net Git - ffmpeg/blob - libavcodec/opt.c
Switch idct_mmx_xvid.c from GPL to LGPL as permitted by the
[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 static int opt_list(void *obj, void *av_log_obj, char *unit)
262 {
263     AVOption *opt=NULL;
264
265     while((opt= av_next_option(obj, opt))){
266         if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
267             continue;
268
269         /* Don't print CONST's on level one.
270          * Don't print anything but CONST's on level two.
271          * Only print items from the requested unit.
272          */
273         if (!unit && opt->type==FF_OPT_TYPE_CONST)
274             continue;
275         else if (unit && opt->type!=FF_OPT_TYPE_CONST)
276             continue;
277         else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit))
278             continue;
279         else if (unit && opt->type == FF_OPT_TYPE_CONST)
280             av_log(av_log_obj, AV_LOG_INFO, "   %-15s ", opt->name);
281         else
282             av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
283
284         switch( opt->type )
285         {
286             case FF_OPT_TYPE_FLAGS:
287                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" );
288                 break;
289             case FF_OPT_TYPE_INT:
290                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" );
291                 break;
292             case FF_OPT_TYPE_INT64:
293                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" );
294                 break;
295             case FF_OPT_TYPE_DOUBLE:
296                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" );
297                 break;
298             case FF_OPT_TYPE_FLOAT:
299                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" );
300                 break;
301             case FF_OPT_TYPE_STRING:
302                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" );
303                 break;
304             case FF_OPT_TYPE_RATIONAL:
305                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
306                 break;
307             case FF_OPT_TYPE_CONST:
308             default:
309                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
310                 break;
311         }
312         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
313         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
314         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
315         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
316         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
317
318         if(opt->help)
319             av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
320         av_log(av_log_obj, AV_LOG_INFO, "\n");
321         if (opt->unit && opt->type != FF_OPT_TYPE_CONST) {
322             opt_list(obj, av_log_obj, opt->unit);
323         }
324     }
325 }
326
327 int av_opt_show(void *obj, void *av_log_obj){
328     if(!obj)
329         return -1;
330
331     av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
332
333     opt_list(obj, av_log_obj, NULL);
334
335     return 0;
336 }
337
338 /** Set the values of the AVCodecContext or AVFormatContext structure.
339  * They are set to the defaults specified in the according AVOption options
340  * array default_val field.
341  *
342  * @param s AVCodecContext or AVFormatContext for which the defaults will be set
343  */
344 void av_opt_set_defaults(void *s)
345 {
346     AVOption *opt = NULL;
347     while ((opt = av_next_option(s, opt)) != NULL) {
348         switch(opt->type) {
349             case FF_OPT_TYPE_CONST:
350                 /* Nothing to be done here */
351             break;
352             case FF_OPT_TYPE_FLAGS:
353             case FF_OPT_TYPE_INT: {
354                 int val;
355                 val = opt->default_val;
356                 av_set_int(s, opt->name, val);
357             }
358             break;
359             case FF_OPT_TYPE_FLOAT: {
360                 double val;
361                 val = opt->default_val;
362                 av_set_double(s, opt->name, val);
363             }
364             break;
365             case FF_OPT_TYPE_RATIONAL: {
366                 AVRational val;
367                 val = av_d2q(opt->default_val, INT_MAX);
368                 av_set_q(s, opt->name, val);
369             }
370             break;
371             case FF_OPT_TYPE_STRING:
372                 /* Cannot set default for string as default_val is of type * double */
373             break;
374             default:
375                 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
376         }
377     }
378 }
379