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