imc: make IMDCT support stereo output
[ffmpeg.git] / libavutil / opt.c
1 /*
2  * AVOptions
3  * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * AVOptions
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27
28 #include "avutil.h"
29 #include "avstring.h"
30 #include "opt.h"
31 #include "eval.h"
32 #include "dict.h"
33 #include "log.h"
34
35 #if FF_API_FIND_OPT
36 //FIXME order them and do a bin search
37 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
38 {
39     AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
40     const AVOption *o= c->option;
41
42     for (; o && o->name; o++) {
43         if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
44             return o;
45     }
46     return NULL;
47 }
48 #endif
49
50 #if FF_API_OLD_AVOPTIONS
51 const AVOption *av_next_option(void *obj, const AVOption *last)
52 {
53     return av_opt_next(obj, last);
54 }
55 #endif
56
57 const AVOption *av_opt_next(void *obj, const AVOption *last)
58 {
59     AVClass *class = *(AVClass**)obj;
60     if (!last && class->option[0].name) return class->option;
61     if (last && last[1].name)           return ++last;
62     return NULL;
63 }
64
65 static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
66 {
67     switch (o->type) {
68     case AV_OPT_TYPE_FLAGS:     *intnum = *(unsigned int*)dst;return 0;
69     case AV_OPT_TYPE_INT:       *intnum = *(int         *)dst;return 0;
70     case AV_OPT_TYPE_INT64:     *intnum = *(int64_t     *)dst;return 0;
71     case AV_OPT_TYPE_FLOAT:     *num    = *(float       *)dst;return 0;
72     case AV_OPT_TYPE_DOUBLE:    *num    = *(double      *)dst;return 0;
73     case AV_OPT_TYPE_RATIONAL:  *intnum = ((AVRational*)dst)->num;
74                                 *den    = ((AVRational*)dst)->den;
75                                                         return 0;
76     }
77     return AVERROR(EINVAL);
78 }
79
80 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
81 {
82     if (o->max*den < num*intnum || o->min*den > num*intnum) {
83         av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n",
84                num*intnum/den, o->name);
85         return AVERROR(ERANGE);
86     }
87
88     switch (o->type) {
89     case AV_OPT_TYPE_FLAGS:
90     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
91     case AV_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;
92     case AV_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
93     case AV_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
94     case AV_OPT_TYPE_RATIONAL:
95         if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
96         else                 *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
97         break;
98     default:
99         return AVERROR(EINVAL);
100     }
101     return 0;
102 }
103
104 static const double const_values[] = {
105     M_PI,
106     M_E,
107     FF_QP2LAMBDA,
108     0
109 };
110
111 static const char * const const_names[] = {
112     "PI",
113     "E",
114     "QP2LAMBDA",
115     0
116 };
117
118 static int hexchar2int(char c) {
119     if (c >= '0' && c <= '9') return c - '0';
120     if (c >= 'a' && c <= 'f') return c - 'a' + 10;
121     if (c >= 'A' && c <= 'F') return c - 'A' + 10;
122     return -1;
123 }
124
125 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
126 {
127     int *lendst = (int *)(dst + 1);
128     uint8_t *bin, *ptr;
129     int len = strlen(val);
130
131     av_freep(dst);
132     *lendst = 0;
133
134     if (len & 1)
135         return AVERROR(EINVAL);
136     len /= 2;
137
138     ptr = bin = av_malloc(len);
139     while (*val) {
140         int a = hexchar2int(*val++);
141         int b = hexchar2int(*val++);
142         if (a < 0 || b < 0) {
143             av_free(bin);
144             return AVERROR(EINVAL);
145         }
146         *ptr++ = (a << 4) | b;
147     }
148     *dst = bin;
149     *lendst = len;
150
151     return 0;
152 }
153
154 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
155 {
156     av_freep(dst);
157     *dst = av_strdup(val);
158     return 0;
159 }
160
161 static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
162 {
163     int ret = 0, notfirst = 0;
164     for (;;) {
165         int i, den = 1;
166         char buf[256];
167         int cmd = 0;
168         double d, num = 1;
169         int64_t intnum = 1;
170
171         if (*val == '+' || *val == '-')
172             cmd = *(val++);
173
174         for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
175             buf[i] = val[i];
176         buf[i] = 0;
177
178         {
179             const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
180             if (o_named && o_named->type == AV_OPT_TYPE_CONST)
181                 d = o_named->default_val.dbl;
182             else if (!strcmp(buf, "default")) d = o->default_val.dbl;
183             else if (!strcmp(buf, "max"    )) d = o->max;
184             else if (!strcmp(buf, "min"    )) d = o->min;
185             else if (!strcmp(buf, "none"   )) d = 0;
186             else if (!strcmp(buf, "all"    )) d = ~0;
187             else {
188                 int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
189                 if (res < 0) {
190                     av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
191                     return res;
192                 }
193             }
194         }
195         if (o->type == AV_OPT_TYPE_FLAGS) {
196             read_number(o, dst, NULL, NULL, &intnum);
197             if      (cmd == '+') d = intnum | (int64_t)d;
198             else if (cmd == '-') d = intnum &~(int64_t)d;
199         } else {
200             read_number(o, dst, &num, &den, &intnum);
201             if      (cmd == '+') d = notfirst*num*intnum/den + d;
202             else if (cmd == '-') d = notfirst*num*intnum/den - d;
203         }
204
205         if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
206             return ret;
207         val += i;
208         if (!*val)
209             return 0;
210         notfirst = 1;
211     }
212
213     return 0;
214 }
215
216 #if FF_API_OLD_AVOPTIONS
217 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
218 {
219     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
220     if (o_out)
221         *o_out = o;
222     return av_opt_set(obj, name, val, 0);
223 }
224 #endif
225
226 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
227 {
228     void *dst, *target_obj;
229     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
230     if (!o || !target_obj)
231         return AVERROR_OPTION_NOT_FOUND;
232     if (!val)
233         return AVERROR(EINVAL);
234
235     dst = ((uint8_t*)target_obj) + o->offset;
236     switch (o->type) {
237     case AV_OPT_TYPE_STRING:   return set_string(obj, o, val, dst);
238     case AV_OPT_TYPE_BINARY:   return set_string_binary(obj, o, val, dst);
239     case AV_OPT_TYPE_FLAGS:
240     case AV_OPT_TYPE_INT:
241     case AV_OPT_TYPE_INT64:
242     case AV_OPT_TYPE_FLOAT:
243     case AV_OPT_TYPE_DOUBLE:
244     case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
245     }
246
247     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
248     return AVERROR(EINVAL);
249 }
250
251 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
252     int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
253     {\
254         if (!o || o->type != opttype)\
255             return AVERROR(EINVAL);\
256         return set_string_number(obj, o, val, name ## _out);\
257     }
258
259 OPT_EVAL_NUMBER(flags,  AV_OPT_TYPE_FLAGS,    int)
260 OPT_EVAL_NUMBER(int,    AV_OPT_TYPE_INT,      int)
261 OPT_EVAL_NUMBER(int64,  AV_OPT_TYPE_INT64,    int64_t)
262 OPT_EVAL_NUMBER(float,  AV_OPT_TYPE_FLOAT,    float)
263 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE,   double)
264 OPT_EVAL_NUMBER(q,      AV_OPT_TYPE_RATIONAL, AVRational)
265
266 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
267                                   int search_flags)
268 {
269     void *dst, *target_obj;
270     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
271
272     if (!o || !target_obj)
273         return AVERROR_OPTION_NOT_FOUND;
274
275     dst = ((uint8_t*)target_obj) + o->offset;
276     return write_number(obj, o, dst, num, den, intnum);
277 }
278
279 #if FF_API_OLD_AVOPTIONS
280 const AVOption *av_set_double(void *obj, const char *name, double n)
281 {
282     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
283     if (set_number(obj, name, n, 1, 1, 0) < 0)
284         return NULL;
285     return o;
286 }
287
288 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
289 {
290     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
291     if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
292         return NULL;
293     return o;
294 }
295
296 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
297 {
298     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
299     if (set_number(obj, name, 1, 1, n, 0) < 0)
300         return NULL;
301     return o;
302 }
303 #endif
304
305 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
306 {
307     return set_number(obj, name, 1, 1, val, search_flags);
308 }
309
310 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
311 {
312     return set_number(obj, name, val, 1, 1, search_flags);
313 }
314
315 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
316 {
317     return set_number(obj, name, val.num, val.den, 1, search_flags);
318 }
319
320 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
321 {
322     void *target_obj;
323     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
324     uint8_t *ptr;
325     uint8_t **dst;
326     int *lendst;
327
328     if (!o || !target_obj)
329         return AVERROR_OPTION_NOT_FOUND;
330
331     if (o->type != AV_OPT_TYPE_BINARY)
332         return AVERROR(EINVAL);
333
334     ptr = av_malloc(len);
335     if (!ptr)
336         return AVERROR(ENOMEM);
337
338     dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
339     lendst = (int *)(dst + 1);
340
341     av_free(*dst);
342     *dst = ptr;
343     *lendst = len;
344     memcpy(ptr, val, len);
345
346     return 0;
347 }
348
349 #if FF_API_OLD_AVOPTIONS
350 /**
351  *
352  * @param buf a buffer which is used for returning non string values as strings, can be NULL
353  * @param buf_len allocated length in bytes of buf
354  */
355 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
356 {
357     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
358     void *dst;
359     uint8_t *bin;
360     int len, i;
361     if (!o)
362         return NULL;
363     if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
364         return NULL;
365
366     dst= ((uint8_t*)obj) + o->offset;
367     if (o_out) *o_out= o;
368
369     switch (o->type) {
370     case AV_OPT_TYPE_FLAGS:     snprintf(buf, buf_len, "0x%08X",*(int    *)dst);break;
371     case AV_OPT_TYPE_INT:       snprintf(buf, buf_len, "%d" , *(int    *)dst);break;
372     case AV_OPT_TYPE_INT64:     snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
373     case AV_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
374     case AV_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
375     case AV_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
376     case AV_OPT_TYPE_STRING:    return *(void**)dst;
377     case AV_OPT_TYPE_BINARY:
378         len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
379         if (len >= (buf_len + 1)/2) return NULL;
380         bin = *(uint8_t**)dst;
381         for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
382         break;
383     default: return NULL;
384     }
385     return buf;
386 }
387 #endif
388
389 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
390 {
391     void *dst, *target_obj;
392     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
393     uint8_t *bin, buf[128];
394     int len, i, ret;
395
396     if (!o || !target_obj)
397         return AVERROR_OPTION_NOT_FOUND;
398
399     dst = (uint8_t*)target_obj + o->offset;
400
401     buf[0] = 0;
402     switch (o->type) {
403     case AV_OPT_TYPE_FLAGS:     ret = snprintf(buf, sizeof(buf), "0x%08X",  *(int    *)dst);break;
404     case AV_OPT_TYPE_INT:       ret = snprintf(buf, sizeof(buf), "%d" ,     *(int    *)dst);break;
405     case AV_OPT_TYPE_INT64:     ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
406     case AV_OPT_TYPE_FLOAT:     ret = snprintf(buf, sizeof(buf), "%f" ,     *(float  *)dst);break;
407     case AV_OPT_TYPE_DOUBLE:    ret = snprintf(buf, sizeof(buf), "%f" ,     *(double *)dst);break;
408     case AV_OPT_TYPE_RATIONAL:  ret = snprintf(buf, sizeof(buf), "%d/%d",   ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
409     case AV_OPT_TYPE_STRING:
410         if (*(uint8_t**)dst)
411             *out_val = av_strdup(*(uint8_t**)dst);
412         else
413             *out_val = av_strdup("");
414         return 0;
415     case AV_OPT_TYPE_BINARY:
416         len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
417         if ((uint64_t)len*2 + 1 > INT_MAX)
418             return AVERROR(EINVAL);
419         if (!(*out_val = av_malloc(len*2 + 1)))
420             return AVERROR(ENOMEM);
421         bin = *(uint8_t**)dst;
422         for (i = 0; i < len; i++)
423             snprintf(*out_val + i*2, 3, "%02X", bin[i]);
424         return 0;
425     default:
426         return AVERROR(EINVAL);
427     }
428
429     if (ret >= sizeof(buf))
430         return AVERROR(EINVAL);
431     *out_val = av_strdup(buf);
432     return 0;
433 }
434
435 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
436                       int search_flags)
437 {
438     void *dst, *target_obj;
439     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
440     if (!o || !target_obj)
441         goto error;
442
443     dst = ((uint8_t*)target_obj) + o->offset;
444
445     if (o_out) *o_out= o;
446
447     return read_number(o, dst, num, den, intnum);
448
449 error:
450     *den=*intnum=0;
451     return -1;
452 }
453
454 #if FF_API_OLD_AVOPTIONS
455 double av_get_double(void *obj, const char *name, const AVOption **o_out)
456 {
457     int64_t intnum=1;
458     double num=1;
459     int den=1;
460
461     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
462         return NAN;
463     return num*intnum/den;
464 }
465
466 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
467 {
468     int64_t intnum=1;
469     double num=1;
470     int den=1;
471
472     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
473         return (AVRational){0, 0};
474     if (num == 1.0 && (int)intnum == intnum)
475         return (AVRational){intnum, den};
476     else
477         return av_d2q(num*intnum/den, 1<<24);
478 }
479
480 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
481 {
482     int64_t intnum=1;
483     double num=1;
484     int den=1;
485
486     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
487         return -1;
488     return num*intnum/den;
489 }
490 #endif
491
492 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
493 {
494     int64_t intnum = 1;
495     double     num = 1;
496     int   ret, den = 1;
497
498     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
499         return ret;
500     *out_val = num*intnum/den;
501     return 0;
502 }
503
504 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
505 {
506     int64_t intnum = 1;
507     double     num = 1;
508     int   ret, den = 1;
509
510     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
511         return ret;
512     *out_val = num*intnum/den;
513     return 0;
514 }
515
516 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
517 {
518     int64_t intnum = 1;
519     double     num = 1;
520     int   ret, den = 1;
521
522     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
523         return ret;
524
525     if (num == 1.0 && (int)intnum == intnum)
526         *out_val = (AVRational){intnum, den};
527     else
528         *out_val = av_d2q(num*intnum/den, 1<<24);
529     return 0;
530 }
531
532 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
533 {
534     const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
535     const AVOption *flag  = av_opt_find(obj, flag_name,
536                                         field ? field->unit : NULL, 0, 0);
537     int64_t res;
538
539     if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
540         av_opt_get_int(obj, field_name, 0, &res) < 0)
541         return 0;
542     return res & (int) flag->default_val.dbl;
543 }
544
545 static void opt_list(void *obj, void *av_log_obj, const char *unit,
546                      int req_flags, int rej_flags)
547 {
548     const AVOption *opt=NULL;
549
550     while ((opt = av_opt_next(obj, opt))) {
551         if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
552             continue;
553
554         /* Don't print CONST's on level one.
555          * Don't print anything but CONST's on level two.
556          * Only print items from the requested unit.
557          */
558         if (!unit && opt->type==AV_OPT_TYPE_CONST)
559             continue;
560         else if (unit && opt->type!=AV_OPT_TYPE_CONST)
561             continue;
562         else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
563             continue;
564         else if (unit && opt->type == AV_OPT_TYPE_CONST)
565             av_log(av_log_obj, AV_LOG_INFO, "   %-15s ", opt->name);
566         else
567             av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
568
569         switch (opt->type) {
570             case AV_OPT_TYPE_FLAGS:
571                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>");
572                 break;
573             case AV_OPT_TYPE_INT:
574                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int>");
575                 break;
576             case AV_OPT_TYPE_INT64:
577                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>");
578                 break;
579             case AV_OPT_TYPE_DOUBLE:
580                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<double>");
581                 break;
582             case AV_OPT_TYPE_FLOAT:
583                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<float>");
584                 break;
585             case AV_OPT_TYPE_STRING:
586                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<string>");
587                 break;
588             case AV_OPT_TYPE_RATIONAL:
589                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>");
590                 break;
591             case AV_OPT_TYPE_BINARY:
592                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>");
593                 break;
594             case AV_OPT_TYPE_CONST:
595             default:
596                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "");
597                 break;
598         }
599         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
600         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
601         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
602         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
603         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
604
605         if (opt->help)
606             av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
607         av_log(av_log_obj, AV_LOG_INFO, "\n");
608         if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
609             opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
610         }
611     }
612 }
613
614 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
615 {
616     if (!obj)
617         return -1;
618
619     av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
620
621     opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
622
623     return 0;
624 }
625
626 void av_opt_set_defaults(void *s)
627 {
628 #if FF_API_OLD_AVOPTIONS
629     av_opt_set_defaults2(s, 0, 0);
630 }
631
632 void av_opt_set_defaults2(void *s, int mask, int flags)
633 {
634 #endif
635     const AVOption *opt = NULL;
636     while ((opt = av_opt_next(s, opt)) != NULL) {
637 #if FF_API_OLD_AVOPTIONS
638         if ((opt->flags & mask) != flags)
639             continue;
640 #endif
641         switch (opt->type) {
642             case AV_OPT_TYPE_CONST:
643                 /* Nothing to be done here */
644             break;
645             case AV_OPT_TYPE_FLAGS:
646             case AV_OPT_TYPE_INT: {
647                 int val;
648                 val = opt->default_val.dbl;
649                 av_opt_set_int(s, opt->name, val, 0);
650             }
651             break;
652             case AV_OPT_TYPE_INT64:
653                 if ((double)(opt->default_val.dbl+0.6) == opt->default_val.dbl)
654                     av_log(s, AV_LOG_DEBUG, "loss of precision in default of %s\n", opt->name);
655                 av_opt_set_int(s, opt->name, opt->default_val.dbl, 0);
656             break;
657             case AV_OPT_TYPE_DOUBLE:
658             case AV_OPT_TYPE_FLOAT: {
659                 double val;
660                 val = opt->default_val.dbl;
661                 av_opt_set_double(s, opt->name, val, 0);
662             }
663             break;
664             case AV_OPT_TYPE_RATIONAL: {
665                 AVRational val;
666                 val = av_d2q(opt->default_val.dbl, INT_MAX);
667                 av_opt_set_q(s, opt->name, val, 0);
668             }
669             break;
670             case AV_OPT_TYPE_STRING:
671                 av_opt_set(s, opt->name, opt->default_val.str, 0);
672                 break;
673             case AV_OPT_TYPE_BINARY:
674                 /* Cannot set default for binary */
675             break;
676             default:
677                 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
678         }
679     }
680 }
681
682 /**
683  * Store the value in the field in ctx that is named like key.
684  * ctx must be an AVClass context, storing is done using AVOptions.
685  *
686  * @param buf the string to parse, buf will be updated to point at the
687  * separator just after the parsed key/value pair
688  * @param key_val_sep a 0-terminated list of characters used to
689  * separate key from value
690  * @param pairs_sep a 0-terminated list of characters used to separate
691  * two pairs from each other
692  * @return 0 if the key/value pair has been successfully parsed and
693  * set, or a negative value corresponding to an AVERROR code in case
694  * of error:
695  * AVERROR(EINVAL) if the key/value pair cannot be parsed,
696  * the error code issued by av_opt_set() if the key/value pair
697  * cannot be set
698  */
699 static int parse_key_value_pair(void *ctx, const char **buf,
700                                 const char *key_val_sep, const char *pairs_sep)
701 {
702     char *key = av_get_token(buf, key_val_sep);
703     char *val;
704     int ret;
705
706     if (*key && strspn(*buf, key_val_sep)) {
707         (*buf)++;
708         val = av_get_token(buf, pairs_sep);
709     } else {
710         av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
711         av_free(key);
712         return AVERROR(EINVAL);
713     }
714
715     av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
716
717     ret = av_opt_set(ctx, key, val, 0);
718     if (ret == AVERROR_OPTION_NOT_FOUND)
719         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
720
721     av_free(key);
722     av_free(val);
723     return ret;
724 }
725
726 int av_set_options_string(void *ctx, const char *opts,
727                           const char *key_val_sep, const char *pairs_sep)
728 {
729     int ret, count = 0;
730
731     if (!opts)
732         return 0;
733
734     while (*opts) {
735         if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
736             return ret;
737         count++;
738
739         if (*opts)
740             opts++;
741     }
742
743     return count;
744 }
745
746 void av_opt_free(void *obj)
747 {
748     const AVOption *o = NULL;
749     while ((o = av_opt_next(obj, o)))
750         if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
751             av_freep((uint8_t *)obj + o->offset);
752 }
753
754 int av_opt_set_dict(void *obj, AVDictionary **options)
755 {
756     AVDictionaryEntry *t = NULL;
757     AVDictionary    *tmp = NULL;
758     int ret = 0;
759
760     while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
761         ret = av_opt_set(obj, t->key, t->value, 0);
762         if (ret == AVERROR_OPTION_NOT_FOUND)
763             av_dict_set(&tmp, t->key, t->value, 0);
764         else if (ret < 0) {
765             av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
766             break;
767         }
768         ret = 0;
769     }
770     av_dict_free(options);
771     *options = tmp;
772     return ret;
773 }
774
775 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
776                             int opt_flags, int search_flags)
777 {
778     return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
779 }
780
781 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
782                              int opt_flags, int search_flags, void **target_obj)
783 {
784     const AVClass  *c = *(AVClass**)obj;
785     const AVOption *o = NULL;
786
787     if (search_flags & AV_OPT_SEARCH_CHILDREN) {
788         if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
789             const AVClass *child = NULL;
790             while (child = av_opt_child_class_next(c, child))
791                 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
792                     return o;
793         } else {
794             void *child = NULL;
795             while (child = av_opt_child_next(obj, child))
796                 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
797                     return o;
798         }
799     }
800
801     while (o = av_opt_next(obj, o)) {
802         if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
803             ((!unit && o->type != AV_OPT_TYPE_CONST) ||
804              (unit  && o->unit && !strcmp(o->unit, unit)))) {
805             if (target_obj) {
806                 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
807                     *target_obj = obj;
808                 else
809                     *target_obj = NULL;
810             }
811             return o;
812         }
813     }
814     return NULL;
815 }
816
817 void *av_opt_child_next(void *obj, void *prev)
818 {
819     const AVClass *c = *(AVClass**)obj;
820     if (c->child_next)
821         return c->child_next(obj, prev);
822     return NULL;
823 }
824
825 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
826 {
827     if (parent->child_class_next)
828         return parent->child_class_next(prev);
829     return NULL;
830 }
831
832 #ifdef TEST
833
834 #undef printf
835
836 typedef struct TestContext
837 {
838     const AVClass *class;
839     int num;
840     int toggle;
841     char *string;
842     int flags;
843     AVRational rational;
844 } TestContext;
845
846 #define OFFSET(x) offsetof(TestContext, x)
847
848 #define TEST_FLAG_COOL 01
849 #define TEST_FLAG_LAME 02
850 #define TEST_FLAG_MU   04
851
852 static const AVOption test_options[]= {
853 {"num",      "set num",        OFFSET(num),      AV_OPT_TYPE_INT,      {0},              0,        100                 },
854 {"toggle",   "set toggle",     OFFSET(toggle),   AV_OPT_TYPE_INT,      {0},              0,        1                   },
855 {"rational", "set rational",   OFFSET(rational), AV_OPT_TYPE_RATIONAL, {0},              0,        10                  },
856 {"string",   "set string",     OFFSET(string),   AV_OPT_TYPE_STRING,   {0},              CHAR_MIN, CHAR_MAX            },
857 {"flags",    "set flags",      OFFSET(flags),    AV_OPT_TYPE_FLAGS,    {0},              0,        INT_MAX, 0, "flags" },
858 {"cool",     "set cool flag ", 0,                AV_OPT_TYPE_CONST,    {TEST_FLAG_COOL}, INT_MIN,  INT_MAX, 0, "flags" },
859 {"lame",     "set lame flag ", 0,                AV_OPT_TYPE_CONST,    {TEST_FLAG_LAME}, INT_MIN,  INT_MAX, 0, "flags" },
860 {"mu",       "set mu flag ",   0,                AV_OPT_TYPE_CONST,    {TEST_FLAG_MU},   INT_MIN,  INT_MAX, 0, "flags" },
861 {NULL},
862 };
863
864 static const char *test_get_name(void *ctx)
865 {
866     return "test";
867 }
868
869 static const AVClass test_class = {
870     "TestContext",
871     test_get_name,
872     test_options
873 };
874
875 int main(void)
876 {
877     int i;
878
879     printf("\nTesting av_set_options_string()\n");
880     {
881         TestContext test_ctx;
882         const char *options[] = {
883             "",
884             ":",
885             "=",
886             "foo=:",
887             ":=foo",
888             "=foo",
889             "foo=",
890             "foo",
891             "foo=val",
892             "foo==val",
893             "toggle=:",
894             "string=:",
895             "toggle=1 : foo",
896             "toggle=100",
897             "toggle==1",
898             "flags=+mu-lame : num=42: toggle=0",
899             "num=42 : string=blahblah",
900             "rational=0 : rational=1/2 : rational=1/-1",
901             "rational=-1/0",
902         };
903
904         test_ctx.class = &test_class;
905         av_opt_set_defaults(&test_ctx);
906         test_ctx.string = av_strdup("default");
907
908         av_log_set_level(AV_LOG_DEBUG);
909
910         for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
911             av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
912             if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
913                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
914             printf("\n");
915         }
916     }
917
918     return 0;
919 }
920
921 #endif