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 #if FF_API_OLD_AVOPTIONS
45 const AVOption *av_next_option(FF_CONST_AVUTIL55 void *obj, const AVOption *last)
47 return av_opt_next(obj, last);
51 const AVOption *av_opt_next(FF_CONST_AVUTIL55 void *obj, const AVOption *last)
56 class = *(const AVClass**)obj;
57 if (!last && class && class->option && class->option[0].name)
59 if (last && last[1].name)
64 static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
67 case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
68 case AV_OPT_TYPE_PIXEL_FMT: *intnum = *(enum AVPixelFormat *)dst;return 0;
69 case AV_OPT_TYPE_SAMPLE_FMT:*intnum = *(enum AVSampleFormat*)dst;return 0;
70 case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
71 case AV_OPT_TYPE_CHANNEL_LAYOUT:
72 case AV_OPT_TYPE_DURATION:
73 case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
74 case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
75 case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
76 case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
77 *den = ((AVRational*)dst)->den;
79 case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0;
81 return AVERROR(EINVAL);
84 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
86 if (o->type != AV_OPT_TYPE_FLAGS &&
87 (o->max * den < num * intnum || o->min * den > num * intnum)) {
88 num = den ? num*intnum/den : (num*intnum ? INFINITY : NAN);
89 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
90 num, o->name, o->min, o->max);
91 return AVERROR(ERANGE);
93 if (o->type == AV_OPT_TYPE_FLAGS) {
94 double d = num*intnum/den;
95 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
96 av_log(obj, AV_LOG_ERROR,
97 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
98 num*intnum/den, o->name);
99 return AVERROR(ERANGE);
104 case AV_OPT_TYPE_PIXEL_FMT: *(enum AVPixelFormat *)dst = llrint(num/den) * intnum; break;
105 case AV_OPT_TYPE_SAMPLE_FMT:*(enum AVSampleFormat*)dst = llrint(num/den) * intnum; break;
106 case AV_OPT_TYPE_FLAGS:
107 case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
108 case AV_OPT_TYPE_DURATION:
109 case AV_OPT_TYPE_CHANNEL_LAYOUT:
110 case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
111 case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
112 case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
113 case AV_OPT_TYPE_RATIONAL:
114 if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
115 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
118 return AVERROR(EINVAL);
123 static int hexchar2int(char c) {
124 if (c >= '0' && c <= '9') return c - '0';
125 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
126 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
130 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
132 int *lendst = (int *)(dst + 1);
139 if (!val || !(len = strlen(val)))
143 return AVERROR(EINVAL);
146 ptr = bin = av_malloc(len);
148 return AVERROR(ENOMEM);
150 int a = hexchar2int(*val++);
151 int b = hexchar2int(*val++);
152 if (a < 0 || b < 0) {
154 return AVERROR(EINVAL);
156 *ptr++ = (a << 4) | b;
164 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
167 *dst = av_strdup(val);
168 return *dst ? 0 : AVERROR(ENOMEM);
171 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
172 opt->type == AV_OPT_TYPE_CONST || \
173 opt->type == AV_OPT_TYPE_FLAGS || \
174 opt->type == AV_OPT_TYPE_INT) ? \
175 opt->default_val.i64 : opt->default_val.dbl)
177 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
183 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
184 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
196 if (o->type == AV_OPT_TYPE_FLAGS) {
197 if (*val == '+' || *val == '-')
199 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
205 const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, 0);
208 double const_values[64];
209 const char * const_names[64];
210 if (o_named && o_named->type == AV_OPT_TYPE_CONST)
211 d = DEFAULT_NUMVAL(o_named);
214 for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
215 if (o_named->type == AV_OPT_TYPE_CONST &&
217 !strcmp(o_named->unit, o->unit)) {
218 if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
219 av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
220 return AVERROR_PATCHWELCOME;
222 const_names [ci ] = o_named->name;
223 const_values[ci++] = DEFAULT_NUMVAL(o_named);
227 const_names [ci ] = "default";
228 const_values[ci++] = DEFAULT_NUMVAL(o);
229 const_names [ci ] = "max";
230 const_values[ci++] = o->max;
231 const_names [ci ] = "min";
232 const_values[ci++] = o->min;
233 const_names [ci ] = "none";
234 const_values[ci++] = 0;
235 const_names [ci ] = "all";
236 const_values[ci++] = ~0;
237 const_names [ci] = NULL;
238 const_values[ci] = 0;
240 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
241 const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
243 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
248 if (o->type == AV_OPT_TYPE_FLAGS) {
249 read_number(o, dst, NULL, NULL, &intnum);
250 if (cmd == '+') d = intnum | (int64_t)d;
251 else if (cmd == '-') d = intnum &~(int64_t)d;
254 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
264 static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
268 if (!val || !strcmp(val, "none")) {
273 ret = av_parse_video_size(dst, dst + 1, val);
275 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
279 static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
283 ret = AVERROR(EINVAL);
285 ret = av_parse_video_rate(dst, val);
288 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
292 static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst)
299 ret = av_parse_color(dst, val, -1, obj);
301 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
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)
312 if (!val || !strcmp(val, "none")) {
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);
327 min = FFMAX(o->min, -1);
328 max = FFMIN(o->max, fmt_nb-1);
330 // hack for compatibility with old ffmpeg
331 if(min == 0 && max == 0) {
336 if (fmt < min || fmt > max) {
337 av_log(obj, AV_LOG_ERROR,
338 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
339 fmt, o->name, desc, min, max);
340 return AVERROR(ERANGE);
347 static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
349 return set_string_fmt(obj, o, val, dst,
350 AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format");
353 static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
355 return set_string_fmt(obj, o, val, dst,
356 AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
359 #if FF_API_OLD_AVOPTIONS
360 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
362 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
365 return av_opt_set(obj, name, val, 0);
369 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
372 void *dst, *target_obj;
373 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
374 if (!o || !target_obj)
375 return AVERROR_OPTION_NOT_FOUND;
376 if (!val && (o->type != AV_OPT_TYPE_STRING &&
377 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
378 o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
379 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
380 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
381 return AVERROR(EINVAL);
383 if (o->flags & AV_OPT_FLAG_READONLY)
384 return AVERROR(EINVAL);
386 dst = ((uint8_t*)target_obj) + o->offset;
388 case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
389 case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
390 case AV_OPT_TYPE_FLAGS:
391 case AV_OPT_TYPE_INT:
392 case AV_OPT_TYPE_INT64:
393 case AV_OPT_TYPE_FLOAT:
394 case AV_OPT_TYPE_DOUBLE:
395 case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
396 case AV_OPT_TYPE_IMAGE_SIZE: return set_string_image_size(obj, o, val, dst);
397 case AV_OPT_TYPE_VIDEO_RATE: return set_string_video_rate(obj, o, val, dst);
398 case AV_OPT_TYPE_PIXEL_FMT: return set_string_pixel_fmt(obj, o, val, dst);
399 case AV_OPT_TYPE_SAMPLE_FMT: return set_string_sample_fmt(obj, o, val, dst);
400 case AV_OPT_TYPE_DURATION:
405 if ((ret = av_parse_time(dst, val, 1)) < 0)
406 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
410 case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst);
411 case AV_OPT_TYPE_CHANNEL_LAYOUT:
412 if (!val || !strcmp(val, "none")) {
415 #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
416 int64_t cl = ff_get_channel_layout(val, 0);
418 int64_t cl = av_get_channel_layout(val);
421 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
422 ret = AVERROR(EINVAL);
424 *(int64_t *)dst = cl;
430 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
431 return AVERROR(EINVAL);
434 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
435 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
437 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)\
438 return AVERROR(EINVAL);\
439 return set_string_number(obj, obj, o, val, name ## _out);\
442 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
443 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
444 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
445 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
446 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
447 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
449 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
452 void *dst, *target_obj;
453 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
455 if (!o || !target_obj)
456 return AVERROR_OPTION_NOT_FOUND;
458 if (o->flags & AV_OPT_FLAG_READONLY)
459 return AVERROR(EINVAL);
461 dst = ((uint8_t*)target_obj) + o->offset;
462 return write_number(obj, o, dst, num, den, intnum);
465 #if FF_API_OLD_AVOPTIONS
466 const AVOption *av_set_double(void *obj, const char *name, double n)
468 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
469 if (set_number(obj, name, n, 1, 1, 0) < 0)
474 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
476 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
477 if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
482 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
484 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
485 if (set_number(obj, name, 1, 1, n, 0) < 0)
491 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
493 return set_number(obj, name, 1, 1, val, search_flags);
496 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
498 return set_number(obj, name, val, 1, 1, search_flags);
501 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
503 return set_number(obj, name, val.num, val.den, 1, search_flags);
506 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
509 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
514 if (!o || !target_obj)
515 return AVERROR_OPTION_NOT_FOUND;
517 if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY)
518 return AVERROR(EINVAL);
520 ptr = len ? av_malloc(len) : NULL;
522 return AVERROR(ENOMEM);
524 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
525 lendst = (int *)(dst + 1);
531 memcpy(ptr, val, len);
536 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
539 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
541 if (!o || !target_obj)
542 return AVERROR_OPTION_NOT_FOUND;
543 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
544 av_log(obj, AV_LOG_ERROR,
545 "The value set by option '%s' is not an image size.\n", o->name);
546 return AVERROR(EINVAL);
549 av_log(obj, AV_LOG_ERROR,
550 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
551 return AVERROR(EINVAL);
553 *(int *)(((uint8_t *)target_obj) + o->offset) = w;
554 *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
558 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
561 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
563 if (!o || !target_obj)
564 return AVERROR_OPTION_NOT_FOUND;
565 if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
566 av_log(obj, AV_LOG_ERROR,
567 "The value set by option '%s' is not a video rate.\n", o->name);
568 return AVERROR(EINVAL);
570 if (val.num <= 0 || val.den <= 0)
571 return AVERROR(EINVAL);
572 return set_number(obj, name, val.num, val.den, 1, search_flags);
575 static int set_format(void *obj, const char *name, int fmt, int search_flags,
576 enum AVOptionType type, const char *desc, int nb_fmts)
579 const AVOption *o = av_opt_find2(obj, name, NULL, 0,
580 search_flags, &target_obj);
583 if (!o || !target_obj)
584 return AVERROR_OPTION_NOT_FOUND;
585 if (o->type != type) {
586 av_log(obj, AV_LOG_ERROR,
587 "The value set by option '%s' is not a %s format", name, desc);
588 return AVERROR(EINVAL);
591 min = FFMAX(o->min, -1);
592 max = FFMIN(o->max, nb_fmts-1);
594 if (fmt < min || fmt > max) {
595 av_log(obj, AV_LOG_ERROR,
596 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
597 fmt, name, desc, min, max);
598 return AVERROR(ERANGE);
600 *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
604 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
606 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
609 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
611 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
614 int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
617 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
619 if (!o || !target_obj)
620 return AVERROR_OPTION_NOT_FOUND;
621 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
622 av_log(obj, AV_LOG_ERROR,
623 "The value set by option '%s' is not a channel layout.\n", o->name);
624 return AVERROR(EINVAL);
626 *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
630 #if FF_API_OLD_AVOPTIONS
633 * @param buf a buffer which is used for returning non string values as strings, can be NULL
634 * @param buf_len allocated length in bytes of buf
636 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
638 const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
644 if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
647 dst= ((uint8_t*)obj) + o->offset;
648 if (o_out) *o_out= o;
651 case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
652 case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
653 case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
654 case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
655 case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
656 case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
657 case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
658 case AV_OPT_TYPE_STRING: return *(void**)dst;
659 case AV_OPT_TYPE_BINARY:
660 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
661 if (len >= (buf_len + 1)/2) return NULL;
662 bin = *(uint8_t**)dst;
663 for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
665 default: return NULL;
671 int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags)
675 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
677 if (!o || !target_obj)
678 return AVERROR_OPTION_NOT_FOUND;
679 if (o->flags & AV_OPT_FLAG_READONLY)
680 return AVERROR(EINVAL);
682 dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset);
684 av_dict_copy(dst, val, 0);
689 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
691 void *dst, *target_obj;
692 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
693 uint8_t *bin, buf[128];
697 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
698 return AVERROR_OPTION_NOT_FOUND;
700 dst = (uint8_t*)target_obj + o->offset;
704 case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
705 case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
706 case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
707 case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
708 case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
709 case AV_OPT_TYPE_VIDEO_RATE:
710 case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
711 case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break;
712 case AV_OPT_TYPE_STRING:
714 *out_val = av_strdup(*(uint8_t**)dst);
716 *out_val = av_strdup("");
717 return *out_val ? 0 : AVERROR(ENOMEM);
718 case AV_OPT_TYPE_BINARY:
719 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
720 if ((uint64_t)len*2 + 1 > INT_MAX)
721 return AVERROR(EINVAL);
722 if (!(*out_val = av_malloc(len*2 + 1)))
723 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":%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",
749 (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
750 (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
752 case AV_OPT_TYPE_CHANNEL_LAYOUT:
753 i64 = *(int64_t *)dst;
754 ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
757 return AVERROR(EINVAL);
760 if (ret >= sizeof(buf))
761 return AVERROR(EINVAL);
762 *out_val = av_strdup(buf);
763 return *out_val ? 0 : AVERROR(ENOMEM);
766 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
769 void *dst, *target_obj;
770 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
771 if (!o || !target_obj)
774 dst = ((uint8_t*)target_obj) + o->offset;
776 if (o_out) *o_out= o;
778 return read_number(o, dst, num, den, intnum);
785 #if FF_API_OLD_AVOPTIONS
786 double av_get_double(void *obj, const char *name, const AVOption **o_out)
792 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
794 return num*intnum/den;
797 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
803 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
804 return (AVRational){0, 0};
805 if (num == 1.0 && (int)intnum == intnum)
806 return (AVRational){intnum, den};
808 return av_d2q(num*intnum/den, 1<<24);
811 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
817 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
819 return num*intnum/den;
823 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
829 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
831 *out_val = num*intnum/den;
835 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
841 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
843 *out_val = num*intnum/den;
847 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
853 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
856 if (num == 1.0 && (int)intnum == intnum)
857 *out_val = (AVRational){intnum, den};
859 *out_val = av_d2q(num*intnum/den, 1<<24);
863 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
865 void *dst, *target_obj;
866 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
867 if (!o || !target_obj)
868 return AVERROR_OPTION_NOT_FOUND;
869 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
870 av_log(obj, AV_LOG_ERROR,
871 "The value for option '%s' is not an image size.\n", name);
872 return AVERROR(EINVAL);
875 dst = ((uint8_t*)target_obj) + o->offset;
876 if (w_out) *w_out = *(int *)dst;
877 if (h_out) *h_out = *((int *)dst+1);
881 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
887 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
890 if (num == 1.0 && (int)intnum == intnum)
891 *out_val = (AVRational){intnum, den};
893 *out_val = av_d2q(num*intnum/den, 1<<24);
897 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
898 enum AVOptionType type, const char *desc)
900 void *dst, *target_obj;
901 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
902 if (!o || !target_obj)
903 return AVERROR_OPTION_NOT_FOUND;
904 if (o->type != type) {
905 av_log(obj, AV_LOG_ERROR,
906 "The value for option '%s' is not a %s format.\n", desc, name);
907 return AVERROR(EINVAL);
910 dst = ((uint8_t*)target_obj) + o->offset;
911 *out_fmt = *(int *)dst;
915 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
917 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
920 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
922 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
925 int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
927 void *dst, *target_obj;
928 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
929 if (!o || !target_obj)
930 return AVERROR_OPTION_NOT_FOUND;
931 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
932 av_log(obj, AV_LOG_ERROR,
933 "The value for option '%s' is not a channel layout.\n", name);
934 return AVERROR(EINVAL);
937 dst = ((uint8_t*)target_obj) + o->offset;
938 *cl = *(int64_t *)dst;
942 int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val)
946 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
948 if (!o || !target_obj)
949 return AVERROR_OPTION_NOT_FOUND;
950 if (o->type != AV_OPT_TYPE_DICT)
951 return AVERROR(EINVAL);
953 src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset);
954 av_dict_copy(out_val, src, 0);
959 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
961 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
962 const AVOption *flag = av_opt_find(obj, flag_name,
963 field ? field->unit : NULL, 0, 0);
966 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
967 av_opt_get_int(obj, field_name, 0, &res) < 0)
969 return res & flag->default_val.i64;
972 static void log_value(void *av_log_obj, int level, double d)
975 av_log(av_log_obj, level, "INT_MAX");
976 } else if (d == INT_MIN) {
977 av_log(av_log_obj, level, "INT_MIN");
978 } else if (d == UINT32_MAX) {
979 av_log(av_log_obj, level, "UINT32_MAX");
980 } else if (d == (double)INT64_MAX) {
981 av_log(av_log_obj, level, "I64_MAX");
982 } else if (d == INT64_MIN) {
983 av_log(av_log_obj, level, "I64_MIN");
984 } else if (d == FLT_MAX) {
985 av_log(av_log_obj, level, "FLT_MAX");
986 } else if (d == FLT_MIN) {
987 av_log(av_log_obj, level, "FLT_MIN");
988 } else if (d == -FLT_MAX) {
989 av_log(av_log_obj, level, "-FLT_MAX");
990 } else if (d == -FLT_MIN) {
991 av_log(av_log_obj, level, "-FLT_MIN");
992 } else if (d == DBL_MAX) {
993 av_log(av_log_obj, level, "DBL_MAX");
994 } else if (d == DBL_MIN) {
995 av_log(av_log_obj, level, "DBL_MIN");
996 } else if (d == -DBL_MAX) {
997 av_log(av_log_obj, level, "-DBL_MAX");
998 } else if (d == -DBL_MIN) {
999 av_log(av_log_obj, level, "-DBL_MIN");
1001 av_log(av_log_obj, level, "%g", d);
1005 static void opt_list(void *obj, void *av_log_obj, const char *unit,
1006 int req_flags, int rej_flags)
1008 const AVOption *opt=NULL;
1012 while ((opt = av_opt_next(obj, opt))) {
1013 if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
1016 /* Don't print CONST's on level one.
1017 * Don't print anything but CONST's on level two.
1018 * Only print items from the requested unit.
1020 if (!unit && opt->type==AV_OPT_TYPE_CONST)
1022 else if (unit && opt->type!=AV_OPT_TYPE_CONST)
1024 else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
1026 else if (unit && opt->type == AV_OPT_TYPE_CONST)
1027 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
1029 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ",
1030 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-",
1033 switch (opt->type) {
1034 case AV_OPT_TYPE_FLAGS:
1035 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
1037 case AV_OPT_TYPE_INT:
1038 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
1040 case AV_OPT_TYPE_INT64:
1041 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
1043 case AV_OPT_TYPE_DOUBLE:
1044 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
1046 case AV_OPT_TYPE_FLOAT:
1047 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
1049 case AV_OPT_TYPE_STRING:
1050 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
1052 case AV_OPT_TYPE_RATIONAL:
1053 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
1055 case AV_OPT_TYPE_BINARY:
1056 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
1058 case AV_OPT_TYPE_IMAGE_SIZE:
1059 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
1061 case AV_OPT_TYPE_VIDEO_RATE:
1062 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
1064 case AV_OPT_TYPE_PIXEL_FMT:
1065 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
1067 case AV_OPT_TYPE_SAMPLE_FMT:
1068 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
1070 case AV_OPT_TYPE_DURATION:
1071 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
1073 case AV_OPT_TYPE_COLOR:
1074 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
1076 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1077 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
1079 case AV_OPT_TYPE_CONST:
1081 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
1084 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
1085 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
1086 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
1087 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
1088 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
1089 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
1090 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.');
1091 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.');
1094 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
1096 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
1097 switch (opt->type) {
1098 case AV_OPT_TYPE_INT:
1099 case AV_OPT_TYPE_INT64:
1100 case AV_OPT_TYPE_DOUBLE:
1101 case AV_OPT_TYPE_FLOAT:
1102 case AV_OPT_TYPE_RATIONAL:
1103 for (i = 0; i < r->nb_ranges; i++) {
1104 av_log(av_log_obj, AV_LOG_INFO, " (from ");
1105 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
1106 av_log(av_log_obj, AV_LOG_INFO, " to ");
1107 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
1108 av_log(av_log_obj, AV_LOG_INFO, ")");
1112 av_opt_freep_ranges(&r);
1115 if (opt->type != AV_OPT_TYPE_CONST &&
1116 opt->type != AV_OPT_TYPE_BINARY &&
1117 !((opt->type == AV_OPT_TYPE_COLOR ||
1118 opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
1119 opt->type == AV_OPT_TYPE_STRING ||
1120 opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
1121 !opt->default_val.str)) {
1122 av_log(av_log_obj, AV_LOG_INFO, " (default ");
1123 switch (opt->type) {
1124 case AV_OPT_TYPE_FLAGS:
1125 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
1127 case AV_OPT_TYPE_DURATION:
1128 case AV_OPT_TYPE_INT:
1129 case AV_OPT_TYPE_INT64:
1130 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
1132 case AV_OPT_TYPE_DOUBLE:
1133 case AV_OPT_TYPE_FLOAT:
1134 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
1136 case AV_OPT_TYPE_RATIONAL: {
1137 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
1138 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
1140 case AV_OPT_TYPE_PIXEL_FMT:
1141 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
1143 case AV_OPT_TYPE_SAMPLE_FMT:
1144 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
1146 case AV_OPT_TYPE_COLOR:
1147 case AV_OPT_TYPE_IMAGE_SIZE:
1148 case AV_OPT_TYPE_STRING:
1149 case AV_OPT_TYPE_VIDEO_RATE:
1150 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
1152 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1153 av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
1156 av_log(av_log_obj, AV_LOG_INFO, ")");
1159 av_log(av_log_obj, AV_LOG_INFO, "\n");
1160 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
1161 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
1166 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
1171 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
1173 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
1178 void av_opt_set_defaults(void *s)
1180 #if FF_API_OLD_AVOPTIONS
1181 av_opt_set_defaults2(s, 0, 0);
1184 void av_opt_set_defaults2(void *s, int mask, int flags)
1187 const AVOption *opt = NULL;
1188 while ((opt = av_opt_next(s, opt))) {
1189 void *dst = ((uint8_t*)s) + opt->offset;
1190 #if FF_API_OLD_AVOPTIONS
1191 if ((opt->flags & mask) != flags)
1195 if (opt->flags & AV_OPT_FLAG_READONLY)
1198 switch (opt->type) {
1199 case AV_OPT_TYPE_CONST:
1200 /* Nothing to be done here */
1202 case AV_OPT_TYPE_FLAGS:
1203 case AV_OPT_TYPE_INT:
1204 case AV_OPT_TYPE_INT64:
1205 case AV_OPT_TYPE_DURATION:
1206 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1207 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
1209 case AV_OPT_TYPE_DOUBLE:
1210 case AV_OPT_TYPE_FLOAT: {
1212 val = opt->default_val.dbl;
1213 write_number(s, opt, dst, val, 1, 1);
1216 case AV_OPT_TYPE_RATIONAL: {
1218 val = av_d2q(opt->default_val.dbl, INT_MAX);
1219 write_number(s, opt, dst, 1, val.den, val.num);
1222 case AV_OPT_TYPE_COLOR:
1223 set_string_color(s, opt, opt->default_val.str, dst);
1225 case AV_OPT_TYPE_STRING:
1226 set_string(s, opt, opt->default_val.str, dst);
1228 case AV_OPT_TYPE_IMAGE_SIZE:
1229 set_string_image_size(s, opt, opt->default_val.str, dst);
1231 case AV_OPT_TYPE_VIDEO_RATE:
1232 set_string_video_rate(s, opt, opt->default_val.str, dst);
1234 case AV_OPT_TYPE_PIXEL_FMT:
1235 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
1237 case AV_OPT_TYPE_SAMPLE_FMT:
1238 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
1240 case AV_OPT_TYPE_BINARY:
1241 set_string_binary(s, opt, opt->default_val.str, dst);
1243 case AV_OPT_TYPE_DICT:
1244 /* Cannot set defaults for these types */
1247 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
1253 * Store the value in the field in ctx that is named like key.
1254 * ctx must be an AVClass context, storing is done using AVOptions.
1256 * @param buf the string to parse, buf will be updated to point at the
1257 * separator just after the parsed key/value pair
1258 * @param key_val_sep a 0-terminated list of characters used to
1259 * separate key from value
1260 * @param pairs_sep a 0-terminated list of characters used to separate
1261 * two pairs from each other
1262 * @return 0 if the key/value pair has been successfully parsed and
1263 * set, or a negative value corresponding to an AVERROR code in case
1265 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1266 * the error code issued by av_opt_set() if the key/value pair
1269 static int parse_key_value_pair(void *ctx, const char **buf,
1270 const char *key_val_sep, const char *pairs_sep)
1272 char *key = av_get_token(buf, key_val_sep);
1277 return AVERROR(ENOMEM);
1279 if (*key && strspn(*buf, key_val_sep)) {
1281 val = av_get_token(buf, pairs_sep);
1284 return AVERROR(ENOMEM);
1287 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
1289 return AVERROR(EINVAL);
1292 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
1294 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
1295 if (ret == AVERROR_OPTION_NOT_FOUND)
1296 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
1303 int av_set_options_string(void *ctx, const char *opts,
1304 const char *key_val_sep, const char *pairs_sep)
1312 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
1323 #define WHITESPACES " \n\t"
1325 static int is_key_char(char c)
1327 return (unsigned)((c | 32) - 'a') < 26 ||
1328 (unsigned)(c - '0') < 10 ||
1329 c == '-' || c == '_' || c == '/' || c == '.';
1333 * Read a key from a string.
1335 * The key consists of is_key_char characters and must be terminated by a
1336 * character from the delim string; spaces are ignored.
1338 * @return 0 for success (even with ellipsis), <0 for failure
1340 static int get_key(const char **ropts, const char *delim, char **rkey)
1342 const char *opts = *ropts;
1343 const char *key_start, *key_end;
1345 key_start = opts += strspn(opts, WHITESPACES);
1346 while (is_key_char(*opts))
1349 opts += strspn(opts, WHITESPACES);
1350 if (!*opts || !strchr(delim, *opts))
1351 return AVERROR(EINVAL);
1353 if (!(*rkey = av_malloc(key_end - key_start + 1)))
1354 return AVERROR(ENOMEM);
1355 memcpy(*rkey, key_start, key_end - key_start);
1356 (*rkey)[key_end - key_start] = 0;
1361 int av_opt_get_key_value(const char **ropts,
1362 const char *key_val_sep, const char *pairs_sep,
1364 char **rkey, char **rval)
1367 char *key = NULL, *val;
1368 const char *opts = *ropts;
1370 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
1371 !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
1372 return AVERROR(EINVAL);
1373 if (!(val = av_get_token(&opts, pairs_sep))) {
1375 return AVERROR(ENOMEM);
1383 int av_opt_set_from_string(void *ctx, const char *opts,
1384 const char *const *shorthand,
1385 const char *key_val_sep, const char *pairs_sep)
1388 const char *dummy_shorthand = NULL;
1389 char *av_uninit(parsed_key), *av_uninit(value);
1395 shorthand = &dummy_shorthand;
1398 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
1399 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
1400 &parsed_key, &value);
1402 if (ret == AVERROR(EINVAL))
1403 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
1405 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
1413 while (*shorthand) /* discard all remaining shorthand */
1416 key = *(shorthand++);
1419 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
1420 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
1421 if (ret == AVERROR_OPTION_NOT_FOUND)
1422 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
1424 av_free(parsed_key);
1429 av_free(parsed_key);
1435 void av_opt_free(void *obj)
1437 const AVOption *o = NULL;
1438 while ((o = av_opt_next(obj, o))) {
1440 case AV_OPT_TYPE_STRING:
1441 case AV_OPT_TYPE_BINARY:
1442 av_freep((uint8_t *)obj + o->offset);
1445 case AV_OPT_TYPE_DICT:
1446 av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
1455 int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
1457 AVDictionaryEntry *t = NULL;
1458 AVDictionary *tmp = NULL;
1464 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
1465 ret = av_opt_set(obj, t->key, t->value, search_flags);
1466 if (ret == AVERROR_OPTION_NOT_FOUND)
1467 av_dict_set(&tmp, t->key, t->value, 0);
1469 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
1474 av_dict_free(options);
1479 int av_opt_set_dict(void *obj, AVDictionary **options)
1481 return av_opt_set_dict2(obj, options, 0);
1484 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
1485 int opt_flags, int search_flags)
1487 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1490 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
1491 int opt_flags, int search_flags, void **target_obj)
1494 const AVOption *o = NULL;
1504 if (search_flags & AV_OPT_SEARCH_CHILDREN) {
1505 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
1506 const AVClass *child = NULL;
1507 while (child = av_opt_child_class_next(c, child))
1508 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
1512 while (child = av_opt_child_next(obj, child))
1513 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1518 while (o = av_opt_next(obj, o)) {
1519 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
1520 ((!unit && o->type != AV_OPT_TYPE_CONST) ||
1521 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
1523 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
1534 void *av_opt_child_next(void *obj, void *prev)
1536 const AVClass *c = *(AVClass**)obj;
1538 return c->child_next(obj, prev);
1542 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
1544 if (parent->child_class_next)
1545 return parent->child_class_next(prev);
1549 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
1551 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
1554 return (uint8_t*)obj + opt->offset;
1557 static int opt_size(enum AVOptionType type)
1560 case AV_OPT_TYPE_INT:
1561 case AV_OPT_TYPE_FLAGS: return sizeof(int);
1562 case AV_OPT_TYPE_DURATION:
1563 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1564 case AV_OPT_TYPE_INT64: return sizeof(int64_t);
1565 case AV_OPT_TYPE_DOUBLE: return sizeof(double);
1566 case AV_OPT_TYPE_FLOAT: return sizeof(float);
1567 case AV_OPT_TYPE_STRING: return sizeof(uint8_t*);
1568 case AV_OPT_TYPE_VIDEO_RATE:
1569 case AV_OPT_TYPE_RATIONAL: return sizeof(AVRational);
1570 case AV_OPT_TYPE_BINARY: return sizeof(uint8_t*) + sizeof(int);
1571 case AV_OPT_TYPE_IMAGE_SIZE:return sizeof(int[2]);
1572 case AV_OPT_TYPE_PIXEL_FMT: return sizeof(enum AVPixelFormat);
1573 case AV_OPT_TYPE_SAMPLE_FMT:return sizeof(enum AVSampleFormat);
1574 case AV_OPT_TYPE_COLOR: return 4;
1579 int av_opt_copy(void *dst, FF_CONST_AVUTIL55 void *src)
1581 const AVOption *o = NULL;
1588 c = *(AVClass**)src;
1589 if (*(AVClass**)dst && c != *(AVClass**)dst)
1590 return AVERROR(EINVAL);
1592 while ((o = av_opt_next(src, o))) {
1593 void *field_dst = ((uint8_t*)dst) + o->offset;
1594 void *field_src = ((uint8_t*)src) + o->offset;
1595 uint8_t **field_dst8 = (uint8_t**)field_dst;
1596 uint8_t **field_src8 = (uint8_t**)field_src;
1598 if (o->type == AV_OPT_TYPE_STRING) {
1599 if (*field_dst8 != *field_src8)
1600 av_freep(field_dst8);
1601 *field_dst8 = av_strdup(*field_src8);
1602 if (*field_src8 && !*field_dst8)
1603 ret = AVERROR(ENOMEM);
1604 } else if (o->type == AV_OPT_TYPE_BINARY) {
1605 int len = *(int*)(field_src8 + 1);
1606 if (*field_dst8 != *field_src8)
1607 av_freep(field_dst8);
1608 *field_dst8 = av_memdup(*field_src8, len);
1609 if (len && !*field_dst8) {
1610 ret = AVERROR(ENOMEM);
1613 *(int*)(field_dst8 + 1) = len;
1614 } else if (o->type == AV_OPT_TYPE_CONST) {
1616 } else if (o->type == AV_OPT_TYPE_DICT) {
1617 AVDictionary **sdict = (AVDictionary **) field_src;
1618 AVDictionary **ddict = (AVDictionary **) field_dst;
1619 if (*sdict != *ddict)
1620 av_dict_free(ddict);
1622 av_dict_copy(ddict, *sdict, 0);
1623 if (av_dict_count(*sdict) != av_dict_count(*ddict))
1624 ret = AVERROR(ENOMEM);
1626 memcpy(field_dst, field_src, opt_size(o->type));
1632 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1635 const AVClass *c = *(AVClass**)obj;
1636 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
1638 if (c->version > (52 << 16 | 11 << 8))
1639 callback = c->query_ranges;
1642 callback = av_opt_query_ranges_default;
1644 ret = callback(ranges_arg, obj, key, flags);
1646 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE))
1648 (*ranges_arg)->nb_components = ret;
1653 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1655 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
1656 AVOptionRange **range_array = av_mallocz(sizeof(void*));
1657 AVOptionRange *range = av_mallocz(sizeof(*range));
1658 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
1663 if (!ranges || !range || !range_array || !field) {
1664 ret = AVERROR(ENOMEM);
1668 ranges->range = range_array;
1669 ranges->range[0] = range;
1670 ranges->nb_ranges = 1;
1671 ranges->nb_components = 1;
1672 range->is_range = 1;
1673 range->value_min = field->min;
1674 range->value_max = field->max;
1676 switch (field->type) {
1677 case AV_OPT_TYPE_INT:
1678 case AV_OPT_TYPE_INT64:
1679 case AV_OPT_TYPE_PIXEL_FMT:
1680 case AV_OPT_TYPE_SAMPLE_FMT:
1681 case AV_OPT_TYPE_FLOAT:
1682 case AV_OPT_TYPE_DOUBLE:
1683 case AV_OPT_TYPE_DURATION:
1684 case AV_OPT_TYPE_COLOR:
1685 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1687 case AV_OPT_TYPE_STRING:
1688 range->component_min = 0;
1689 range->component_max = 0x10FFFF; // max unicode value
1690 range->value_min = -1;
1691 range->value_max = INT_MAX;
1693 case AV_OPT_TYPE_RATIONAL:
1694 range->component_min = INT_MIN;
1695 range->component_max = INT_MAX;
1697 case AV_OPT_TYPE_IMAGE_SIZE:
1698 range->component_min = 0;
1699 range->component_max = INT_MAX/128/8;
1700 range->value_min = 0;
1701 range->value_max = INT_MAX/8;
1703 case AV_OPT_TYPE_VIDEO_RATE:
1704 range->component_min = 1;
1705 range->component_max = INT_MAX;
1706 range->value_min = 1;
1707 range->value_max = INT_MAX;
1710 ret = AVERROR(ENOSYS);
1714 *ranges_arg = ranges;
1719 av_free(range_array);
1723 void av_opt_freep_ranges(AVOptionRanges **rangesp)
1726 AVOptionRanges *ranges = *rangesp;
1731 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) {
1732 AVOptionRange *range = ranges->range[i];
1734 av_freep(&range->str);
1735 av_freep(&ranges->range[i]);
1738 av_freep(&ranges->range);
1742 int av_opt_is_set_to_default(void *obj, const AVOption *o)
1753 return AVERROR(EINVAL);
1755 dst = ((uint8_t*)obj) + o->offset;
1758 case AV_OPT_TYPE_CONST:
1760 case AV_OPT_TYPE_FLAGS:
1761 case AV_OPT_TYPE_PIXEL_FMT:
1762 case AV_OPT_TYPE_SAMPLE_FMT:
1763 case AV_OPT_TYPE_INT:
1764 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1765 case AV_OPT_TYPE_DURATION:
1766 case AV_OPT_TYPE_INT64:
1767 read_number(o, dst, NULL, NULL, &i64);
1768 return o->default_val.i64 == i64;
1769 case AV_OPT_TYPE_STRING:
1770 str = *(char **)dst;
1771 if (str == o->default_val.str) //2 NULLs
1773 if (!str || !o->default_val.str) //1 NULL
1775 return !strcmp(str, o->default_val.str);
1776 case AV_OPT_TYPE_DOUBLE:
1777 read_number(o, dst, &d, NULL, NULL);
1778 return o->default_val.dbl == d;
1779 case AV_OPT_TYPE_FLOAT:
1780 read_number(o, dst, &d, NULL, NULL);
1781 f = o->default_val.dbl;
1784 case AV_OPT_TYPE_RATIONAL:
1785 q = av_d2q(o->default_val.dbl, INT_MAX);
1786 return !av_cmp_q(*(AVRational*)dst, q);
1787 case AV_OPT_TYPE_BINARY: {
1792 int opt_size = *(int *)((void **)dst + 1);
1793 void *opt_ptr = *(void **)dst;
1794 if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str)))
1796 if (!opt_size || !o->default_val.str || !strlen(o->default_val.str ))
1798 if (opt_size != strlen(o->default_val.str) / 2)
1800 ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);
1802 ret = !memcmp(opt_ptr, tmp.data, tmp.size);
1806 case AV_OPT_TYPE_DICT:
1807 /* Binary and dict have not default support yet. Any pointer is not default. */
1808 return !!(*(void **)dst);
1809 case AV_OPT_TYPE_IMAGE_SIZE:
1810 if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
1812 else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)
1814 return (w == *(int *)dst) && (h == *((int *)dst+1));
1815 case AV_OPT_TYPE_VIDEO_RATE:
1816 q = (AVRational){0, 0};
1817 if (o->default_val.str) {
1818 if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0)
1821 return !av_cmp_q(*(AVRational*)dst, q);
1822 case AV_OPT_TYPE_COLOR: {
1823 uint8_t color[4] = {0, 0, 0, 0};
1824 if (o->default_val.str) {
1825 if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0)
1828 return !memcmp(color, dst, sizeof(color));
1831 av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);
1834 return AVERROR_PATCHWELCOME;
1837 int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
1842 return AVERROR(EINVAL);
1843 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target);
1845 return AVERROR_OPTION_NOT_FOUND;
1846 return av_opt_is_set_to_default(target, o);
1849 int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
1850 const char key_val_sep, const char pairs_sep)
1852 const AVOption *o = NULL;
1856 const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
1858 if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
1859 pairs_sep == '\\' || key_val_sep == '\\') {
1860 av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
1861 return AVERROR(EINVAL);
1864 if (!obj || !buffer)
1865 return AVERROR(EINVAL);
1868 av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
1870 while (o = av_opt_next(obj, o)) {
1871 if (o->type == AV_OPT_TYPE_CONST)
1873 if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
1875 else if (((o->flags & opt_flags) != opt_flags))
1877 if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
1879 if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
1880 av_bprint_finalize(&bprint, NULL);
1885 av_bprint_append_data(&bprint, &pairs_sep, 1);
1886 av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
1887 av_bprint_append_data(&bprint, &key_val_sep, 1);
1888 av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
1892 av_bprint_finalize(&bprint, buffer);
1898 typedef struct TestContext
1900 const AVClass *class;
1905 AVRational rational;
1906 AVRational video_rate;
1908 enum AVPixelFormat pix_fmt;
1909 enum AVSampleFormat sample_fmt;
1912 int64_t channel_layout;
1925 #define OFFSET(x) offsetof(TestContext, x)
1927 #define TEST_FLAG_COOL 01
1928 #define TEST_FLAG_LAME 02
1929 #define TEST_FLAG_MU 04
1931 static const AVOption test_options[]= {
1932 {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100, 1 },
1933 {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, 1 },
1934 {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 1}, 0, 10, 1 },
1935 {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX, 1 },
1936 {"escape", "set escape str", OFFSET(escape), AV_OPT_TYPE_STRING, {.str = "\\=,"}, CHAR_MIN, CHAR_MAX, 1 },
1937 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 1}, 0, INT_MAX, 1, "flags" },
1938 {"cool", "set cool flag", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 1, "flags" },
1939 {"lame", "set lame flag", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 1, "flags" },
1940 {"mu", "set mu flag", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 1, "flags" },
1941 {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{.str="200x300"}, 0, 0, 1},
1942 {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_0BGR}, -1, INT_MAX, 1},
1943 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_S16}, -1, INT_MAX, 1},
1944 {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 , 1},
1945 {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 1000}, 0, INT64_MAX, 1},
1946 {"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0, 1},
1947 {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX, 1},
1948 {"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, {.str="62696e00"}, 0, 0, 1 },
1949 {"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, {.str=NULL}, 0, 0, 1 },
1950 {"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, {.str=""}, 0, 0, 1 },
1951 {"num64", "set num 64bit", OFFSET(num64), AV_OPT_TYPE_INT64, {.i64 = 1}, 0, 100, 1 },
1952 {"flt", "set float", OFFSET(flt), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3}, 0, 100, 1},
1953 {"dbl", "set double", OFFSET(dbl), AV_OPT_TYPE_DOUBLE, {.dbl = 1.0/3}, 0, 100, 1 },
1957 static const char *test_get_name(void *ctx)
1962 static const AVClass test_class = {
1968 static void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
1970 vfprintf(stdout, fmt, vl);
1977 av_log_set_level(AV_LOG_DEBUG);
1978 av_log_set_callback(log_callback_help);
1980 printf("Testing default values\n");
1982 TestContext test_ctx = { 0 };
1983 test_ctx.class = &test_class;
1984 av_opt_set_defaults(&test_ctx);
1986 printf("num=%d\n", test_ctx.num);
1987 printf("toggle=%d\n", test_ctx.toggle);
1988 printf("string=%s\n", test_ctx.string);
1989 printf("escape=%s\n", test_ctx.escape);
1990 printf("flags=%d\n", test_ctx.flags);
1991 printf("rational=%d/%d\n", test_ctx.rational.num, test_ctx.rational.den);
1992 printf("video_rate=%d/%d\n", test_ctx.video_rate.num, test_ctx.video_rate.den);
1993 printf("width=%d height=%d\n", test_ctx.w, test_ctx.h);
1994 printf("pix_fmt=%s\n", av_get_pix_fmt_name(test_ctx.pix_fmt));
1995 printf("sample_fmt=%s\n", av_get_sample_fmt_name(test_ctx.sample_fmt));
1996 printf("duration=%"PRId64"\n", test_ctx.duration);
1997 printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]);
1998 printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout, (int64_t)AV_CH_LAYOUT_HEXAGONAL);
1999 if (test_ctx.binary)
2000 printf("binary=%x %x %x %x\n", ((uint8_t*)test_ctx.binary)[0], ((uint8_t*)test_ctx.binary)[1], ((uint8_t*)test_ctx.binary)[2], ((uint8_t*)test_ctx.binary)[3]);
2001 printf("binary_size=%d\n", test_ctx.binary_size);
2002 printf("num64=%"PRId64"\n", test_ctx.num64);
2003 printf("flt=%.6f\n", test_ctx.flt);
2004 printf("dbl=%.6f\n", test_ctx.dbl);
2006 av_opt_show2(&test_ctx, NULL, -1, 0);
2008 av_opt_free(&test_ctx);
2011 printf("\nTesting av_opt_is_set_to_default()\n");
2014 TestContext test_ctx = { 0 };
2015 const AVOption *o = NULL;
2016 test_ctx.class = &test_class;
2018 av_log_set_level(AV_LOG_QUIET);
2020 while (o = av_opt_next(&test_ctx, o)) {
2021 ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0);
2022 printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : "");
2024 av_opt_set_defaults(&test_ctx);
2025 while (o = av_opt_next(&test_ctx, o)) {
2026 ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0);
2027 printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : "");
2029 av_opt_free(&test_ctx);
2032 printf("\nTest av_opt_serialize()\n");
2034 TestContext test_ctx = { 0 };
2036 test_ctx.class = &test_class;
2038 av_log_set_level(AV_LOG_QUIET);
2040 av_opt_set_defaults(&test_ctx);
2041 if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
2042 printf("%s\n", buf);
2043 av_opt_free(&test_ctx);
2044 memset(&test_ctx, 0, sizeof(test_ctx));
2045 test_ctx.class = &test_class;
2046 av_set_options_string(&test_ctx, buf, "=", ",");
2048 if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
2049 printf("%s\n", buf);
2053 av_opt_free(&test_ctx);
2056 printf("\nTesting av_set_options_string()\n");
2058 TestContext test_ctx = { 0 };
2059 static const char * const options[] = {
2075 "flags=+mu-lame : num=42: toggle=0",
2076 "num=42 : string=blahblah",
2077 "rational=0 : rational=1/2 : rational=1/-1",
2090 "video_rate=30000/1001",
2091 "video_rate=30/1.001",
2095 "duration=1\\:23\\:45.67",
2099 "cl=stereo+downmix",
2121 test_ctx.class = &test_class;
2122 av_opt_set_defaults(&test_ctx);
2124 av_log_set_level(AV_LOG_QUIET);
2126 for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
2127 int silence_log = !strcmp(options[i], "rational=-1/0"); // inf formating differs between platforms
2128 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
2130 av_log_set_callback(NULL);
2131 if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
2132 printf("Error '%s'\n", options[i]);
2134 printf("OK '%s'\n", options[i]);
2135 av_log_set_callback(log_callback_help);
2137 av_opt_free(&test_ctx);
2140 printf("\nTesting av_opt_set_from_string()\n");
2142 TestContext test_ctx = { 0 };
2143 static const char * const options[] = {
2151 " 5 : hello : size = pal ",
2152 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
2154 static const char * const shorthand[] = { "num", "string", NULL };
2156 test_ctx.class = &test_class;
2157 av_opt_set_defaults(&test_ctx);
2159 av_log_set_level(AV_LOG_QUIET);
2161 for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
2162 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
2163 if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
2164 printf("Error '%s'\n", options[i]);
2166 printf("OK '%s'\n", options[i]);
2168 av_opt_free(&test_ctx);