1 /*
2 * AVOptions
3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * AVOptions
25 * @author Michael Niedermayer <michaelni@gmx.at>
26 */
27
28 #include "avutil.h"
29 #include "avassert.h"
30 #include "avstring.h"
31 #include "channel_layout.h"
32 #include "common.h"
33 #include "dict.h"
34 #include "eval.h"
35 #include "log.h"
36 #include "parseutils.h"
37 #include "pixdesc.h"
38 #include "mathematics.h"
39 #include "opt.h"
40 #include "samplefmt.h"
41 #include "bprint.h"
42 #include "version.h"
43
44 #include <float.h>
45
av_opt_next(const void * obj,const AVOption * last)46 const AVOption *av_opt_next(const void *obj, const AVOption *last)
47 {
48 const AVClass *class;
49 if (!obj)
50 return NULL;
51 class = *(const AVClass**)obj;
52 if (!last && class && class->option && class->option[0].name)
53 return class->option;
54 if (last && last[1].name)
55 return ++last;
56 return NULL;
57 }
58
read_number(const AVOption * o,const void * dst,double * num,int * den,int64_t * intnum)59 static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
60 {
61 switch (o->type) {
62 case AV_OPT_TYPE_FLAGS:
63 *intnum = *(unsigned int*)dst;
64 return 0;
65 case AV_OPT_TYPE_PIXEL_FMT:
66 *intnum = *(enum AVPixelFormat *)dst;
67 return 0;
68 case AV_OPT_TYPE_SAMPLE_FMT:
69 *intnum = *(enum AVSampleFormat *)dst;
70 return 0;
71 case AV_OPT_TYPE_BOOL:
72 case AV_OPT_TYPE_INT:
73 *intnum = *(int *)dst;
74 return 0;
75 #if FF_API_OLD_CHANNEL_LAYOUT
76 FF_DISABLE_DEPRECATION_WARNINGS
77 case AV_OPT_TYPE_CHANNEL_LAYOUT:
78 FF_ENABLE_DEPRECATION_WARNINGS
79 #endif
80 case AV_OPT_TYPE_DURATION:
81 case AV_OPT_TYPE_INT64:
82 case AV_OPT_TYPE_UINT64:
83 *intnum = *(int64_t *)dst;
84 return 0;
85 case AV_OPT_TYPE_FLOAT:
86 *num = *(float *)dst;
87 return 0;
88 case AV_OPT_TYPE_DOUBLE:
89 *num = *(double *)dst;
90 return 0;
91 case AV_OPT_TYPE_RATIONAL:
92 *intnum = ((AVRational *)dst)->num;
93 *den = ((AVRational *)dst)->den;
94 return 0;
95 case AV_OPT_TYPE_CONST:
96 *num = o->default_val.dbl;
97 return 0;
98 }
99 return AVERROR(EINVAL);
100 }
101
write_number(void * obj,const AVOption * o,void * dst,double num,int den,int64_t intnum)102 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
103 {
104 if (o->type != AV_OPT_TYPE_FLAGS &&
105 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
106 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
107 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
108 num, o->name, o->min, o->max);
109 return AVERROR(ERANGE);
110 }
111 if (o->type == AV_OPT_TYPE_FLAGS) {
112 double d = num*intnum/den;
113 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
114 av_log(obj, AV_LOG_ERROR,
115 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
116 num*intnum/den, o->name);
117 return AVERROR(ERANGE);
118 }
119 }
120
121 switch (o->type) {
122 case AV_OPT_TYPE_PIXEL_FMT:
123 *(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
124 break;
125 case AV_OPT_TYPE_SAMPLE_FMT:
126 *(enum AVSampleFormat *)dst = llrint(num / den) * intnum;
127 break;
128 case AV_OPT_TYPE_BOOL:
129 case AV_OPT_TYPE_FLAGS:
130 case AV_OPT_TYPE_INT:
131 *(int *)dst = llrint(num / den) * intnum;
132 break;
133 case AV_OPT_TYPE_DURATION:
134 #if FF_API_OLD_CHANNEL_LAYOUT
135 FF_DISABLE_DEPRECATION_WARNINGS
136 case AV_OPT_TYPE_CHANNEL_LAYOUT:
137 FF_ENABLE_DEPRECATION_WARNINGS
138 #endif
139 case AV_OPT_TYPE_INT64:{
140 double d = num / den;
141 if (intnum == 1 && d == (double)INT64_MAX) {
142 *(int64_t *)dst = INT64_MAX;
143 } else
144 *(int64_t *)dst = llrint(d) * intnum;
145 break;}
146 case AV_OPT_TYPE_UINT64:{
147 double d = num / den;
148 // We must special case uint64_t here as llrint() does not support values
149 // outside the int64_t range and there is no portable function which does
150 // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double
151 // while INT64_MAX is not
152 if (intnum == 1 && d == (double)UINT64_MAX) {
153 *(uint64_t *)dst = UINT64_MAX;
154 } else if (d > INT64_MAX + 1ULL) {
155 *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum;
156 } else {
157 *(uint64_t *)dst = llrint(d) * intnum;
158 }
159 break;}
160 case AV_OPT_TYPE_FLOAT:
161 *(float *)dst = num * intnum / den;
162 break;
163 case AV_OPT_TYPE_DOUBLE:
164 *(double *)dst = num * intnum / den;
165 break;
166 case AV_OPT_TYPE_RATIONAL:
167 case AV_OPT_TYPE_VIDEO_RATE:
168 if ((int) num == num)
169 *(AVRational *)dst = (AVRational) { num *intnum, den };
170 else
171 *(AVRational *)dst = av_d2q(num * intnum / den, 1 << 24);
172 break;
173 default:
174 return AVERROR(EINVAL);
175 }
176 return 0;
177 }
178
hexchar2int(char c)179 static int hexchar2int(char c) {
180 if (c >= '0' && c <= '9')
181 return c - '0';
182 if (c >= 'a' && c <= 'f')
183 return c - 'a' + 10;
184 if (c >= 'A' && c <= 'F')
185 return c - 'A' + 10;
186 return -1;
187 }
188
set_string_binary(void * obj,const AVOption * o,const char * val,uint8_t ** dst)189 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
190 {
191 int *lendst = (int *)(dst + 1);
192 uint8_t *bin, *ptr;
193 int len;
194
195 av_freep(dst);
196 *lendst = 0;
197
198 if (!val || !(len = strlen(val)))
199 return 0;
200
201 if (len & 1)
202 return AVERROR(EINVAL);
203 len /= 2;
204
205 ptr = bin = av_malloc(len);
206 if (!ptr)
207 return AVERROR(ENOMEM);
208 while (*val) {
209 int a = hexchar2int(*val++);
210 int b = hexchar2int(*val++);
211 if (a < 0 || b < 0) {
212 av_free(bin);
213 return AVERROR(EINVAL);
214 }
215 *ptr++ = (a << 4) | b;
216 }
217 *dst = bin;
218 *lendst = len;
219
220 return 0;
221 }
222
set_string(void * obj,const AVOption * o,const char * val,uint8_t ** dst)223 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
224 {
225 av_freep(dst);
226 *dst = av_strdup(val);
227 return *dst ? 0 : AVERROR(ENOMEM);
228 }
229
230 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
231 opt->type == AV_OPT_TYPE_UINT64 || \
232 opt->type == AV_OPT_TYPE_CONST || \
233 opt->type == AV_OPT_TYPE_FLAGS || \
234 opt->type == AV_OPT_TYPE_INT) \
235 ? opt->default_val.i64 \
236 : opt->default_val.dbl)
237
set_string_number(void * obj,void * target_obj,const AVOption * o,const char * val,void * dst)238 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
239 {
240 int ret = 0;
241
242 if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
243 int num, den;
244 char c;
245 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
246 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
247 return ret;
248 ret = 0;
249 }
250 }
251
252 for (;;) {
253 int i = 0;
254 char buf[256];
255 int cmd = 0;
256 double d;
257 int64_t intnum = 1;
258
259 if (o->type == AV_OPT_TYPE_FLAGS) {
260 if (*val == '+' || *val == '-')
261 cmd = *(val++);
262 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
263 buf[i] = val[i];
264 buf[i] = 0;
265 }
266
267 {
268 int res;
269 int ci = 0;
270 double const_values[64];
271 const char * const_names[64];
272 int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0;
273 const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags);
274 if (o_named && o_named->type == AV_OPT_TYPE_CONST) {
275 d = DEFAULT_NUMVAL(o_named);
276 if (o_named->flags & AV_OPT_FLAG_DEPRECATED)
277 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n",
278 o_named->name, o_named->help);
279 } else {
280 if (o->unit) {
281 for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
282 if (o_named->type == AV_OPT_TYPE_CONST &&
283 o_named->unit &&
284 !strcmp(o_named->unit, o->unit)) {
285 if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
286 av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
287 return AVERROR_PATCHWELCOME;
288 }
289 const_names [ci ] = o_named->name;
290 const_values[ci++] = DEFAULT_NUMVAL(o_named);
291 }
292 }
293 }
294 const_names [ci ] = "default";
295 const_values[ci++] = DEFAULT_NUMVAL(o);
296 const_names [ci ] = "max";
297 const_values[ci++] = o->max;
298 const_names [ci ] = "min";
299 const_values[ci++] = o->min;
300 const_names [ci ] = "none";
301 const_values[ci++] = 0;
302 const_names [ci ] = "all";
303 const_values[ci++] = ~0;
304 const_names [ci] = NULL;
305 const_values[ci] = 0;
306
307 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
308 const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
309 if (res < 0) {
310 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
311 return res;
312 }
313 }
314 }
315 if (o->type == AV_OPT_TYPE_FLAGS) {
316 read_number(o, dst, NULL, NULL, &intnum);
317 if (cmd == '+')
318 d = intnum | (int64_t)d;
319 else if (cmd == '-')
320 d = intnum &~(int64_t)d;
321 }
322
323 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
324 return ret;
325 val += i;
326 if (!i || !*val)
327 return 0;
328 }
329 }
330
set_string_image_size(void * obj,const AVOption * o,const char * val,int * dst)331 static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
332 {
333 int ret;
334
335 if (!val || !strcmp(val, "none")) {
336 dst[0] =
337 dst[1] = 0;
338 return 0;
339 }
340 ret = av_parse_video_size(dst, dst + 1, val);
341 if (ret < 0)
342 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
343 return ret;
344 }
345
set_string_video_rate(void * obj,const AVOption * o,const char * val,AVRational * dst)346 static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
347 {
348 int ret = av_parse_video_rate(dst, val);
349 if (ret < 0)
350 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
351 return ret;
352 }
353
set_string_color(void * obj,const AVOption * o,const char * val,uint8_t * dst)354 static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst)
355 {
356 int ret;
357
358 if (!val) {
359 return 0;
360 } else {
361 ret = av_parse_color(dst, val, -1, obj);
362 if (ret < 0)
363 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
364 return ret;
365 }
366 return 0;
367 }
368
get_bool_name(int val)369 static const char *get_bool_name(int val)
370 {
371 if (val < 0)
372 return "auto";
373 return val ? "true" : "false";
374 }
375
set_string_bool(void * obj,const AVOption * o,const char * val,int * dst)376 static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst)
377 {
378 int n;
379
380 if (!val)
381 return 0;
382
383 if (!strcmp(val, "auto")) {
384 n = -1;
385 } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) {
386 n = 1;
387 } else if (av_match_name(val, "false,n,no,disable,disabled,off")) {
388 n = 0;
389 } else {
390 char *end = NULL;
391 n = strtol(val, &end, 10);
392 if (val + strlen(val) != end)
393 goto fail;
394 }
395
396 if (n < o->min || n > o->max)
397 goto fail;
398
399 *dst = n;
400 return 0;
401
402 fail:
403 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val);
404 return AVERROR(EINVAL);
405 }
406
set_string_fmt(void * obj,const AVOption * o,const char * val,uint8_t * dst,int fmt_nb,int ((* get_fmt)(const char *)),const char * desc)407 static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst,
408 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc)
409 {
410 int fmt, min, max;
411
412 if (!val || !strcmp(val, "none")) {
413 fmt = -1;
414 } else {
415 fmt = get_fmt(val);
416 if (fmt == -1) {
417 char *tail;
418 fmt = strtol(val, &tail, 0);
419 if (*tail || (unsigned)fmt >= fmt_nb) {
420 av_log(obj, AV_LOG_ERROR,
421 "Unable to parse option value \"%s\" as %s\n", val, desc);
422 return AVERROR(EINVAL);
423 }
424 }
425 }
426
427 min = FFMAX(o->min, -1);
428 max = FFMIN(o->max, fmt_nb-1);
429
430 // hack for compatibility with old ffmpeg
431 if(min == 0 && max == 0) {
432 min = -1;
433 max = fmt_nb-1;
434 }
435
436 if (fmt < min || fmt > max) {
437 av_log(obj, AV_LOG_ERROR,
438 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
439 fmt, o->name, desc, min, max);
440 return AVERROR(ERANGE);
441 }
442
443 *(int *)dst = fmt;
444 return 0;
445 }
446
set_string_pixel_fmt(void * obj,const AVOption * o,const char * val,uint8_t * dst)447 static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
448 {
449 return set_string_fmt(obj, o, val, dst,
450 AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format");
451 }
452
set_string_sample_fmt(void * obj,const AVOption * o,const char * val,uint8_t * dst)453 static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
454 {
455 return set_string_fmt(obj, o, val, dst,
456 AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
457 }
458
set_string_dict(void * obj,const AVOption * o,const char * val,uint8_t ** dst)459 static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
460 {
461 AVDictionary *options = NULL;
462
463 if (val) {
464 int ret = av_dict_parse_string(&options, val, "=", ":", 0);
465 if (ret < 0) {
466 av_dict_free(&options);
467 return ret;
468 }
469 }
470
471 av_dict_free((AVDictionary **)dst);
472 *dst = (uint8_t *)options;
473
474 return 0;
475 }
476
set_string_channel_layout(void * obj,const AVOption * o,const char * val,void * dst)477 static int set_string_channel_layout(void *obj, const AVOption *o,
478 const char *val, void *dst)
479 {
480 AVChannelLayout *channel_layout = dst;
481 av_channel_layout_uninit(channel_layout);
482 if (!val)
483 return 0;
484 return av_channel_layout_from_string(channel_layout, val);
485 }
486
av_opt_set(void * obj,const char * name,const char * val,int search_flags)487 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
488 {
489 int ret = 0;
490 void *dst, *target_obj;
491 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
492 if (!o || !target_obj)
493 return AVERROR_OPTION_NOT_FOUND;
494 FF_DISABLE_DEPRECATION_WARNINGS
495 if (!val && (o->type != AV_OPT_TYPE_STRING &&
496 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
497 o->type != AV_OPT_TYPE_IMAGE_SIZE &&
498 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
499 #if FF_API_OLD_CHANNEL_LAYOUT
500 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT &&
501 #endif
502 o->type != AV_OPT_TYPE_BOOL))
503 return AVERROR(EINVAL);
504 FF_ENABLE_DEPRECATION_WARNINGS
505
506 if (o->flags & AV_OPT_FLAG_READONLY)
507 return AVERROR(EINVAL);
508
509 if (o->flags & AV_OPT_FLAG_DEPRECATED)
510 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
511
512 dst = ((uint8_t *)target_obj) + o->offset;
513 switch (o->type) {
514 case AV_OPT_TYPE_BOOL:
515 return set_string_bool(obj, o, val, dst);
516 case AV_OPT_TYPE_STRING:
517 return set_string(obj, o, val, dst);
518 case AV_OPT_TYPE_BINARY:
519 return set_string_binary(obj, o, val, dst);
520 case AV_OPT_TYPE_FLAGS:
521 case AV_OPT_TYPE_INT:
522 case AV_OPT_TYPE_INT64:
523 case AV_OPT_TYPE_UINT64:
524 case AV_OPT_TYPE_FLOAT:
525 case AV_OPT_TYPE_DOUBLE:
526 case AV_OPT_TYPE_RATIONAL:
527 return set_string_number(obj, target_obj, o, val, dst);
528 case AV_OPT_TYPE_IMAGE_SIZE:
529 return set_string_image_size(obj, o, val, dst);
530 case AV_OPT_TYPE_VIDEO_RATE: {
531 AVRational tmp;
532 ret = set_string_video_rate(obj, o, val, &tmp);
533 if (ret < 0)
534 return ret;
535 return write_number(obj, o, dst, 1, tmp.den, tmp.num);
536 }
537 case AV_OPT_TYPE_PIXEL_FMT:
538 return set_string_pixel_fmt(obj, o, val, dst);
539 case AV_OPT_TYPE_SAMPLE_FMT:
540 return set_string_sample_fmt(obj, o, val, dst);
541 case AV_OPT_TYPE_DURATION:
542 {
543 int64_t usecs = 0;
544 if (val) {
545 if ((ret = av_parse_time(&usecs, val, 1)) < 0) {
546 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
547 return ret;
548 }
549 }
550 if (usecs < o->min || usecs > o->max) {
551 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
552 usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0);
553 return AVERROR(ERANGE);
554 }
555 *(int64_t *)dst = usecs;
556 return 0;
557 }
558 case AV_OPT_TYPE_COLOR:
559 return set_string_color(obj, o, val, dst);
560 #if FF_API_OLD_CHANNEL_LAYOUT
561 FF_DISABLE_DEPRECATION_WARNINGS
562 case AV_OPT_TYPE_CHANNEL_LAYOUT:
563 if (!val || !strcmp(val, "none")) {
564 *(int64_t *)dst = 0;
565 } else {
566 int64_t cl = av_get_channel_layout(val);
567 if (!cl) {
568 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
569 ret = AVERROR(EINVAL);
570 }
571 *(int64_t *)dst = cl;
572 return ret;
573 }
574 break;
575 FF_ENABLE_DEPRECATION_WARNINGS
576 #endif
577 case AV_OPT_TYPE_CHLAYOUT:
578 ret = set_string_channel_layout(obj, o, val, dst);
579 if (ret < 0) {
580 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
581 ret = AVERROR(EINVAL);
582 }
583 return ret;
584 case AV_OPT_TYPE_DICT:
585 return set_string_dict(obj, o, val, dst);
586 }
587
588 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
589 return AVERROR(EINVAL);
590 }
591
592 #define OPT_EVAL_NUMBER(name, opttype, vartype) \
593 int av_opt_eval_ ## name(void *obj, const AVOption *o, \
594 const char *val, vartype *name ## _out) \
595 { \
596 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \
597 return AVERROR(EINVAL); \
598 return set_string_number(obj, obj, o, val, name ## _out); \
599 }
600
OPT_EVAL_NUMBER(flags,AV_OPT_TYPE_FLAGS,int)601 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
602 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
603 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
604 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
605 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
606 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
607
608 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
609 int search_flags)
610 {
611 void *dst, *target_obj;
612 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
613
614 if (!o || !target_obj)
615 return AVERROR_OPTION_NOT_FOUND;
616
617 if (o->flags & AV_OPT_FLAG_READONLY)
618 return AVERROR(EINVAL);
619
620 dst = ((uint8_t *)target_obj) + o->offset;
621 return write_number(obj, o, dst, num, den, intnum);
622 }
623
av_opt_set_int(void * obj,const char * name,int64_t val,int search_flags)624 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
625 {
626 return set_number(obj, name, 1, 1, val, search_flags);
627 }
628
av_opt_set_double(void * obj,const char * name,double val,int search_flags)629 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
630 {
631 return set_number(obj, name, val, 1, 1, search_flags);
632 }
633
av_opt_set_q(void * obj,const char * name,AVRational val,int search_flags)634 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
635 {
636 return set_number(obj, name, val.num, val.den, 1, search_flags);
637 }
638
av_opt_set_bin(void * obj,const char * name,const uint8_t * val,int len,int search_flags)639 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
640 {
641 void *target_obj;
642 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
643 uint8_t *ptr;
644 uint8_t **dst;
645 int *lendst;
646
647 if (!o || !target_obj)
648 return AVERROR_OPTION_NOT_FOUND;
649
650 if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY)
651 return AVERROR(EINVAL);
652
653 ptr = len ? av_malloc(len) : NULL;
654 if (len && !ptr)
655 return AVERROR(ENOMEM);
656
657 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
658 lendst = (int *)(dst + 1);
659
660 av_free(*dst);
661 *dst = ptr;
662 *lendst = len;
663 if (len)
664 memcpy(ptr, val, len);
665
666 return 0;
667 }
668
av_opt_set_image_size(void * obj,const char * name,int w,int h,int search_flags)669 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
670 {
671 void *target_obj;
672 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
673
674 if (!o || !target_obj)
675 return AVERROR_OPTION_NOT_FOUND;
676 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
677 av_log(obj, AV_LOG_ERROR,
678 "The value set by option '%s' is not an image size.\n", o->name);
679 return AVERROR(EINVAL);
680 }
681 if (w<0 || h<0) {
682 av_log(obj, AV_LOG_ERROR,
683 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
684 return AVERROR(EINVAL);
685 }
686 *(int *)(((uint8_t *)target_obj) + o->offset) = w;
687 *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
688 return 0;
689 }
690
av_opt_set_video_rate(void * obj,const char * name,AVRational val,int search_flags)691 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
692 {
693 void *target_obj;
694 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
695
696 if (!o || !target_obj)
697 return AVERROR_OPTION_NOT_FOUND;
698 if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
699 av_log(obj, AV_LOG_ERROR,
700 "The value set by option '%s' is not a video rate.\n", o->name);
701 return AVERROR(EINVAL);
702 }
703 if (val.num <= 0 || val.den <= 0)
704 return AVERROR(EINVAL);
705 return set_number(obj, name, val.num, val.den, 1, search_flags);
706 }
707
set_format(void * obj,const char * name,int fmt,int search_flags,enum AVOptionType type,const char * desc,int nb_fmts)708 static int set_format(void *obj, const char *name, int fmt, int search_flags,
709 enum AVOptionType type, const char *desc, int nb_fmts)
710 {
711 void *target_obj;
712 const AVOption *o = av_opt_find2(obj, name, NULL, 0,
713 search_flags, &target_obj);
714 int min, max;
715
716 if (!o || !target_obj)
717 return AVERROR_OPTION_NOT_FOUND;
718 if (o->type != type) {
719 av_log(obj, AV_LOG_ERROR,
720 "The value set by option '%s' is not a %s format", name, desc);
721 return AVERROR(EINVAL);
722 }
723
724 min = FFMAX(o->min, -1);
725 max = FFMIN(o->max, nb_fmts-1);
726
727 if (fmt < min || fmt > max) {
728 av_log(obj, AV_LOG_ERROR,
729 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
730 fmt, name, desc, min, max);
731 return AVERROR(ERANGE);
732 }
733 *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
734 return 0;
735 }
736
av_opt_set_pixel_fmt(void * obj,const char * name,enum AVPixelFormat fmt,int search_flags)737 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
738 {
739 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
740 }
741
av_opt_set_sample_fmt(void * obj,const char * name,enum AVSampleFormat fmt,int search_flags)742 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
743 {
744 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
745 }
746
747 #if FF_API_OLD_CHANNEL_LAYOUT
748 FF_DISABLE_DEPRECATION_WARNINGS
av_opt_set_channel_layout(void * obj,const char * name,int64_t cl,int search_flags)749 int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
750 {
751 void *target_obj;
752 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
753
754 if (!o || !target_obj)
755 return AVERROR_OPTION_NOT_FOUND;
756 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
757 av_log(obj, AV_LOG_ERROR,
758 "The value set by option '%s' is not a channel layout.\n", o->name);
759 return AVERROR(EINVAL);
760 }
761 *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
762 return 0;
763 }
764 FF_ENABLE_DEPRECATION_WARNINGS
765 #endif
766
av_opt_set_dict_val(void * obj,const char * name,const AVDictionary * val,int search_flags)767 int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
768 int search_flags)
769 {
770 void *target_obj;
771 AVDictionary **dst;
772 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
773
774 if (!o || !target_obj)
775 return AVERROR_OPTION_NOT_FOUND;
776 if (o->flags & AV_OPT_FLAG_READONLY)
777 return AVERROR(EINVAL);
778
779 dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset);
780 av_dict_free(dst);
781 av_dict_copy(dst, val, 0);
782
783 return 0;
784 }
785
av_opt_set_chlayout(void * obj,const char * name,const AVChannelLayout * channel_layout,int search_flags)786 int av_opt_set_chlayout(void *obj, const char *name,
787 const AVChannelLayout *channel_layout,
788 int search_flags)
789 {
790 void *target_obj;
791 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
792 AVChannelLayout *dst;
793
794 if (!o || !target_obj)
795 return AVERROR_OPTION_NOT_FOUND;
796
797 dst = (AVChannelLayout*)((uint8_t*)target_obj + o->offset);
798
799 return av_channel_layout_copy(dst, channel_layout);
800 }
801
format_duration(char * buf,size_t size,int64_t d)802 static void format_duration(char *buf, size_t size, int64_t d)
803 {
804 char *e;
805
806 av_assert0(size >= 25);
807 if (d < 0 && d != INT64_MIN) {
808 *(buf++) = '-';
809 size--;
810 d = -d;
811 }
812 if (d == INT64_MAX)
813 snprintf(buf, size, "INT64_MAX");
814 else if (d == INT64_MIN)
815 snprintf(buf, size, "INT64_MIN");
816 else if (d > (int64_t)3600*1000000)
817 snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000,
818 (int)((d / 60000000) % 60),
819 (int)((d / 1000000) % 60),
820 (int)(d % 1000000));
821 else if (d > 60*1000000)
822 snprintf(buf, size, "%d:%02d.%06d",
823 (int)(d / 60000000),
824 (int)((d / 1000000) % 60),
825 (int)(d % 1000000));
826 else
827 snprintf(buf, size, "%d.%06d",
828 (int)(d / 1000000),
829 (int)(d % 1000000));
830 e = buf + strlen(buf);
831 while (e > buf && e[-1] == '0')
832 *(--e) = 0;
833 if (e > buf && e[-1] == '.')
834 *(--e) = 0;
835 }
836
av_opt_get(void * obj,const char * name,int search_flags,uint8_t ** out_val)837 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
838 {
839 void *dst, *target_obj;
840 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
841 uint8_t *bin, buf[128];
842 int len, i, ret;
843 int64_t i64;
844
845 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
846 return AVERROR_OPTION_NOT_FOUND;
847
848 if (o->flags & AV_OPT_FLAG_DEPRECATED)
849 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
850
851 dst = (uint8_t *)target_obj + o->offset;
852
853 buf[0] = 0;
854 switch (o->type) {
855 case AV_OPT_TYPE_BOOL:
856 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
857 break;
858 case AV_OPT_TYPE_FLAGS:
859 ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);
860 break;
861 case AV_OPT_TYPE_INT:
862 ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
863 break;
864 case AV_OPT_TYPE_INT64:
865 ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
866 break;
867 case AV_OPT_TYPE_UINT64:
868 ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst);
869 break;
870 case AV_OPT_TYPE_FLOAT:
871 ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst);
872 break;
873 case AV_OPT_TYPE_DOUBLE:
874 ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst);
875 break;
876 case AV_OPT_TYPE_VIDEO_RATE:
877 case AV_OPT_TYPE_RATIONAL:
878 ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
879 break;
880 case AV_OPT_TYPE_CONST:
881 ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl);
882 break;
883 case AV_OPT_TYPE_STRING:
884 if (*(uint8_t **)dst) {
885 *out_val = av_strdup(*(uint8_t **)dst);
886 } else if (search_flags & AV_OPT_ALLOW_NULL) {
887 *out_val = NULL;
888 return 0;
889 } else {
890 *out_val = av_strdup("");
891 }
892 return *out_val ? 0 : AVERROR(ENOMEM);
893 case AV_OPT_TYPE_BINARY:
894 if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
895 *out_val = NULL;
896 return 0;
897 }
898 len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
899 if ((uint64_t)len * 2 + 1 > INT_MAX)
900 return AVERROR(EINVAL);
901 if (!(*out_val = av_malloc(len * 2 + 1)))
902 return AVERROR(ENOMEM);
903 if (!len) {
904 *out_val[0] = '\0';
905 return 0;
906 }
907 bin = *(uint8_t **)dst;
908 for (i = 0; i < len; i++)
909 snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
910 return 0;
911 case AV_OPT_TYPE_IMAGE_SIZE:
912 ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
913 break;
914 case AV_OPT_TYPE_PIXEL_FMT:
915 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
916 break;
917 case AV_OPT_TYPE_SAMPLE_FMT:
918 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
919 break;
920 case AV_OPT_TYPE_DURATION:
921 i64 = *(int64_t *)dst;
922 format_duration(buf, sizeof(buf), i64);
923 ret = strlen(buf); // no overflow possible, checked by an assert
924 break;
925 case AV_OPT_TYPE_COLOR:
926 ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
927 (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
928 (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
929 break;
930 #if FF_API_OLD_CHANNEL_LAYOUT
931 FF_DISABLE_DEPRECATION_WARNINGS
932 case AV_OPT_TYPE_CHANNEL_LAYOUT:
933
934 i64 = *(int64_t *)dst;
935 ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
936 break;
937 FF_ENABLE_DEPRECATION_WARNINGS
938 #endif
939 case AV_OPT_TYPE_CHLAYOUT:
940 ret = av_channel_layout_describe(dst, buf, sizeof(buf));
941 break;
942 case AV_OPT_TYPE_DICT:
943 if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
944 *out_val = NULL;
945 return 0;
946 }
947 return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
948 default:
949 return AVERROR(EINVAL);
950 }
951
952 if (ret >= sizeof(buf))
953 return AVERROR(EINVAL);
954 *out_val = av_strdup(buf);
955 return *out_val ? 0 : AVERROR(ENOMEM);
956 }
957
get_number(void * obj,const char * name,const AVOption ** o_out,double * num,int * den,int64_t * intnum,int search_flags)958 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
959 int search_flags)
960 {
961 void *dst, *target_obj;
962 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
963 if (!o || !target_obj)
964 goto error;
965
966 dst = ((uint8_t *)target_obj) + o->offset;
967
968 if (o_out) *o_out= o;
969
970 return read_number(o, dst, num, den, intnum);
971
972 error:
973 *den =
974 *intnum = 0;
975 return -1;
976 }
977
av_opt_get_int(void * obj,const char * name,int search_flags,int64_t * out_val)978 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
979 {
980 int64_t intnum = 1;
981 double num = 1;
982 int ret, den = 1;
983
984 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
985 return ret;
986 if (num == den)
987 *out_val = intnum;
988 else
989 *out_val = num * intnum / den;
990 return 0;
991 }
992
av_opt_get_double(void * obj,const char * name,int search_flags,double * out_val)993 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
994 {
995 int64_t intnum = 1;
996 double num = 1;
997 int ret, den = 1;
998
999 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
1000 return ret;
1001 *out_val = num * intnum / den;
1002 return 0;
1003 }
1004
av_opt_get_q(void * obj,const char * name,int search_flags,AVRational * out_val)1005 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
1006 {
1007 int64_t intnum = 1;
1008 double num = 1;
1009 int ret, den = 1;
1010
1011 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
1012 return ret;
1013
1014 if (num == 1.0 && (int)intnum == intnum)
1015 *out_val = (AVRational){intnum, den};
1016 else
1017 *out_val = av_d2q(num*intnum/den, 1<<24);
1018 return 0;
1019 }
1020
av_opt_get_image_size(void * obj,const char * name,int search_flags,int * w_out,int * h_out)1021 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
1022 {
1023 void *dst, *target_obj;
1024 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1025 if (!o || !target_obj)
1026 return AVERROR_OPTION_NOT_FOUND;
1027 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
1028 av_log(obj, AV_LOG_ERROR,
1029 "The value for option '%s' is not an image size.\n", name);
1030 return AVERROR(EINVAL);
1031 }
1032
1033 dst = ((uint8_t*)target_obj) + o->offset;
1034 if (w_out) *w_out = *(int *)dst;
1035 if (h_out) *h_out = *((int *)dst+1);
1036 return 0;
1037 }
1038
av_opt_get_video_rate(void * obj,const char * name,int search_flags,AVRational * out_val)1039 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
1040 {
1041 int64_t intnum = 1;
1042 double num = 1;
1043 int ret, den = 1;
1044
1045 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
1046 return ret;
1047
1048 if (num == 1.0 && (int)intnum == intnum)
1049 *out_val = (AVRational) { intnum, den };
1050 else
1051 *out_val = av_d2q(num * intnum / den, 1 << 24);
1052 return 0;
1053 }
1054
get_format(void * obj,const char * name,int search_flags,int * out_fmt,enum AVOptionType type,const char * desc)1055 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
1056 enum AVOptionType type, const char *desc)
1057 {
1058 void *dst, *target_obj;
1059 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1060 if (!o || !target_obj)
1061 return AVERROR_OPTION_NOT_FOUND;
1062 if (o->type != type) {
1063 av_log(obj, AV_LOG_ERROR,
1064 "The value for option '%s' is not a %s format.\n", desc, name);
1065 return AVERROR(EINVAL);
1066 }
1067
1068 dst = ((uint8_t*)target_obj) + o->offset;
1069 *out_fmt = *(int *)dst;
1070 return 0;
1071 }
1072
av_opt_get_pixel_fmt(void * obj,const char * name,int search_flags,enum AVPixelFormat * out_fmt)1073 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
1074 {
1075 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
1076 }
1077
av_opt_get_sample_fmt(void * obj,const char * name,int search_flags,enum AVSampleFormat * out_fmt)1078 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
1079 {
1080 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
1081 }
1082
1083 #if FF_API_OLD_CHANNEL_LAYOUT
1084 FF_DISABLE_DEPRECATION_WARNINGS
av_opt_get_channel_layout(void * obj,const char * name,int search_flags,int64_t * cl)1085 int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
1086 {
1087 void *dst, *target_obj;
1088 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1089 if (!o || !target_obj)
1090 return AVERROR_OPTION_NOT_FOUND;
1091 if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
1092 av_log(obj, AV_LOG_ERROR,
1093 "The value for option '%s' is not a channel layout.\n", name);
1094 return AVERROR(EINVAL);
1095 }
1096
1097 dst = ((uint8_t*)target_obj) + o->offset;
1098 *cl = *(int64_t *)dst;
1099 return 0;
1100 }
1101 FF_ENABLE_DEPRECATION_WARNINGS
1102 #endif
1103
av_opt_get_chlayout(void * obj,const char * name,int search_flags,AVChannelLayout * cl)1104 int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl)
1105 {
1106 void *dst, *target_obj;
1107 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1108 if (!o || !target_obj)
1109 return AVERROR_OPTION_NOT_FOUND;
1110 if (o->type != AV_OPT_TYPE_CHLAYOUT) {
1111 av_log(obj, AV_LOG_ERROR,
1112 "The value for option '%s' is not a channel layout.\n", name);
1113 return AVERROR(EINVAL);
1114 }
1115
1116 dst = ((uint8_t*)target_obj) + o->offset;
1117 return av_channel_layout_copy(cl, dst);
1118 }
1119
av_opt_get_dict_val(void * obj,const char * name,int search_flags,AVDictionary ** out_val)1120 int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val)
1121 {
1122 void *target_obj;
1123 AVDictionary *src;
1124 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1125
1126 if (!o || !target_obj)
1127 return AVERROR_OPTION_NOT_FOUND;
1128 if (o->type != AV_OPT_TYPE_DICT)
1129 return AVERROR(EINVAL);
1130
1131 src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset);
1132 av_dict_copy(out_val, src, 0);
1133
1134 return 0;
1135 }
1136
av_opt_flag_is_set(void * obj,const char * field_name,const char * flag_name)1137 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
1138 {
1139 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
1140 const AVOption *flag = av_opt_find(obj, flag_name,
1141 field ? field->unit : NULL, 0, 0);
1142 int64_t res;
1143
1144 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
1145 av_opt_get_int(obj, field_name, 0, &res) < 0)
1146 return 0;
1147 return res & flag->default_val.i64;
1148 }
1149
log_int_value(void * av_log_obj,int level,int64_t i)1150 static void log_int_value(void *av_log_obj, int level, int64_t i)
1151 {
1152 if (i == INT_MAX) {
1153 av_log(av_log_obj, level, "INT_MAX");
1154 } else if (i == INT_MIN) {
1155 av_log(av_log_obj, level, "INT_MIN");
1156 } else if (i == UINT32_MAX) {
1157 av_log(av_log_obj, level, "UINT32_MAX");
1158 } else if (i == INT64_MAX) {
1159 av_log(av_log_obj, level, "I64_MAX");
1160 } else if (i == INT64_MIN) {
1161 av_log(av_log_obj, level, "I64_MIN");
1162 } else {
1163 av_log(av_log_obj, level, "%"PRId64, i);
1164 }
1165 }
1166
log_value(void * av_log_obj,int level,double d)1167 static void log_value(void *av_log_obj, int level, double d)
1168 {
1169 if (d == INT_MAX) {
1170 av_log(av_log_obj, level, "INT_MAX");
1171 } else if (d == INT_MIN) {
1172 av_log(av_log_obj, level, "INT_MIN");
1173 } else if (d == UINT32_MAX) {
1174 av_log(av_log_obj, level, "UINT32_MAX");
1175 } else if (d == (double)INT64_MAX) {
1176 av_log(av_log_obj, level, "I64_MAX");
1177 } else if (d == INT64_MIN) {
1178 av_log(av_log_obj, level, "I64_MIN");
1179 } else if (d == FLT_MAX) {
1180 av_log(av_log_obj, level, "FLT_MAX");
1181 } else if (d == FLT_MIN) {
1182 av_log(av_log_obj, level, "FLT_MIN");
1183 } else if (d == -FLT_MAX) {
1184 av_log(av_log_obj, level, "-FLT_MAX");
1185 } else if (d == -FLT_MIN) {
1186 av_log(av_log_obj, level, "-FLT_MIN");
1187 } else if (d == DBL_MAX) {
1188 av_log(av_log_obj, level, "DBL_MAX");
1189 } else if (d == DBL_MIN) {
1190 av_log(av_log_obj, level, "DBL_MIN");
1191 } else if (d == -DBL_MAX) {
1192 av_log(av_log_obj, level, "-DBL_MAX");
1193 } else if (d == -DBL_MIN) {
1194 av_log(av_log_obj, level, "-DBL_MIN");
1195 } else {
1196 av_log(av_log_obj, level, "%g", d);
1197 }
1198 }
1199
get_opt_const_name(void * obj,const char * unit,int64_t value)1200 static const char *get_opt_const_name(void *obj, const char *unit, int64_t value)
1201 {
1202 const AVOption *opt = NULL;
1203
1204 if (!unit)
1205 return NULL;
1206 while ((opt = av_opt_next(obj, opt)))
1207 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
1208 opt->default_val.i64 == value)
1209 return opt->name;
1210 return NULL;
1211 }
1212
get_opt_flags_string(void * obj,const char * unit,int64_t value)1213 static char *get_opt_flags_string(void *obj, const char *unit, int64_t value)
1214 {
1215 const AVOption *opt = NULL;
1216 char flags[512];
1217
1218 flags[0] = 0;
1219 if (!unit)
1220 return NULL;
1221 while ((opt = av_opt_next(obj, opt))) {
1222 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
1223 opt->default_val.i64 & value) {
1224 if (flags[0])
1225 av_strlcatf(flags, sizeof(flags), "+");
1226 av_strlcatf(flags, sizeof(flags), "%s", opt->name);
1227 }
1228 }
1229 if (flags[0])
1230 return av_strdup(flags);
1231 return NULL;
1232 }
1233
opt_list(void * obj,void * av_log_obj,const char * unit,int req_flags,int rej_flags,enum AVOptionType parent_type)1234 static void opt_list(void *obj, void *av_log_obj, const char *unit,
1235 int req_flags, int rej_flags, enum AVOptionType parent_type)
1236 {
1237 const AVOption *opt = NULL;
1238 AVOptionRanges *r;
1239 int i;
1240
1241 while ((opt = av_opt_next(obj, opt))) {
1242 if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
1243 continue;
1244
1245 /* Don't print CONST's on level one.
1246 * Don't print anything but CONST's on level two.
1247 * Only print items from the requested unit.
1248 */
1249 if (!unit && opt->type == AV_OPT_TYPE_CONST)
1250 continue;
1251 else if (unit && opt->type != AV_OPT_TYPE_CONST)
1252 continue;
1253 else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
1254 continue;
1255 else if (unit && opt->type == AV_OPT_TYPE_CONST)
1256 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
1257 else
1258 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ",
1259 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-",
1260 opt->name);
1261
1262 switch (opt->type) {
1263 case AV_OPT_TYPE_FLAGS:
1264 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
1265 break;
1266 case AV_OPT_TYPE_INT:
1267 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
1268 break;
1269 case AV_OPT_TYPE_INT64:
1270 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
1271 break;
1272 case AV_OPT_TYPE_UINT64:
1273 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<uint64>");
1274 break;
1275 case AV_OPT_TYPE_DOUBLE:
1276 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
1277 break;
1278 case AV_OPT_TYPE_FLOAT:
1279 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
1280 break;
1281 case AV_OPT_TYPE_STRING:
1282 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
1283 break;
1284 case AV_OPT_TYPE_RATIONAL:
1285 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
1286 break;
1287 case AV_OPT_TYPE_BINARY:
1288 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
1289 break;
1290 case AV_OPT_TYPE_DICT:
1291 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
1292 break;
1293 case AV_OPT_TYPE_IMAGE_SIZE:
1294 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
1295 break;
1296 case AV_OPT_TYPE_VIDEO_RATE:
1297 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
1298 break;
1299 case AV_OPT_TYPE_PIXEL_FMT:
1300 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
1301 break;
1302 case AV_OPT_TYPE_SAMPLE_FMT:
1303 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
1304 break;
1305 case AV_OPT_TYPE_DURATION:
1306 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
1307 break;
1308 case AV_OPT_TYPE_COLOR:
1309 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
1310 break;
1311 case AV_OPT_TYPE_CHLAYOUT:
1312 #if FF_API_OLD_CHANNEL_LAYOUT
1313 FF_DISABLE_DEPRECATION_WARNINGS
1314 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1315 FF_ENABLE_DEPRECATION_WARNINGS
1316 #endif
1317 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
1318 break;
1319 case AV_OPT_TYPE_BOOL:
1320 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
1321 break;
1322 case AV_OPT_TYPE_CONST:
1323 if (parent_type == AV_OPT_TYPE_INT)
1324 av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64);
1325 else
1326 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
1327 break;
1328 default:
1329 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
1330 break;
1331 }
1332 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
1333 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
1334 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
1335 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
1336 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
1337 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
1338 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.');
1339 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.');
1340 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.');
1341 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.');
1342 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.');
1343
1344 if (opt->help)
1345 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
1346
1347 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
1348 switch (opt->type) {
1349 case AV_OPT_TYPE_INT:
1350 case AV_OPT_TYPE_INT64:
1351 case AV_OPT_TYPE_UINT64:
1352 case AV_OPT_TYPE_DOUBLE:
1353 case AV_OPT_TYPE_FLOAT:
1354 case AV_OPT_TYPE_RATIONAL:
1355 for (i = 0; i < r->nb_ranges; i++) {
1356 av_log(av_log_obj, AV_LOG_INFO, " (from ");
1357 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
1358 av_log(av_log_obj, AV_LOG_INFO, " to ");
1359 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
1360 av_log(av_log_obj, AV_LOG_INFO, ")");
1361 }
1362 break;
1363 }
1364 av_opt_freep_ranges(&r);
1365 }
1366
1367 if (opt->type != AV_OPT_TYPE_CONST &&
1368 opt->type != AV_OPT_TYPE_BINARY &&
1369 !((opt->type == AV_OPT_TYPE_COLOR ||
1370 opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
1371 opt->type == AV_OPT_TYPE_STRING ||
1372 opt->type == AV_OPT_TYPE_DICT ||
1373 opt->type == AV_OPT_TYPE_CHLAYOUT ||
1374 opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
1375 !opt->default_val.str)) {
1376 av_log(av_log_obj, AV_LOG_INFO, " (default ");
1377 switch (opt->type) {
1378 case AV_OPT_TYPE_BOOL:
1379 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid"));
1380 break;
1381 case AV_OPT_TYPE_FLAGS: {
1382 char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
1383 if (def_flags) {
1384 av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
1385 av_freep(&def_flags);
1386 } else {
1387 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
1388 }
1389 break;
1390 }
1391 case AV_OPT_TYPE_DURATION: {
1392 char buf[25];
1393 format_duration(buf, sizeof(buf), opt->default_val.i64);
1394 av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
1395 break;
1396 }
1397 case AV_OPT_TYPE_INT:
1398 case AV_OPT_TYPE_UINT64:
1399 case AV_OPT_TYPE_INT64: {
1400 const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
1401 if (def_const)
1402 av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
1403 else
1404 log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
1405 break;
1406 }
1407 case AV_OPT_TYPE_DOUBLE:
1408 case AV_OPT_TYPE_FLOAT:
1409 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
1410 break;
1411 case AV_OPT_TYPE_RATIONAL: {
1412 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
1413 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
1414 break;
1415 case AV_OPT_TYPE_PIXEL_FMT:
1416 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
1417 break;
1418 case AV_OPT_TYPE_SAMPLE_FMT:
1419 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
1420 break;
1421 case AV_OPT_TYPE_COLOR:
1422 case AV_OPT_TYPE_IMAGE_SIZE:
1423 case AV_OPT_TYPE_STRING:
1424 case AV_OPT_TYPE_DICT:
1425 case AV_OPT_TYPE_VIDEO_RATE:
1426 case AV_OPT_TYPE_CHLAYOUT:
1427 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
1428 break;
1429 #if FF_API_OLD_CHANNEL_LAYOUT
1430 FF_DISABLE_DEPRECATION_WARNINGS
1431 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1432 av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
1433 break;
1434 FF_ENABLE_DEPRECATION_WARNINGS
1435 #endif
1436 }
1437 av_log(av_log_obj, AV_LOG_INFO, ")");
1438 }
1439
1440 av_log(av_log_obj, AV_LOG_INFO, "\n");
1441 if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
1442 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type);
1443 }
1444 }
1445
av_opt_show2(void * obj,void * av_log_obj,int req_flags,int rej_flags)1446 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
1447 {
1448 if (!obj)
1449 return -1;
1450
1451 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name);
1452
1453 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1);
1454
1455 return 0;
1456 }
1457
av_opt_set_defaults(void * s)1458 void av_opt_set_defaults(void *s)
1459 {
1460 av_opt_set_defaults2(s, 0, 0);
1461 }
1462
av_opt_set_defaults2(void * s,int mask,int flags)1463 void av_opt_set_defaults2(void *s, int mask, int flags)
1464 {
1465 const AVOption *opt = NULL;
1466 while ((opt = av_opt_next(s, opt))) {
1467 void *dst = ((uint8_t*)s) + opt->offset;
1468
1469 if ((opt->flags & mask) != flags)
1470 continue;
1471
1472 if (opt->flags & AV_OPT_FLAG_READONLY)
1473 continue;
1474
1475 switch (opt->type) {
1476 case AV_OPT_TYPE_CONST:
1477 /* Nothing to be done here */
1478 break;
1479 case AV_OPT_TYPE_BOOL:
1480 case AV_OPT_TYPE_FLAGS:
1481 case AV_OPT_TYPE_INT:
1482 case AV_OPT_TYPE_INT64:
1483 case AV_OPT_TYPE_UINT64:
1484 case AV_OPT_TYPE_DURATION:
1485 #if FF_API_OLD_CHANNEL_LAYOUT
1486 FF_DISABLE_DEPRECATION_WARNINGS
1487 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1488 FF_ENABLE_DEPRECATION_WARNINGS
1489 #endif
1490 case AV_OPT_TYPE_PIXEL_FMT:
1491 case AV_OPT_TYPE_SAMPLE_FMT:
1492 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
1493 break;
1494 case AV_OPT_TYPE_DOUBLE:
1495 case AV_OPT_TYPE_FLOAT: {
1496 double val;
1497 val = opt->default_val.dbl;
1498 write_number(s, opt, dst, val, 1, 1);
1499 }
1500 break;
1501 case AV_OPT_TYPE_RATIONAL: {
1502 AVRational val;
1503 val = av_d2q(opt->default_val.dbl, INT_MAX);
1504 write_number(s, opt, dst, 1, val.den, val.num);
1505 }
1506 break;
1507 case AV_OPT_TYPE_COLOR:
1508 set_string_color(s, opt, opt->default_val.str, dst);
1509 break;
1510 case AV_OPT_TYPE_STRING:
1511 set_string(s, opt, opt->default_val.str, dst);
1512 break;
1513 case AV_OPT_TYPE_IMAGE_SIZE:
1514 set_string_image_size(s, opt, opt->default_val.str, dst);
1515 break;
1516 case AV_OPT_TYPE_VIDEO_RATE:
1517 set_string_video_rate(s, opt, opt->default_val.str, dst);
1518 break;
1519 case AV_OPT_TYPE_BINARY:
1520 set_string_binary(s, opt, opt->default_val.str, dst);
1521 break;
1522 case AV_OPT_TYPE_CHLAYOUT:
1523 set_string_channel_layout(s, opt, opt->default_val.str, dst);
1524 break;
1525 case AV_OPT_TYPE_DICT:
1526 set_string_dict(s, opt, opt->default_val.str, dst);
1527 break;
1528 default:
1529 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
1530 opt->type, opt->name);
1531 }
1532 }
1533 }
1534
1535 /**
1536 * Store the value in the field in ctx that is named like key.
1537 * ctx must be an AVClass context, storing is done using AVOptions.
1538 *
1539 * @param buf the string to parse, buf will be updated to point at the
1540 * separator just after the parsed key/value pair
1541 * @param key_val_sep a 0-terminated list of characters used to
1542 * separate key from value
1543 * @param pairs_sep a 0-terminated list of characters used to separate
1544 * two pairs from each other
1545 * @return 0 if the key/value pair has been successfully parsed and
1546 * set, or a negative value corresponding to an AVERROR code in case
1547 * of error:
1548 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1549 * the error code issued by av_opt_set() if the key/value pair
1550 * cannot be set
1551 */
parse_key_value_pair(void * ctx,const char ** buf,const char * key_val_sep,const char * pairs_sep)1552 static int parse_key_value_pair(void *ctx, const char **buf,
1553 const char *key_val_sep, const char *pairs_sep)
1554 {
1555 char *key = av_get_token(buf, key_val_sep);
1556 char *val;
1557 int ret;
1558
1559 if (!key)
1560 return AVERROR(ENOMEM);
1561
1562 if (*key && strspn(*buf, key_val_sep)) {
1563 (*buf)++;
1564 val = av_get_token(buf, pairs_sep);
1565 if (!val) {
1566 av_freep(&key);
1567 return AVERROR(ENOMEM);
1568 }
1569 } else {
1570 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
1571 av_free(key);
1572 return AVERROR(EINVAL);
1573 }
1574
1575 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
1576
1577 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
1578 if (ret == AVERROR_OPTION_NOT_FOUND)
1579 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
1580
1581 av_free(key);
1582 av_free(val);
1583 return ret;
1584 }
1585
av_set_options_string(void * ctx,const char * opts,const char * key_val_sep,const char * pairs_sep)1586 int av_set_options_string(void *ctx, const char *opts,
1587 const char *key_val_sep, const char *pairs_sep)
1588 {
1589 int ret, count = 0;
1590
1591 if (!opts)
1592 return 0;
1593
1594 while (*opts) {
1595 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
1596 return ret;
1597 count++;
1598
1599 if (*opts)
1600 opts++;
1601 }
1602
1603 return count;
1604 }
1605
1606 #define WHITESPACES " \n\t\r"
1607
is_key_char(char c)1608 static int is_key_char(char c)
1609 {
1610 return (unsigned)((c | 32) - 'a') < 26 ||
1611 (unsigned)(c - '0') < 10 ||
1612 c == '-' || c == '_' || c == '/' || c == '.';
1613 }
1614
1615 /**
1616 * Read a key from a string.
1617 *
1618 * The key consists of is_key_char characters and must be terminated by a
1619 * character from the delim string; spaces are ignored.
1620 *
1621 * @return 0 for success (even with ellipsis), <0 for failure
1622 */
get_key(const char ** ropts,const char * delim,char ** rkey)1623 static int get_key(const char **ropts, const char *delim, char **rkey)
1624 {
1625 const char *opts = *ropts;
1626 const char *key_start, *key_end;
1627
1628 key_start = opts += strspn(opts, WHITESPACES);
1629 while (is_key_char(*opts))
1630 opts++;
1631 key_end = opts;
1632 opts += strspn(opts, WHITESPACES);
1633 if (!*opts || !strchr(delim, *opts))
1634 return AVERROR(EINVAL);
1635 opts++;
1636 if (!(*rkey = av_malloc(key_end - key_start + 1)))
1637 return AVERROR(ENOMEM);
1638 memcpy(*rkey, key_start, key_end - key_start);
1639 (*rkey)[key_end - key_start] = 0;
1640 *ropts = opts;
1641 return 0;
1642 }
1643
av_opt_get_key_value(const char ** ropts,const char * key_val_sep,const char * pairs_sep,unsigned flags,char ** rkey,char ** rval)1644 int av_opt_get_key_value(const char **ropts,
1645 const char *key_val_sep, const char *pairs_sep,
1646 unsigned flags,
1647 char **rkey, char **rval)
1648 {
1649 int ret;
1650 char *key = NULL, *val;
1651 const char *opts = *ropts;
1652
1653 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
1654 !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
1655 return AVERROR(EINVAL);
1656 if (!(val = av_get_token(&opts, pairs_sep))) {
1657 av_free(key);
1658 return AVERROR(ENOMEM);
1659 }
1660 *ropts = opts;
1661 *rkey = key;
1662 *rval = val;
1663 return 0;
1664 }
1665
av_opt_set_from_string(void * ctx,const char * opts,const char * const * shorthand,const char * key_val_sep,const char * pairs_sep)1666 int av_opt_set_from_string(void *ctx, const char *opts,
1667 const char *const *shorthand,
1668 const char *key_val_sep, const char *pairs_sep)
1669 {
1670 int ret, count = 0;
1671 const char *dummy_shorthand = NULL;
1672 char *av_uninit(parsed_key), *av_uninit(value);
1673 const char *key;
1674
1675 if (!opts)
1676 return 0;
1677 if (!shorthand)
1678 shorthand = &dummy_shorthand;
1679
1680 while (*opts) {
1681 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
1682 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
1683 &parsed_key, &value);
1684 if (ret < 0) {
1685 if (ret == AVERROR(EINVAL))
1686 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
1687 else
1688 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
1689 av_err2str(ret));
1690 return ret;
1691 }
1692 if (*opts)
1693 opts++;
1694 if (parsed_key) {
1695 key = parsed_key;
1696 while (*shorthand) /* discard all remaining shorthand */
1697 shorthand++;
1698 } else {
1699 key = *(shorthand++);
1700 }
1701
1702 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
1703 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
1704 if (ret == AVERROR_OPTION_NOT_FOUND)
1705 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
1706 av_free(value);
1707 av_free(parsed_key);
1708 return ret;
1709 }
1710
1711 av_free(value);
1712 av_free(parsed_key);
1713 count++;
1714 }
1715 return count;
1716 }
1717
av_opt_free(void * obj)1718 void av_opt_free(void *obj)
1719 {
1720 const AVOption *o = NULL;
1721 while ((o = av_opt_next(obj, o))) {
1722 switch (o->type) {
1723 case AV_OPT_TYPE_STRING:
1724 case AV_OPT_TYPE_BINARY:
1725 av_freep((uint8_t *)obj + o->offset);
1726 break;
1727
1728 case AV_OPT_TYPE_DICT:
1729 av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
1730 break;
1731
1732 case AV_OPT_TYPE_CHLAYOUT:
1733 av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset));
1734 break;
1735
1736 default:
1737 break;
1738 }
1739 }
1740 }
1741
av_opt_set_dict2(void * obj,AVDictionary ** options,int search_flags)1742 int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
1743 {
1744 AVDictionaryEntry *t = NULL;
1745 AVDictionary *tmp = NULL;
1746 int ret;
1747
1748 if (!options)
1749 return 0;
1750
1751 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
1752 ret = av_opt_set(obj, t->key, t->value, search_flags);
1753 if (ret == AVERROR_OPTION_NOT_FOUND)
1754 ret = av_dict_set(&tmp, t->key, t->value, 0);
1755 if (ret < 0) {
1756 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
1757 av_dict_free(&tmp);
1758 return ret;
1759 }
1760 }
1761 av_dict_free(options);
1762 *options = tmp;
1763 return 0;
1764 }
1765
av_opt_set_dict(void * obj,AVDictionary ** options)1766 int av_opt_set_dict(void *obj, AVDictionary **options)
1767 {
1768 return av_opt_set_dict2(obj, options, 0);
1769 }
1770
av_opt_find(void * obj,const char * name,const char * unit,int opt_flags,int search_flags)1771 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
1772 int opt_flags, int search_flags)
1773 {
1774 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1775 }
1776
av_opt_find2(void * obj,const char * name,const char * unit,int opt_flags,int search_flags,void ** target_obj)1777 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
1778 int opt_flags, int search_flags, void **target_obj)
1779 {
1780 const AVClass *c;
1781 const AVOption *o = NULL;
1782
1783 if(!obj)
1784 return NULL;
1785
1786 c= *(AVClass**)obj;
1787
1788 if (!c)
1789 return NULL;
1790
1791 if (search_flags & AV_OPT_SEARCH_CHILDREN) {
1792 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
1793 void *iter = NULL;
1794 const AVClass *child;
1795 while (child = av_opt_child_class_iterate(c, &iter))
1796 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
1797 return o;
1798 } else {
1799 void *child = NULL;
1800 while (child = av_opt_child_next(obj, child))
1801 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1802 return o;
1803 }
1804 }
1805
1806 while (o = av_opt_next(obj, o)) {
1807 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
1808 ((!unit && o->type != AV_OPT_TYPE_CONST) ||
1809 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
1810 if (target_obj) {
1811 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
1812 *target_obj = obj;
1813 else
1814 *target_obj = NULL;
1815 }
1816 return o;
1817 }
1818 }
1819 return NULL;
1820 }
1821
av_opt_child_next(void * obj,void * prev)1822 void *av_opt_child_next(void *obj, void *prev)
1823 {
1824 const AVClass *c = *(AVClass **)obj;
1825 if (c->child_next)
1826 return c->child_next(obj, prev);
1827 return NULL;
1828 }
1829
av_opt_child_class_iterate(const AVClass * parent,void ** iter)1830 const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter)
1831 {
1832 if (parent->child_class_iterate)
1833 return parent->child_class_iterate(iter);
1834 return NULL;
1835 }
1836
av_opt_ptr(const AVClass * class,void * obj,const char * name)1837 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
1838 {
1839 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
1840 if(!opt)
1841 return NULL;
1842 return (uint8_t*)obj + opt->offset;
1843 }
1844
opt_size(enum AVOptionType type)1845 static int opt_size(enum AVOptionType type)
1846 {
1847 switch(type) {
1848 case AV_OPT_TYPE_BOOL:
1849 case AV_OPT_TYPE_INT:
1850 case AV_OPT_TYPE_FLAGS:
1851 return sizeof(int);
1852 case AV_OPT_TYPE_DURATION:
1853 #if FF_API_OLD_CHANNEL_LAYOUT
1854 FF_DISABLE_DEPRECATION_WARNINGS
1855 case AV_OPT_TYPE_CHANNEL_LAYOUT:
1856 FF_ENABLE_DEPRECATION_WARNINGS
1857 #endif
1858 case AV_OPT_TYPE_INT64:
1859 case AV_OPT_TYPE_UINT64:
1860 return sizeof(int64_t);
1861 case AV_OPT_TYPE_DOUBLE:
1862 return sizeof(double);
1863 case AV_OPT_TYPE_FLOAT:
1864 return sizeof(float);
1865 case AV_OPT_TYPE_STRING:
1866 return sizeof(uint8_t*);
1867 case AV_OPT_TYPE_VIDEO_RATE:
1868 case AV_OPT_TYPE_RATIONAL:
1869 return sizeof(AVRational);
1870 case AV_OPT_TYPE_BINARY:
1871 return sizeof(uint8_t*) + sizeof(int);
1872 case AV_OPT_TYPE_IMAGE_SIZE:
1873 return sizeof(int[2]);
1874 case AV_OPT_TYPE_PIXEL_FMT:
1875 return sizeof(enum AVPixelFormat);
1876 case AV_OPT_TYPE_SAMPLE_FMT:
1877 return sizeof(enum AVSampleFormat);
1878 case AV_OPT_TYPE_COLOR:
1879 return 4;
1880 }
1881 return AVERROR(EINVAL);
1882 }
1883
av_opt_copy(void * dst,const void * src)1884 int av_opt_copy(void *dst, const void *src)
1885 {
1886 const AVOption *o = NULL;
1887 const AVClass *c;
1888 int ret = 0;
1889
1890 if (!src)
1891 return AVERROR(EINVAL);
1892
1893 c = *(AVClass **)src;
1894 if (!c || c != *(AVClass **)dst)
1895 return AVERROR(EINVAL);
1896
1897 while ((o = av_opt_next(src, o))) {
1898 void *field_dst = (uint8_t *)dst + o->offset;
1899 void *field_src = (uint8_t *)src + o->offset;
1900 uint8_t **field_dst8 = (uint8_t **)field_dst;
1901 uint8_t **field_src8 = (uint8_t **)field_src;
1902
1903 if (o->type == AV_OPT_TYPE_STRING) {
1904 if (*field_dst8 != *field_src8)
1905 av_freep(field_dst8);
1906 *field_dst8 = av_strdup(*field_src8);
1907 if (*field_src8 && !*field_dst8)
1908 ret = AVERROR(ENOMEM);
1909 } else if (o->type == AV_OPT_TYPE_BINARY) {
1910 int len = *(int *)(field_src8 + 1);
1911 if (*field_dst8 != *field_src8)
1912 av_freep(field_dst8);
1913 *field_dst8 = av_memdup(*field_src8, len);
1914 if (len && !*field_dst8) {
1915 ret = AVERROR(ENOMEM);
1916 len = 0;
1917 }
1918 *(int *)(field_dst8 + 1) = len;
1919 } else if (o->type == AV_OPT_TYPE_CONST) {
1920 // do nothing
1921 } else if (o->type == AV_OPT_TYPE_DICT) {
1922 AVDictionary **sdict = (AVDictionary **) field_src;
1923 AVDictionary **ddict = (AVDictionary **) field_dst;
1924 int ret2;
1925 if (*sdict != *ddict)
1926 av_dict_free(ddict);
1927 *ddict = NULL;
1928 ret2 = av_dict_copy(ddict, *sdict, 0);
1929 if (ret2 < 0)
1930 ret = ret2;
1931 } else if (o->type == AV_OPT_TYPE_CHLAYOUT) {
1932 if (field_dst != field_src)
1933 ret = av_channel_layout_copy(field_dst, field_src);
1934 } else {
1935 int size = opt_size(o->type);
1936 if (size < 0)
1937 ret = size;
1938 else
1939 memcpy(field_dst, field_src, size);
1940 }
1941 }
1942 return ret;
1943 }
1944
av_opt_query_ranges(AVOptionRanges ** ranges_arg,void * obj,const char * key,int flags)1945 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1946 {
1947 int ret;
1948 const AVClass *c = *(AVClass**)obj;
1949 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = c->query_ranges;
1950
1951 if (!callback)
1952 callback = av_opt_query_ranges_default;
1953
1954 ret = callback(ranges_arg, obj, key, flags);
1955 if (ret >= 0) {
1956 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE))
1957 ret = 1;
1958 (*ranges_arg)->nb_components = ret;
1959 }
1960 return ret;
1961 }
1962
av_opt_query_ranges_default(AVOptionRanges ** ranges_arg,void * obj,const char * key,int flags)1963 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1964 {
1965 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
1966 AVOptionRange **range_array = av_mallocz(sizeof(void*));
1967 AVOptionRange *range = av_mallocz(sizeof(*range));
1968 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
1969 int ret;
1970
1971 *ranges_arg = NULL;
1972
1973 if (!ranges || !range || !range_array || !field) {
1974 ret = AVERROR(ENOMEM);
1975 goto fail;
1976 }
1977
1978 ranges->range = range_array;
1979 ranges->range[0] = range;
1980 ranges->nb_ranges = 1;
1981 ranges->nb_components = 1;
1982 range->is_range = 1;
1983 range->value_min = field->min;
1984 range->value_max = field->max;
1985
1986 switch (field->type) {
1987 case AV_OPT_TYPE_BOOL:
1988 case AV_OPT_TYPE_INT:
1989 case AV_OPT_TYPE_INT64:
1990 case AV_OPT_TYPE_UINT64:
1991 case AV_OPT_TYPE_PIXEL_FMT:
1992 case AV_OPT_TYPE_SAMPLE_FMT:
1993 case AV_OPT_TYPE_FLOAT:
1994 case AV_OPT_TYPE_DOUBLE:
1995 case AV_OPT_TYPE_DURATION:
1996 case AV_OPT_TYPE_COLOR:
1997 #if FF_API_OLD_CHANNEL_LAYOUT
1998 FF_DISABLE_DEPRECATION_WARNINGS
1999 case AV_OPT_TYPE_CHANNEL_LAYOUT:
2000 FF_ENABLE_DEPRECATION_WARNINGS
2001 #endif
2002 break;
2003 case AV_OPT_TYPE_STRING:
2004 range->component_min = 0;
2005 range->component_max = 0x10FFFF; // max unicode value
2006 range->value_min = -1;
2007 range->value_max = INT_MAX;
2008 break;
2009 case AV_OPT_TYPE_RATIONAL:
2010 range->component_min = INT_MIN;
2011 range->component_max = INT_MAX;
2012 break;
2013 case AV_OPT_TYPE_IMAGE_SIZE:
2014 range->component_min = 0;
2015 range->component_max = INT_MAX/128/8;
2016 range->value_min = 0;
2017 range->value_max = INT_MAX/8;
2018 break;
2019 case AV_OPT_TYPE_VIDEO_RATE:
2020 range->component_min = 1;
2021 range->component_max = INT_MAX;
2022 range->value_min = 1;
2023 range->value_max = INT_MAX;
2024 break;
2025 default:
2026 ret = AVERROR(ENOSYS);
2027 goto fail;
2028 }
2029
2030 *ranges_arg = ranges;
2031 return 1;
2032 fail:
2033 av_free(ranges);
2034 av_free(range);
2035 av_free(range_array);
2036 return ret;
2037 }
2038
av_opt_freep_ranges(AVOptionRanges ** rangesp)2039 void av_opt_freep_ranges(AVOptionRanges **rangesp)
2040 {
2041 int i;
2042 AVOptionRanges *ranges = *rangesp;
2043
2044 if (!ranges)
2045 return;
2046
2047 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) {
2048 AVOptionRange *range = ranges->range[i];
2049 if (range) {
2050 av_freep(&range->str);
2051 av_freep(&ranges->range[i]);
2052 }
2053 }
2054 av_freep(&ranges->range);
2055 av_freep(rangesp);
2056 }
2057
av_opt_is_set_to_default(void * obj,const AVOption * o)2058 int av_opt_is_set_to_default(void *obj, const AVOption *o)
2059 {
2060 int64_t i64;
2061 double d, d2;
2062 float f;
2063 AVRational q;
2064 int ret, w, h;
2065 char *str;
2066 void *dst;
2067
2068 if (!o || !obj)
2069 return AVERROR(EINVAL);
2070
2071 dst = ((uint8_t*)obj) + o->offset;
2072
2073 switch (o->type) {
2074 case AV_OPT_TYPE_CONST:
2075 return 1;
2076 case AV_OPT_TYPE_BOOL:
2077 case AV_OPT_TYPE_FLAGS:
2078 case AV_OPT_TYPE_PIXEL_FMT:
2079 case AV_OPT_TYPE_SAMPLE_FMT:
2080 case AV_OPT_TYPE_INT:
2081 #if FF_API_OLD_CHANNEL_LAYOUT
2082 FF_DISABLE_DEPRECATION_WARNINGS
2083 case AV_OPT_TYPE_CHANNEL_LAYOUT:
2084 FF_ENABLE_DEPRECATION_WARNINGS
2085 #endif
2086 case AV_OPT_TYPE_DURATION:
2087 case AV_OPT_TYPE_INT64:
2088 case AV_OPT_TYPE_UINT64:
2089 read_number(o, dst, NULL, NULL, &i64);
2090 return o->default_val.i64 == i64;
2091 case AV_OPT_TYPE_CHLAYOUT: {
2092 AVChannelLayout ch_layout = { 0 };
2093 if (o->default_val.str) {
2094 if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0)
2095 return ret;
2096 }
2097 return !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout);
2098 }
2099 case AV_OPT_TYPE_STRING:
2100 str = *(char **)dst;
2101 if (str == o->default_val.str) //2 NULLs
2102 return 1;
2103 if (!str || !o->default_val.str) //1 NULL
2104 return 0;
2105 return !strcmp(str, o->default_val.str);
2106 case AV_OPT_TYPE_DOUBLE:
2107 read_number(o, dst, &d, NULL, NULL);
2108 return o->default_val.dbl == d;
2109 case AV_OPT_TYPE_FLOAT:
2110 read_number(o, dst, &d, NULL, NULL);
2111 f = o->default_val.dbl;
2112 d2 = f;
2113 return d2 == d;
2114 case AV_OPT_TYPE_RATIONAL:
2115 q = av_d2q(o->default_val.dbl, INT_MAX);
2116 return !av_cmp_q(*(AVRational*)dst, q);
2117 case AV_OPT_TYPE_BINARY: {
2118 struct {
2119 uint8_t *data;
2120 int size;
2121 } tmp = {0};
2122 int opt_size = *(int *)((void **)dst + 1);
2123 void *opt_ptr = *(void **)dst;
2124 if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str)))
2125 return 1;
2126 if (!opt_size || !o->default_val.str || !strlen(o->default_val.str ))
2127 return 0;
2128 if (opt_size != strlen(o->default_val.str) / 2)
2129 return 0;
2130 ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);
2131 if (!ret)
2132 ret = !memcmp(opt_ptr, tmp.data, tmp.size);
2133 av_free(tmp.data);
2134 return ret;
2135 }
2136 case AV_OPT_TYPE_DICT: {
2137 AVDictionary *dict1 = NULL;
2138 AVDictionary *dict2 = *(AVDictionary **)dst;
2139 AVDictionaryEntry *en1 = NULL;
2140 AVDictionaryEntry *en2 = NULL;
2141 ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0);
2142 if (ret < 0) {
2143 av_dict_free(&dict1);
2144 return ret;
2145 }
2146 do {
2147 en1 = av_dict_get(dict1, "", en1, AV_DICT_IGNORE_SUFFIX);
2148 en2 = av_dict_get(dict2, "", en2, AV_DICT_IGNORE_SUFFIX);
2149 } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value));
2150 av_dict_free(&dict1);
2151 return (!en1 && !en2);
2152 }
2153 case AV_OPT_TYPE_IMAGE_SIZE:
2154 if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
2155 w = h = 0;
2156 else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)
2157 return ret;
2158 return (w == *(int *)dst) && (h == *((int *)dst+1));
2159 case AV_OPT_TYPE_VIDEO_RATE:
2160 q = (AVRational){0, 0};
2161 if (o->default_val.str) {
2162 if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0)
2163 return ret;
2164 }
2165 return !av_cmp_q(*(AVRational*)dst, q);
2166 case AV_OPT_TYPE_COLOR: {
2167 uint8_t color[4] = {0, 0, 0, 0};
2168 if (o->default_val.str) {
2169 if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0)
2170 return ret;
2171 }
2172 return !memcmp(color, dst, sizeof(color));
2173 }
2174 default:
2175 av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);
2176 break;
2177 }
2178 return AVERROR_PATCHWELCOME;
2179 }
2180
av_opt_is_set_to_default_by_name(void * obj,const char * name,int search_flags)2181 int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
2182 {
2183 const AVOption *o;
2184 void *target;
2185 if (!obj)
2186 return AVERROR(EINVAL);
2187 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target);
2188 if (!o)
2189 return AVERROR_OPTION_NOT_FOUND;
2190 return av_opt_is_set_to_default(target, o);
2191 }
2192
av_opt_serialize(void * obj,int opt_flags,int flags,char ** buffer,const char key_val_sep,const char pairs_sep)2193 int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
2194 const char key_val_sep, const char pairs_sep)
2195 {
2196 const AVOption *o = NULL;
2197 uint8_t *buf;
2198 AVBPrint bprint;
2199 int ret, cnt = 0;
2200 const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
2201
2202 if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
2203 pairs_sep == '\\' || key_val_sep == '\\') {
2204 av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
2205 return AVERROR(EINVAL);
2206 }
2207
2208 if (!obj || !buffer)
2209 return AVERROR(EINVAL);
2210
2211 *buffer = NULL;
2212 av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
2213
2214 while (o = av_opt_next(obj, o)) {
2215 if (o->type == AV_OPT_TYPE_CONST)
2216 continue;
2217 if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
2218 continue;
2219 else if (((o->flags & opt_flags) != opt_flags))
2220 continue;
2221 if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
2222 continue;
2223 if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
2224 av_bprint_finalize(&bprint, NULL);
2225 return ret;
2226 }
2227 if (buf) {
2228 if (cnt++)
2229 av_bprint_append_data(&bprint, &pairs_sep, 1);
2230 av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
2231 av_bprint_append_data(&bprint, &key_val_sep, 1);
2232 av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
2233 av_freep(&buf);
2234 }
2235 }
2236 ret = av_bprint_finalize(&bprint, buffer);
2237 if (ret < 0)
2238 return ret;
2239 return 0;
2240 }
2241