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