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