avutil/opt: check flags validity in write_number()
[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 "channel_layout.h"
31 #include "common.h"
32 #include "opt.h"
33 #include "eval.h"
34 #include "dict.h"
35 #include "log.h"
36 #include "parseutils.h"
37 #include "pixdesc.h"
38 #include "mathematics.h"
39 #include "samplefmt.h"
40
41 #include <float.h>
42
43 #if FF_API_FIND_OPT
44 //FIXME order them and do a bin search
45 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
46 {
47     const AVOption *o = NULL;
48
49     while ((o = av_next_option(v, o))) {
50         if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
51             return o;
52     }
53     return NULL;
54 }
55 #endif
56
57 #if FF_API_OLD_AVOPTIONS
58 const AVOption *av_next_option(void *obj, const AVOption *last)
59 {
60     return av_opt_next(obj, last);
61 }
62 #endif
63
64 const AVOption *av_opt_next(void *obj, const AVOption *last)
65 {
66     AVClass *class = *(AVClass**)obj;
67     if (!last && class && class->option && class->option[0].name)
68         return class->option;
69     if (last && last[1].name)
70         return ++last;
71     return NULL;
72 }
73
74 static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
75 {
76     switch (o->type) {
77     case AV_OPT_TYPE_FLAGS:     *intnum = *(unsigned int*)dst;return 0;
78     case AV_OPT_TYPE_PIXEL_FMT:
79     case AV_OPT_TYPE_SAMPLE_FMT:
80     case AV_OPT_TYPE_INT:       *intnum = *(int         *)dst;return 0;
81     case AV_OPT_TYPE_CHANNEL_LAYOUT:
82     case AV_OPT_TYPE_DURATION:
83     case AV_OPT_TYPE_INT64:     *intnum = *(int64_t     *)dst;return 0;
84     case AV_OPT_TYPE_FLOAT:     *num    = *(float       *)dst;return 0;
85     case AV_OPT_TYPE_DOUBLE:    *num    = *(double      *)dst;return 0;
86     case AV_OPT_TYPE_RATIONAL:  *intnum = ((AVRational*)dst)->num;
87                                 *den    = ((AVRational*)dst)->den;
88                                                         return 0;
89     case AV_OPT_TYPE_CONST:     *num    = o->default_val.dbl; return 0;
90     }
91     return AVERROR(EINVAL);
92 }
93
94 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
95 {
96     if (o->type != AV_OPT_TYPE_FLAGS &&
97         (o->max * den < num * intnum || o->min * den > num * intnum)) {
98         av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
99                num*intnum/den, o->name, o->min, o->max);
100         return AVERROR(ERANGE);
101     }
102     if (o->type == AV_OPT_TYPE_FLAGS) {
103         double d = num*intnum/den;
104         if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (lrint(d*256) & 255)) {
105             av_log(obj, AV_LOG_ERROR,
106                    "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
107                    num*intnum/den, o->name);
108             return AVERROR(ERANGE);
109         }
110     }
111
112     switch (o->type) {
113     case AV_OPT_TYPE_FLAGS:
114     case AV_OPT_TYPE_PIXEL_FMT:
115     case AV_OPT_TYPE_SAMPLE_FMT:
116     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
117     case AV_OPT_TYPE_DURATION:
118     case AV_OPT_TYPE_CHANNEL_LAYOUT:
119     case AV_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;
120     case AV_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
121     case AV_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
122     case AV_OPT_TYPE_RATIONAL:
123         if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
124         else                 *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
125         break;
126     default:
127         return AVERROR(EINVAL);
128     }
129     return 0;
130 }
131
132 static const double const_values[] = {
133     M_PI,
134     M_E,
135     FF_QP2LAMBDA,
136     0
137 };
138
139 static const char * const const_names[] = {
140     "PI",
141     "E",
142     "QP2LAMBDA",
143     0
144 };
145
146 static int hexchar2int(char c) {
147     if (c >= '0' && c <= '9') return c - '0';
148     if (c >= 'a' && c <= 'f') return c - 'a' + 10;
149     if (c >= 'A' && c <= 'F') return c - 'A' + 10;
150     return -1;
151 }
152
153 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
154 {
155     int *lendst = (int *)(dst + 1);
156     uint8_t *bin, *ptr;
157     int len = strlen(val);
158
159     av_freep(dst);
160     *lendst = 0;
161
162     if (len & 1)
163         return AVERROR(EINVAL);
164     len /= 2;
165
166     ptr = bin = av_malloc(len);
167     while (*val) {
168         int a = hexchar2int(*val++);
169         int b = hexchar2int(*val++);
170         if (a < 0 || b < 0) {
171             av_free(bin);
172             return AVERROR(EINVAL);
173         }
174         *ptr++ = (a << 4) | b;
175     }
176     *dst = bin;
177     *lendst = len;
178
179     return 0;
180 }
181
182 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
183 {
184     av_freep(dst);
185     *dst = av_strdup(val);
186     return 0;
187 }
188
189 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
190                               opt->type == AV_OPT_TYPE_CONST || \
191                               opt->type == AV_OPT_TYPE_FLAGS || \
192                               opt->type == AV_OPT_TYPE_INT) ? \
193                              opt->default_val.i64 : opt->default_val.dbl)
194
195 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
196 {
197     int ret = 0, notfirst = 0;
198     for (;;) {
199         int i, den = 1;
200         char buf[256];
201         int cmd = 0;
202         double d, num = 1;
203         int64_t intnum = 1;
204
205         i = 0;
206         if (*val == '+' || *val == '-') {
207             if (o->type == AV_OPT_TYPE_FLAGS)
208                 cmd = *(val++);
209             else if (!notfirst)
210                 buf[i++] = *val;
211         }
212
213         for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
214             buf[i] = val[i];
215         buf[i] = 0;
216
217         {
218             const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0);
219             if (o_named && o_named->type == AV_OPT_TYPE_CONST)
220                 d = DEFAULT_NUMVAL(o_named);
221             else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
222             else if (!strcmp(buf, "max"    )) d = o->max;
223             else if (!strcmp(buf, "min"    )) d = o->min;
224             else if (!strcmp(buf, "none"   )) d = 0;
225             else if (!strcmp(buf, "all"    )) d = ~0;
226             else {
227                 int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
228                 if (res < 0) {
229                     av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
230                     return res;
231                 }
232             }
233         }
234         if (o->type == AV_OPT_TYPE_FLAGS) {
235             read_number(o, dst, NULL, NULL, &intnum);
236             if      (cmd == '+') d = intnum | (int64_t)d;
237             else if (cmd == '-') d = intnum &~(int64_t)d;
238         } else {
239             read_number(o, dst, &num, &den, &intnum);
240             if      (cmd == '+') d = notfirst*num*intnum/den + d;
241             else if (cmd == '-') d = notfirst*num*intnum/den - d;
242         }
243
244         if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
245             return ret;
246         val += i;
247         if (!*val)
248             return 0;
249         notfirst = 1;
250     }
251
252     return 0;
253 }
254
255 #if FF_API_OLD_AVOPTIONS
256 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
257 {
258     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
259     if (o_out)
260         *o_out = o;
261     return av_opt_set(obj, name, val, 0);
262 }
263 #endif
264
265 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
266 {
267     int ret = 0;
268     void *dst, *target_obj;
269     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
270     if (!o || !target_obj)
271         return AVERROR_OPTION_NOT_FOUND;
272     if (!val && (o->type != AV_OPT_TYPE_STRING &&
273                  o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
274                  o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
275                  o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
276                  o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
277         return AVERROR(EINVAL);
278
279     dst = ((uint8_t*)target_obj) + o->offset;
280     switch (o->type) {
281     case AV_OPT_TYPE_STRING:   return set_string(obj, o, val, dst);
282     case AV_OPT_TYPE_BINARY:   return set_string_binary(obj, o, val, dst);
283     case AV_OPT_TYPE_FLAGS:
284     case AV_OPT_TYPE_INT:
285     case AV_OPT_TYPE_INT64:
286     case AV_OPT_TYPE_FLOAT:
287     case AV_OPT_TYPE_DOUBLE:
288     case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
289     case AV_OPT_TYPE_IMAGE_SIZE:
290         if (!val || !strcmp(val, "none")) {
291             *(int *)dst = *((int *)dst + 1) = 0;
292             return 0;
293         }
294         ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
295         if (ret < 0)
296             av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
297         return ret;
298     case AV_OPT_TYPE_VIDEO_RATE:
299         if (!val) {
300             ret = AVERROR(EINVAL);
301         } else {
302             ret = av_parse_video_rate(dst, val);
303         }
304         if (ret < 0)
305             av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
306         return ret;
307     case AV_OPT_TYPE_PIXEL_FMT:
308         if (!val || !strcmp(val, "none")) {
309             ret = AV_PIX_FMT_NONE;
310         } else {
311             ret = av_get_pix_fmt(val);
312             if (ret == AV_PIX_FMT_NONE) {
313                 char *tail;
314                 ret = strtol(val, &tail, 0);
315                 if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) {
316                     av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
317                     return AVERROR(EINVAL);
318                 }
319             }
320         }
321         *(enum AVPixelFormat *)dst = ret;
322         return 0;
323     case AV_OPT_TYPE_SAMPLE_FMT:
324         if (!val || !strcmp(val, "none")) {
325             ret = AV_SAMPLE_FMT_NONE;
326         } else {
327             ret = av_get_sample_fmt(val);
328             if (ret == AV_SAMPLE_FMT_NONE) {
329                 char *tail;
330                 ret = strtol(val, &tail, 0);
331                 if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) {
332                     av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val);
333                     return AVERROR(EINVAL);
334                 }
335             }
336         }
337         *(enum AVSampleFormat *)dst = ret;
338         return 0;
339     case AV_OPT_TYPE_DURATION:
340         if (!val) {
341             *(int64_t *)dst = 0;
342             return 0;
343         } else {
344             if ((ret = av_parse_time(dst, val, 1)) < 0)
345                 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
346             return ret;
347         }
348         break;
349     case AV_OPT_TYPE_COLOR:
350         if (!val) {
351             return 0;
352         } else {
353             ret = av_parse_color(dst, val, -1, obj);
354             if (ret < 0)
355                 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
356             return ret;
357         }
358         break;
359     case AV_OPT_TYPE_CHANNEL_LAYOUT:
360         if (!val || !strcmp(val, "none")) {
361             *(int64_t *)dst = 0;
362         } else {
363 #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
364             int64_t cl = ff_get_channel_layout(val, 0);
365 #else
366             int64_t cl = av_get_channel_layout(val);
367 #endif
368             if (!cl) {
369                 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
370                 ret = AVERROR(EINVAL);
371             }
372             *(int64_t *)dst = cl;
373             return ret;
374         }
375         break;
376     }
377
378     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
379     return AVERROR(EINVAL);
380 }
381
382 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
383     int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
384     {\
385         if (!o || o->type != opttype)\
386             return AVERROR(EINVAL);\
387         return set_string_number(obj, obj, o, val, name ## _out);\
388     }
389
390 OPT_EVAL_NUMBER(flags,  AV_OPT_TYPE_FLAGS,    int)
391 OPT_EVAL_NUMBER(int,    AV_OPT_TYPE_INT,      int)
392 OPT_EVAL_NUMBER(int64,  AV_OPT_TYPE_INT64,    int64_t)
393 OPT_EVAL_NUMBER(float,  AV_OPT_TYPE_FLOAT,    float)
394 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE,   double)
395 OPT_EVAL_NUMBER(q,      AV_OPT_TYPE_RATIONAL, AVRational)
396
397 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
398                                   int search_flags)
399 {
400     void *dst, *target_obj;
401     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
402
403     if (!o || !target_obj)
404         return AVERROR_OPTION_NOT_FOUND;
405
406     dst = ((uint8_t*)target_obj) + o->offset;
407     return write_number(obj, o, dst, num, den, intnum);
408 }
409
410 #if FF_API_OLD_AVOPTIONS
411 const AVOption *av_set_double(void *obj, const char *name, double n)
412 {
413     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
414     if (set_number(obj, name, n, 1, 1, 0) < 0)
415         return NULL;
416     return o;
417 }
418
419 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
420 {
421     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
422     if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
423         return NULL;
424     return o;
425 }
426
427 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
428 {
429     const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
430     if (set_number(obj, name, 1, 1, n, 0) < 0)
431         return NULL;
432     return o;
433 }
434 #endif
435
436 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
437 {
438     return set_number(obj, name, 1, 1, val, search_flags);
439 }
440
441 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
442 {
443     return set_number(obj, name, val, 1, 1, search_flags);
444 }
445
446 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
447 {
448     return set_number(obj, name, val.num, val.den, 1, search_flags);
449 }
450
451 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
452 {
453     void *target_obj;
454     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
455     uint8_t *ptr;
456     uint8_t **dst;
457     int *lendst;
458
459     if (!o || !target_obj)
460         return AVERROR_OPTION_NOT_FOUND;
461
462     if (o->type != AV_OPT_TYPE_BINARY)
463         return AVERROR(EINVAL);
464
465     ptr = len ? av_malloc(len) : NULL;
466     if (len && !ptr)
467         return AVERROR(ENOMEM);
468
469     dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
470     lendst = (int *)(dst + 1);
471
472     av_free(*dst);
473     *dst = ptr;
474     *lendst = len;
475     if (len)
476         memcpy(ptr, val, len);
477
478     return 0;
479 }
480
481 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
482 {
483     void *target_obj;
484     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
485
486     if (!o || !target_obj)
487         return AVERROR_OPTION_NOT_FOUND;
488     if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
489         av_log(obj, AV_LOG_ERROR,
490                "The value set by option '%s' is not an image size.\n", o->name);
491         return AVERROR(EINVAL);
492     }
493     if (w<0 || h<0) {
494         av_log(obj, AV_LOG_ERROR,
495                "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
496         return AVERROR(EINVAL);
497     }
498     *(int *)(((uint8_t *)target_obj)             + o->offset) = w;
499     *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
500     return 0;
501 }
502
503 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
504 {
505     void *target_obj;
506     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
507
508     if (!o || !target_obj)
509         return AVERROR_OPTION_NOT_FOUND;
510     if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
511         av_log(obj, AV_LOG_ERROR,
512                "The value set by option '%s' is not a video rate.\n", o->name);
513         return AVERROR(EINVAL);
514     }
515     if (val.num <= 0 || val.den <= 0)
516         return AVERROR(EINVAL);
517     return set_number(obj, name, val.num, val.den, 1, search_flags);
518 }
519
520 static int set_format(void *obj, const char *name, int fmt, int search_flags,
521                       enum AVOptionType type, const char *desc, int nb_fmts)
522 {
523     void *target_obj;
524     const AVOption *o = av_opt_find2(obj, name, NULL, 0,
525                                      search_flags, &target_obj);
526     int min, max;
527     const AVClass *class = *(AVClass **)obj;
528
529     if (!o || !target_obj)
530         return AVERROR_OPTION_NOT_FOUND;
531     if (o->type != type) {
532         av_log(obj, AV_LOG_ERROR,
533                "The value set by option '%s' is not a %s format", name, desc);
534         return AVERROR(EINVAL);
535     }
536
537 #if LIBAVUTIL_VERSION_MAJOR < 53
538     if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) {
539         min = -1;
540         max = nb_fmts-1;
541     } else
542 #endif
543     {
544         min = FFMIN(o->min, -1);
545         max = FFMAX(o->max, nb_fmts-1);
546     }
547     if (fmt < min || fmt > max) {
548         av_log(obj, AV_LOG_ERROR,
549                "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
550                fmt, name, desc, min, max);
551         return AVERROR(ERANGE);
552     }
553     *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
554     return 0;
555 }
556
557 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
558 {
559     return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
560 }
561
562 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
563 {
564     return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
565 }
566
567 int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
568 {
569     void *target_obj;
570     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
571
572     if (!o || !target_obj)
573         return AVERROR_OPTION_NOT_FOUND;
574     if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
575         av_log(obj, AV_LOG_ERROR,
576                "The value set by option '%s' is not a channel layout.\n", o->name);
577         return AVERROR(EINVAL);
578     }
579     *(int *)(((int64_t *)target_obj) + o->offset) = cl;
580     return 0;
581 }
582
583 #if FF_API_OLD_AVOPTIONS
584 /**
585  *
586  * @param buf a buffer which is used for returning non string values as strings, can be NULL
587  * @param buf_len allocated length in bytes of buf
588  */
589 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
590 {
591     const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
592     void *dst;
593     uint8_t *bin;
594     int len, i;
595     if (!o)
596         return NULL;
597     if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
598         return NULL;
599
600     dst= ((uint8_t*)obj) + o->offset;
601     if (o_out) *o_out= o;
602
603     switch (o->type) {
604     case AV_OPT_TYPE_FLAGS:     snprintf(buf, buf_len, "0x%08X",*(int    *)dst);break;
605     case AV_OPT_TYPE_INT:       snprintf(buf, buf_len, "%d" , *(int    *)dst);break;
606     case AV_OPT_TYPE_INT64:     snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
607     case AV_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
608     case AV_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
609     case AV_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
610     case AV_OPT_TYPE_CONST:     snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
611     case AV_OPT_TYPE_STRING:    return *(void**)dst;
612     case AV_OPT_TYPE_BINARY:
613         len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
614         if (len >= (buf_len + 1)/2) return NULL;
615         bin = *(uint8_t**)dst;
616         for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
617         break;
618     default: return NULL;
619     }
620     return buf;
621 }
622 #endif
623
624 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
625 {
626     void *dst, *target_obj;
627     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
628     uint8_t *bin, buf[128];
629     int len, i, ret;
630     int64_t i64;
631
632     if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
633         return AVERROR_OPTION_NOT_FOUND;
634
635     dst = (uint8_t*)target_obj + o->offset;
636
637     buf[0] = 0;
638     switch (o->type) {
639     case AV_OPT_TYPE_FLAGS:     ret = snprintf(buf, sizeof(buf), "0x%08X",  *(int    *)dst);break;
640     case AV_OPT_TYPE_INT:       ret = snprintf(buf, sizeof(buf), "%d" ,     *(int    *)dst);break;
641     case AV_OPT_TYPE_INT64:     ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
642     case AV_OPT_TYPE_FLOAT:     ret = snprintf(buf, sizeof(buf), "%f" ,     *(float  *)dst);break;
643     case AV_OPT_TYPE_DOUBLE:    ret = snprintf(buf, sizeof(buf), "%f" ,     *(double *)dst);break;
644     case AV_OPT_TYPE_VIDEO_RATE:
645     case AV_OPT_TYPE_RATIONAL:  ret = snprintf(buf, sizeof(buf), "%d/%d",   ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
646     case AV_OPT_TYPE_CONST:     ret = snprintf(buf, sizeof(buf), "%f" ,     o->default_val.dbl);break;
647     case AV_OPT_TYPE_STRING:
648         if (*(uint8_t**)dst)
649             *out_val = av_strdup(*(uint8_t**)dst);
650         else
651             *out_val = av_strdup("");
652         return 0;
653     case AV_OPT_TYPE_BINARY:
654         len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
655         if ((uint64_t)len*2 + 1 > INT_MAX)
656             return AVERROR(EINVAL);
657         if (!(*out_val = av_malloc(len*2 + 1)))
658             return AVERROR(ENOMEM);
659         bin = *(uint8_t**)dst;
660         for (i = 0; i < len; i++)
661             snprintf(*out_val + i*2, 3, "%02X", bin[i]);
662         return 0;
663     case AV_OPT_TYPE_IMAGE_SIZE:
664         ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
665         break;
666     case AV_OPT_TYPE_PIXEL_FMT:
667         ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
668         break;
669     case AV_OPT_TYPE_SAMPLE_FMT:
670         ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
671         break;
672     case AV_OPT_TYPE_DURATION:
673         i64 = *(int64_t *)dst;
674         ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d",
675                        i64 / 3600000000, (int)((i64 / 60000000) % 60),
676                        (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
677         break;
678     case AV_OPT_TYPE_COLOR:
679         ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]);
680         break;
681     case AV_OPT_TYPE_CHANNEL_LAYOUT:
682         i64 = *(int64_t *)dst;
683         ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
684         break;
685     default:
686         return AVERROR(EINVAL);
687     }
688
689     if (ret >= sizeof(buf))
690         return AVERROR(EINVAL);
691     *out_val = av_strdup(buf);
692     return 0;
693 }
694
695 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
696                       int search_flags)
697 {
698     void *dst, *target_obj;
699     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
700     if (!o || !target_obj)
701         goto error;
702
703     dst = ((uint8_t*)target_obj) + o->offset;
704
705     if (o_out) *o_out= o;
706
707     return read_number(o, dst, num, den, intnum);
708
709 error:
710     *den=*intnum=0;
711     return -1;
712 }
713
714 #if FF_API_OLD_AVOPTIONS
715 double av_get_double(void *obj, const char *name, const AVOption **o_out)
716 {
717     int64_t intnum=1;
718     double num=1;
719     int den=1;
720
721     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
722         return NAN;
723     return num*intnum/den;
724 }
725
726 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
727 {
728     int64_t intnum=1;
729     double num=1;
730     int den=1;
731
732     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
733         return (AVRational){0, 0};
734     if (num == 1.0 && (int)intnum == intnum)
735         return (AVRational){intnum, den};
736     else
737         return av_d2q(num*intnum/den, 1<<24);
738 }
739
740 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
741 {
742     int64_t intnum=1;
743     double num=1;
744     int den=1;
745
746     if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
747         return -1;
748     return num*intnum/den;
749 }
750 #endif
751
752 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
753 {
754     int64_t intnum = 1;
755     double     num = 1;
756     int   ret, den = 1;
757
758     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
759         return ret;
760     *out_val = num*intnum/den;
761     return 0;
762 }
763
764 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
765 {
766     int64_t intnum = 1;
767     double     num = 1;
768     int   ret, den = 1;
769
770     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
771         return ret;
772     *out_val = num*intnum/den;
773     return 0;
774 }
775
776 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
777 {
778     int64_t intnum = 1;
779     double     num = 1;
780     int   ret, den = 1;
781
782     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
783         return ret;
784
785     if (num == 1.0 && (int)intnum == intnum)
786         *out_val = (AVRational){intnum, den};
787     else
788         *out_val = av_d2q(num*intnum/den, 1<<24);
789     return 0;
790 }
791
792 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
793 {
794     void *dst, *target_obj;
795     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
796     if (!o || !target_obj)
797         return AVERROR_OPTION_NOT_FOUND;
798     if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
799         av_log(obj, AV_LOG_ERROR,
800                "The value for option '%s' is not an image size.\n", name);
801         return AVERROR(EINVAL);
802     }
803
804     dst = ((uint8_t*)target_obj) + o->offset;
805     if (w_out) *w_out = *(int *)dst;
806     if (h_out) *h_out = *((int *)dst+1);
807     return 0;
808 }
809
810 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
811 {
812     int64_t intnum = 1;
813     double     num = 1;
814     int   ret, den = 1;
815
816     if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
817         return ret;
818
819     if (num == 1.0 && (int)intnum == intnum)
820         *out_val = (AVRational){intnum, den};
821     else
822         *out_val = av_d2q(num*intnum/den, 1<<24);
823     return 0;
824 }
825
826 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
827                       enum AVOptionType type, const char *desc)
828 {
829     void *dst, *target_obj;
830     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
831     if (!o || !target_obj)
832         return AVERROR_OPTION_NOT_FOUND;
833     if (o->type != type) {
834         av_log(obj, AV_LOG_ERROR,
835                "The value for option '%s' is not a %s format.\n", desc, name);
836         return AVERROR(EINVAL);
837     }
838
839     dst = ((uint8_t*)target_obj) + o->offset;
840     *out_fmt = *(int *)dst;
841     return 0;
842 }
843
844 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
845 {
846     return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
847 }
848
849 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
850 {
851     return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
852 }
853
854 int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
855 {
856     void *dst, *target_obj;
857     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
858     if (!o || !target_obj)
859         return AVERROR_OPTION_NOT_FOUND;
860     if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
861         av_log(obj, AV_LOG_ERROR,
862                "The value for option '%s' is not a channel layout.\n", name);
863         return AVERROR(EINVAL);
864     }
865
866     dst = ((uint8_t*)target_obj) + o->offset;
867     *cl = *(int64_t *)dst;
868     return 0;
869 }
870
871 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
872 {
873     const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
874     const AVOption *flag  = av_opt_find(obj, flag_name,
875                                         field ? field->unit : NULL, 0, 0);
876     int64_t res;
877
878     if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
879         av_opt_get_int(obj, field_name, 0, &res) < 0)
880         return 0;
881     return res & flag->default_val.i64;
882 }
883
884 static void log_value(void *av_log_obj, int level, double d)
885 {
886     if      (d == INT_MAX) {
887         av_log(av_log_obj, level, "INT_MAX");
888     } else if (d == INT_MIN) {
889         av_log(av_log_obj, level, "INT_MIN");
890     } else if (d == (double)INT64_MAX) {
891         av_log(av_log_obj, level, "I64_MAX");
892     } else if (d == INT64_MIN) {
893         av_log(av_log_obj, level, "I64_MIN");
894     } else if (d == FLT_MAX) {
895         av_log(av_log_obj, level, "FLT_MAX");
896     } else if (d == FLT_MIN) {
897         av_log(av_log_obj, level, "FLT_MIN");
898     } else {
899         av_log(av_log_obj, level, "%g", d);
900     }
901 }
902
903 static void opt_list(void *obj, void *av_log_obj, const char *unit,
904                      int req_flags, int rej_flags)
905 {
906     const AVOption *opt=NULL;
907     AVOptionRanges *r;
908     int i;
909
910     while ((opt = av_opt_next(obj, opt))) {
911         if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
912             continue;
913
914         /* Don't print CONST's on level one.
915          * Don't print anything but CONST's on level two.
916          * Only print items from the requested unit.
917          */
918         if (!unit && opt->type==AV_OPT_TYPE_CONST)
919             continue;
920         else if (unit && opt->type!=AV_OPT_TYPE_CONST)
921             continue;
922         else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
923             continue;
924         else if (unit && opt->type == AV_OPT_TYPE_CONST)
925             av_log(av_log_obj, AV_LOG_INFO, "     %-15s ", opt->name);
926         else
927             av_log(av_log_obj, AV_LOG_INFO, "  %s%-17s ",
928                    (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-",
929                    opt->name);
930
931         switch (opt->type) {
932             case AV_OPT_TYPE_FLAGS:
933                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
934                 break;
935             case AV_OPT_TYPE_INT:
936                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
937                 break;
938             case AV_OPT_TYPE_INT64:
939                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
940                 break;
941             case AV_OPT_TYPE_DOUBLE:
942                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
943                 break;
944             case AV_OPT_TYPE_FLOAT:
945                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
946                 break;
947             case AV_OPT_TYPE_STRING:
948                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
949                 break;
950             case AV_OPT_TYPE_RATIONAL:
951                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
952                 break;
953             case AV_OPT_TYPE_BINARY:
954                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
955                 break;
956             case AV_OPT_TYPE_IMAGE_SIZE:
957                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
958                 break;
959             case AV_OPT_TYPE_VIDEO_RATE:
960                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
961                 break;
962             case AV_OPT_TYPE_PIXEL_FMT:
963                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
964                 break;
965             case AV_OPT_TYPE_SAMPLE_FMT:
966                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
967                 break;
968             case AV_OPT_TYPE_DURATION:
969                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
970                 break;
971             case AV_OPT_TYPE_COLOR:
972                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
973                 break;
974             case AV_OPT_TYPE_CHANNEL_LAYOUT:
975                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
976                 break;
977             case AV_OPT_TYPE_CONST:
978             default:
979                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
980                 break;
981         }
982         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
983         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
984         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
985         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
986         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
987         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
988
989         if (opt->help)
990             av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
991
992         if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
993             switch (opt->type) {
994             case AV_OPT_TYPE_INT:
995             case AV_OPT_TYPE_INT64:
996             case AV_OPT_TYPE_DOUBLE:
997             case AV_OPT_TYPE_FLOAT:
998             case AV_OPT_TYPE_RATIONAL:
999                 for (i = 0; i < r->nb_ranges; i++) {
1000                     av_log(av_log_obj, AV_LOG_INFO, " (from ");
1001                     log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
1002                     av_log(av_log_obj, AV_LOG_INFO, " to ");
1003                     log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
1004                     av_log(av_log_obj, AV_LOG_INFO, ")");
1005                 }
1006                 break;
1007             }
1008             av_opt_freep_ranges(&r);
1009         }
1010
1011         if (opt->type != AV_OPT_TYPE_CONST  &&
1012             opt->type != AV_OPT_TYPE_BINARY &&
1013                 !((opt->type == AV_OPT_TYPE_COLOR      ||
1014                    opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
1015                    opt->type == AV_OPT_TYPE_STRING     ||
1016                    opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
1017                   !opt->default_val.str)) {
1018             av_log(av_log_obj, AV_LOG_INFO, " (default ");
1019             switch (opt->type) {
1020             case AV_OPT_TYPE_FLAGS:
1021                 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
1022                 break;
1023             case AV_OPT_TYPE_DURATION:
1024             case AV_OPT_TYPE_INT:
1025             case AV_OPT_TYPE_INT64:
1026                 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
1027                 break;
1028             case AV_OPT_TYPE_DOUBLE:
1029             case AV_OPT_TYPE_FLOAT:
1030                 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
1031                 break;
1032             case AV_OPT_TYPE_RATIONAL: {
1033                 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
1034                 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
1035                 break;
1036             case AV_OPT_TYPE_PIXEL_FMT:
1037                 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
1038                 break;
1039             case AV_OPT_TYPE_SAMPLE_FMT:
1040                 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
1041                 break;
1042             case AV_OPT_TYPE_COLOR:
1043             case AV_OPT_TYPE_IMAGE_SIZE:
1044             case AV_OPT_TYPE_STRING:
1045             case AV_OPT_TYPE_VIDEO_RATE:
1046                 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
1047                 break;
1048             case AV_OPT_TYPE_CHANNEL_LAYOUT:
1049                 av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
1050                 break;
1051             }
1052             av_log(av_log_obj, AV_LOG_INFO, ")");
1053         }
1054
1055         av_log(av_log_obj, AV_LOG_INFO, "\n");
1056         if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
1057             opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
1058         }
1059     }
1060 }
1061
1062 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
1063 {
1064     if (!obj)
1065         return -1;
1066
1067     av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
1068
1069     opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
1070
1071     return 0;
1072 }
1073
1074 void av_opt_set_defaults(void *s)
1075 {
1076 #if FF_API_OLD_AVOPTIONS
1077     av_opt_set_defaults2(s, 0, 0);
1078 }
1079
1080 void av_opt_set_defaults2(void *s, int mask, int flags)
1081 {
1082 #endif
1083     const AVClass *class = *(AVClass **)s;
1084     const AVOption *opt = NULL;
1085     while ((opt = av_opt_next(s, opt)) != NULL) {
1086 #if FF_API_OLD_AVOPTIONS
1087         if ((opt->flags & mask) != flags)
1088             continue;
1089 #endif
1090         switch (opt->type) {
1091             case AV_OPT_TYPE_CONST:
1092                 /* Nothing to be done here */
1093             break;
1094             case AV_OPT_TYPE_FLAGS:
1095             case AV_OPT_TYPE_INT:
1096             case AV_OPT_TYPE_INT64:
1097             case AV_OPT_TYPE_DURATION:
1098             case AV_OPT_TYPE_CHANNEL_LAYOUT:
1099                 av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
1100             break;
1101             case AV_OPT_TYPE_DOUBLE:
1102             case AV_OPT_TYPE_FLOAT: {
1103                 double val;
1104                 val = opt->default_val.dbl;
1105                 av_opt_set_double(s, opt->name, val, 0);
1106             }
1107             break;
1108             case AV_OPT_TYPE_RATIONAL: {
1109                 AVRational val;
1110                 val = av_d2q(opt->default_val.dbl, INT_MAX);
1111                 av_opt_set_q(s, opt->name, val, 0);
1112             }
1113             break;
1114             case AV_OPT_TYPE_COLOR:
1115             case AV_OPT_TYPE_STRING:
1116             case AV_OPT_TYPE_IMAGE_SIZE:
1117             case AV_OPT_TYPE_VIDEO_RATE:
1118                 av_opt_set(s, opt->name, opt->default_val.str, 0);
1119                 break;
1120             case AV_OPT_TYPE_PIXEL_FMT:
1121 #if LIBAVUTIL_VERSION_MAJOR < 53
1122                 if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
1123                     av_opt_set(s, opt->name, opt->default_val.str, 0);
1124                 else
1125 #endif
1126                     av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
1127                 break;
1128             case AV_OPT_TYPE_SAMPLE_FMT:
1129 #if LIBAVUTIL_VERSION_MAJOR < 53
1130                 if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
1131                     av_opt_set(s, opt->name, opt->default_val.str, 0);
1132                 else
1133 #endif
1134                     av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
1135                 break;
1136             case AV_OPT_TYPE_BINARY:
1137                 /* Cannot set default for binary */
1138             break;
1139             default:
1140                 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
1141         }
1142     }
1143 }
1144
1145 /**
1146  * Store the value in the field in ctx that is named like key.
1147  * ctx must be an AVClass context, storing is done using AVOptions.
1148  *
1149  * @param buf the string to parse, buf will be updated to point at the
1150  * separator just after the parsed key/value pair
1151  * @param key_val_sep a 0-terminated list of characters used to
1152  * separate key from value
1153  * @param pairs_sep a 0-terminated list of characters used to separate
1154  * two pairs from each other
1155  * @return 0 if the key/value pair has been successfully parsed and
1156  * set, or a negative value corresponding to an AVERROR code in case
1157  * of error:
1158  * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1159  * the error code issued by av_opt_set() if the key/value pair
1160  * cannot be set
1161  */
1162 static int parse_key_value_pair(void *ctx, const char **buf,
1163                                 const char *key_val_sep, const char *pairs_sep)
1164 {
1165     char *key = av_get_token(buf, key_val_sep);
1166     char *val;
1167     int ret;
1168
1169     if (!key)
1170         return AVERROR(ENOMEM);
1171
1172     if (*key && strspn(*buf, key_val_sep)) {
1173         (*buf)++;
1174         val = av_get_token(buf, pairs_sep);
1175         if (!val) {
1176             av_freep(&key);
1177             return AVERROR(ENOMEM);
1178         }
1179     } else {
1180         av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
1181         av_free(key);
1182         return AVERROR(EINVAL);
1183     }
1184
1185     av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
1186
1187     ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
1188     if (ret == AVERROR_OPTION_NOT_FOUND)
1189         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
1190
1191     av_free(key);
1192     av_free(val);
1193     return ret;
1194 }
1195
1196 int av_set_options_string(void *ctx, const char *opts,
1197                           const char *key_val_sep, const char *pairs_sep)
1198 {
1199     int ret, count = 0;
1200
1201     if (!opts)
1202         return 0;
1203
1204     while (*opts) {
1205         if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
1206             return ret;
1207         count++;
1208
1209         if (*opts)
1210             opts++;
1211     }
1212
1213     return count;
1214 }
1215
1216 #define WHITESPACES " \n\t"
1217
1218 static int is_key_char(char c)
1219 {
1220     return (unsigned)((c | 32) - 'a') < 26 ||
1221            (unsigned)(c - '0') < 10 ||
1222            c == '-' || c == '_' || c == '/' || c == '.';
1223 }
1224
1225 /**
1226  * Read a key from a string.
1227  *
1228  * The key consists of is_key_char characters and must be terminated by a
1229  * character from the delim string; spaces are ignored.
1230  *
1231  * @return  0 for success (even with ellipsis), <0 for failure
1232  */
1233 static int get_key(const char **ropts, const char *delim, char **rkey)
1234 {
1235     const char *opts = *ropts;
1236     const char *key_start, *key_end;
1237
1238     key_start = opts += strspn(opts, WHITESPACES);
1239     while (is_key_char(*opts))
1240         opts++;
1241     key_end = opts;
1242     opts += strspn(opts, WHITESPACES);
1243     if (!*opts || !strchr(delim, *opts))
1244         return AVERROR(EINVAL);
1245     opts++;
1246     if (!(*rkey = av_malloc(key_end - key_start + 1)))
1247         return AVERROR(ENOMEM);
1248     memcpy(*rkey, key_start, key_end - key_start);
1249     (*rkey)[key_end - key_start] = 0;
1250     *ropts = opts;
1251     return 0;
1252 }
1253
1254 int av_opt_get_key_value(const char **ropts,
1255                          const char *key_val_sep, const char *pairs_sep,
1256                          unsigned flags,
1257                          char **rkey, char **rval)
1258 {
1259     int ret;
1260     char *key = NULL, *val;
1261     const char *opts = *ropts;
1262
1263     if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
1264         !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
1265         return AVERROR(EINVAL);
1266     if (!(val = av_get_token(&opts, pairs_sep))) {
1267         av_free(key);
1268         return AVERROR(ENOMEM);
1269     }
1270     *ropts = opts;
1271     *rkey  = key;
1272     *rval  = val;
1273     return 0;
1274 }
1275
1276 int av_opt_set_from_string(void *ctx, const char *opts,
1277                            const char *const *shorthand,
1278                            const char *key_val_sep, const char *pairs_sep)
1279 {
1280     int ret, count = 0;
1281     const char *dummy_shorthand = NULL;
1282     char *av_uninit(parsed_key), *av_uninit(value);
1283     const char *key;
1284
1285     if (!opts)
1286         return 0;
1287     if (!shorthand)
1288         shorthand = &dummy_shorthand;
1289
1290     while (*opts) {
1291         ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
1292                                    *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
1293                                    &parsed_key, &value);
1294         if (ret < 0) {
1295             if (ret == AVERROR(EINVAL))
1296                 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
1297             else
1298                 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
1299                        av_err2str(ret));
1300             return ret;
1301         }
1302         if (*opts)
1303             opts++;
1304         if (parsed_key) {
1305             key = parsed_key;
1306             while (*shorthand) /* discard all remaining shorthand */
1307                 shorthand++;
1308         } else {
1309             key = *(shorthand++);
1310         }
1311
1312         av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
1313         if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
1314             if (ret == AVERROR_OPTION_NOT_FOUND)
1315                 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
1316             av_free(value);
1317             av_free(parsed_key);
1318             return ret;
1319         }
1320
1321         av_free(value);
1322         av_free(parsed_key);
1323         count++;
1324     }
1325     return count;
1326 }
1327
1328 void av_opt_free(void *obj)
1329 {
1330     const AVOption *o = NULL;
1331     while ((o = av_opt_next(obj, o)))
1332         if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
1333             av_freep((uint8_t *)obj + o->offset);
1334 }
1335
1336 int av_opt_set_dict(void *obj, AVDictionary **options)
1337 {
1338     AVDictionaryEntry *t = NULL;
1339     AVDictionary    *tmp = NULL;
1340     int ret = 0;
1341
1342     while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
1343         ret = av_opt_set(obj, t->key, t->value, 0);
1344         if (ret == AVERROR_OPTION_NOT_FOUND)
1345             av_dict_set(&tmp, t->key, t->value, 0);
1346         else if (ret < 0) {
1347             av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
1348             break;
1349         }
1350         ret = 0;
1351     }
1352     av_dict_free(options);
1353     *options = tmp;
1354     return ret;
1355 }
1356
1357 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
1358                             int opt_flags, int search_flags)
1359 {
1360     return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1361 }
1362
1363 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
1364                              int opt_flags, int search_flags, void **target_obj)
1365 {
1366     const AVClass  *c;
1367     const AVOption *o = NULL;
1368
1369     if(!obj)
1370         return NULL;
1371
1372     c= *(AVClass**)obj;
1373
1374     if (!c)
1375         return NULL;
1376
1377     if (search_flags & AV_OPT_SEARCH_CHILDREN) {
1378         if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
1379             const AVClass *child = NULL;
1380             while (child = av_opt_child_class_next(c, child))
1381                 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
1382                     return o;
1383         } else {
1384             void *child = NULL;
1385             while (child = av_opt_child_next(obj, child))
1386                 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1387                     return o;
1388         }
1389     }
1390
1391     while (o = av_opt_next(obj, o)) {
1392         if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
1393             ((!unit && o->type != AV_OPT_TYPE_CONST) ||
1394              (unit  && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
1395             if (target_obj) {
1396                 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
1397                     *target_obj = obj;
1398                 else
1399                     *target_obj = NULL;
1400             }
1401             return o;
1402         }
1403     }
1404     return NULL;
1405 }
1406
1407 void *av_opt_child_next(void *obj, void *prev)
1408 {
1409     const AVClass *c = *(AVClass**)obj;
1410     if (c->child_next)
1411         return c->child_next(obj, prev);
1412     return NULL;
1413 }
1414
1415 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
1416 {
1417     if (parent->child_class_next)
1418         return parent->child_class_next(prev);
1419     return NULL;
1420 }
1421
1422 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
1423 {
1424     const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
1425     if(!opt)
1426         return NULL;
1427     return (uint8_t*)obj + opt->offset;
1428 }
1429
1430 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1431 {
1432     const AVClass *c = *(AVClass**)obj;
1433     int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
1434
1435     if (c->version > (52 << 16 | 11 << 8))
1436         callback = c->query_ranges;
1437
1438     if (!callback)
1439         callback = av_opt_query_ranges_default;
1440
1441     return callback(ranges_arg, obj, key, flags);
1442 }
1443
1444 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1445 {
1446     AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
1447     AVOptionRange **range_array = av_mallocz(sizeof(void*));
1448     AVOptionRange *range = av_mallocz(sizeof(*range));
1449     const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
1450     int ret;
1451
1452     *ranges_arg = NULL;
1453
1454     if (!ranges || !range || !range_array || !field) {
1455         ret = AVERROR(ENOMEM);
1456         goto fail;
1457     }
1458
1459     ranges->range = range_array;
1460     ranges->range[0] = range;
1461     ranges->nb_ranges = 1;
1462     range->is_range = 1;
1463     range->value_min = field->min;
1464     range->value_max = field->max;
1465
1466     switch (field->type) {
1467     case AV_OPT_TYPE_INT:
1468     case AV_OPT_TYPE_INT64:
1469     case AV_OPT_TYPE_PIXEL_FMT:
1470     case AV_OPT_TYPE_SAMPLE_FMT:
1471     case AV_OPT_TYPE_FLOAT:
1472     case AV_OPT_TYPE_DOUBLE:
1473     case AV_OPT_TYPE_DURATION:
1474     case AV_OPT_TYPE_COLOR:
1475     case AV_OPT_TYPE_CHANNEL_LAYOUT:
1476         break;
1477     case AV_OPT_TYPE_STRING:
1478         range->component_min = 0;
1479         range->component_max = 0x10FFFF; // max unicode value
1480         range->value_min = -1;
1481         range->value_max = INT_MAX;
1482         break;
1483     case AV_OPT_TYPE_RATIONAL:
1484         range->component_min = INT_MIN;
1485         range->component_max = INT_MAX;
1486         break;
1487     case AV_OPT_TYPE_IMAGE_SIZE:
1488         range->component_min = 0;
1489         range->component_max = INT_MAX/128/8;
1490         range->value_min = 0;
1491         range->value_max = INT_MAX/8;
1492         break;
1493     case AV_OPT_TYPE_VIDEO_RATE:
1494         range->component_min = 1;
1495         range->component_max = INT_MAX;
1496         range->value_min = 1;
1497         range->value_max = INT_MAX;
1498         break;
1499     default:
1500         ret = AVERROR(ENOSYS);
1501         goto fail;
1502     }
1503
1504     *ranges_arg = ranges;
1505     return 0;
1506 fail:
1507     av_free(ranges);
1508     av_free(range);
1509     av_free(range_array);
1510     return ret;
1511 }
1512
1513 void av_opt_freep_ranges(AVOptionRanges **rangesp)
1514 {
1515     int i;
1516     AVOptionRanges *ranges = *rangesp;
1517
1518     for (i = 0; i < ranges->nb_ranges; i++) {
1519         AVOptionRange *range = ranges->range[i];
1520         av_freep(&range->str);
1521         av_freep(&ranges->range[i]);
1522     }
1523     av_freep(&ranges->range);
1524     av_freep(rangesp);
1525 }
1526
1527 #ifdef TEST
1528
1529 typedef struct TestContext
1530 {
1531     const AVClass *class;
1532     int num;
1533     int toggle;
1534     char *string;
1535     int flags;
1536     AVRational rational;
1537     AVRational video_rate;
1538     int w, h;
1539     enum AVPixelFormat pix_fmt;
1540     enum AVSampleFormat sample_fmt;
1541     int64_t duration;
1542     uint8_t color[4];
1543     int64_t channel_layout;
1544 } TestContext;
1545
1546 #define OFFSET(x) offsetof(TestContext, x)
1547
1548 #define TEST_FLAG_COOL 01
1549 #define TEST_FLAG_LAME 02
1550 #define TEST_FLAG_MU   04
1551
1552 static const AVOption test_options[]= {
1553 {"num",      "set num",        OFFSET(num),      AV_OPT_TYPE_INT,      {.i64 = 0},       0,        100                 },
1554 {"toggle",   "set toggle",     OFFSET(toggle),   AV_OPT_TYPE_INT,      {.i64 = 0},       0,        1                   },
1555 {"rational", "set rational",   OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0},       0,        10                  },
1556 {"string",   "set string",     OFFSET(string),   AV_OPT_TYPE_STRING,   {.str = "default"}, CHAR_MIN, CHAR_MAX          },
1557 {"flags",    "set flags",      OFFSET(flags),    AV_OPT_TYPE_FLAGS,    {.i64 = 0},       0,        INT_MAX, 0, "flags" },
1558 {"cool",     "set cool flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_COOL}, INT_MIN,  INT_MAX, 0, "flags" },
1559 {"lame",     "set lame flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_LAME}, INT_MIN,  INT_MAX, 0, "flags" },
1560 {"mu",       "set mu flag ",   0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_MU},   INT_MIN,  INT_MAX, 0, "flags" },
1561 {"size",     "set size",       OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE,{0},             0,        0                   },
1562 {"pix_fmt",  "set pixfmt",     OFFSET(pix_fmt),  AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1},
1563 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1},
1564 {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE,  {.str = "25"}, 0,     0                   },
1565 {"duration", "set duration",   OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
1566 {"color", "set color",   OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0},
1567 {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX},
1568 {NULL},
1569 };
1570
1571 static const char *test_get_name(void *ctx)
1572 {
1573     return "test";
1574 }
1575
1576 static const AVClass test_class = {
1577     "TestContext",
1578     test_get_name,
1579     test_options
1580 };
1581
1582 int main(void)
1583 {
1584     int i;
1585
1586     printf("\nTesting av_set_options_string()\n");
1587     {
1588         TestContext test_ctx = { 0 };
1589         static const char * const options[] = {
1590             "",
1591             ":",
1592             "=",
1593             "foo=:",
1594             ":=foo",
1595             "=foo",
1596             "foo=",
1597             "foo",
1598             "foo=val",
1599             "foo==val",
1600             "toggle=:",
1601             "string=:",
1602             "toggle=1 : foo",
1603             "toggle=100",
1604             "toggle==1",
1605             "flags=+mu-lame : num=42: toggle=0",
1606             "num=42 : string=blahblah",
1607             "rational=0 : rational=1/2 : rational=1/-1",
1608             "rational=-1/0",
1609             "size=1024x768",
1610             "size=pal",
1611             "size=bogus",
1612             "pix_fmt=yuv420p",
1613             "pix_fmt=2",
1614             "pix_fmt=bogus",
1615             "sample_fmt=s16",
1616             "sample_fmt=2",
1617             "sample_fmt=bogus",
1618             "video_rate=pal",
1619             "video_rate=25",
1620             "video_rate=30000/1001",
1621             "video_rate=30/1.001",
1622             "video_rate=bogus",
1623             "duration=bogus",
1624             "duration=123.45",
1625             "duration=1\\:23\\:45.67",
1626             "color=blue",
1627             "color=0x223300",
1628             "color=0x42FF07AA",
1629             "cl=stereo+downmix",
1630             "cl=foo",
1631         };
1632
1633         test_ctx.class = &test_class;
1634         av_opt_set_defaults(&test_ctx);
1635
1636         av_log_set_level(AV_LOG_DEBUG);
1637
1638         for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
1639             av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
1640             if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
1641                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
1642             printf("\n");
1643         }
1644         av_opt_free(&test_ctx);
1645     }
1646
1647     printf("\nTesting av_opt_set_from_string()\n");
1648     {
1649         TestContext test_ctx = { 0 };
1650         static const char * const options[] = {
1651             "",
1652             "5",
1653             "5:hello",
1654             "5:hello:size=pal",
1655             "5:size=pal:hello",
1656             ":",
1657             "=",
1658             " 5 : hello : size = pal ",
1659             "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
1660         };
1661         static const char * const shorthand[] = { "num", "string", NULL };
1662
1663         test_ctx.class = &test_class;
1664         av_opt_set_defaults(&test_ctx);
1665
1666         av_log_set_level(AV_LOG_DEBUG);
1667
1668         for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
1669             av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
1670             if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
1671                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
1672             printf("\n");
1673         }
1674         av_opt_free(&test_ctx);
1675     }
1676
1677     return 0;
1678 }
1679
1680 #endif