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