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