962
|
1 /*
|
|
2 * LGPL
|
|
3 */
|
|
4
|
1106
|
5 /**
|
|
6 * @file opts.c
|
|
7 * options parser.
|
962
|
8 * typical parsed command line:
|
|
9 * msmpeg4:bitrate=720000:qmax=16
|
|
10 *
|
|
11 */
|
|
12
|
|
13 #include "avcodec.h"
|
1058
|
14
|
1114
|
15 #ifdef HAVE_MMX
|
|
16 extern const AVOption common_options[3 + 5];
|
|
17 #else
|
|
18 extern const AVOption common_options[3];
|
|
19 #endif
|
962
|
20
|
1114
|
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
|
1058
|
31 AVOPTION_END()
|
|
32 };
|
962
|
33
|
1058
|
34 static int parse_bool(const AVOption *c, char *s, int *var)
|
1019
|
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
|
1058
|
48 *var = b;
|
1019
|
49 return 0;
|
|
50 }
|
|
51
|
1058
|
52 static int parse_double(const AVOption *c, char *s, double *var)
|
1019
|
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 }
|
1058
|
65 *var = d;
|
1019
|
66 return 0;
|
|
67 }
|
|
68
|
1058
|
69 static int parse_int(const AVOption* c, char* s, int* var)
|
1019
|
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 }
|
1058
|
82 *var = i;
|
1019
|
83 return 0;
|
|
84 }
|
|
85
|
1114
|
86 static int parse_string(const AVOption *c, char *s, void* strct, char **var)
|
1019
|
87 {
|
|
88 if (!s)
|
|
89 return -1;
|
|
90
|
1058
|
91 if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
|
1019
|
92 int sf, ef, qs;
|
|
93 float qf;
|
|
94 if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
|
1114
|
95 AVCodecContext *avctx = (AVCodecContext *) strct;
|
1058
|
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++;
|
1019
|
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
|
1058
|
110 *var = av_strdup(s);
|
1019
|
111 return 0;
|
|
112 }
|
|
113
|
1114
|
114 int avoption_parse(void* strct, const AVOption* list, const char *opts)
|
962
|
115 {
|
1058
|
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];
|
1114
|
123 const AVOption *c = list;
|
1058
|
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;
|
962
|
133
|
1058
|
134 // going through option structures
|
|
135 for (;;) {
|
|
136 if (!c->name) {
|
1114
|
137 if (c->help) {
|
1058
|
138 stack[depth++] = c;
|
1114
|
139 c = (const AVOption*) c->help;
|
1058
|
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)) {
|
1114
|
149 void* ptr = (char*)strct + c->offset;
|
962
|
150
|
1058
|
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:
|
1114
|
162 r = parse_string(c, p, strct, (char**)ptr);
|
1058
|
163 break;
|
|
164 default:
|
|
165 assert(0 == 1);
|
|
166 }
|
|
167 }
|
|
168 c++;
|
|
169 }
|
1019
|
170 }
|
1058
|
171 str = e;
|
1019
|
172 }
|
1058
|
173 av_free(dopts);
|
962
|
174 }
|
1058
|
175 return r;
|
962
|
176 }
|