3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
5 * This file is part of FFmpeg.
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.
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.
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
25 * @author Michael Niedermayer <michaelni@gmx.at>
30 #include "channel_layout.h"
36 #include "parseutils.h"
38 #include "mathematics.h"
39 #include "samplefmt.h"
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
)
47 const AVOption
*o
= NULL
;
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
)
57 #if FF_API_OLD_AVOPTIONS
58 const AVOption
*av_next_option(void *obj
, const AVOption
*last
)
60 return av_opt_next(obj
, last
);
64 const AVOption
*av_opt_next(void *obj
, const AVOption
*last
)
66 AVClass
*class = *(AVClass
**)obj
;
67 if (!last
&& class && class->option
&& class->option
[0].name
)
69 if (last
&& last
[1].name
)
74 static int read_number(const AVOption
*o
, void *dst
, double *num
, int *den
, int64_t *intnum
)
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
;
89 case AV_OPT_TYPE_CONST
: *num
= o
->default_val
.dbl
; return 0;
91 return AVERROR(EINVAL
);
94 static int write_number(void *obj
, const AVOption
*o
, void *dst
, double num
, int den
, int64_t intnum
)
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
);
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
);
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);
127 return AVERROR(EINVAL
);
132 static int hexchar2int(char c
) {
133 if (c
>= '0' && c
<= '9') return c
- '0';
134 if (c
>= 'a' && c
<= 'f') return c
- 'a' + 10;
135 if (c
>= 'A' && c
<= 'F') return c
- 'A' + 10;
139 static int set_string_binary(void *obj
, const AVOption
*o
, const char *val
, uint8_t **dst
)
141 int *lendst
= (int *)(dst
+ 1);
143 int len
= strlen(val
);
149 return AVERROR(EINVAL
);
152 ptr
= bin
= av_malloc(len
);
154 int a
= hexchar2int(*val
++);
155 int b
= hexchar2int(*val
++);
156 if (a
< 0 || b
< 0) {
158 return AVERROR(EINVAL
);
160 *ptr
++ = (a
<< 4) | b
;
168 static int set_string(void *obj
, const AVOption
*o
, const char *val
, uint8_t **dst
)
171 *dst
= av_strdup(val
);
175 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
176 opt->type == AV_OPT_TYPE_CONST || \
177 opt->type == AV_OPT_TYPE_FLAGS || \
178 opt->type == AV_OPT_TYPE_INT) ? \
179 opt->default_val.i64 : opt->default_val.dbl)
181 static int set_string_number(void *obj
, void *target_obj
, const AVOption
*o
, const char *val
, void *dst
)
187 if (sscanf(val
, "%d%*1[:/]%d%c", &num
, &den
, &c
) == 2) {
188 if ((ret
= write_number(obj
, o
, dst
, 1, den
, num
)) >= 0)
200 if (o
->type
== AV_OPT_TYPE_FLAGS
) {
201 if (*val
== '+' || *val
== '-')
203 for (; i
< sizeof(buf
) - 1 && val
[i
] && val
[i
] != '+' && val
[i
] != '-'; i
++)
209 const AVOption
*o_named
= av_opt_find(target_obj
, i
? buf
: val
, o
->unit
, 0, 0);
212 double const_values
[64];
213 const char * const_names
[64];
214 if (o_named
&& o_named
->type
== AV_OPT_TYPE_CONST
)
215 d
= DEFAULT_NUMVAL(o_named
);
218 for (o_named
= NULL
; o_named
= av_opt_next(target_obj
, o_named
); ) {
219 if (o_named
->type
== AV_OPT_TYPE_CONST
&&
221 !strcmp(o_named
->unit
, o
->unit
)) {
222 if (ci
+ 6 >= FF_ARRAY_ELEMS(const_values
)) {
223 av_log(obj
, AV_LOG_ERROR
, "const_values array too small for %s\n", o
->unit
);
224 return AVERROR_PATCHWELCOME
;
226 const_names
[ci
] = o_named
->name
;
227 const_values
[ci
++] = DEFAULT_NUMVAL(o_named
);
231 const_names
[ci
] = "default";
232 const_values
[ci
++] = DEFAULT_NUMVAL(o
);
233 const_names
[ci
] = "max";
234 const_values
[ci
++] = o
->max
;
235 const_names
[ci
] = "min";
236 const_values
[ci
++] = o
->min
;
237 const_names
[ci
] = "none";
238 const_values
[ci
++] = 0;
239 const_names
[ci
] = "all";
240 const_values
[ci
++] = ~0;
241 const_names
[ci
] = NULL
;
242 const_values
[ci
] = 0;
244 res
= av_expr_parse_and_eval(&d
, i
? buf
: val
, const_names
,
245 const_values
, NULL
, NULL
, NULL
, NULL
, NULL
, 0, obj
);
247 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\"\n", val
);
252 if (o
->type
== AV_OPT_TYPE_FLAGS
) {
253 read_number(o
, dst
, NULL
, NULL
, &intnum
);
254 if (cmd
== '+') d
= intnum
| (int64_t)d
;
255 else if (cmd
== '-') d
= intnum
&~(int64_t)d
;
258 if ((ret
= write_number(obj
, o
, dst
, d
, 1, 1)) < 0)
268 static int set_string_image_size(void *obj
, const AVOption
*o
, const char *val
, int *dst
)
272 if (!val
|| !strcmp(val
, "none")) {
277 ret
= av_parse_video_size(dst
, dst
+ 1, val
);
279 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\" as image size\n", val
);
283 static int set_string_video_rate(void *obj
, const AVOption
*o
, const char *val
, AVRational
*dst
)
287 ret
= AVERROR(EINVAL
);
289 ret
= av_parse_video_rate(dst
, val
);
292 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\" as video rate\n", val
);
296 static int set_string_color(void *obj
, const AVOption
*o
, const char *val
, uint8_t *dst
)
303 ret
= av_parse_color(dst
, val
, -1, obj
);
305 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\" as color\n", val
);
311 static int set_string_fmt(void *obj
, const AVOption
*o
, const char *val
, uint8_t *dst
,
312 int fmt_nb
, int ((*get_fmt
)(const char *)), const char *desc
)
316 if (!val
|| !strcmp(val
, "none")) {
322 fmt
= strtol(val
, &tail
, 0);
323 if (*tail
|| (unsigned)fmt
>= fmt_nb
) {
324 av_log(obj
, AV_LOG_ERROR
,
325 "Unable to parse option value \"%s\" as %s\n", val
, desc
);
326 return AVERROR(EINVAL
);
331 min
= FFMAX(o
->min
, -1);
332 max
= FFMIN(o
->max
, fmt_nb
-1);
334 // hack for compatibility with old ffmpeg
335 if(min
== 0 && max
== 0) {
340 if (fmt
< min
|| fmt
> max
) {
341 av_log(obj
, AV_LOG_ERROR
,
342 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
343 fmt
, o
->name
, desc
, min
, max
);
344 return AVERROR(ERANGE
);
351 static int set_string_pixel_fmt(void *obj
, const AVOption
*o
, const char *val
, uint8_t *dst
)
353 return set_string_fmt(obj
, o
, val
, dst
,
354 AV_PIX_FMT_NB
, av_get_pix_fmt
, "pixel format");
357 static int set_string_sample_fmt(void *obj
, const AVOption
*o
, const char *val
, uint8_t *dst
)
359 return set_string_fmt(obj
, o
, val
, dst
,
360 AV_SAMPLE_FMT_NB
, av_get_sample_fmt
, "sample format");
363 #if FF_API_OLD_AVOPTIONS
364 int av_set_string3(void *obj
, const char *name
, const char *val
, int alloc
, const AVOption
**o_out
)
366 const AVOption
*o
= av_opt_find(obj
, name
, NULL
, 0, 0);
369 return av_opt_set(obj
, name
, val
, 0);
373 int av_opt_set(void *obj
, const char *name
, const char *val
, int search_flags
)
376 void *dst
, *target_obj
;
377 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
378 if (!o
|| !target_obj
)
379 return AVERROR_OPTION_NOT_FOUND
;
380 if (!val
&& (o
->type
!= AV_OPT_TYPE_STRING
&&
381 o
->type
!= AV_OPT_TYPE_PIXEL_FMT
&& o
->type
!= AV_OPT_TYPE_SAMPLE_FMT
&&
382 o
->type
!= AV_OPT_TYPE_IMAGE_SIZE
&& o
->type
!= AV_OPT_TYPE_VIDEO_RATE
&&
383 o
->type
!= AV_OPT_TYPE_DURATION
&& o
->type
!= AV_OPT_TYPE_COLOR
&&
384 o
->type
!= AV_OPT_TYPE_CHANNEL_LAYOUT
))
385 return AVERROR(EINVAL
);
387 if (o
->flags
& AV_OPT_FLAG_READONLY
)
388 return AVERROR(EINVAL
);
390 dst
= ((uint8_t*)target_obj
) + o
->offset
;
392 case AV_OPT_TYPE_STRING
: return set_string(obj
, o
, val
, dst
);
393 case AV_OPT_TYPE_BINARY
: return set_string_binary(obj
, o
, val
, dst
);
394 case AV_OPT_TYPE_FLAGS
:
395 case AV_OPT_TYPE_INT
:
396 case AV_OPT_TYPE_INT64
:
397 case AV_OPT_TYPE_FLOAT
:
398 case AV_OPT_TYPE_DOUBLE
:
399 case AV_OPT_TYPE_RATIONAL
: return set_string_number(obj
, target_obj
, o
, val
, dst
);
400 case AV_OPT_TYPE_IMAGE_SIZE
: return set_string_image_size(obj
, o
, val
, dst
);
401 case AV_OPT_TYPE_VIDEO_RATE
: return set_string_video_rate(obj
, o
, val
, dst
);
402 case AV_OPT_TYPE_PIXEL_FMT
: return set_string_pixel_fmt(obj
, o
, val
, dst
);
403 case AV_OPT_TYPE_SAMPLE_FMT
: return set_string_sample_fmt(obj
, o
, val
, dst
);
404 case AV_OPT_TYPE_DURATION
:
409 if ((ret
= av_parse_time(dst
, val
, 1)) < 0)
410 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\" as duration\n", val
);
414 case AV_OPT_TYPE_COLOR
: return set_string_color(obj
, o
, val
, dst
);
415 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
416 if (!val
|| !strcmp(val
, "none")) {
419 #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
420 int64_t cl
= ff_get_channel_layout(val
, 0);
422 int64_t cl
= av_get_channel_layout(val
);
425 av_log(obj
, AV_LOG_ERROR
, "Unable to parse option value \"%s\" as channel layout\n", val
);
426 ret
= AVERROR(EINVAL
);
428 *(int64_t *)dst
= cl
;
434 av_log(obj
, AV_LOG_ERROR
, "Invalid option type.\n");
435 return AVERROR(EINVAL
);
438 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
439 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
441 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)\
442 return AVERROR(EINVAL);\
443 return set_string_number(obj, obj, o, val, name ## _out);\
446 OPT_EVAL_NUMBER(flags
, AV_OPT_TYPE_FLAGS
, int)
447 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT
, int)
448 OPT_EVAL_NUMBER(int64
, AV_OPT_TYPE_INT64
, int64_t)
449 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT
, float)
450 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE
, double)
451 OPT_EVAL_NUMBER(q
, AV_OPT_TYPE_RATIONAL
, AVRational
)
453 static int set_number(void *obj
, const char *name
, double num
, int den
, int64_t intnum
,
456 void *dst
, *target_obj
;
457 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
459 if (!o
|| !target_obj
)
460 return AVERROR_OPTION_NOT_FOUND
;
462 if (o
->flags
& AV_OPT_FLAG_READONLY
)
463 return AVERROR(EINVAL
);
465 dst
= ((uint8_t*)target_obj
) + o
->offset
;
466 return write_number(obj
, o
, dst
, num
, den
, intnum
);
469 #if FF_API_OLD_AVOPTIONS
470 const AVOption
*av_set_double(void *obj
, const char *name
, double n
)
472 const AVOption
*o
= av_opt_find(obj
, name
, NULL
, 0, 0);
473 if (set_number(obj
, name
, n
, 1, 1, 0) < 0)
478 const AVOption
*av_set_q(void *obj
, const char *name
, AVRational n
)
480 const AVOption
*o
= av_opt_find(obj
, name
, NULL
, 0, 0);
481 if (set_number(obj
, name
, n
.num
, n
.den
, 1, 0) < 0)
486 const AVOption
*av_set_int(void *obj
, const char *name
, int64_t n
)
488 const AVOption
*o
= av_opt_find(obj
, name
, NULL
, 0, 0);
489 if (set_number(obj
, name
, 1, 1, n
, 0) < 0)
495 int av_opt_set_int(void *obj
, const char *name
, int64_t val
, int search_flags
)
497 return set_number(obj
, name
, 1, 1, val
, search_flags
);
500 int av_opt_set_double(void *obj
, const char *name
, double val
, int search_flags
)
502 return set_number(obj
, name
, val
, 1, 1, search_flags
);
505 int av_opt_set_q(void *obj
, const char *name
, AVRational val
, int search_flags
)
507 return set_number(obj
, name
, val
.num
, val
.den
, 1, search_flags
);
510 int av_opt_set_bin(void *obj
, const char *name
, const uint8_t *val
, int len
, int search_flags
)
513 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
518 if (!o
|| !target_obj
)
519 return AVERROR_OPTION_NOT_FOUND
;
521 if (o
->type
!= AV_OPT_TYPE_BINARY
|| o
->flags
& AV_OPT_FLAG_READONLY
)
522 return AVERROR(EINVAL
);
524 ptr
= len
? av_malloc(len
) : NULL
;
526 return AVERROR(ENOMEM
);
528 dst
= (uint8_t **)(((uint8_t *)target_obj
) + o
->offset
);
529 lendst
= (int *)(dst
+ 1);
535 memcpy(ptr
, val
, len
);
540 int av_opt_set_image_size(void *obj
, const char *name
, int w
, int h
, int search_flags
)
543 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
545 if (!o
|| !target_obj
)
546 return AVERROR_OPTION_NOT_FOUND
;
547 if (o
->type
!= AV_OPT_TYPE_IMAGE_SIZE
) {
548 av_log(obj
, AV_LOG_ERROR
,
549 "The value set by option '%s' is not an image size.\n", o
->name
);
550 return AVERROR(EINVAL
);
553 av_log(obj
, AV_LOG_ERROR
,
554 "Invalid negative size value %dx%d for size '%s'\n", w
, h
, o
->name
);
555 return AVERROR(EINVAL
);
557 *(int *)(((uint8_t *)target_obj
) + o
->offset
) = w
;
558 *(int *)(((uint8_t *)target_obj
+sizeof(int)) + o
->offset
) = h
;
562 int av_opt_set_video_rate(void *obj
, const char *name
, AVRational val
, int search_flags
)
565 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
567 if (!o
|| !target_obj
)
568 return AVERROR_OPTION_NOT_FOUND
;
569 if (o
->type
!= AV_OPT_TYPE_VIDEO_RATE
) {
570 av_log(obj
, AV_LOG_ERROR
,
571 "The value set by option '%s' is not a video rate.\n", o
->name
);
572 return AVERROR(EINVAL
);
574 if (val
.num
<= 0 || val
.den
<= 0)
575 return AVERROR(EINVAL
);
576 return set_number(obj
, name
, val
.num
, val
.den
, 1, search_flags
);
579 static int set_format(void *obj
, const char *name
, int fmt
, int search_flags
,
580 enum AVOptionType type
, const char *desc
, int nb_fmts
)
583 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0,
584 search_flags
, &target_obj
);
587 if (!o
|| !target_obj
)
588 return AVERROR_OPTION_NOT_FOUND
;
589 if (o
->type
!= type
) {
590 av_log(obj
, AV_LOG_ERROR
,
591 "The value set by option '%s' is not a %s format", name
, desc
);
592 return AVERROR(EINVAL
);
595 min
= FFMAX(o
->min
, -1);
596 max
= FFMIN(o
->max
, nb_fmts
-1);
598 if (fmt
< min
|| fmt
> max
) {
599 av_log(obj
, AV_LOG_ERROR
,
600 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
601 fmt
, name
, desc
, min
, max
);
602 return AVERROR(ERANGE
);
604 *(int *)(((uint8_t *)target_obj
) + o
->offset
) = fmt
;
608 int av_opt_set_pixel_fmt(void *obj
, const char *name
, enum AVPixelFormat fmt
, int search_flags
)
610 return set_format(obj
, name
, fmt
, search_flags
, AV_OPT_TYPE_PIXEL_FMT
, "pixel", AV_PIX_FMT_NB
);
613 int av_opt_set_sample_fmt(void *obj
, const char *name
, enum AVSampleFormat fmt
, int search_flags
)
615 return set_format(obj
, name
, fmt
, search_flags
, AV_OPT_TYPE_SAMPLE_FMT
, "sample", AV_SAMPLE_FMT_NB
);
618 int av_opt_set_channel_layout(void *obj
, const char *name
, int64_t cl
, int search_flags
)
621 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
623 if (!o
|| !target_obj
)
624 return AVERROR_OPTION_NOT_FOUND
;
625 if (o
->type
!= AV_OPT_TYPE_CHANNEL_LAYOUT
) {
626 av_log(obj
, AV_LOG_ERROR
,
627 "The value set by option '%s' is not a channel layout.\n", o
->name
);
628 return AVERROR(EINVAL
);
630 *(int64_t *)(((uint8_t *)target_obj
) + o
->offset
) = cl
;
634 #if FF_API_OLD_AVOPTIONS
637 * @param buf a buffer which is used for returning non string values as strings, can be NULL
638 * @param buf_len allocated length in bytes of buf
640 const char *av_get_string(void *obj
, const char *name
, const AVOption
**o_out
, char *buf
, int buf_len
)
642 const AVOption
*o
= av_opt_find(obj
, name
, NULL
, 0, AV_OPT_SEARCH_CHILDREN
);
648 if (o
->type
!= AV_OPT_TYPE_STRING
&& (!buf
|| !buf_len
))
651 dst
= ((uint8_t*)obj
) + o
->offset
;
652 if (o_out
) *o_out
= o
;
655 case AV_OPT_TYPE_FLAGS
: snprintf(buf
, buf_len
, "0x%08X",*(int *)dst
);break;
656 case AV_OPT_TYPE_INT
: snprintf(buf
, buf_len
, "%d" , *(int *)dst
);break;
657 case AV_OPT_TYPE_INT64
: snprintf(buf
, buf_len
, "%"PRId64
, *(int64_t*)dst
);break;
658 case AV_OPT_TYPE_FLOAT
: snprintf(buf
, buf_len
, "%f" , *(float *)dst
);break;
659 case AV_OPT_TYPE_DOUBLE
: snprintf(buf
, buf_len
, "%f" , *(double *)dst
);break;
660 case AV_OPT_TYPE_RATIONAL
: snprintf(buf
, buf_len
, "%d/%d", ((AVRational
*)dst
)->num
, ((AVRational
*)dst
)->den
);break;
661 case AV_OPT_TYPE_CONST
: snprintf(buf
, buf_len
, "%f" , o
->default_val
.dbl
);break;
662 case AV_OPT_TYPE_STRING
: return *(void**)dst
;
663 case AV_OPT_TYPE_BINARY
:
664 len
= *(int*)(((uint8_t *)dst
) + sizeof(uint8_t *));
665 if (len
>= (buf_len
+ 1)/2) return NULL
;
666 bin
= *(uint8_t**)dst
;
667 for (i
= 0; i
< len
; i
++) snprintf(buf
+ i
*2, 3, "%02X", bin
[i
]);
669 default: return NULL
;
675 int av_opt_set_dict_val(void *obj
, const char *name
, const AVDictionary
*val
, int search_flags
)
679 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
->flags
& AV_OPT_FLAG_READONLY
)
684 return AVERROR(EINVAL
);
686 dst
= (AVDictionary
**)(((uint8_t *)target_obj
) + o
->offset
);
688 av_dict_copy(dst
, val
, 0);
693 int av_opt_get(void *obj
, const char *name
, int search_flags
, uint8_t **out_val
)
695 void *dst
, *target_obj
;
696 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
697 uint8_t *bin
, buf
[128];
701 if (!o
|| !target_obj
|| (o
->offset
<=0 && o
->type
!= AV_OPT_TYPE_CONST
))
702 return AVERROR_OPTION_NOT_FOUND
;
704 dst
= (uint8_t*)target_obj
+ o
->offset
;
708 case AV_OPT_TYPE_FLAGS
: ret
= snprintf(buf
, sizeof(buf
), "0x%08X", *(int *)dst
);break;
709 case AV_OPT_TYPE_INT
: ret
= snprintf(buf
, sizeof(buf
), "%d" , *(int *)dst
);break;
710 case AV_OPT_TYPE_INT64
: ret
= snprintf(buf
, sizeof(buf
), "%"PRId64
, *(int64_t*)dst
);break;
711 case AV_OPT_TYPE_FLOAT
: ret
= snprintf(buf
, sizeof(buf
), "%f" , *(float *)dst
);break;
712 case AV_OPT_TYPE_DOUBLE
: ret
= snprintf(buf
, sizeof(buf
), "%f" , *(double *)dst
);break;
713 case AV_OPT_TYPE_VIDEO_RATE
:
714 case AV_OPT_TYPE_RATIONAL
: ret
= snprintf(buf
, sizeof(buf
), "%d/%d", ((AVRational
*)dst
)->num
, ((AVRational
*)dst
)->den
);break;
715 case AV_OPT_TYPE_CONST
: ret
= snprintf(buf
, sizeof(buf
), "%f" , o
->default_val
.dbl
);break;
716 case AV_OPT_TYPE_STRING
:
718 *out_val
= av_strdup(*(uint8_t**)dst
);
720 *out_val
= av_strdup("");
722 case AV_OPT_TYPE_BINARY
:
723 len
= *(int*)(((uint8_t *)dst
) + sizeof(uint8_t *));
724 if ((uint64_t)len
*2 + 1 > INT_MAX
)
725 return AVERROR(EINVAL
);
726 if (!(*out_val
= av_malloc(len
*2 + 1)))
727 return AVERROR(ENOMEM
);
728 bin
= *(uint8_t**)dst
;
729 for (i
= 0; i
< len
; i
++)
730 snprintf(*out_val
+ i
*2, 3, "%02X", bin
[i
]);
732 case AV_OPT_TYPE_IMAGE_SIZE
:
733 ret
= snprintf(buf
, sizeof(buf
), "%dx%d", ((int *)dst
)[0], ((int *)dst
)[1]);
735 case AV_OPT_TYPE_PIXEL_FMT
:
736 ret
= snprintf(buf
, sizeof(buf
), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat
*)dst
), "none"));
738 case AV_OPT_TYPE_SAMPLE_FMT
:
739 ret
= snprintf(buf
, sizeof(buf
), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat
*)dst
), "none"));
741 case AV_OPT_TYPE_DURATION
:
742 i64
= *(int64_t *)dst
;
743 ret
= snprintf(buf
, sizeof(buf
), "%"PRIi64
"d:%02d:%02d.%06d",
744 i64
/ 3600000000, (int)((i64
/ 60000000) % 60),
745 (int)((i64
/ 1000000) % 60), (int)(i64
% 1000000));
747 case AV_OPT_TYPE_COLOR
:
748 ret
= snprintf(buf
, sizeof(buf
), "0x%02x%02x%02x%02x", ((int *)dst
)[0], ((int *)dst
)[1], ((int *)dst
)[2], ((int *)dst
)[3]);
750 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
751 i64
= *(int64_t *)dst
;
752 ret
= snprintf(buf
, sizeof(buf
), "0x%"PRIx64
, i64
);
755 return AVERROR(EINVAL
);
758 if (ret
>= sizeof(buf
))
759 return AVERROR(EINVAL
);
760 *out_val
= av_strdup(buf
);
764 static int get_number(void *obj
, const char *name
, const AVOption
**o_out
, double *num
, int *den
, int64_t *intnum
,
767 void *dst
, *target_obj
;
768 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
769 if (!o
|| !target_obj
)
772 dst
= ((uint8_t*)target_obj
) + o
->offset
;
774 if (o_out
) *o_out
= o
;
776 return read_number(o
, dst
, num
, den
, intnum
);
783 #if FF_API_OLD_AVOPTIONS
784 double av_get_double(void *obj
, const char *name
, const AVOption
**o_out
)
790 if (get_number(obj
, name
, o_out
, &num
, &den
, &intnum
, 0) < 0)
792 return num
*intnum
/den
;
795 AVRational
av_get_q(void *obj
, const char *name
, const AVOption
**o_out
)
801 if (get_number(obj
, name
, o_out
, &num
, &den
, &intnum
, 0) < 0)
802 return (AVRational
){0, 0};
803 if (num
== 1.0 && (int)intnum
== intnum
)
804 return (AVRational
){intnum
, den
};
806 return av_d2q(num
*intnum
/den
, 1<<24);
809 int64_t av_get_int(void *obj
, const char *name
, const AVOption
**o_out
)
815 if (get_number(obj
, name
, o_out
, &num
, &den
, &intnum
, 0) < 0)
817 return num
*intnum
/den
;
821 int av_opt_get_int(void *obj
, const char *name
, int search_flags
, int64_t *out_val
)
827 if ((ret
= get_number(obj
, name
, NULL
, &num
, &den
, &intnum
, search_flags
)) < 0)
829 *out_val
= num
*intnum
/den
;
833 int av_opt_get_double(void *obj
, const char *name
, int search_flags
, double *out_val
)
839 if ((ret
= get_number(obj
, name
, NULL
, &num
, &den
, &intnum
, search_flags
)) < 0)
841 *out_val
= num
*intnum
/den
;
845 int av_opt_get_q(void *obj
, const char *name
, int search_flags
, AVRational
*out_val
)
851 if ((ret
= get_number(obj
, name
, NULL
, &num
, &den
, &intnum
, search_flags
)) < 0)
854 if (num
== 1.0 && (int)intnum
== intnum
)
855 *out_val
= (AVRational
){intnum
, den
};
857 *out_val
= av_d2q(num
*intnum
/den
, 1<<24);
861 int av_opt_get_image_size(void *obj
, const char *name
, int search_flags
, int *w_out
, int *h_out
)
863 void *dst
, *target_obj
;
864 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
865 if (!o
|| !target_obj
)
866 return AVERROR_OPTION_NOT_FOUND
;
867 if (o
->type
!= AV_OPT_TYPE_IMAGE_SIZE
) {
868 av_log(obj
, AV_LOG_ERROR
,
869 "The value for option '%s' is not an image size.\n", name
);
870 return AVERROR(EINVAL
);
873 dst
= ((uint8_t*)target_obj
) + o
->offset
;
874 if (w_out
) *w_out
= *(int *)dst
;
875 if (h_out
) *h_out
= *((int *)dst
+1);
879 int av_opt_get_video_rate(void *obj
, const char *name
, int search_flags
, AVRational
*out_val
)
885 if ((ret
= get_number(obj
, name
, NULL
, &num
, &den
, &intnum
, search_flags
)) < 0)
888 if (num
== 1.0 && (int)intnum
== intnum
)
889 *out_val
= (AVRational
){intnum
, den
};
891 *out_val
= av_d2q(num
*intnum
/den
, 1<<24);
895 static int get_format(void *obj
, const char *name
, int search_flags
, int *out_fmt
,
896 enum AVOptionType type
, const char *desc
)
898 void *dst
, *target_obj
;
899 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
900 if (!o
|| !target_obj
)
901 return AVERROR_OPTION_NOT_FOUND
;
902 if (o
->type
!= type
) {
903 av_log(obj
, AV_LOG_ERROR
,
904 "The value for option '%s' is not a %s format.\n", desc
, name
);
905 return AVERROR(EINVAL
);
908 dst
= ((uint8_t*)target_obj
) + o
->offset
;
909 *out_fmt
= *(int *)dst
;
913 int av_opt_get_pixel_fmt(void *obj
, const char *name
, int search_flags
, enum AVPixelFormat
*out_fmt
)
915 return get_format(obj
, name
, search_flags
, out_fmt
, AV_OPT_TYPE_PIXEL_FMT
, "pixel");
918 int av_opt_get_sample_fmt(void *obj
, const char *name
, int search_flags
, enum AVSampleFormat
*out_fmt
)
920 return get_format(obj
, name
, search_flags
, out_fmt
, AV_OPT_TYPE_SAMPLE_FMT
, "sample");
923 int av_opt_get_channel_layout(void *obj
, const char *name
, int search_flags
, int64_t *cl
)
925 void *dst
, *target_obj
;
926 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
927 if (!o
|| !target_obj
)
928 return AVERROR_OPTION_NOT_FOUND
;
929 if (o
->type
!= AV_OPT_TYPE_CHANNEL_LAYOUT
) {
930 av_log(obj
, AV_LOG_ERROR
,
931 "The value for option '%s' is not a channel layout.\n", name
);
932 return AVERROR(EINVAL
);
935 dst
= ((uint8_t*)target_obj
) + o
->offset
;
936 *cl
= *(int64_t *)dst
;
940 int av_opt_get_dict_val(void *obj
, const char *name
, int search_flags
, AVDictionary
**out_val
)
944 const AVOption
*o
= av_opt_find2(obj
, name
, NULL
, 0, search_flags
, &target_obj
);
946 if (!o
|| !target_obj
)
947 return AVERROR_OPTION_NOT_FOUND
;
948 if (o
->type
!= AV_OPT_TYPE_DICT
)
949 return AVERROR(EINVAL
);
951 src
= *(AVDictionary
**)(((uint8_t *)target_obj
) + o
->offset
);
952 av_dict_copy(out_val
, src
, 0);
957 int av_opt_flag_is_set(void *obj
, const char *field_name
, const char *flag_name
)
959 const AVOption
*field
= av_opt_find(obj
, field_name
, NULL
, 0, 0);
960 const AVOption
*flag
= av_opt_find(obj
, flag_name
,
961 field
? field
->unit
: NULL
, 0, 0);
964 if (!field
|| !flag
|| flag
->type
!= AV_OPT_TYPE_CONST
||
965 av_opt_get_int(obj
, field_name
, 0, &res
) < 0)
967 return res
& flag
->default_val
.i64
;
970 static void log_value(void *av_log_obj
, int level
, double d
)
973 av_log(av_log_obj
, level
, "INT_MAX");
974 } else if (d
== INT_MIN
) {
975 av_log(av_log_obj
, level
, "INT_MIN");
976 } else if (d
== UINT32_MAX
) {
977 av_log(av_log_obj
, level
, "UINT32_MAX");
978 } else if (d
== (double)INT64_MAX
) {
979 av_log(av_log_obj
, level
, "I64_MAX");
980 } else if (d
== INT64_MIN
) {
981 av_log(av_log_obj
, level
, "I64_MIN");
982 } else if (d
== FLT_MAX
) {
983 av_log(av_log_obj
, level
, "FLT_MAX");
984 } else if (d
== FLT_MIN
) {
985 av_log(av_log_obj
, level
, "FLT_MIN");
986 } else if (d
== -FLT_MAX
) {
987 av_log(av_log_obj
, level
, "-FLT_MAX");
988 } else if (d
== -FLT_MIN
) {
989 av_log(av_log_obj
, level
, "-FLT_MIN");
990 } else if (d
== DBL_MAX
) {
991 av_log(av_log_obj
, level
, "DBL_MAX");
992 } else if (d
== DBL_MIN
) {
993 av_log(av_log_obj
, level
, "DBL_MIN");
994 } else if (d
== -DBL_MAX
) {
995 av_log(av_log_obj
, level
, "-DBL_MAX");
996 } else if (d
== -DBL_MIN
) {
997 av_log(av_log_obj
, level
, "-DBL_MIN");
999 av_log(av_log_obj
, level
, "%g", d
);
1003 static void opt_list(void *obj
, void *av_log_obj
, const char *unit
,
1004 int req_flags
, int rej_flags
)
1006 const AVOption
*opt
=NULL
;
1010 while ((opt
= av_opt_next(obj
, opt
))) {
1011 if (!(opt
->flags
& req_flags
) || (opt
->flags
& rej_flags
))
1014 /* Don't print CONST's on level one.
1015 * Don't print anything but CONST's on level two.
1016 * Only print items from the requested unit.
1018 if (!unit
&& opt
->type
==AV_OPT_TYPE_CONST
)
1020 else if (unit
&& opt
->type
!=AV_OPT_TYPE_CONST
)
1022 else if (unit
&& opt
->type
==AV_OPT_TYPE_CONST
&& strcmp(unit
, opt
->unit
))
1024 else if (unit
&& opt
->type
== AV_OPT_TYPE_CONST
)
1025 av_log(av_log_obj
, AV_LOG_INFO
, " %-15s ", opt
->name
);
1027 av_log(av_log_obj
, AV_LOG_INFO
, " %s%-17s ",
1028 (opt
->flags
& AV_OPT_FLAG_FILTERING_PARAM
) ? "" : "-",
1031 switch (opt
->type
) {
1032 case AV_OPT_TYPE_FLAGS
:
1033 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<flags>");
1035 case AV_OPT_TYPE_INT
:
1036 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<int>");
1038 case AV_OPT_TYPE_INT64
:
1039 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<int64>");
1041 case AV_OPT_TYPE_DOUBLE
:
1042 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<double>");
1044 case AV_OPT_TYPE_FLOAT
:
1045 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<float>");
1047 case AV_OPT_TYPE_STRING
:
1048 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<string>");
1050 case AV_OPT_TYPE_RATIONAL
:
1051 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<rational>");
1053 case AV_OPT_TYPE_BINARY
:
1054 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<binary>");
1056 case AV_OPT_TYPE_IMAGE_SIZE
:
1057 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<image_size>");
1059 case AV_OPT_TYPE_VIDEO_RATE
:
1060 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<video_rate>");
1062 case AV_OPT_TYPE_PIXEL_FMT
:
1063 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<pix_fmt>");
1065 case AV_OPT_TYPE_SAMPLE_FMT
:
1066 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<sample_fmt>");
1068 case AV_OPT_TYPE_DURATION
:
1069 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<duration>");
1071 case AV_OPT_TYPE_COLOR
:
1072 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<color>");
1074 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
1075 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "<channel_layout>");
1077 case AV_OPT_TYPE_CONST
:
1079 av_log(av_log_obj
, AV_LOG_INFO
, "%-12s ", "");
1082 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_ENCODING_PARAM
) ? 'E' : '.');
1083 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_DECODING_PARAM
) ? 'D' : '.');
1084 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_FILTERING_PARAM
)? 'F' : '.');
1085 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_VIDEO_PARAM
) ? 'V' : '.');
1086 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_AUDIO_PARAM
) ? 'A' : '.');
1087 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_SUBTITLE_PARAM
) ? 'S' : '.');
1088 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_EXPORT
) ? 'X' : '.');
1089 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_READONLY
) ? 'R' : '.');
1092 av_log(av_log_obj
, AV_LOG_INFO
, " %s", opt
->help
);
1094 if (av_opt_query_ranges(&r
, obj
, opt
->name
, AV_OPT_SEARCH_FAKE_OBJ
) >= 0) {
1095 switch (opt
->type
) {
1096 case AV_OPT_TYPE_INT
:
1097 case AV_OPT_TYPE_INT64
:
1098 case AV_OPT_TYPE_DOUBLE
:
1099 case AV_OPT_TYPE_FLOAT
:
1100 case AV_OPT_TYPE_RATIONAL
:
1101 for (i
= 0; i
< r
->nb_ranges
; i
++) {
1102 av_log(av_log_obj
, AV_LOG_INFO
, " (from ");
1103 log_value(av_log_obj
, AV_LOG_INFO
, r
->range
[i
]->value_min
);
1104 av_log(av_log_obj
, AV_LOG_INFO
, " to ");
1105 log_value(av_log_obj
, AV_LOG_INFO
, r
->range
[i
]->value_max
);
1106 av_log(av_log_obj
, AV_LOG_INFO
, ")");
1110 av_opt_freep_ranges(&r
);
1113 if (opt
->type
!= AV_OPT_TYPE_CONST
&&
1114 opt
->type
!= AV_OPT_TYPE_BINARY
&&
1115 !((opt
->type
== AV_OPT_TYPE_COLOR
||
1116 opt
->type
== AV_OPT_TYPE_IMAGE_SIZE
||
1117 opt
->type
== AV_OPT_TYPE_STRING
||
1118 opt
->type
== AV_OPT_TYPE_VIDEO_RATE
) &&
1119 !opt
->default_val
.str
)) {
1120 av_log(av_log_obj
, AV_LOG_INFO
, " (default ");
1121 switch (opt
->type
) {
1122 case AV_OPT_TYPE_FLAGS
:
1123 av_log(av_log_obj
, AV_LOG_INFO
, "%"PRIX64
, opt
->default_val
.i64
);
1125 case AV_OPT_TYPE_DURATION
:
1126 case AV_OPT_TYPE_INT
:
1127 case AV_OPT_TYPE_INT64
:
1128 log_value(av_log_obj
, AV_LOG_INFO
, opt
->default_val
.i64
);
1130 case AV_OPT_TYPE_DOUBLE
:
1131 case AV_OPT_TYPE_FLOAT
:
1132 log_value(av_log_obj
, AV_LOG_INFO
, opt
->default_val
.dbl
);
1134 case AV_OPT_TYPE_RATIONAL
: {
1135 AVRational q
= av_d2q(opt
->default_val
.dbl
, INT_MAX
);
1136 av_log(av_log_obj
, AV_LOG_INFO
, "%d/%d", q
.num
, q
.den
); }
1138 case AV_OPT_TYPE_PIXEL_FMT
:
1139 av_log(av_log_obj
, AV_LOG_INFO
, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt
->default_val
.i64
), "none"));
1141 case AV_OPT_TYPE_SAMPLE_FMT
:
1142 av_log(av_log_obj
, AV_LOG_INFO
, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt
->default_val
.i64
), "none"));
1144 case AV_OPT_TYPE_COLOR
:
1145 case AV_OPT_TYPE_IMAGE_SIZE
:
1146 case AV_OPT_TYPE_STRING
:
1147 case AV_OPT_TYPE_VIDEO_RATE
:
1148 av_log(av_log_obj
, AV_LOG_INFO
, "\"%s\"", opt
->default_val
.str
);
1150 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
1151 av_log(av_log_obj
, AV_LOG_INFO
, "0x%"PRIx64
, opt
->default_val
.i64
);
1154 av_log(av_log_obj
, AV_LOG_INFO
, ")");
1157 av_log(av_log_obj
, AV_LOG_INFO
, "\n");
1158 if (opt
->unit
&& opt
->type
!= AV_OPT_TYPE_CONST
) {
1159 opt_list(obj
, av_log_obj
, opt
->unit
, req_flags
, rej_flags
);
1164 int av_opt_show2(void *obj
, void *av_log_obj
, int req_flags
, int rej_flags
)
1169 av_log(av_log_obj
, AV_LOG_INFO
, "%s AVOptions:\n", (*(AVClass
**)obj
)->class_name
);
1171 opt_list(obj
, av_log_obj
, NULL
, req_flags
, rej_flags
);
1176 void av_opt_set_defaults(void *s
)
1178 #if FF_API_OLD_AVOPTIONS
1179 av_opt_set_defaults2(s
, 0, 0);
1182 void av_opt_set_defaults2(void *s
, int mask
, int flags
)
1185 const AVOption
*opt
= NULL
;
1186 while ((opt
= av_opt_next(s
, opt
))) {
1187 void *dst
= ((uint8_t*)s
) + opt
->offset
;
1188 #if FF_API_OLD_AVOPTIONS
1189 if ((opt
->flags
& mask
) != flags
)
1193 if (opt
->flags
& AV_OPT_FLAG_READONLY
)
1196 switch (opt
->type
) {
1197 case AV_OPT_TYPE_CONST
:
1198 /* Nothing to be done here */
1200 case AV_OPT_TYPE_FLAGS
:
1201 case AV_OPT_TYPE_INT
:
1202 case AV_OPT_TYPE_INT64
:
1203 case AV_OPT_TYPE_DURATION
:
1204 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
1205 write_number(s
, opt
, dst
, 1, 1, opt
->default_val
.i64
);
1207 case AV_OPT_TYPE_DOUBLE
:
1208 case AV_OPT_TYPE_FLOAT
: {
1210 val
= opt
->default_val
.dbl
;
1211 write_number(s
, opt
, dst
, val
, 1, 1);
1214 case AV_OPT_TYPE_RATIONAL
: {
1216 val
= av_d2q(opt
->default_val
.dbl
, INT_MAX
);
1217 write_number(s
, opt
, dst
, 1, val
.den
, val
.num
);
1220 case AV_OPT_TYPE_COLOR
:
1221 set_string_color(s
, opt
, opt
->default_val
.str
, dst
);
1223 case AV_OPT_TYPE_STRING
:
1224 set_string(s
, opt
, opt
->default_val
.str
, dst
);
1226 case AV_OPT_TYPE_IMAGE_SIZE
:
1227 set_string_image_size(s
, opt
, opt
->default_val
.str
, dst
);
1229 case AV_OPT_TYPE_VIDEO_RATE
:
1230 set_string_video_rate(s
, opt
, opt
->default_val
.str
, dst
);
1232 case AV_OPT_TYPE_PIXEL_FMT
:
1233 write_number(s
, opt
, dst
, 1, 1, opt
->default_val
.i64
);
1235 case AV_OPT_TYPE_SAMPLE_FMT
:
1236 write_number(s
, opt
, dst
, 1, 1, opt
->default_val
.i64
);
1238 case AV_OPT_TYPE_BINARY
:
1239 case AV_OPT_TYPE_DICT
:
1240 /* Cannot set defaults for these types */
1243 av_log(s
, AV_LOG_DEBUG
, "AVOption type %d of option %s not implemented yet\n", opt
->type
, opt
->name
);
1249 * Store the value in the field in ctx that is named like key.
1250 * ctx must be an AVClass context, storing is done using AVOptions.
1252 * @param buf the string to parse, buf will be updated to point at the
1253 * separator just after the parsed key/value pair
1254 * @param key_val_sep a 0-terminated list of characters used to
1255 * separate key from value
1256 * @param pairs_sep a 0-terminated list of characters used to separate
1257 * two pairs from each other
1258 * @return 0 if the key/value pair has been successfully parsed and
1259 * set, or a negative value corresponding to an AVERROR code in case
1261 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1262 * the error code issued by av_opt_set() if the key/value pair
1265 static int parse_key_value_pair(void *ctx
, const char **buf
,
1266 const char *key_val_sep
, const char *pairs_sep
)
1268 char *key
= av_get_token(buf
, key_val_sep
);
1273 return AVERROR(ENOMEM
);
1275 if (*key
&& strspn(*buf
, key_val_sep
)) {
1277 val
= av_get_token(buf
, pairs_sep
);
1280 return AVERROR(ENOMEM
);
1283 av_log(ctx
, AV_LOG_ERROR
, "Missing key or no key/value separator found after key '%s'\n", key
);
1285 return AVERROR(EINVAL
);
1288 av_log(ctx
, AV_LOG_DEBUG
, "Setting entry with key '%s' to value '%s'\n", key
, val
);
1290 ret
= av_opt_set(ctx
, key
, val
, AV_OPT_SEARCH_CHILDREN
);
1291 if (ret
== AVERROR_OPTION_NOT_FOUND
)
1292 av_log(ctx
, AV_LOG_ERROR
, "Key '%s' not found.\n", key
);
1299 int av_set_options_string(void *ctx
, const char *opts
,
1300 const char *key_val_sep
, const char *pairs_sep
)
1308 if ((ret
= parse_key_value_pair(ctx
, &opts
, key_val_sep
, pairs_sep
)) < 0)
1319 #define WHITESPACES " \n\t"
1321 static int is_key_char(char c
)
1323 return (unsigned)((c
| 32) - 'a') < 26 ||
1324 (unsigned)(c
- '0') < 10 ||
1325 c
== '-' || c
== '_' || c
== '/' || c
== '.';
1329 * Read a key from a string.
1331 * The key consists of is_key_char characters and must be terminated by a
1332 * character from the delim string; spaces are ignored.
1334 * @return 0 for success (even with ellipsis), <0 for failure
1336 static int get_key(const char **ropts
, const char *delim
, char **rkey
)
1338 const char *opts
= *ropts
;
1339 const char *key_start
, *key_end
;
1341 key_start
= opts
+= strspn(opts
, WHITESPACES
);
1342 while (is_key_char(*opts
))
1345 opts
+= strspn(opts
, WHITESPACES
);
1346 if (!*opts
|| !strchr(delim
, *opts
))
1347 return AVERROR(EINVAL
);
1349 if (!(*rkey
= av_malloc(key_end
- key_start
+ 1)))
1350 return AVERROR(ENOMEM
);
1351 memcpy(*rkey
, key_start
, key_end
- key_start
);
1352 (*rkey
)[key_end
- key_start
] = 0;
1357 int av_opt_get_key_value(const char **ropts
,
1358 const char *key_val_sep
, const char *pairs_sep
,
1360 char **rkey
, char **rval
)
1363 char *key
= NULL
, *val
;
1364 const char *opts
= *ropts
;
1366 if ((ret
= get_key(&opts
, key_val_sep
, &key
)) < 0 &&
1367 !(flags
& AV_OPT_FLAG_IMPLICIT_KEY
))
1368 return AVERROR(EINVAL
);
1369 if (!(val
= av_get_token(&opts
, pairs_sep
))) {
1371 return AVERROR(ENOMEM
);
1379 int av_opt_set_from_string(void *ctx
, const char *opts
,
1380 const char *const *shorthand
,
1381 const char *key_val_sep
, const char *pairs_sep
)
1384 const char *dummy_shorthand
= NULL
;
1385 char *av_uninit(parsed_key
), *av_uninit(value
);
1391 shorthand
= &dummy_shorthand
;
1394 ret
= av_opt_get_key_value(&opts
, key_val_sep
, pairs_sep
,
1395 *shorthand
? AV_OPT_FLAG_IMPLICIT_KEY
: 0,
1396 &parsed_key
, &value
);
1398 if (ret
== AVERROR(EINVAL
))
1399 av_log(ctx
, AV_LOG_ERROR
, "No option name near '%s'\n", opts
);
1401 av_log(ctx
, AV_LOG_ERROR
, "Unable to parse '%s': %s\n", opts
,
1409 while (*shorthand
) /* discard all remaining shorthand */
1412 key
= *(shorthand
++);
1415 av_log(ctx
, AV_LOG_DEBUG
, "Setting '%s' to value '%s'\n", key
, value
);
1416 if ((ret
= av_opt_set(ctx
, key
, value
, 0)) < 0) {
1417 if (ret
== AVERROR_OPTION_NOT_FOUND
)
1418 av_log(ctx
, AV_LOG_ERROR
, "Option '%s' not found\n", key
);
1420 av_free(parsed_key
);
1425 av_free(parsed_key
);
1431 void av_opt_free(void *obj
)
1433 const AVOption
*o
= NULL
;
1434 while ((o
= av_opt_next(obj
, o
))) {
1436 case AV_OPT_TYPE_STRING
:
1437 case AV_OPT_TYPE_BINARY
:
1438 av_freep((uint8_t *)obj
+ o
->offset
);
1441 case AV_OPT_TYPE_DICT
:
1442 av_dict_free((AVDictionary
**)(((uint8_t *)obj
) + o
->offset
));
1451 int av_opt_set_dict2(void *obj
, AVDictionary
**options
, int search_flags
)
1453 AVDictionaryEntry
*t
= NULL
;
1454 AVDictionary
*tmp
= NULL
;
1460 while ((t
= av_dict_get(*options
, "", t
, AV_DICT_IGNORE_SUFFIX
))) {
1461 ret
= av_opt_set(obj
, t
->key
, t
->value
, search_flags
);
1462 if (ret
== AVERROR_OPTION_NOT_FOUND
)
1463 av_dict_set(&tmp
, t
->key
, t
->value
, 0);
1465 av_log(obj
, AV_LOG_ERROR
, "Error setting option %s to value %s.\n", t
->key
, t
->value
);
1470 av_dict_free(options
);
1475 int av_opt_set_dict(void *obj
, AVDictionary
**options
)
1477 return av_opt_set_dict2(obj
, options
, 0);
1480 const AVOption
*av_opt_find(void *obj
, const char *name
, const char *unit
,
1481 int opt_flags
, int search_flags
)
1483 return av_opt_find2(obj
, name
, unit
, opt_flags
, search_flags
, NULL
);
1486 const AVOption
*av_opt_find2(void *obj
, const char *name
, const char *unit
,
1487 int opt_flags
, int search_flags
, void **target_obj
)
1490 const AVOption
*o
= NULL
;
1500 if (search_flags
& AV_OPT_SEARCH_CHILDREN
) {
1501 if (search_flags
& AV_OPT_SEARCH_FAKE_OBJ
) {
1502 const AVClass
*child
= NULL
;
1503 while (child
= av_opt_child_class_next(c
, child
))
1504 if (o
= av_opt_find2(&child
, name
, unit
, opt_flags
, search_flags
, NULL
))
1508 while (child
= av_opt_child_next(obj
, child
))
1509 if (o
= av_opt_find2(child
, name
, unit
, opt_flags
, search_flags
, target_obj
))
1514 while (o
= av_opt_next(obj
, o
)) {
1515 if (!strcmp(o
->name
, name
) && (o
->flags
& opt_flags
) == opt_flags
&&
1516 ((!unit
&& o
->type
!= AV_OPT_TYPE_CONST
) ||
1517 (unit
&& o
->type
== AV_OPT_TYPE_CONST
&& o
->unit
&& !strcmp(o
->unit
, unit
)))) {
1519 if (!(search_flags
& AV_OPT_SEARCH_FAKE_OBJ
))
1530 void *av_opt_child_next(void *obj
, void *prev
)
1532 const AVClass
*c
= *(AVClass
**)obj
;
1534 return c
->child_next(obj
, prev
);
1538 const AVClass
*av_opt_child_class_next(const AVClass
*parent
, const AVClass
*prev
)
1540 if (parent
->child_class_next
)
1541 return parent
->child_class_next(prev
);
1545 void *av_opt_ptr(const AVClass
*class, void *obj
, const char *name
)
1547 const AVOption
*opt
= av_opt_find2(&class, name
, NULL
, 0, AV_OPT_SEARCH_FAKE_OBJ
, NULL
);
1550 return (uint8_t*)obj
+ opt
->offset
;
1553 static int opt_size(enum AVOptionType type
)
1556 case AV_OPT_TYPE_INT
:
1557 case AV_OPT_TYPE_FLAGS
: return sizeof(int);
1558 case AV_OPT_TYPE_DURATION
:
1559 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
1560 case AV_OPT_TYPE_INT64
: return sizeof(int64_t);
1561 case AV_OPT_TYPE_DOUBLE
: return sizeof(double);
1562 case AV_OPT_TYPE_FLOAT
: return sizeof(float);
1563 case AV_OPT_TYPE_STRING
: return sizeof(uint8_t*);
1564 case AV_OPT_TYPE_VIDEO_RATE
:
1565 case AV_OPT_TYPE_RATIONAL
: return sizeof(AVRational
);
1566 case AV_OPT_TYPE_BINARY
: return sizeof(uint8_t*) + sizeof(int);
1567 case AV_OPT_TYPE_IMAGE_SIZE
:return sizeof(int[2]);
1568 case AV_OPT_TYPE_PIXEL_FMT
: return sizeof(enum AVPixelFormat
);
1569 case AV_OPT_TYPE_SAMPLE_FMT
:return sizeof(enum AVSampleFormat
);
1570 case AV_OPT_TYPE_COLOR
: return 4;
1575 int av_opt_copy(void *dst
, void *src
)
1577 const AVOption
*o
= NULL
;
1584 c
= *(AVClass
**)src
;
1585 if (*(AVClass
**)dst
&& c
!= *(AVClass
**)dst
)
1586 return AVERROR(EINVAL
);
1588 while ((o
= av_opt_next(src
, o
))) {
1589 void *field_dst
= ((uint8_t*)dst
) + o
->offset
;
1590 void *field_src
= ((uint8_t*)src
) + o
->offset
;
1591 uint8_t **field_dst8
= (uint8_t**)field_dst
;
1592 uint8_t **field_src8
= (uint8_t**)field_src
;
1594 if (o
->type
== AV_OPT_TYPE_STRING
) {
1595 if (*field_dst8
!= *field_src8
)
1596 av_freep(field_dst8
);
1597 *field_dst8
= av_strdup(*field_src8
);
1598 if (*field_src8
&& !*field_dst8
)
1599 ret
= AVERROR(ENOMEM
);
1600 } else if (o
->type
== AV_OPT_TYPE_BINARY
) {
1601 int len
= *(int*)(field_src8
+ 1);
1602 if (*field_dst8
!= *field_src8
)
1603 av_freep(field_dst8
);
1604 *field_dst8
= av_memdup(*field_src8
, len
);
1605 if (len
&& !*field_dst8
) {
1606 ret
= AVERROR(ENOMEM
);
1609 *(int*)(field_dst8
+ 1) = len
;
1610 } else if (o
->type
== AV_OPT_TYPE_CONST
) {
1613 memcpy(field_dst
, field_src
, opt_size(o
->type
));
1619 int av_opt_query_ranges(AVOptionRanges
**ranges_arg
, void *obj
, const char *key
, int flags
)
1622 const AVClass
*c
= *(AVClass
**)obj
;
1623 int (*callback
)(AVOptionRanges
**, void *obj
, const char *key
, int flags
) = NULL
;
1625 if (c
->version
> (52 << 16 | 11 << 8))
1626 callback
= c
->query_ranges
;
1629 callback
= av_opt_query_ranges_default
;
1631 ret
= callback(ranges_arg
, obj
, key
, flags
);
1633 if (!(flags
& AV_OPT_MULTI_COMPONENT_RANGE
))
1635 (*ranges_arg
)->nb_components
= ret
;
1640 int av_opt_query_ranges_default(AVOptionRanges
**ranges_arg
, void *obj
, const char *key
, int flags
)
1642 AVOptionRanges
*ranges
= av_mallocz(sizeof(*ranges
));
1643 AVOptionRange
**range_array
= av_mallocz(sizeof(void*));
1644 AVOptionRange
*range
= av_mallocz(sizeof(*range
));
1645 const AVOption
*field
= av_opt_find(obj
, key
, NULL
, 0, flags
);
1650 if (!ranges
|| !range
|| !range_array
|| !field
) {
1651 ret
= AVERROR(ENOMEM
);
1655 ranges
->range
= range_array
;
1656 ranges
->range
[0] = range
;
1657 ranges
->nb_ranges
= 1;
1658 ranges
->nb_components
= 1;
1659 range
->is_range
= 1;
1660 range
->value_min
= field
->min
;
1661 range
->value_max
= field
->max
;
1663 switch (field
->type
) {
1664 case AV_OPT_TYPE_INT
:
1665 case AV_OPT_TYPE_INT64
:
1666 case AV_OPT_TYPE_PIXEL_FMT
:
1667 case AV_OPT_TYPE_SAMPLE_FMT
:
1668 case AV_OPT_TYPE_FLOAT
:
1669 case AV_OPT_TYPE_DOUBLE
:
1670 case AV_OPT_TYPE_DURATION
:
1671 case AV_OPT_TYPE_COLOR
:
1672 case AV_OPT_TYPE_CHANNEL_LAYOUT
:
1674 case AV_OPT_TYPE_STRING
:
1675 range
->component_min
= 0;
1676 range
->component_max
= 0x10FFFF; // max unicode value
1677 range
->value_min
= -1;
1678 range
->value_max
= INT_MAX
;
1680 case AV_OPT_TYPE_RATIONAL
:
1681 range
->component_min
= INT_MIN
;
1682 range
->component_max
= INT_MAX
;
1684 case AV_OPT_TYPE_IMAGE_SIZE
:
1685 range
->component_min
= 0;
1686 range
->component_max
= INT_MAX
/128/8;
1687 range
->value_min
= 0;
1688 range
->value_max
= INT_MAX
/8;
1690 case AV_OPT_TYPE_VIDEO_RATE
:
1691 range
->component_min
= 1;
1692 range
->component_max
= INT_MAX
;
1693 range
->value_min
= 1;
1694 range
->value_max
= INT_MAX
;
1697 ret
= AVERROR(ENOSYS
);
1701 *ranges_arg
= ranges
;
1706 av_free(range_array
);
1710 void av_opt_freep_ranges(AVOptionRanges
**rangesp
)
1713 AVOptionRanges
*ranges
= *rangesp
;
1718 for (i
= 0; i
< ranges
->nb_ranges
* ranges
->nb_components
; i
++) {
1719 AVOptionRange
*range
= ranges
->range
[i
];
1721 av_freep(&range
->str
);
1722 av_freep(&ranges
->range
[i
]);
1725 av_freep(&ranges
->range
);
1731 typedef struct TestContext
1733 const AVClass
*class;
1738 AVRational rational
;
1739 AVRational video_rate
;
1741 enum AVPixelFormat pix_fmt
;
1742 enum AVSampleFormat sample_fmt
;
1745 int64_t channel_layout
;
1748 #define OFFSET(x) offsetof(TestContext, x)
1750 #define TEST_FLAG_COOL 01
1751 #define TEST_FLAG_LAME 02
1752 #define TEST_FLAG_MU 04
1754 static const AVOption test_options
[]= {
1755 {"num", "set num", OFFSET(num
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 100 },
1756 {"toggle", "set toggle", OFFSET(toggle
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 1 },
1757 {"rational", "set rational", OFFSET(rational
), AV_OPT_TYPE_RATIONAL
, {.dbl
= 0}, 0, 10 },
1758 {"string", "set string", OFFSET(string
), AV_OPT_TYPE_STRING
, {.str
= "default"}, CHAR_MIN
, CHAR_MAX
},
1759 {"flags", "set flags", OFFSET(flags
), AV_OPT_TYPE_FLAGS
, {.i64
= 0}, 0, INT_MAX
, 0, "flags" },
1760 {"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST
, {.i64
= TEST_FLAG_COOL
}, INT_MIN
, INT_MAX
, 0, "flags" },
1761 {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST
, {.i64
= TEST_FLAG_LAME
}, INT_MIN
, INT_MAX
, 0, "flags" },
1762 {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST
, {.i64
= TEST_FLAG_MU
}, INT_MIN
, INT_MAX
, 0, "flags" },
1763 {"size", "set size", OFFSET(w
), AV_OPT_TYPE_IMAGE_SIZE
,{0}, 0, 0 },
1764 {"pix_fmt", "set pixfmt", OFFSET(pix_fmt
), AV_OPT_TYPE_PIXEL_FMT
, {.i64
= AV_PIX_FMT_NONE
}, -1, INT_MAX
},
1765 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt
), AV_OPT_TYPE_SAMPLE_FMT
, {.i64
= AV_SAMPLE_FMT_NONE
}, -1, INT_MAX
},
1766 {"video_rate", "set videorate", OFFSET(video_rate
), AV_OPT_TYPE_VIDEO_RATE
, {.str
= "25"}, 0, 0 },
1767 {"duration", "set duration", OFFSET(duration
), AV_OPT_TYPE_DURATION
, {.i64
= 0}, 0, INT64_MAX
},
1768 {"color", "set color", OFFSET(color
), AV_OPT_TYPE_COLOR
, {.str
= "pink"}, 0, 0},
1769 {"cl", "set channel layout", OFFSET(channel_layout
), AV_OPT_TYPE_CHANNEL_LAYOUT
, {.i64
= AV_CH_LAYOUT_HEXAGONAL
}, 0, INT64_MAX
},
1773 static const char *test_get_name(void *ctx
)
1778 static const AVClass test_class
= {
1788 printf("\nTesting av_set_options_string()\n");
1790 TestContext test_ctx
= { 0 };
1791 static const char * const options
[] = {
1807 "flags=+mu-lame : num=42: toggle=0",
1808 "num=42 : string=blahblah",
1809 "rational=0 : rational=1/2 : rational=1/-1",
1822 "video_rate=30000/1001",
1823 "video_rate=30/1.001",
1827 "duration=1\\:23\\:45.67",
1831 "cl=stereo+downmix",
1835 test_ctx
.class = &test_class
;
1836 av_opt_set_defaults(&test_ctx
);
1838 av_log_set_level(AV_LOG_DEBUG
);
1840 for (i
=0; i
< FF_ARRAY_ELEMS(options
); i
++) {
1841 av_log(&test_ctx
, AV_LOG_DEBUG
, "Setting options string '%s'\n", options
[i
]);
1842 if (av_set_options_string(&test_ctx
, options
[i
], "=", ":") < 0)
1843 av_log(&test_ctx
, AV_LOG_ERROR
, "Error setting options string: '%s'\n", options
[i
]);
1846 av_opt_free(&test_ctx
);
1849 printf("\nTesting av_opt_set_from_string()\n");
1851 TestContext test_ctx
= { 0 };
1852 static const char * const options
[] = {
1860 " 5 : hello : size = pal ",
1861 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
1863 static const char * const shorthand
[] = { "num", "string", NULL
};
1865 test_ctx
.class = &test_class
;
1866 av_opt_set_defaults(&test_ctx
);
1868 av_log_set_level(AV_LOG_DEBUG
);
1870 for (i
=0; i
< FF_ARRAY_ELEMS(options
); i
++) {
1871 av_log(&test_ctx
, AV_LOG_DEBUG
, "Setting options string '%s'\n", options
[i
]);
1872 if (av_opt_set_from_string(&test_ctx
, options
[i
], shorthand
, "=", ":") < 0)
1873 av_log(&test_ctx
, AV_LOG_ERROR
, "Error setting options string: '%s'\n", options
[i
]);
1876 av_opt_free(&test_ctx
);