Mercurial > mplayer.hg
annotate m_config.c @ 10252:d275152390ee
I've found some time to implement the encoding support for the new
DivX API. Now it's possible to play and encode movies with the
latest DivX release.
One thing that doesn't work is the new Video Buffer Verifier (VBV)
multipass encoding. The encoder segfaults. Maybe it just isn't
supported with the standard profile of the released binary encoder.
Andreas Hess <jaska@gmx.net>
author | arpi |
---|---|
date | Fri, 06 Jun 2003 19:57:37 +0000 |
parents | 39444d65c4cb |
children | 57bdcdb061d7 |
rev | line source |
---|---|
8164 | 1 |
2 #include "config.h" | |
3 | |
4 #ifdef NEW_CONFIG | |
5 | |
6 #include <stdlib.h> | |
7 #include <stdio.h> | |
8 #include <errno.h> | |
9 #include <string.h> | |
10 #ifdef MP_DEBUG | |
11 #include <assert.h> | |
12 #endif | |
13 | |
14 | |
15 #include "m_config.h" | |
16 #include "m_option.h" | |
17 #include "mp_msg.h" | |
18 | |
19 m_config_t* | |
20 m_config_new(void) { | |
21 m_config_t* config; | |
22 | |
23 config = (m_config_t*)calloc(1,sizeof(m_config_t)); | |
24 config->lvl = 1; // 0 Is the defaults | |
25 return config; | |
26 } | |
27 | |
28 void | |
29 m_config_free(m_config_t* config) { | |
30 m_config_option_t *i = config->opts, *ct; | |
31 m_config_save_slot_t *sl,*st; | |
32 | |
33 #ifdef MP_DEBUG | |
34 assert(config != NULL); | |
35 #endif | |
36 | |
37 while(i) { | |
38 sl = i->slots; | |
39 while(sl) { | |
40 m_option_free(i->opt,sl->data); | |
41 st = sl->prev; | |
42 free(sl); | |
43 sl = st; | |
44 } | |
45 if(i->name != i->opt->name) | |
46 free(i->name); | |
47 ct = i->next; | |
48 free(i); | |
49 ct = i; | |
50 } | |
51 free(config); | |
52 } | |
53 | |
54 void | |
55 m_config_push(m_config_t* config) { | |
56 m_config_option_t *co; | |
57 m_config_save_slot_t *slot; | |
58 | |
59 #ifdef MP_DEBUG | |
60 assert(config != NULL); | |
61 assert(config->lvl > 0); | |
62 #endif | |
63 | |
64 config->lvl++; | |
65 | |
66 for(co = config->opts ; co ; co = co->next ) { | |
67 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
68 continue; | |
69 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
70 continue; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
71 if((co->opt->flags & M_OPT_OLD) && !(co->flags && M_CFG_OPT_SET)) |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
72 continue; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
73 if(co->flags & M_CFG_OPT_ALIAS) |
8164 | 74 continue; |
75 | |
76 // Update the current status | |
77 m_option_save(co->opt,co->slots->data,co->opt->p); | |
78 | |
79 // Allocate a new slot | |
80 slot = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); | |
81 slot->lvl = config->lvl; | |
82 slot->prev = co->slots; | |
83 co->slots = slot; | |
84 m_option_copy(co->opt,co->slots->data,co->slots->prev->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
85 // Reset our set flag |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
86 co->flags &= ~M_CFG_OPT_SET; |
8164 | 87 } |
88 | |
89 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl); | |
90 } | |
91 | |
92 void | |
93 m_config_pop(m_config_t* config) { | |
94 m_config_option_t *co; | |
95 m_config_save_slot_t *slot; | |
96 | |
97 #ifdef MP_DEBUG | |
98 assert(config != NULL); | |
99 assert(config->lvl > 1); | |
100 #endif | |
101 | |
102 for(co = config->opts ; co ; co = co->next ) { | |
103 int pop = 0; | |
104 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
105 continue; | |
106 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
107 continue; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
108 if(co->flags & M_CFG_OPT_ALIAS) |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
109 continue; |
8164 | 110 if(co->slots->lvl > config->lvl) |
111 mp_msg(MSGT_CFGPARSER, MSGL_WARN,"Too old save slot found from lvl %d : %d !!!\n",config->lvl,co->slots->lvl); | |
112 | |
113 while(co->slots->lvl >= config->lvl) { | |
114 m_option_free(co->opt,co->slots->data); | |
115 slot = co->slots; | |
116 co->slots = slot->prev; | |
117 free(slot); | |
118 pop++; | |
119 } | |
120 if(pop) // We removed some ctx -> set the previous value | |
121 m_option_set(co->opt,co->opt->p,co->slots->data); | |
122 } | |
123 | |
124 config->lvl--; | |
125 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl); | |
126 } | |
127 | |
128 static void | |
129 m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix) { | |
130 m_config_option_t *co; | |
131 m_config_save_slot_t* sl; | |
132 | |
133 #ifdef MP_DEBUG | |
134 assert(config != NULL); | |
135 assert(config->lvl > 0); | |
136 assert(arg != NULL); | |
137 #endif | |
138 | |
139 // Allocate a new entry for this option | |
140 co = (m_config_option_t*)calloc(1,sizeof(m_config_option_t) + arg->type->size); | |
141 co->opt = arg; | |
142 | |
143 // Fill in the full name | |
144 if(prefix && strlen(prefix) > 0) { | |
145 int l = strlen(prefix) + 1 + strlen(arg->name) + 1; | |
146 co->name = (char*) malloc(l); | |
147 sprintf(co->name,"%s:%s",prefix,arg->name); | |
148 } else | |
149 co->name = arg->name; | |
150 | |
151 // Option with childs -> add them | |
152 if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
153 m_option_t *ol = arg->p; | |
154 int i; | |
155 for(i = 0 ; ol[i].name != NULL ; i++) | |
156 m_config_add_option(config,&ol[i], co->name); | |
157 } else { | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
158 m_config_option_t *i; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
159 // Check if there is alredy an option pointing to this address |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
160 if(arg->p) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
161 for(i = config->opts ; i ; i = i->next ) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
162 if(i->opt->p == arg->p) { // So we don't save the same vars more than 1 time |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
163 co->slots = i->slots; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
164 co->flags |= M_CFG_OPT_ALIAS; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
165 break; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
166 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
167 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
168 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
169 if(!(co->flags & M_CFG_OPT_ALIAS)) { |
8164 | 170 // Allocate a slot for the defaults |
171 sl = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); | |
172 m_option_save(arg,sl->data,(void**)arg->p); | |
173 // Hack to avoid too much trouble with dynamicly allocated data : | |
174 // We always use a dynamic version | |
175 if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { | |
176 *(void**)arg->p = NULL; | |
177 m_option_set(arg,arg->p,sl->data); | |
178 } | |
179 sl->lvl = 0; | |
180 co->slots = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); | |
181 co->slots->prev = sl; | |
182 co->slots->lvl = config->lvl; | |
183 m_option_copy(co->opt,co->slots->data,sl->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
184 } // !M_OPT_ALIAS |
8164 | 185 } |
186 co->next = config->opts; | |
187 config->opts = co; | |
188 } | |
189 | |
190 int | |
191 m_config_register_options(m_config_t *config, m_option_t *args) { | |
192 int i; | |
193 | |
194 #ifdef MP_DEBUG | |
195 assert(config != NULL); | |
196 assert(config->lvl > 0); | |
197 assert(args != NULL); | |
198 #endif | |
199 | |
200 for(i = 0 ; args[i].name != NULL ; i++) | |
201 m_config_add_option(config,&args[i],NULL); | |
202 | |
203 return 1; | |
204 } | |
205 | |
206 static m_config_option_t* | |
207 m_config_get_co(m_config_t *config, char* arg) { | |
208 m_config_option_t *co; | |
209 | |
210 for(co = config->opts ; co ; co = co->next ) { | |
211 int l = strlen(co->name) - 1; | |
212 if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && | |
213 (co->name[l] == '*')) { | |
214 if(strncasecmp(co->name,arg,l) == 0) | |
215 return co; | |
216 } else if(strcasecmp(co->name,arg) == 0) | |
217 return co; | |
218 } | |
219 return NULL; | |
220 } | |
221 | |
222 static int | |
223 m_config_parse_option(m_config_t *config, char* arg, char* param,int set) { | |
224 m_config_option_t *co; | |
225 int r = 0; | |
226 | |
227 #ifdef MP_DEBUG | |
228 assert(config != NULL); | |
229 assert(config->lvl > 0); | |
230 assert(arg != NULL); | |
231 #endif | |
232 | |
233 co = m_config_get_co(config,arg); | |
8892 | 234 if(!co){ |
8894 | 235 // mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Unknown option: %s\n",arg); |
8164 | 236 return M_OPT_UNKNOW; |
8892 | 237 } |
8164 | 238 |
239 #ifdef MP_DEBUG | |
240 // This is the only mandatory function | |
241 assert(co->opt->type->parse); | |
242 #endif | |
243 | |
244 // Check if this option isn't forbiden in the current mode | |
245 if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) { | |
8512 | 246 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used in a config file\n",arg); |
8164 | 247 return M_OPT_INVALID; |
248 } | |
249 if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) { | |
8512 | 250 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used on the command line\n",arg); |
8164 | 251 return M_OPT_INVALID; |
252 } | |
253 | |
254 // Option with childs are a bit different to parse | |
255 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
256 char** lst = NULL; | |
257 int i,sr; | |
258 // Parse the child options | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9222
diff
changeset
|
259 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 260 // Set them now |
8894 | 261 if(r >= 0) |
8164 | 262 for(i = 0 ; lst && lst[2*i] ; i++) { |
263 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
264 if(r >= 0) { | |
265 // Build the full name | |
266 char n[l]; | |
267 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
268 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 269 if(sr < 0){ |
270 if(sr == M_OPT_UNKNOW){ | |
271 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: option '%s' has no suboption '%s'\n",co->name,lst[2*i]); | |
272 r = M_OPT_INVALID; | |
273 } else | |
9222 | 274 if(sr == M_OPT_MISSING_PARAM){ |
275 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: suboption '%s' of '%s' must have a parameter!\n",lst[2*i],co->name); | |
276 r = M_OPT_INVALID; | |
277 } else | |
8894 | 278 r = sr; |
279 } | |
8164 | 280 } |
281 free(lst[2*i]); | |
282 free(lst[2*i+1]); | |
283 } | |
284 if(lst) free(lst); | |
285 } else | |
286 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
287 | |
288 // Parsing failed ? | |
289 if(r < 0) | |
290 return r; | |
291 // Set the option | |
292 if(set) { | |
293 m_option_set(co->opt,co->opt->p,co->slots->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
294 co->flags |= M_CFG_OPT_SET; |
8164 | 295 } |
296 | |
297 return r; | |
298 } | |
299 | |
300 int | |
301 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
302 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
303 return m_config_parse_option(config,arg,param,1); | |
304 } | |
305 | |
306 int | |
307 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
9222 | 308 int r; |
8164 | 309 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 310 r=m_config_parse_option(config,arg,param,0); |
311 if(r==M_OPT_MISSING_PARAM){ | |
312 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: option '%s' must have a parameter!\n",arg); | |
313 return M_OPT_INVALID; | |
314 } | |
315 return r; | |
8164 | 316 } |
317 | |
318 | |
319 m_option_t* | |
320 m_config_get_option(m_config_t *config, char* arg) { | |
321 m_config_option_t *co; | |
322 | |
323 #ifdef MP_DEBUG | |
324 assert(config != NULL); | |
325 assert(config->lvl > 0); | |
326 assert(arg != NULL); | |
327 #endif | |
328 | |
329 co = m_config_get_co(config,arg); | |
330 if(co) | |
331 return co->opt; | |
332 else | |
333 return NULL; | |
334 } | |
335 | |
336 void* | |
337 m_config_get_option_ptr(m_config_t *config, char* arg) { | |
338 m_option_t* conf; | |
339 | |
340 #ifdef MP_DEBUG | |
341 assert(config != NULL); | |
342 assert(arg != NULL); | |
343 #endif | |
344 | |
345 conf = m_config_get_option(config,arg); | |
346 if(!conf) return NULL; | |
347 return conf->p; | |
348 } | |
349 | |
350 void | |
351 m_config_print_option_list(m_config_t *config) { | |
352 char min[50],max[50]; | |
353 m_config_option_t* co; | |
354 int count = 0; | |
355 | |
356 if(!config->opts) return; | |
357 | |
358 printf("\n Name Type Min Max Global CL Cfg\n\n"); | |
359 for(co = config->opts ; co ; co = co->next) { | |
360 m_option_t* opt = co->opt; | |
361 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; | |
362 if(opt->flags & M_OPT_MIN) | |
363 sprintf(min,"%-8.0f",opt->min); | |
364 else | |
365 strcpy(min,"No"); | |
366 if(opt->flags & M_OPT_MAX) | |
367 sprintf(max,"%-8.0f",opt->max); | |
368 else | |
369 strcpy(max,"No"); | |
370 printf(" %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", | |
371 co->name, | |
372 co->opt->type->name, | |
373 min, | |
374 max, | |
375 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
376 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
377 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
378 count++; | |
379 } | |
380 printf("\nTotal: %d options\n",count); | |
381 } | |
382 | |
383 #endif // NEW_CONFIG |