Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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;
  78.     case AV_OPT_TYPE_PIXEL_FMT:
  79.     case AV_OPT_TYPE_SAMPLE_FMT:
  80.     case AV_OPT_TYPE_INT:       *intnum = *(int         *)dst;return 0;
  81.     case AV_OPT_TYPE_CHANNEL_LAYOUT:
  82.     case AV_OPT_TYPE_DURATION:
  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:
  104.     case AV_OPT_TYPE_PIXEL_FMT:
  105.     case AV_OPT_TYPE_SAMPLE_FMT:
  106.     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
  107.     case AV_OPT_TYPE_DURATION:
  108.     case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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;
  112.     case AV_OPT_TYPE_RATIONAL:
  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)
  261.         return AVERROR_OPTION_NOT_FOUND;
  262.     if (!val && (o->type != AV_OPT_TYPE_STRING &&
  263.                  o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
  264.                  o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
  265.                  o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
  266.                  o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
  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);
  279.     case AV_OPT_TYPE_IMAGE_SIZE:
  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;
  288.     case AV_OPT_TYPE_VIDEO_RATE:
  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;
  297.     case AV_OPT_TYPE_PIXEL_FMT:
  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;
  313.     case AV_OPT_TYPE_SAMPLE_FMT:
  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;
  329.     case AV_OPT_TYPE_DURATION:
  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;
  349.     case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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.  
  380. OPT_EVAL_NUMBER(flags,  AV_OPT_TYPE_FLAGS,    int)
  381. OPT_EVAL_NUMBER(int,    AV_OPT_TYPE_INT,      int)
  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)
  385. OPT_EVAL_NUMBER(q,      AV_OPT_TYPE_RATIONAL, AVRational)
  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)
  394.         return AVERROR_OPTION_NOT_FOUND;
  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)
  450.         return AVERROR_OPTION_NOT_FOUND;
  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)
  477.         return AVERROR_OPTION_NOT_FOUND;
  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)
  499.         return AVERROR_OPTION_NOT_FOUND;
  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)
  520.         return AVERROR_OPTION_NOT_FOUND;
  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)
  563.         return AVERROR_OPTION_NOT_FOUND;
  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))
  623.         return AVERROR_OPTION_NOT_FOUND;
  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;
  634.     case AV_OPT_TYPE_VIDEO_RATE:
  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;
  653.     case AV_OPT_TYPE_IMAGE_SIZE:
  654.         ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
  655.         break;
  656.     case AV_OPT_TYPE_PIXEL_FMT:
  657.         ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
  658.         break;
  659.     case AV_OPT_TYPE_SAMPLE_FMT:
  660.         ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
  661.         break;
  662.     case AV_OPT_TYPE_DURATION:
  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;
  671.     case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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)
  787.         return AVERROR_OPTION_NOT_FOUND;
  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)
  822.         return AVERROR_OPTION_NOT_FOUND;
  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)
  849.         return AVERROR_OPTION_NOT_FOUND;
  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;
  940.             case AV_OPT_TYPE_RATIONAL:
  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;
  946.             case AV_OPT_TYPE_IMAGE_SIZE:
  947.                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
  948.                 break;
  949.             case AV_OPT_TYPE_VIDEO_RATE:
  950.                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
  951.                 break;
  952.             case AV_OPT_TYPE_PIXEL_FMT:
  953.                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
  954.                 break;
  955.             case AV_OPT_TYPE_SAMPLE_FMT:
  956.                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
  957.                 break;
  958.             case AV_OPT_TYPE_DURATION:
  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;
  964.             case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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:
  988.             case AV_OPT_TYPE_RATIONAL:
  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.             }
  998.             av_opt_freep_ranges(&r);
  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;
  1029.             case AV_OPT_TYPE_SAMPLE_FMT:
  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:
  1033.             case AV_OPT_TYPE_IMAGE_SIZE:
  1034.             case AV_OPT_TYPE_STRING:
  1035.             case AV_OPT_TYPE_VIDEO_RATE:
  1036.                 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
  1037.                 break;
  1038.             case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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.  
  1064. void av_opt_set_defaults(void *s)
  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:
  1088.             case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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:
  1106.             case AV_OPT_TYPE_IMAGE_SIZE:
  1107.             case AV_OPT_TYPE_VIDEO_RATE:
  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;
  1118.             case AV_OPT_TYPE_SAMPLE_FMT:
  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.  
  1326. int av_opt_set_dict(void *obj, AVDictionary **options)
  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)
  1429.         callback = av_opt_query_ranges_default;
  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:
  1460.     case AV_OPT_TYPE_SAMPLE_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:
  1465.     case AV_OPT_TYPE_CHANNEL_LAYOUT:
  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;
  1477.     case AV_OPT_TYPE_IMAGE_SIZE:
  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;
  1483.     case AV_OPT_TYPE_VIDEO_RATE:
  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.  
  1503. void av_opt_freep_ranges(AVOptionRanges **rangesp)
  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.  
  1626.         av_log_set_level(AV_LOG_DEBUG);
  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.  
  1656.         av_log_set_level(AV_LOG_DEBUG);
  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
  1671.