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