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