fc00d76393a385e8d18464f42d2fb7ebcceb1493
[ffmpeg.git] / libavcodec / opts.c
1 /*
2  * LGPL
3  */
4
5 /**
6  * @file opts.c
7  * options parser.
8  * typical parsed command line:
9  * msmpeg4:bitrate=720000:qmax=16
10  *
11  */
12
13 #include "avcodec.h"
14
15 #ifdef HAVE_MMX
16 extern const AVOption common_options[3 + 5];
17 #else
18 extern const AVOption common_options[3];
19 #endif
20
21 const AVOption common_options[] = {
22     AVOPTION_CODEC_FLAG("bit_exact", "use only bit-exact stuff", flags, CODEC_FLAG_BITEXACT, 0),
23     AVOPTION_CODEC_FLAG("mm_force", "force mm flags", dsp_mask, FF_MM_FORCE, 0),
24 #ifdef HAVE_MMX
25     AVOPTION_CODEC_FLAG("mm_mmx", "mask MMX feature", dsp_mask, FF_MM_MMX, 0),
26     AVOPTION_CODEC_FLAG("mm_3dnow", "mask 3DNow feature", dsp_mask, FF_MM_3DNOW, 0),
27     AVOPTION_CODEC_FLAG("mm_mmxext", "mask MMXEXT (MMX2) feature", dsp_mask, FF_MM_MMXEXT, 0),
28     AVOPTION_CODEC_FLAG("mm_sse", "mask SSE feature", dsp_mask, FF_MM_SSE, 0),
29     AVOPTION_CODEC_FLAG("mm_sse2", "mask SSE2 feature", dsp_mask, FF_MM_SSE2, 0),
30 #endif
31     AVOPTION_END()
32 };
33
34 static int parse_bool(const AVOption *c, char *s, int *var)
35 {
36     int b = 1; /* by default -on- when present */
37     if (s) {
38         if (!strcasecmp(s, "off") || !strcasecmp(s, "false")
39             || !strcmp(s, "0"))
40             b = 0;
41         else if (!strcasecmp(s, "on") || !strcasecmp(s, "true")
42                  || !strcmp(s, "1"))
43             b = 1;
44         else
45             return -1;
46     }
47
48     *var = b;
49     return 0;
50 }
51
52 static int parse_double(const AVOption *c, char *s, double *var)
53 {
54     double d;
55     if (!s)
56         return -1;
57     d = atof(s);
58     if (c->min != c->max) {
59         if (d < c->min || d > c->max) {
60             fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n",
61                     c->name, d, c->min, c->max);
62             return -1;
63         }
64     }
65     *var = d;
66     return 0;
67 }
68
69 static int parse_int(const AVOption* c, char* s, int* var)
70 {
71     int i;
72     if (!s)
73         return -1;
74     i = atoi(s);
75     if (c->min != c->max) {
76         if (i < (int)c->min || i > (int)c->max) {
77             fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n",
78                     c->name, i, (int)c->min, (int)c->max);
79             return -1;
80         }
81     }
82     *var = i;
83     return 0;
84 }
85
86 static int parse_string(const AVOption *c, char *s, void* strct, char **var)
87 {
88     if (!s)
89         return -1;
90
91     if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
92         int sf, ef, qs;
93         float qf;
94         if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
95             AVCodecContext *avctx = (AVCodecContext *) strct;
96             RcOverride *o;
97             avctx->rc_override = av_realloc(avctx->rc_override,
98                                             sizeof(RcOverride) * (avctx->rc_override_count + 1));
99             o = avctx->rc_override + avctx->rc_override_count++;
100             o->start_frame = sf;
101             o->end_frame = ef;
102             o->qscale = qs;
103             o->quality_factor = qf;
104
105             //printf("parsed Rc:  %d,%d,%d,%f  (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
106         } else {
107             printf("incorrect/unparsable Rc: \"%s\"\n", s);
108         }
109     } else
110         *var = av_strdup(s);
111     return 0;
112 }
113
114 int avoption_parse(void* strct, const AVOption* list, const char *opts)
115 {
116     int r = 0;
117     char* dopts = av_strdup(opts);
118     if (dopts) {
119         char *str = dopts;
120
121         while (str && *str && r == 0) {
122             const AVOption *stack[FF_OPT_MAX_DEPTH];
123             const AVOption *c = list;
124             int depth = 0;
125             char* e = strchr(str, ':');
126             char* p;
127             if (e)
128                 *e++ = 0;
129
130             p = strchr(str, '=');
131             if (p)
132                 *p++ = 0;
133
134             // going through option structures
135             for (;;) {
136                 if (!c->name) {
137                     if (c->help) {
138                         stack[depth++] = c;
139                         c = (const AVOption*) c->help;
140                         assert(depth > FF_OPT_MAX_DEPTH);
141                     } else {
142                         if (depth == 0)
143                             break; // finished
144                         c = stack[--depth];
145                         c++;
146                     }
147                 } else {
148                     if (!strcmp(c->name, str)) {
149                         void* ptr = (char*)strct + c->offset;
150
151                         switch (c->type & FF_OPT_TYPE_MASK) {
152                         case FF_OPT_TYPE_BOOL:
153                             r = parse_bool(c, p, (int*)ptr);
154                             break;
155                         case FF_OPT_TYPE_DOUBLE:
156                             r = parse_double(c, p, (double*)ptr);
157                             break;
158                         case FF_OPT_TYPE_INT:
159                             r = parse_int(c, p, (int*)ptr);
160                             break;
161                         case FF_OPT_TYPE_STRING:
162                             r = parse_string(c, p, strct, (char**)ptr);
163                             break;
164                         default:
165                             assert(0 == 1);
166                         }
167                     }
168                     c++;
169                 }
170             }
171             str = e;
172         }
173         av_free(dopts);
174     }
175     return r;
176 }