comparison opts.c @ 1058:3c3da6edc9a1 libavcodec

* still unfinished code for Options
author kabi
date Mon, 10 Feb 2003 09:38:38 +0000
parents ef905ded19fe
children 1e39f273ecd6
comparison
equal deleted inserted replaced
1057:bb5de8a59da8 1058:3c3da6edc9a1
7 * msmpeg4:bitrate=720000:qmax=16 7 * msmpeg4:bitrate=720000:qmax=16
8 * 8 *
9 */ 9 */
10 10
11 #include "avcodec.h" 11 #include "avcodec.h"
12 #ifdef OPTS_MAIN
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #endif
17 12
18 /* 13 extern const AVOption common_options[2];
19 * todo - use for decoder options also
20 */
21 14
22 static int parse_bool(avc_config_t* c, char* s) 15 const AVOption common_options[2] = {
16 AVOPTION_CODEC_INT("common", "test", bit_rate, 0, 10, 0),
17 AVOPTION_END()
18 };
19
20 static int parse_bool(const AVOption *c, char *s, int *var)
23 { 21 {
24 int b = 1; /* by default -on- when present */ 22 int b = 1; /* by default -on- when present */
25 if (s) { 23 if (s) {
26 if (!strcasecmp(s, "off") || !strcasecmp(s, "false") 24 if (!strcasecmp(s, "off") || !strcasecmp(s, "false")
27 || !strcmp(s, "0")) 25 || !strcmp(s, "0"))
31 b = 1; 29 b = 1;
32 else 30 else
33 return -1; 31 return -1;
34 } 32 }
35 33
36 if (c && c->val) 34 *var = b;
37 *(int*)(c->val) = b;
38 return 0; 35 return 0;
39 } 36 }
40 37
41 static int parse_double(avc_config_t* c, char* s) 38 static int parse_double(const AVOption *c, char *s, double *var)
42 { 39 {
43 double d; 40 double d;
44 if (!s) 41 if (!s)
45 return -1; 42 return -1;
46 d = atof(s); 43 d = atof(s);
49 fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n", 46 fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n",
50 c->name, d, c->min, c->max); 47 c->name, d, c->min, c->max);
51 return -1; 48 return -1;
52 } 49 }
53 } 50 }
54 if (c && c->val) 51 *var = d;
55 *(double*)(c->val) = d;
56 return 0; 52 return 0;
57 } 53 }
58 54
59 static int parse_int(avc_config_t* c, char* s) 55 static int parse_int(const AVOption* c, char* s, int* var)
60 { 56 {
61 int i; 57 int i;
62 if (!s) 58 if (!s)
63 return -1; 59 return -1;
64 i = atoi(s); 60 i = atoi(s);
67 fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n", 63 fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n",
68 c->name, i, (int)c->min, (int)c->max); 64 c->name, i, (int)c->min, (int)c->max);
69 return -1; 65 return -1;
70 } 66 }
71 } 67 }
72 if (c && c->val) 68 *var = i;
73 *(int*)(c->val) = i;
74 return 0; 69 return 0;
75 } 70 }
76 71
77 static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s) 72 static int parse_string(const AVOption *c, char *s, AVCodecContext *avctx, char **var)
78 { 73 {
79 if (!s) 74 if (!s)
80 return -1; 75 return -1;
81 76
82 if (c->type == FF_CONF_TYPE_RCOVERIDE) { 77 if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
83 int sf, ef, qs; 78 int sf, ef, qs;
84 float qf; 79 float qf;
85 if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) { 80 if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
86 RcOverride* o; 81 RcOverride *o;
87 *((RcOverride**)c->val) = 82 avctx->rc_override = av_realloc(avctx->rc_override,
88 realloc(*((RcOverride**)c->val), 83 sizeof(RcOverride) * (avctx->rc_override_count + 1));
89 sizeof(RcOverride) * (avctx->rc_override_count + 1)); 84 o = avctx->rc_override + avctx->rc_override_count++;
90 o = *((RcOverride**)c->val) + avctx->rc_override_count++;
91 o->start_frame = sf; 85 o->start_frame = sf;
92 o->end_frame = ef; 86 o->end_frame = ef;
93 o->qscale = qs; 87 o->qscale = qs;
94 o->quality_factor = qf; 88 o->quality_factor = qf;
95 89
96 //printf("parsed Rc: %d,%d,%d,%f (%d)\n", sf,ef,qs,qf, avctx->rc_override_count); 90 //printf("parsed Rc: %d,%d,%d,%f (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
97 } else { 91 } else {
98 printf("incorrect/unparsable Rc: \"%s\"\n", s); 92 printf("incorrect/unparsable Rc: \"%s\"\n", s);
99 } 93 }
100 } else 94 } else
101 (char*)(c->val) = strdup(s); 95 *var = av_strdup(s);
102 return 0;
103 }
104
105 static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
106 {
107 while (str && *str) {
108 avc_config_t* c = config;
109 char* e = strchr(str, ':');
110 char* p;
111 if (e)
112 *e++ = 0;
113
114 p = strchr(str, '=');
115 if (p)
116 *p++ = 0;
117
118 while (c->name) {
119 if (!strcmp(c->name, str)) {
120 switch (c->type & FF_CONF_TYPE_MASK) {
121 case FF_CONF_TYPE_BOOL:
122 parse_bool(c, p);
123 break;
124 case FF_CONF_TYPE_DOUBLE:
125 parse_double(c, p);
126 break;
127 case FF_CONF_TYPE_INT:
128 parse_int(c, p);
129 break;
130 case FF_CONF_TYPE_STRING:
131 parse_string(avctx, c, p);
132 break;
133 default:
134 abort();
135 break;
136 }
137 }
138 c++;
139 }
140 str = e;
141 }
142 return 0; 96 return 0;
143 } 97 }
144 98
145 /** 99 /**
146 * 100 *
101 * \param codec codec for option parsing
102 * \param opts string with options for parsing
147 * \param avctx where to store parsed results 103 * \param avctx where to store parsed results
148 * \param str string with options for parsing 104 */
149 * or selectional string (pick only options appliable 105 int avcodec_parse(const AVCodec *codec, const char *opts, AVCodecContext *avctx)
150 * for codec - use ,msmpeg4, (with commas to avoid mismatch)
151 * \param config allocated avc_config_t for external parsing
152 * i.e. external program might learn about all available
153 * options for given codec
154 **/
155 void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
156 { 106 {
157 AVCodecContext avctx_tmp; 107 int r = 0;
158 AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp; 108 char* dopts = av_strdup(opts);
159 static const char* class_h263 = ",msmpeg4,"; 109 if (dopts) {
160 //"huffyuv,wmv1,msmpeg4v2,msmpeg4,mpeg4,mpeg1,mpeg1video,mjpeg,rv10,h263,h263p" 110 char *str = dopts;
161 111
162 avc_config_t cnf[] = 112 while (str && *str && r == 0) {
163 { 113 const AVOption *stack[FF_OPT_MAX_DEPTH];
164 // FIXME: sorted by importance!!! 114 int depth = 0;
165 // expert option should follow more common ones 115 const AVOption *c = codec->options;
166 { 116 char* e = strchr(str, ':');
167 "bitrate", "desired video bitrate", 117 char* p;
168 FF_CONF_TYPE_INT, &ctx->bit_rate, 4, 240000000, 800000, NULL, class_h263 118 if (e)
169 }, { 119 *e++ = 0;
170 "vhq", "very high quality",
171 FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_HQ, 0, NULL, class_h263
172 }, {
173 "ratetol", "number of bits the bitstream is allowed to diverge from the reference"
174 "the reference can be CBR (for CBR pass1) or VBR (for pass2)",
175 FF_CONF_TYPE_INT, &ctx->bit_rate_tolerance, 4, 240000000, 8000, NULL, class_h263
176 }, {
177 "qmin", "minimum quantizer", FF_CONF_TYPE_INT, &ctx->qmin, 1, 31, 2, NULL, class_h263
178 }, {
179 "qmax", "maximum qunatizer", FF_CONF_TYPE_INT, &ctx->qmax, 1, 31, 31, NULL, class_h263
180 }, {
181 "rc_eq", "rate control equation",
182 FF_CONF_TYPE_STRING, &ctx->rc_eq, 0, 0, 0, "tex^qComp" /* FILLME options */, class_h263
183 }, {
184 "rc_minrate", "rate control minimum bitrate",
185 FF_CONF_TYPE_INT, &ctx->rc_min_rate, 4, 24000000, 0, NULL, class_h263
186 }, {
187 "rc_maxrate", "rate control maximum bitrate",
188 FF_CONF_TYPE_INT, &ctx->rc_max_rate, 4, 24000000, 0, NULL, class_h263
189 }, {
190 "psnr", "calculate PSNR of compressed frames",
191 FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_PSNR, 0, NULL, class_h263
192 }, {
193 "rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)",
194 FF_CONF_TYPE_RCOVERIDE, &ctx->rc_override, 0, 0, 0, "0,0,0,0", class_h263
195 },
196 120
197 { NULL, NULL, 0, NULL, 0, 0, 0, NULL, NULL } 121 p = strchr(str, '=');
198 }; 122 if (p)
123 *p++ = 0;
199 124
200 if (config) { 125 // going through option structures
201 *config = malloc(sizeof(cnf)); 126 for (;;) {
202 if (*config) { 127 if (!c->name) {
203 avc_config_t* src = cnf; 128 if (c->sub) {
204 avc_config_t* dst = *config; 129 stack[depth++] = c;
205 while (src->name) { 130 c = c->sub;
206 if (!str || !src->supported || strstr(src->supported, str)) 131 assert(depth > FF_OPT_MAX_DEPTH);
207 memcpy(dst++, src, sizeof(avc_config_t)); 132 } else {
208 src++; 133 if (depth == 0)
134 break; // finished
135 c = stack[--depth];
136 c++;
137 }
138 } else {
139 if (!strcmp(c->name, str)) {
140 void* ptr = (char*)avctx + c->offset;
141
142 switch (c->type & FF_OPT_TYPE_MASK) {
143 case FF_OPT_TYPE_BOOL:
144 r = parse_bool(c, p, (int*)ptr);
145 break;
146 case FF_OPT_TYPE_DOUBLE:
147 r = parse_double(c, p, (double*)ptr);
148 break;
149 case FF_OPT_TYPE_INT:
150 r = parse_int(c, p, (int*)ptr);
151 break;
152 case FF_OPT_TYPE_STRING:
153 r = parse_string(c, p, avctx, (char**)ptr);
154 break;
155 default:
156 assert(0 == 1);
157 }
158 }
159 c++;
160 }
209 } 161 }
210 memset(dst, 0, sizeof(avc_config_t)); 162 str = e;
211 } 163 }
212 } else if (str) { 164 av_free(dopts);
213 char* s = strdup(str);
214 if (s) {
215 parse(avctx, cnf, s);
216 free(s);
217 }
218 } 165 }
166 return r;
219 } 167 }
220
221 #ifdef OPTS_MAIN
222 /*
223 * API test -
224 * arg1: options
225 * arg2: codec type
226 *
227 * compile standalone: make CFLAGS="-DOPTS_MAIN" opts
228 */
229 int main(int argc, char* argv[])
230 {
231 AVCodecContext avctx;
232 avc_config_t* config;
233 char* def = malloc(5000);
234 const char* col = "";
235 int i = 0;
236
237 memset(&avctx, 0, sizeof(avctx));
238 *def = 0;
239 avcodec_getopt(&avctx, argv[1], NULL);
240
241 avcodec_getopt(NULL, (argc > 2) ? argv[2] : NULL, &config);
242 if (config)
243 while (config->name) {
244 int t = config->type & FF_CONF_TYPE_MASK;
245 printf("Config %s %s\n", config->name,
246 t == FF_CONF_TYPE_BOOL ? "bool" :
247 t == FF_CONF_TYPE_DOUBLE ? "double" :
248 t == FF_CONF_TYPE_INT ? "integer" :
249 t == FF_CONF_TYPE_STRING ? "string" :
250 "unknown??");
251 switch (t) {
252 case FF_CONF_TYPE_BOOL:
253 i += sprintf(def + i, "%s%s=%s",
254 col, config->name,
255 config->defval != 0. ? "on" : "off");
256 break;
257 case FF_CONF_TYPE_DOUBLE:
258 i += sprintf(def + i, "%s%s=%f",
259 col, config->name, config->defval);
260 break;
261 case FF_CONF_TYPE_INT:
262 i += sprintf(def + i, "%s%s=%d",
263 col, config->name, (int) config->defval);
264 break;
265 case FF_CONF_TYPE_STRING:
266 i += sprintf(def + i, "%s%s=%s",
267 col, config->name, config->defstr);
268 break;
269 }
270 col = ":";
271 config++;
272 }
273
274 printf("Default Options: %s\n", def);
275
276 return 0;
277 }
278 #endif