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