FFmpeg  1.2.12
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 
28 #include "avutil.h"
29 #include "avstring.h"
30 #include "common.h"
31 #include "opt.h"
32 #include "eval.h"
33 #include "dict.h"
34 #include "log.h"
35 #include "parseutils.h"
36 #include "pixdesc.h"
37 #include "mathematics.h"
38 #include "samplefmt.h"
39 
40 #include <float.h>
41 
42 #if FF_API_FIND_OPT
43 //FIXME order them and do a bin search
44 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
45 {
46  const AVOption *o = NULL;
47 
48  while ((o = av_next_option(v, o))) {
49  if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
50  return o;
51  }
52  return NULL;
53 }
54 #endif
55 
56 #if FF_API_OLD_AVOPTIONS
57 const AVOption *av_next_option(void *obj, const AVOption *last)
58 {
59  return av_opt_next(obj, last);
60 }
61 #endif
62 
63 const AVOption *av_opt_next(void *obj, const AVOption *last)
64 {
65  AVClass *class = *(AVClass**)obj;
66  if (!last && class->option && class->option[0].name)
67  return class->option;
68  if (last && last[1].name)
69  return ++last;
70  return NULL;
71 }
72 
73 static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
74 {
75  switch (o->type) {
76  case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
77  case AV_OPT_TYPE_PIXEL_FMT: *intnum = *(enum AVPixelFormat *)dst;return 0;
78  case AV_OPT_TYPE_SAMPLE_FMT:*intnum = *(enum AVSampleFormat*)dst;return 0;
79  case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
80  case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
81  case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
82  case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
83  case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
84  *den = ((AVRational*)dst)->den;
85  return 0;
86  case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0;
87  }
88  return AVERROR(EINVAL);
89 }
90 
91 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
92 {
93  if (o->max*den < num*intnum || o->min*den > num*intnum) {
94  av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
95  num*intnum/den, o->name, o->min, o->max);
96  return AVERROR(ERANGE);
97  }
98 
99  switch (o->type) {
100  case AV_OPT_TYPE_PIXEL_FMT: *(enum AVPixelFormat *)dst = llrint(num/den) * intnum; break;
101  case AV_OPT_TYPE_SAMPLE_FMT:*(enum AVSampleFormat*)dst = llrint(num/den) * intnum; break;
102  case AV_OPT_TYPE_FLAGS:
103  case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
104  case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
105  case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
106  case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
108  if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
109  else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
110  break;
111  default:
112  return AVERROR(EINVAL);
113  }
114  return 0;
115 }
116 
117 static const double const_values[] = {
118  M_PI,
119  M_E,
120  FF_QP2LAMBDA,
121  0
122 };
123 
124 static const char * const const_names[] = {
125  "PI",
126  "E",
127  "QP2LAMBDA",
128  0
129 };
130 
131 static int hexchar2int(char c) {
132  if (c >= '0' && c <= '9') return c - '0';
133  if (c >= 'a' && c <= 'f') return c - 'a' + 10;
134  if (c >= 'A' && c <= 'F') return c - 'A' + 10;
135  return -1;
136 }
137 
138 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
139 {
140  int *lendst = (int *)(dst + 1);
141  uint8_t *bin, *ptr;
142  int len = strlen(val);
143 
144  av_freep(dst);
145  *lendst = 0;
146 
147  if (len & 1)
148  return AVERROR(EINVAL);
149  len /= 2;
150 
151  ptr = bin = av_malloc(len);
152  if (!ptr)
153  return AVERROR(ENOMEM);
154  while (*val) {
155  int a = hexchar2int(*val++);
156  int b = hexchar2int(*val++);
157  if (a < 0 || b < 0) {
158  av_free(bin);
159  return AVERROR(EINVAL);
160  }
161  *ptr++ = (a << 4) | b;
162  }
163  *dst = bin;
164  *lendst = len;
165 
166  return 0;
167 }
168 
169 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
170 {
171  av_freep(dst);
172  *dst = av_strdup(val);
173  return 0;
174 }
175 
176 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
177  opt->type == AV_OPT_TYPE_CONST || \
178  opt->type == AV_OPT_TYPE_FLAGS || \
179  opt->type == AV_OPT_TYPE_INT) ? \
180  opt->default_val.i64 : opt->default_val.dbl)
181 
182 static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
183 {
184  int ret = 0, notfirst = 0;
185  for (;;) {
186  int i, den = 1;
187  char buf[256];
188  int cmd = 0;
189  double d, num = 1;
190  int64_t intnum = 1;
191 
192  i = 0;
193  if (*val == '+' || *val == '-') {
194  if (o->type == AV_OPT_TYPE_FLAGS)
195  cmd = *(val++);
196  else if (!notfirst)
197  buf[i++] = *val;
198  }
199 
200  for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
201  buf[i] = val[i];
202  buf[i] = 0;
203 
204  {
205  const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
206  if (o_named && o_named->type == AV_OPT_TYPE_CONST)
207  d = DEFAULT_NUMVAL(o_named);
208  else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
209  else if (!strcmp(buf, "max" )) d = o->max;
210  else if (!strcmp(buf, "min" )) d = o->min;
211  else if (!strcmp(buf, "none" )) d = 0;
212  else if (!strcmp(buf, "all" )) d = ~0;
213  else {
214  int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
215  if (res < 0) {
216  av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
217  return res;
218  }
219  }
220  }
221  if (o->type == AV_OPT_TYPE_FLAGS) {
222  read_number(o, dst, NULL, NULL, &intnum);
223  if (cmd == '+') d = intnum | (int64_t)d;
224  else if (cmd == '-') d = intnum &~(int64_t)d;
225  } else {
226  read_number(o, dst, &num, &den, &intnum);
227  if (cmd == '+') d = notfirst*num*intnum/den + d;
228  else if (cmd == '-') d = notfirst*num*intnum/den - d;
229  }
230 
231  if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
232  return ret;
233  val += i;
234  if (!*val)
235  return 0;
236  notfirst = 1;
237  }
238 
239  return 0;
240 }
241 
242 #if FF_API_OLD_AVOPTIONS
243 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
244 {
245  const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
246  if (o_out)
247  *o_out = o;
248  return av_opt_set(obj, name, val, 0);
249 }
250 #endif
251 
252 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
253 {
254  int ret = 0;
255  void *dst, *target_obj;
256  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
257  if (!o || !target_obj)
259  if (!val && (o->type != AV_OPT_TYPE_STRING &&
262  return AVERROR(EINVAL);
263 
264  dst = ((uint8_t*)target_obj) + o->offset;
265  switch (o->type) {
266  case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
267  case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
268  case AV_OPT_TYPE_FLAGS:
269  case AV_OPT_TYPE_INT:
270  case AV_OPT_TYPE_INT64:
271  case AV_OPT_TYPE_FLOAT:
272  case AV_OPT_TYPE_DOUBLE:
273  case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
275  if (!val || !strcmp(val, "none")) {
276  *(int *)dst = *((int *)dst + 1) = 0;
277  return 0;
278  }
279  ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
280  if (ret < 0)
281  av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
282  return ret;
284  if (!val || !strcmp(val, "none")) {
285  ret = AV_PIX_FMT_NONE;
286  } else {
287  ret = av_get_pix_fmt(val);
288  if (ret == AV_PIX_FMT_NONE) {
289  char *tail;
290  ret = strtol(val, &tail, 0);
291  if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) {
292  av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
293  return AVERROR(EINVAL);
294  }
295  }
296  }
297  *(enum AVPixelFormat *)dst = ret;
298  return 0;
300  if (!val || !strcmp(val, "none")) {
301  ret = AV_SAMPLE_FMT_NONE;
302  } else {
303  ret = av_get_sample_fmt(val);
304  if (ret == AV_SAMPLE_FMT_NONE) {
305  char *tail;
306  ret = strtol(val, &tail, 0);
307  if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) {
308  av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val);
309  return AVERROR(EINVAL);
310  }
311  }
312  }
313  *(enum AVSampleFormat *)dst = ret;
314  return 0;
315  }
316 
317  av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
318  return AVERROR(EINVAL);
319 }
320 
321 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
322  int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
323  {\
324  if (!o || o->type != opttype)\
325  return AVERROR(EINVAL);\
326  return set_string_number(obj, o, val, name ## _out);\
327  }
328 
331 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
332 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
333 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
335 
336 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
337  int search_flags)
338 {
339  void *dst, *target_obj;
340  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
341 
342  if (!o || !target_obj)
344 
345  dst = ((uint8_t*)target_obj) + o->offset;
346  return write_number(obj, o, dst, num, den, intnum);
347 }
348 
349 #if FF_API_OLD_AVOPTIONS
350 const AVOption *av_set_double(void *obj, const char *name, double n)
351 {
352  const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
353  if (set_number(obj, name, n, 1, 1, 0) < 0)
354  return NULL;
355  return o;
356 }
357 
358 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
359 {
360  const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
361  if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
362  return NULL;
363  return o;
364 }
365 
366 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
367 {
368  const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
369  if (set_number(obj, name, 1, 1, n, 0) < 0)
370  return NULL;
371  return o;
372 }
373 #endif
374 
375 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
376 {
377  return set_number(obj, name, 1, 1, val, search_flags);
378 }
379 
380 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
381 {
382  return set_number(obj, name, val, 1, 1, search_flags);
383 }
384 
385 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
386 {
387  return set_number(obj, name, val.num, val.den, 1, search_flags);
388 }
389 
390 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
391 {
392  void *target_obj;
393  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
394  uint8_t *ptr;
395  uint8_t **dst;
396  int *lendst;
397 
398  if (!o || !target_obj)
400 
401  if (o->type != AV_OPT_TYPE_BINARY)
402  return AVERROR(EINVAL);
403 
404  ptr = av_malloc(len);
405  if (!ptr)
406  return AVERROR(ENOMEM);
407 
408  dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
409  lendst = (int *)(dst + 1);
410 
411  av_free(*dst);
412  *dst = ptr;
413  *lendst = len;
414  memcpy(ptr, val, len);
415 
416  return 0;
417 }
418 
419 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
420 {
421  void *target_obj;
422  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
423 
424  if (!o || !target_obj)
426  if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
427  av_log(obj, AV_LOG_ERROR,
428  "The value set by option '%s' is not an image size.\n", o->name);
429  return AVERROR(EINVAL);
430  }
431  if (w<0 || h<0) {
432  av_log(obj, AV_LOG_ERROR,
433  "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
434  return AVERROR(EINVAL);
435  }
436  *(int *)(((uint8_t *)target_obj) + o->offset) = w;
437  *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
438  return 0;
439 }
440 
441 static int set_format(void *obj, const char *name, int fmt, int search_flags,
442  enum AVOptionType type, const char *desc, int nb_fmts)
443 {
444  void *target_obj;
445  const AVOption *o = av_opt_find2(obj, name, NULL, 0,
446  search_flags, &target_obj);
447  int min, max;
448  const AVClass *class = *(AVClass **)obj;
449 
450  if (!o || !target_obj)
452  if (o->type != type) {
453  av_log(obj, AV_LOG_ERROR,
454  "The value set by option '%s' is not a %s format", name, desc);
455  return AVERROR(EINVAL);
456  }
457 
458 #if LIBAVUTIL_VERSION_MAJOR < 53
459  if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) {
460  min = -1;
461  max = nb_fmts-1;
462  } else
463 #endif
464  {
465  min = FFMIN(o->min, -1);
466  max = FFMAX(o->max, nb_fmts-1);
467  }
468  if (fmt < min || fmt > max) {
469  av_log(obj, AV_LOG_ERROR,
470  "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
471  fmt, name, desc, min, max);
472  return AVERROR(ERANGE);
473  }
474  *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
475  return 0;
476 }
477 
478 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
479 {
480  return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
481 }
482 
483 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
484 {
485  return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
486 }
487 
488 #if FF_API_OLD_AVOPTIONS
489 
494 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
495 {
496  const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
497  void *dst;
498  uint8_t *bin;
499  int len, i;
500  if (!o)
501  return NULL;
502  if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
503  return NULL;
504 
505  dst= ((uint8_t*)obj) + o->offset;
506  if (o_out) *o_out= o;
507 
508  switch (o->type) {
509  case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
510  case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
511  case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
512  case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
513  case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
514  case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
515  case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
516  case AV_OPT_TYPE_STRING: return *(void**)dst;
517  case AV_OPT_TYPE_BINARY:
518  len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
519  if (len >= (buf_len + 1)/2) return NULL;
520  bin = *(uint8_t**)dst;
521  for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
522  break;
523  default: return NULL;
524  }
525  return buf;
526 }
527 #endif
528 
529 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
530 {
531  void *dst, *target_obj;
532  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
533  uint8_t *bin, buf[128];
534  int len, i, ret;
535 
536  if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
538 
539  dst = (uint8_t*)target_obj + o->offset;
540 
541  buf[0] = 0;
542  switch (o->type) {
543  case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
544  case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
545  case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
546  case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
547  case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
548  case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
549  case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break;
550  case AV_OPT_TYPE_STRING:
551  if (*(uint8_t**)dst)
552  *out_val = av_strdup(*(uint8_t**)dst);
553  else
554  *out_val = av_strdup("");
555  return 0;
556  case AV_OPT_TYPE_BINARY:
557  len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
558  if ((uint64_t)len*2 + 1 > INT_MAX)
559  return AVERROR(EINVAL);
560  if (!(*out_val = av_malloc(len*2 + 1)))
561  return AVERROR(ENOMEM);
562  bin = *(uint8_t**)dst;
563  for (i = 0; i < len; i++)
564  snprintf(*out_val + i*2, 3, "%02X", bin[i]);
565  return 0;
567  ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
568  break;
570  ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
571  break;
573  ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
574  break;
575  default:
576  return AVERROR(EINVAL);
577  }
578 
579  if (ret >= sizeof(buf))
580  return AVERROR(EINVAL);
581  *out_val = av_strdup(buf);
582  return 0;
583 }
584 
585 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
586  int search_flags)
587 {
588  void *dst, *target_obj;
589  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
590  if (!o || !target_obj)
591  goto error;
592 
593  dst = ((uint8_t*)target_obj) + o->offset;
594 
595  if (o_out) *o_out= o;
596 
597  return read_number(o, dst, num, den, intnum);
598 
599 error:
600  *den=*intnum=0;
601  return -1;
602 }
603 
604 #if FF_API_OLD_AVOPTIONS
605 double av_get_double(void *obj, const char *name, const AVOption **o_out)
606 {
607  int64_t intnum=1;
608  double num=1;
609  int den=1;
610 
611  if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
612  return NAN;
613  return num*intnum/den;
614 }
615 
616 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
617 {
618  int64_t intnum=1;
619  double num=1;
620  int den=1;
621 
622  if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
623  return (AVRational){0, 0};
624  if (num == 1.0 && (int)intnum == intnum)
625  return (AVRational){intnum, den};
626  else
627  return av_d2q(num*intnum/den, 1<<24);
628 }
629 
630 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
631 {
632  int64_t intnum=1;
633  double num=1;
634  int den=1;
635 
636  if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
637  return -1;
638  return num*intnum/den;
639 }
640 #endif
641 
642 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
643 {
644  int64_t intnum = 1;
645  double num = 1;
646  int ret, den = 1;
647 
648  if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
649  return ret;
650  *out_val = num*intnum/den;
651  return 0;
652 }
653 
654 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
655 {
656  int64_t intnum = 1;
657  double num = 1;
658  int ret, den = 1;
659 
660  if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
661  return ret;
662  *out_val = num*intnum/den;
663  return 0;
664 }
665 
666 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
667 {
668  int64_t intnum = 1;
669  double num = 1;
670  int ret, den = 1;
671 
672  if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
673  return ret;
674 
675  if (num == 1.0 && (int)intnum == intnum)
676  *out_val = (AVRational){intnum, den};
677  else
678  *out_val = av_d2q(num*intnum/den, 1<<24);
679  return 0;
680 }
681 
682 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
683 {
684  void *dst, *target_obj;
685  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
686  if (!o || !target_obj)
688  if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
689  av_log(obj, AV_LOG_ERROR,
690  "The value for option '%s' is not an image size.\n", name);
691  return AVERROR(EINVAL);
692  }
693 
694  dst = ((uint8_t*)target_obj) + o->offset;
695  if (w_out) *w_out = *(int *)dst;
696  if (h_out) *h_out = *((int *)dst+1);
697  return 0;
698 }
699 
700 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
701  enum AVOptionType type, const char *desc)
702 {
703  void *dst, *target_obj;
704  const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
705  if (!o || !target_obj)
707  if (o->type != type) {
708  av_log(obj, AV_LOG_ERROR,
709  "The value for option '%s' is not a %s format.\n", desc, name);
710  return AVERROR(EINVAL);
711  }
712 
713  dst = ((uint8_t*)target_obj) + o->offset;
714  *out_fmt = *(int *)dst;
715  return 0;
716 }
717 
718 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
719 {
720  return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
721 }
722 
723 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
724 {
725  return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
726 }
727 
728 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
729 {
730  const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
731  const AVOption *flag = av_opt_find(obj, flag_name,
732  field ? field->unit : NULL, 0, 0);
733  int64_t res;
734 
735  if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
736  av_opt_get_int(obj, field_name, 0, &res) < 0)
737  return 0;
738  return res & flag->default_val.i64;
739 }
740 
741 static void log_value(void *av_log_obj, int level, double d)
742 {
743  if (d == INT_MAX) {
744  av_log(av_log_obj, level, "INT_MAX");
745  } else if (d == INT_MIN) {
746  av_log(av_log_obj, level, "INT_MIN");
747  } else if (d == (double)INT64_MAX) {
748  av_log(av_log_obj, level, "I64_MAX");
749  } else if (d == INT64_MIN) {
750  av_log(av_log_obj, level, "I64_MIN");
751  } else if (d == FLT_MAX) {
752  av_log(av_log_obj, level, "FLT_MAX");
753  } else if (d == FLT_MIN) {
754  av_log(av_log_obj, level, "FLT_MIN");
755  } else {
756  av_log(av_log_obj, level, "%g", d);
757  }
758 }
759 
760 static void opt_list(void *obj, void *av_log_obj, const char *unit,
761  int req_flags, int rej_flags)
762 {
763  const AVOption *opt=NULL;
764  AVOptionRanges *r;
765  int i;
766 
767  while ((opt = av_opt_next(obj, opt))) {
768  if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
769  continue;
770 
771  /* Don't print CONST's on level one.
772  * Don't print anything but CONST's on level two.
773  * Only print items from the requested unit.
774  */
775  if (!unit && opt->type==AV_OPT_TYPE_CONST)
776  continue;
777  else if (unit && opt->type!=AV_OPT_TYPE_CONST)
778  continue;
779  else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
780  continue;
781  else if (unit && opt->type == AV_OPT_TYPE_CONST)
782  av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
783  else
784  av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
785 
786  switch (opt->type) {
787  case AV_OPT_TYPE_FLAGS:
788  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
789  break;
790  case AV_OPT_TYPE_INT:
791  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
792  break;
793  case AV_OPT_TYPE_INT64:
794  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
795  break;
796  case AV_OPT_TYPE_DOUBLE:
797  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
798  break;
799  case AV_OPT_TYPE_FLOAT:
800  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
801  break;
802  case AV_OPT_TYPE_STRING:
803  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
804  break;
806  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
807  break;
808  case AV_OPT_TYPE_BINARY:
809  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
810  break;
812  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
813  break;
815  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
816  break;
818  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
819  break;
820  case AV_OPT_TYPE_CONST:
821  default:
822  av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
823  break;
824  }
825  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
826  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
827  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
828  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
829  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
830  av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
831 
832  if (opt->help)
833  av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
834 
835  if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
836  switch (opt->type) {
837  case AV_OPT_TYPE_INT:
838  case AV_OPT_TYPE_INT64:
839  case AV_OPT_TYPE_DOUBLE:
840  case AV_OPT_TYPE_FLOAT:
842  for (i = 0; i < r->nb_ranges; i++) {
843  av_log(av_log_obj, AV_LOG_INFO, " (from ");
844  log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
845  av_log(av_log_obj, AV_LOG_INFO, " to ");
846  log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
847  av_log(av_log_obj, AV_LOG_INFO, ")");
848  }
849  break;
850  }
852  }
853 
854  av_log(av_log_obj, AV_LOG_INFO, "\n");
855  if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
856  opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
857  }
858  }
859 }
860 
861 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
862 {
863  if (!obj)
864  return -1;
865 
866  av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
867 
868  opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
869 
870  return 0;
871 }
872 
873 void av_opt_set_defaults(void *s)
874 {
875 #if FF_API_OLD_AVOPTIONS
876  av_opt_set_defaults2(s, 0, 0);
877 }
878 
879 void av_opt_set_defaults2(void *s, int mask, int flags)
880 {
881 #endif
882  const AVClass *class = *(AVClass **)s;
883  const AVOption *opt = NULL;
884  while ((opt = av_opt_next(s, opt)) != NULL) {
885 #if FF_API_OLD_AVOPTIONS
886  if ((opt->flags & mask) != flags)
887  continue;
888 #endif
889  switch (opt->type) {
890  case AV_OPT_TYPE_CONST:
891  /* Nothing to be done here */
892  break;
893  case AV_OPT_TYPE_FLAGS:
894  case AV_OPT_TYPE_INT:
895  case AV_OPT_TYPE_INT64:
896  av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
897  break;
898  case AV_OPT_TYPE_DOUBLE:
899  case AV_OPT_TYPE_FLOAT: {
900  double val;
901  val = opt->default_val.dbl;
902  av_opt_set_double(s, opt->name, val, 0);
903  }
904  break;
905  case AV_OPT_TYPE_RATIONAL: {
906  AVRational val;
907  val = av_d2q(opt->default_val.dbl, INT_MAX);
908  av_opt_set_q(s, opt->name, val, 0);
909  }
910  break;
911  case AV_OPT_TYPE_STRING:
913  av_opt_set(s, opt->name, opt->default_val.str, 0);
914  break;
916 #if LIBAVUTIL_VERSION_MAJOR < 53
917  if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
918  av_opt_set(s, opt->name, opt->default_val.str, 0);
919  else
920 #endif
921  av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
922  break;
924 #if LIBAVUTIL_VERSION_MAJOR < 53
925  if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
926  av_opt_set(s, opt->name, opt->default_val.str, 0);
927  else
928 #endif
929  av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
930  break;
931  case AV_OPT_TYPE_BINARY:
932  /* Cannot set default for binary */
933  break;
934  default:
935  av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
936  }
937  }
938 }
939 
957 static int parse_key_value_pair(void *ctx, const char **buf,
958  const char *key_val_sep, const char *pairs_sep)
959 {
960  char *key = av_get_token(buf, key_val_sep);
961  char *val;
962  int ret;
963 
964  if (*key && strspn(*buf, key_val_sep)) {
965  (*buf)++;
966  val = av_get_token(buf, pairs_sep);
967  } else {
968  av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
969  av_free(key);
970  return AVERROR(EINVAL);
971  }
972 
973  av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
974 
975  ret = av_opt_set(ctx, key, val, 0);
976  if (ret == AVERROR_OPTION_NOT_FOUND)
977  av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
978 
979  av_free(key);
980  av_free(val);
981  return ret;
982 }
983 
984 int av_set_options_string(void *ctx, const char *opts,
985  const char *key_val_sep, const char *pairs_sep)
986 {
987  int ret, count = 0;
988 
989  if (!opts)
990  return 0;
991 
992  while (*opts) {
993  if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
994  return ret;
995  count++;
996 
997  if (*opts)
998  opts++;
999  }
1000 
1001  return count;
1002 }
1003 
1004 #define WHITESPACES " \n\t"
1005 
1006 static int is_key_char(char c)
1007 {
1008  return (unsigned)((c | 32) - 'a') < 26 ||
1009  (unsigned)(c - '0') < 10 ||
1010  c == '-' || c == '_' || c == '/' || c == '.';
1011 }
1012 
1021 static int get_key(const char **ropts, const char *delim, char **rkey)
1022 {
1023  const char *opts = *ropts;
1024  const char *key_start, *key_end;
1025 
1026  key_start = opts += strspn(opts, WHITESPACES);
1027  while (is_key_char(*opts))
1028  opts++;
1029  key_end = opts;
1030  opts += strspn(opts, WHITESPACES);
1031  if (!*opts || !strchr(delim, *opts))
1032  return AVERROR(EINVAL);
1033  opts++;
1034  if (!(*rkey = av_malloc(key_end - key_start + 1)))
1035  return AVERROR(ENOMEM);
1036  memcpy(*rkey, key_start, key_end - key_start);
1037  (*rkey)[key_end - key_start] = 0;
1038  *ropts = opts;
1039  return 0;
1040 }
1041 
1042 int av_opt_get_key_value(const char **ropts,
1043  const char *key_val_sep, const char *pairs_sep,
1044  unsigned flags,
1045  char **rkey, char **rval)
1046 {
1047  int ret;
1048  char *key = NULL, *val;
1049  const char *opts = *ropts;
1050 
1051  if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
1052  !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
1053  return AVERROR(EINVAL);
1054  if (!(val = av_get_token(&opts, pairs_sep))) {
1055  av_free(key);
1056  return AVERROR(ENOMEM);
1057  }
1058  *ropts = opts;
1059  *rkey = key;
1060  *rval = val;
1061  return 0;
1062 }
1063 
1064 int av_opt_set_from_string(void *ctx, const char *opts,
1065  const char *const *shorthand,
1066  const char *key_val_sep, const char *pairs_sep)
1067 {
1068  int ret, count = 0;
1069  const char *dummy_shorthand = NULL;
1070  char *av_uninit(parsed_key), *av_uninit(value);
1071  const char *key;
1072 
1073  if (!opts)
1074  return 0;
1075  if (!shorthand)
1076  shorthand = &dummy_shorthand;
1077 
1078  while (*opts) {
1079  ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
1080  *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
1081  &parsed_key, &value);
1082  if (ret < 0) {
1083  if (ret == AVERROR(EINVAL))
1084  av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
1085  else
1086  av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
1087  av_err2str(ret));
1088  return ret;
1089  }
1090  if (*opts)
1091  opts++;
1092  if (parsed_key) {
1093  key = parsed_key;
1094  while (*shorthand) /* discard all remaining shorthand */
1095  shorthand++;
1096  } else {
1097  key = *(shorthand++);
1098  }
1099 
1100  av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
1101  if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
1102  if (ret == AVERROR_OPTION_NOT_FOUND)
1103  av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
1104  av_free(value);
1105  av_free(parsed_key);
1106  return ret;
1107  }
1108 
1109  av_free(value);
1110  av_free(parsed_key);
1111  count++;
1112  }
1113  return count;
1114 }
1115 
1116 void av_opt_free(void *obj)
1117 {
1118  const AVOption *o = NULL;
1119  while ((o = av_opt_next(obj, o)))
1120  if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
1121  av_freep((uint8_t *)obj + o->offset);
1122 }
1123 
1125 {
1127  AVDictionary *tmp = NULL;
1128  int ret = 0;
1129 
1130  while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
1131  ret = av_opt_set(obj, t->key, t->value, 0);
1132  if (ret == AVERROR_OPTION_NOT_FOUND)
1133  av_dict_set(&tmp, t->key, t->value, 0);
1134  else if (ret < 0) {
1135  av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
1136  break;
1137  }
1138  ret = 0;
1139  }
1140  av_dict_free(options);
1141  *options = tmp;
1142  return ret;
1143 }
1144 
1145 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
1146  int opt_flags, int search_flags)
1147 {
1148  return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1149 }
1150 
1151 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
1152  int opt_flags, int search_flags, void **target_obj)
1153 {
1154  const AVClass *c;
1155  const AVOption *o = NULL;
1156 
1157  if(!obj)
1158  return NULL;
1159 
1160  c= *(AVClass**)obj;
1161 
1162  if (search_flags & AV_OPT_SEARCH_CHILDREN) {
1163  if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
1164  const AVClass *child = NULL;
1165  while (child = av_opt_child_class_next(c, child))
1166  if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
1167  return o;
1168  } else {
1169  void *child = NULL;
1170  while (child = av_opt_child_next(obj, child))
1171  if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1172  return o;
1173  }
1174  }
1175 
1176  while (o = av_opt_next(obj, o)) {
1177  if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
1178  ((!unit && o->type != AV_OPT_TYPE_CONST) ||
1179  (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
1180  if (target_obj) {
1181  if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
1182  *target_obj = obj;
1183  else
1184  *target_obj = NULL;
1185  }
1186  return o;
1187  }
1188  }
1189  return NULL;
1190 }
1191 
1192 void *av_opt_child_next(void *obj, void *prev)
1193 {
1194  const AVClass *c = *(AVClass**)obj;
1195  if (c->child_next)
1196  return c->child_next(obj, prev);
1197  return NULL;
1198 }
1199 
1200 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
1201 {
1202  if (parent->child_class_next)
1203  return parent->child_class_next(prev);
1204  return NULL;
1205 }
1206 
1207 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
1208 {
1209  const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
1210  if(!opt)
1211  return NULL;
1212  return (uint8_t*)obj + opt->offset;
1213 }
1214 
1215 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1216 {
1217  const AVClass *c = *(AVClass**)obj;
1218  int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
1219 
1220  if (c->version > (52 << 16 | 11 << 8))
1221  callback = c->query_ranges;
1222 
1223  if (!callback)
1225 
1226  return callback(ranges_arg, obj, key, flags);
1227 }
1228 
1229 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
1230 {
1231  AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
1232  AVOptionRange **range_array = av_mallocz(sizeof(void*));
1233  AVOptionRange *range = av_mallocz(sizeof(*range));
1234  const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
1235  int ret;
1236 
1237  *ranges_arg = NULL;
1238 
1239  if (!ranges || !range || !range_array || !field) {
1240  ret = AVERROR(ENOMEM);
1241  goto fail;
1242  }
1243 
1244  ranges->range = range_array;
1245  ranges->range[0] = range;
1246  ranges->nb_ranges = 1;
1247  range->is_range = 1;
1248  range->value_min = field->min;
1249  range->value_max = field->max;
1250 
1251  switch (field->type) {
1252  case AV_OPT_TYPE_INT:
1253  case AV_OPT_TYPE_INT64:
1254  case AV_OPT_TYPE_PIXEL_FMT:
1256  case AV_OPT_TYPE_FLOAT:
1257  case AV_OPT_TYPE_DOUBLE:
1258  break;
1259  case AV_OPT_TYPE_STRING:
1260  range->component_min = 0;
1261  range->component_max = 0x10FFFF; // max unicode value
1262  range->value_min = -1;
1263  range->value_max = INT_MAX;
1264  break;
1265  case AV_OPT_TYPE_RATIONAL:
1266  range->component_min = INT_MIN;
1267  range->component_max = INT_MAX;
1268  break;
1270  range->component_min = 0;
1271  range->component_max = INT_MAX/128/8;
1272  range->value_min = 0;
1273  range->value_max = INT_MAX/8;
1274  break;
1275  default:
1276  ret = AVERROR(ENOSYS);
1277  goto fail;
1278  }
1279 
1280  *ranges_arg = ranges;
1281  return 0;
1282 fail:
1283  av_free(ranges);
1284  av_free(range);
1285  av_free(range_array);
1286  return ret;
1287 }
1288 
1290 {
1291  int i;
1292  AVOptionRanges *ranges = *rangesp;
1293 
1294  for (i = 0; i < ranges->nb_ranges; i++) {
1295  AVOptionRange *range = ranges->range[i];
1296  if (range) {
1297  av_freep(&range->str);
1298  av_freep(&ranges->range[i]);
1299  }
1300  }
1301  av_freep(&ranges->range);
1302  av_freep(rangesp);
1303 }
1304 
1305 #ifdef TEST
1306 
1307 typedef struct TestContext
1308 {
1309  const AVClass *class;
1310  int num;
1311  int toggle;
1312  char *string;
1313  int flags;
1314  AVRational rational;
1315  int w, h;
1316  enum AVPixelFormat pix_fmt;
1317  enum AVSampleFormat sample_fmt;
1318 } TestContext;
1319 
1320 #define OFFSET(x) offsetof(TestContext, x)
1321 
1322 #define TEST_FLAG_COOL 01
1323 #define TEST_FLAG_LAME 02
1324 #define TEST_FLAG_MU 04
1325 
1326 static const AVOption test_options[]= {
1327 {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 },
1328 {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
1329 {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 },
1330 {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX },
1331 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
1332 {"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
1333 {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
1334 {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
1335 {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 },
1336 {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1},
1337 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1},
1338 {NULL},
1339 };
1340 
1341 static const char *test_get_name(void *ctx)
1342 {
1343  return "test";
1344 }
1345 
1346 static const AVClass test_class = {
1347  "TestContext",
1348  test_get_name,
1349  test_options
1350 };
1351 
1352 int main(void)
1353 {
1354  int i;
1355 
1356  printf("\nTesting av_set_options_string()\n");
1357  {
1358  TestContext test_ctx = { 0 };
1359  const char *options[] = {
1360  "",
1361  ":",
1362  "=",
1363  "foo=:",
1364  ":=foo",
1365  "=foo",
1366  "foo=",
1367  "foo",
1368  "foo=val",
1369  "foo==val",
1370  "toggle=:",
1371  "string=:",
1372  "toggle=1 : foo",
1373  "toggle=100",
1374  "toggle==1",
1375  "flags=+mu-lame : num=42: toggle=0",
1376  "num=42 : string=blahblah",
1377  "rational=0 : rational=1/2 : rational=1/-1",
1378  "rational=-1/0",
1379  "size=1024x768",
1380  "size=pal",
1381  "size=bogus",
1382  "pix_fmt=yuv420p",
1383  "pix_fmt=2",
1384  "pix_fmt=bogus",
1385  "sample_fmt=s16",
1386  "sample_fmt=2",
1387  "sample_fmt=bogus",
1388  };
1389 
1390  test_ctx.class = &test_class;
1391  av_opt_set_defaults(&test_ctx);
1392 
1394 
1395  for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
1396  av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
1397  if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
1398  av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
1399  printf("\n");
1400  }
1401  av_freep(&test_ctx.string);
1402  }
1403 
1404  printf("\nTesting av_opt_set_from_string()\n");
1405  {
1406  TestContext test_ctx = { 0 };
1407  const char *options[] = {
1408  "",
1409  "5",
1410  "5:hello",
1411  "5:hello:size=pal",
1412  "5:size=pal:hello",
1413  ":",
1414  "=",
1415  " 5 : hello : size = pal ",
1416  "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
1417  };
1418  const char *shorthand[] = { "num", "string", NULL };
1419 
1420  test_ctx.class = &test_class;
1421  av_opt_set_defaults(&test_ctx);
1422  test_ctx.string = av_strdup("default");
1423 
1425 
1426  for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
1427  av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
1428  if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
1429  av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
1430  printf("\n");
1431  }
1432  av_freep(&test_ctx.string);
1433  }
1434 
1435  return 0;
1436 }
1437 
1438 #endif