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