Mercurial > mplayer.hg
annotate codec-cfg.c @ 33672:e576232a39d5
Prevent balance from hopping.
Only recalculate the balance if the balance has changed, not if just
the volume has changed.
Because (at least with my soundcard) not all volume values can be
stored, but seem to be mapped onto a discrete value set, recalculation
the balance from the volume isn't accurate enough.
author | ib |
---|---|
date | Tue, 28 Jun 2011 18:16:06 +0000 |
parents | 1ff6737f2177 |
children | 277ec491a8a7 |
rev | line source |
---|---|
319 | 1 /* |
2 * codec.conf parser | |
4676 | 3 * |
22501 | 4 * to compile test application: |
5 * cc -I. -DTESTING -o codec-cfg-test codec-cfg.c mp_msg.o osdep/getch2.o -ltermcap | |
15303 | 6 * to compile CODECS2HTML: |
33246 | 7 * gcc -DCODECS2HTML -o codecs2html codec-cfg.c |
4676 | 8 * |
9 * TODO: implement informat in CODECS2HTML too | |
30429
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
10 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
11 * Copyright (C) 2001 Szabolcs Berecz <szabi@inf.elte.hu> |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
12 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
13 * This file is part of MPlayer. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
14 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
15 * MPlayer is free software; you can redistribute it and/or modify |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
16 * it under the terms of the GNU General Public License as published by |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
17 * the Free Software Foundation; either version 2 of the License, or |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
18 * (at your option) any later version. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
19 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
20 * MPlayer is distributed in the hope that it will be useful, |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
23 * GNU General Public License for more details. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
24 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
25 * You should have received a copy of the GNU General Public License along |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
26 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
30115
diff
changeset
|
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
319 | 28 */ |
303 | 29 |
319 | 30 #define DEBUG |
303 | 31 |
3798
d1e3ad5bcd8f
fixed few segfaults, make parse_codec_cfg() return int
iive
parents:
3787
diff
changeset
|
32 //disable asserts |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
33 #define NDEBUG |
3798
d1e3ad5bcd8f
fixed few segfaults, make parse_codec_cfg() return int
iive
parents:
3787
diff
changeset
|
34 |
297 | 35 #include <stdio.h> |
36 #include <stdlib.h> | |
37 #include <fcntl.h> | |
38 #include <unistd.h> | |
39 #include <errno.h> | |
40 #include <ctype.h> | |
41 #include <assert.h> | |
42 #include <string.h> | |
43 | |
5284
0a58c2ef1da1
added missing #include config.h, removed LIBVO2 ifdef.
arpi
parents:
5263
diff
changeset
|
44 #include "config.h" |
5937 | 45 #include "mp_msg.h" |
17841
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
46 #ifdef CODECS2HTML |
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
47 #ifdef __GNUC__ |
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
48 #define mp_msg(t, l, m, args...) fprintf(stderr, m, ##args) |
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
49 #else |
23910
8fcfdfcd6c41
C99 varargs in macros can not be empty, adjust definition so it compiles
reimar
parents:
23806
diff
changeset
|
50 #define mp_msg(t, l, ...) fprintf(stderr, __VA_ARGS__) |
17841
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
51 #endif |
73db10d5f2e3
remove mp_msg.c dependency when compiling codec-cfg binary.
reimar
parents:
17763
diff
changeset
|
52 #endif |
5284
0a58c2ef1da1
added missing #include config.h, removed LIBVO2 ifdef.
arpi
parents:
5263
diff
changeset
|
53 |
13619 | 54 #include "help_mp.h" |
55 | |
33561
1ff6737f2177
Avoid including aviheader.h only for mmioFOURCC, it has too many
reimar
parents:
33364
diff
changeset
|
56 #include "libavutil/avutil.h" |
15305 | 57 #include "libmpcodecs/img_format.h" |
297 | 58 #include "codec-cfg.h" |
59 | |
31406
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
60 #ifdef CODECS2HTML |
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
61 #define CODEC_CFG_MIN 20100000 |
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
62 #else |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
63 #include "codecs.conf.h" |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
64 #endif |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
65 |
5937 | 66 #define PRINT_LINENUM mp_msg(MSGT_CODECCFG,MSGL_ERR," at line %d\n", line_num) |
328 | 67 |
31077 | 68 #define MAX_NR_TOKEN 16 |
297 | 69 |
31077 | 70 #define MAX_LINE_LEN 1000 |
297 | 71 |
31077 | 72 #define RET_EOF -1 |
73 #define RET_EOL -2 | |
297 | 74 |
31077 | 75 #define TYPE_VIDEO 0 |
76 #define TYPE_AUDIO 1 | |
297 | 77 |
31406
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
78 static int codecs_conf_release; |
11759
29eea271490e
add -codecs-file for selecting a specific codecs.conf on the comand line
attila
parents:
11388
diff
changeset
|
79 char * codecs_file = NULL; |
29eea271490e
add -codecs-file for selecting a specific codecs.conf on the comand line
attila
parents:
11388
diff
changeset
|
80 |
303 | 81 static int add_to_fourcc(char *s, char *alias, unsigned int *fourcc, |
31077 | 82 unsigned int *map) |
297 | 83 { |
31077 | 84 int i, j, freeslots; |
85 unsigned int tmp; | |
319 | 86 |
31077 | 87 /* find first unused slot */ |
88 for (i = 0; i < CODECS_MAX_FOURCC && fourcc[i] != 0xffffffff; i++) | |
89 /* NOTHING */; | |
90 freeslots = CODECS_MAX_FOURCC - i; | |
91 if (!freeslots) | |
92 goto err_out_too_many; | |
319 | 93 |
31077 | 94 do { |
33561
1ff6737f2177
Avoid including aviheader.h only for mmioFOURCC, it has too many
reimar
parents:
33364
diff
changeset
|
95 tmp = MKTAG(s[0], s[1], s[2], s[3]); |
31077 | 96 for (j = 0; j < i; j++) |
97 if (tmp == fourcc[j]) | |
98 goto err_out_duplicated; | |
99 fourcc[i] = tmp; | |
33561
1ff6737f2177
Avoid including aviheader.h only for mmioFOURCC, it has too many
reimar
parents:
33364
diff
changeset
|
100 map[i] = alias ? MKTAG(alias[0], alias[1], alias[2], alias[3]) : tmp; |
31077 | 101 s += 4; |
102 i++; | |
103 } while ((*(s++) == ',') && --freeslots); | |
319 | 104 |
31077 | 105 if (!freeslots) |
106 goto err_out_too_many; | |
107 if (*(--s) != '\0') | |
108 goto err_out_parse_error; | |
109 return 1; | |
328 | 110 err_out_duplicated: |
31077 | 111 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_DuplicateFourcc); |
112 return 0; | |
328 | 113 err_out_too_many: |
31077 | 114 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_TooManyFourccs); |
115 return 0; | |
361 | 116 err_out_parse_error: |
31077 | 117 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_ParseError); |
118 return 0; | |
319 | 119 } |
120 | |
7770 | 121 static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int *fourccmap) |
319 | 122 { |
31077 | 123 int i, j; |
124 char *endptr; | |
297 | 125 |
31077 | 126 /* find first unused slot */ |
127 for (i = 0; i < CODECS_MAX_FOURCC && fourcc[i] != 0xffffffff; i++) | |
128 /* NOTHING */; | |
129 if (i == CODECS_MAX_FOURCC) { | |
130 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_TooManyFourccs); | |
131 return 0; | |
132 } | |
297 | 133 |
31077 | 134 fourcc[i]=strtoul(s,&endptr,0); |
135 if (*endptr != '\0') { | |
136 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_ParseErrorFIDNotNumber); | |
137 return 0; | |
138 } | |
7770 | 139 |
31077 | 140 if(alias){ |
141 fourccmap[i]=strtoul(alias,&endptr,0); | |
142 if (*endptr != '\0') { | |
143 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_ParseErrorFIDAliasNotNumber); | |
144 return 0; | |
145 } | |
146 } else | |
147 fourccmap[i]=fourcc[i]; | |
7770 | 148 |
31077 | 149 for (j = 0; j < i; j++) |
150 if (fourcc[j] == fourcc[i]) { | |
151 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_DuplicateFID); | |
152 return 0; | |
153 } | |
300 | 154 |
31077 | 155 return 1; |
297 | 156 } |
157 | |
31159 | 158 static const struct { |
159 const char *name; | |
160 const unsigned int num; | |
161 } fmt_table[] = { | |
162 // note: due to parser deficiencies/simplicity, if one format | |
163 // name matches the beginning of another, the longer one _must_ | |
164 // come first in this list. | |
165 {"YV12", IMGFMT_YV12}, | |
166 {"I420", IMGFMT_I420}, | |
167 {"IYUV", IMGFMT_IYUV}, | |
168 {"NV12", IMGFMT_NV12}, | |
169 {"NV21", IMGFMT_NV21}, | |
170 {"YVU9", IMGFMT_YVU9}, | |
171 {"IF09", IMGFMT_IF09}, | |
172 {"444P16LE", IMGFMT_444P16_LE}, | |
173 {"444P16BE", IMGFMT_444P16_BE}, | |
174 {"422P16LE", IMGFMT_422P16_LE}, | |
175 {"422P16BE", IMGFMT_422P16_BE}, | |
176 {"420P16LE", IMGFMT_420P16_LE}, | |
177 {"420P16BE", IMGFMT_420P16_BE}, | |
178 {"444P16", IMGFMT_444P16}, | |
179 {"422P16", IMGFMT_422P16}, | |
33364
e1ee4895e500
Support displaying of 9- and 10-bit pixel formats,
cehoyos
parents:
33246
diff
changeset
|
180 {"422P10", IMGFMT_422P10}, |
31159 | 181 {"420P16", IMGFMT_420P16}, |
33364
e1ee4895e500
Support displaying of 9- and 10-bit pixel formats,
cehoyos
parents:
33246
diff
changeset
|
182 {"420P10", IMGFMT_420P10}, |
e1ee4895e500
Support displaying of 9- and 10-bit pixel formats,
cehoyos
parents:
33246
diff
changeset
|
183 {"420P9", IMGFMT_420P9}, |
31159 | 184 {"420A", IMGFMT_420A}, |
185 {"444P", IMGFMT_444P}, | |
186 {"422P", IMGFMT_422P}, | |
187 {"411P", IMGFMT_411P}, | |
188 {"440P", IMGFMT_440P}, | |
189 {"Y800", IMGFMT_Y800}, | |
190 {"Y8", IMGFMT_Y8}, | |
408 | 191 |
31159 | 192 {"YUY2", IMGFMT_YUY2}, |
193 {"UYVY", IMGFMT_UYVY}, | |
194 {"YVYU", IMGFMT_YVYU}, | |
408 | 195 |
31159 | 196 {"RGB48LE", IMGFMT_RGB48LE}, |
197 {"RGB48BE", IMGFMT_RGB48BE}, | |
198 {"RGB4", IMGFMT_RGB4}, | |
199 {"RGB8", IMGFMT_RGB8}, | |
200 {"RGB15", IMGFMT_RGB15}, | |
201 {"RGB16", IMGFMT_RGB16}, | |
202 {"RGB24", IMGFMT_RGB24}, | |
203 {"RGB32", IMGFMT_RGB32}, | |
204 {"BGR4", IMGFMT_BGR4}, | |
205 {"BGR8", IMGFMT_BGR8}, | |
206 {"BGR15", IMGFMT_BGR15}, | |
207 {"BGR16", IMGFMT_BGR16}, | |
208 {"BGR24", IMGFMT_BGR24}, | |
209 {"BGR32", IMGFMT_BGR32}, | |
210 {"RGB1", IMGFMT_RGB1}, | |
211 {"BGR1", IMGFMT_BGR1}, | |
1871 | 212 |
31159 | 213 {"MPES", IMGFMT_MPEGPES}, |
214 {"ZRMJPEGNI", IMGFMT_ZRMJPEGNI}, | |
215 {"ZRMJPEGIT", IMGFMT_ZRMJPEGIT}, | |
216 {"ZRMJPEGIB", IMGFMT_ZRMJPEGIB}, | |
10316 | 217 |
31159 | 218 {"IDCT_MPEG2",IMGFMT_XVMC_IDCT_MPEG2}, |
219 {"MOCO_MPEG2",IMGFMT_XVMC_MOCO_MPEG2}, | |
10316 | 220 |
31159 | 221 {"VDPAU_MPEG1",IMGFMT_VDPAU_MPEG1}, |
222 {"VDPAU_MPEG2",IMGFMT_VDPAU_MPEG2}, | |
223 {"VDPAU_H264",IMGFMT_VDPAU_H264}, | |
224 {"VDPAU_WMV3",IMGFMT_VDPAU_WMV3}, | |
225 {"VDPAU_VC1",IMGFMT_VDPAU_VC1}, | |
226 {"VDPAU_MPEG4",IMGFMT_VDPAU_MPEG4}, | |
28516
79b0bd20433e
Add support for image formats and codecs used by VDPAU
reimar
parents:
27343
diff
changeset
|
227 |
31159 | 228 {NULL, 0} |
229 }; | |
408 | 230 |
607 | 231 |
4675 | 232 static int add_to_inout(char *sfmt, char *sflags, unsigned int *outfmt, |
31077 | 233 unsigned char *outflags) |
607 | 234 { |
235 | |
31077 | 236 static char *flagstr[] = { |
237 "flip", | |
238 "noflip", | |
239 "yuvhack", | |
240 "query", | |
241 "static", | |
242 NULL | |
243 }; | |
299 | 244 |
31077 | 245 int i, j, freeslots; |
246 unsigned char flags; | |
297 | 247 |
31077 | 248 for (i = 0; i < CODECS_MAX_OUTFMT && outfmt[i] != 0xffffffff; i++) |
249 /* NOTHING */; | |
250 freeslots = CODECS_MAX_OUTFMT - i; | |
251 if (!freeslots) | |
252 goto err_out_too_many; | |
297 | 253 |
31077 | 254 flags = 0; |
255 if(sflags) { | |
256 do { | |
257 for (j = 0; flagstr[j] != NULL; j++) | |
258 if (!strncmp(sflags, flagstr[j], | |
259 strlen(flagstr[j]))) | |
260 break; | |
261 if (flagstr[j] == NULL) | |
262 goto err_out_parse_error; | |
263 flags|=(1<<j); | |
264 sflags+=strlen(flagstr[j]); | |
265 } while (*(sflags++) == ','); | |
361 | 266 |
31077 | 267 if (*(--sflags) != '\0') |
268 goto err_out_parse_error; | |
269 } | |
297 | 270 |
31077 | 271 do { |
272 for (j = 0; fmt_table[j].name != NULL; j++) | |
273 if (!strncmp(sfmt, fmt_table[j].name, strlen(fmt_table[j].name))) | |
274 break; | |
275 if (fmt_table[j].name == NULL) | |
276 goto err_out_parse_error; | |
277 outfmt[i] = fmt_table[j].num; | |
278 outflags[i] = flags; | |
279 ++i; | |
280 sfmt+=strlen(fmt_table[j].name); | |
281 } while ((*(sfmt++) == ',') && --freeslots); | |
319 | 282 |
31077 | 283 if (!freeslots) |
284 goto err_out_too_many; | |
319 | 285 |
31077 | 286 if (*(--sfmt) != '\0') |
287 goto err_out_parse_error; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
288 |
31077 | 289 return 1; |
328 | 290 err_out_too_many: |
31077 | 291 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_TooManyOut); |
292 return 0; | |
361 | 293 err_out_parse_error: |
31077 | 294 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_ParseError); |
295 return 0; | |
297 | 296 } |
297 | |
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
parents:
6927
diff
changeset
|
298 #if 0 |
303 | 299 static short get_driver(char *s,int audioflag) |
297 | 300 { |
31077 | 301 static char *audiodrv[] = { |
302 "null", | |
303 "mp3lib", | |
304 "pcm", | |
305 "libac3", | |
306 "acm", | |
307 "alaw", | |
308 "msgsm", | |
309 "dshow", | |
310 "dvdpcm", | |
311 "hwac3", | |
312 "libvorbis", | |
313 "ffmpeg", | |
314 "libmad", | |
315 "msadpcm", | |
316 "liba52", | |
317 "g72x", | |
318 "imaadpcm", | |
319 "dk4adpcm", | |
320 "dk3adpcm", | |
321 "roqaudio", | |
322 "faad", | |
323 "realaud", | |
324 "libdv", | |
325 NULL | |
326 }; | |
327 static char *videodrv[] = { | |
328 "null", | |
329 "libmpeg2", | |
330 "vfw", | |
331 "dshow", | |
332 "ffmpeg", | |
333 "vfwex", | |
334 "raw", | |
335 "msrle", | |
336 "xanim", | |
337 "msvidc", | |
338 "fli", | |
339 "cinepak", | |
340 "qtrle", | |
341 "nuv", | |
342 "cyuv", | |
343 "qtsmc", | |
344 "ducktm1", | |
345 "roqvideo", | |
346 "qtrpza", | |
347 "mpng", | |
348 "ijpg", | |
349 "zlib", | |
350 "mpegpes", | |
351 "zrmjpeg", | |
352 "realvid", | |
353 "xvid", | |
354 "libdv", | |
355 NULL | |
356 }; | |
357 char **drv=audioflag?audiodrv:videodrv; | |
358 int i; | |
6863 | 359 |
31077 | 360 for(i=0;drv[i];i++) if(!strcmp(s,drv[i])) return i; |
301 | 361 |
31077 | 362 return -1; |
297 | 363 } |
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
parents:
6927
diff
changeset
|
364 #endif |
297 | 365 |
328 | 366 static int validate_codec(codecs_t *c, int type) |
319 | 367 { |
31077 | 368 unsigned int i; |
369 char *tmp_name = c->name; | |
328 | 370 |
31077 | 371 for (i = 0; i < strlen(tmp_name) && isalnum(tmp_name[i]); i++) |
372 /* NOTHING */; | |
3408 | 373 |
31077 | 374 if (i < strlen(tmp_name)) { |
375 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_InvalidCodecName, c->name); | |
376 return 0; | |
377 } | |
3408 | 378 |
31077 | 379 if (!c->info) |
380 c->info = strdup(c->name); | |
3408 | 381 |
382 #if 0 | |
31077 | 383 if (c->fourcc[0] == 0xffffffff) { |
384 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecLacksFourcc, c->name); | |
385 return 0; | |
386 } | |
13936
589b227e3367
fix crash when a "driver" line is missing in codecs.conf.
reimar
parents:
13807
diff
changeset
|
387 #endif |
3408 | 388 |
31077 | 389 if (!c->drv) { |
390 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecLacksDriver, c->name); | |
391 return 0; | |
392 } | |
3408 | 393 |
394 #if 0 | |
32394
914208d188b9
Remove #warning preprocessor directives or replace them by suitable comments.
diego
parents:
31409
diff
changeset
|
395 //FIXME: codec->driver == 4;... <- this should not be put in here... |
914208d188b9
Remove #warning preprocessor directives or replace them by suitable comments.
diego
parents:
31409
diff
changeset
|
396 //FIXME: Where are they defined ???????????? |
31077 | 397 if (!c->dll && (c->driver == 4 || |
398 (c->driver == 2 && type == TYPE_VIDEO))) { | |
399 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecNeedsDLL, c->name); | |
400 return 0; | |
401 } | |
32394
914208d188b9
Remove #warning preprocessor directives or replace them by suitable comments.
diego
parents:
31409
diff
changeset
|
402 // FIXME: Can guid.f1 be 0? How does one know that it was not given? |
31077 | 403 // if (!(codec->flags & CODECS_FLAG_AUDIO) && codec->driver == 4) |
328 | 404 |
31077 | 405 if (type == TYPE_VIDEO) |
406 if (c->outfmt[0] == 0xffffffff) { | |
407 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecNeedsOutfmt, c->name); | |
408 return 0; | |
409 } | |
329 | 410 #endif |
31077 | 411 return 1; |
319 | 412 } |
413 | |
414 static int add_comment(char *s, char **d) | |
415 { | |
31077 | 416 int pos; |
319 | 417 |
31077 | 418 if (!*d) |
419 pos = 0; | |
420 else { | |
421 pos = strlen(*d); | |
422 (*d)[pos++] = '\n'; | |
423 } | |
424 if (!(*d = realloc(*d, pos + strlen(s) + 1))) { | |
425 mp_msg(MSGT_CODECCFG,MSGL_FATAL,MSGTR_CantAllocateComment); | |
426 return 0; | |
427 } | |
428 strcpy(*d + pos, s); | |
429 return 1; | |
319 | 430 } |
297 | 431 |
361 | 432 static short get_cpuflags(char *s) |
433 { | |
31077 | 434 static char *flagstr[] = { |
435 "mmx", | |
436 "sse", | |
437 "3dnow", | |
438 NULL | |
439 }; | |
440 int i; | |
441 short flags = 0; | |
361 | 442 |
31077 | 443 do { |
444 for (i = 0; flagstr[i]; i++) | |
445 if (!strncmp(s, flagstr[i], strlen(flagstr[i]))) | |
446 break; | |
447 if (!flagstr[i]) | |
448 goto err_out_parse_error; | |
449 flags |= 1<<i; | |
450 s += strlen(flagstr[i]); | |
451 } while (*(s++) == ','); | |
361 | 452 |
31077 | 453 if (*(--s) != '\0') |
454 goto err_out_parse_error; | |
361 | 455 |
31077 | 456 return flags; |
361 | 457 err_out_parse_error: |
31077 | 458 return 0; |
361 | 459 } |
460 | |
328 | 461 static FILE *fp; |
462 static int line_num = 0; | |
463 static char *line; | |
464 static char *token[MAX_NR_TOKEN]; | |
6200
e604be87613d
codecs.conf versioning - patch by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6103
diff
changeset
|
465 static int read_nextline = 1; |
328 | 466 |
467 static int get_token(int min, int max) | |
297 | 468 { |
31077 | 469 static int line_pos; |
470 int i; | |
471 char c; | |
328 | 472 |
31077 | 473 if (max >= MAX_NR_TOKEN) { |
474 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_GetTokenMaxNotLessThanMAX_NR_TOKEN); | |
475 goto out_eof; | |
476 } | |
328 | 477 |
31077 | 478 memset(token, 0x00, sizeof(*token) * max); |
328 | 479 |
31077 | 480 if (read_nextline) { |
481 if (!fgets(line, MAX_LINE_LEN, fp)) | |
482 goto out_eof; | |
483 line_pos = 0; | |
484 ++line_num; | |
485 read_nextline = 0; | |
486 } | |
487 for (i = 0; i < max; i++) { | |
488 while (isspace(line[line_pos])) | |
489 ++line_pos; | |
490 if (line[line_pos] == '\0' || line[line_pos] == '#' || | |
491 line[line_pos] == ';') { | |
492 read_nextline = 1; | |
493 if (i >= min) | |
494 goto out_ok; | |
495 goto out_eol; | |
496 } | |
497 token[i] = line + line_pos; | |
498 c = line[line_pos]; | |
499 if (c == '"' || c == '\'') { | |
500 token[i]++; | |
501 while (line[++line_pos] != c && line[line_pos]) | |
502 /* NOTHING */; | |
503 } else { | |
504 for (/* NOTHING */; !isspace(line[line_pos]) && | |
505 line[line_pos]; line_pos++) | |
506 /* NOTHING */; | |
507 } | |
508 if (!line[line_pos]) { | |
509 read_nextline = 1; | |
510 if (i >= min - 1) | |
511 goto out_ok; | |
512 goto out_eol; | |
513 } | |
514 line[line_pos] = '\0'; | |
515 line_pos++; | |
516 } | |
328 | 517 out_ok: |
31077 | 518 return i; |
328 | 519 out_eof: |
31077 | 520 read_nextline = 1; |
521 return RET_EOF; | |
328 | 522 out_eol: |
31077 | 523 return RET_EOL; |
328 | 524 } |
525 | |
526 static codecs_t *video_codecs=NULL; | |
527 static codecs_t *audio_codecs=NULL; | |
528 static int nr_vcodecs = 0; | |
529 static int nr_acodecs = 0; | |
530 | |
18980
ed69754aa58d
Marks several string parameters as const when they are not modified in the function, Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents:
18034
diff
changeset
|
531 int parse_codec_cfg(const char *cfgfile) |
328 | 532 { |
31077 | 533 codecs_t *codec = NULL; // current codec |
534 codecs_t **codecsp = NULL;// points to audio_codecs or to video_codecs | |
535 char *endptr; // strtoul()... | |
536 int *nr_codecsp; | |
537 int codec_type; /* TYPE_VIDEO/TYPE_AUDIO */ | |
538 int tmp, i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
539 |
31077 | 540 // in case we call it a second time |
541 codecs_uninit_free(); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
542 |
31077 | 543 nr_vcodecs = 0; |
544 nr_acodecs = 0; | |
297 | 545 |
31077 | 546 if(cfgfile==NULL) { |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
547 #ifdef CODECS2HTML |
31077 | 548 return 0; |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
549 #else |
31077 | 550 video_codecs = builtin_video_codecs; |
551 audio_codecs = builtin_audio_codecs; | |
552 nr_vcodecs = sizeof(builtin_video_codecs)/sizeof(codecs_t); | |
553 nr_acodecs = sizeof(builtin_audio_codecs)/sizeof(codecs_t); | |
554 return 1; | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
555 #endif |
31077 | 556 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
557 |
31077 | 558 mp_msg(MSGT_CODECCFG,MSGL_V,MSGTR_ReadingFile, cfgfile); |
297 | 559 |
31077 | 560 if ((fp = fopen(cfgfile, "r")) == NULL) { |
561 mp_msg(MSGT_CODECCFG,MSGL_V,MSGTR_CantOpenFileError, cfgfile, strerror(errno)); | |
562 return 0; | |
563 } | |
297 | 564 |
31077 | 565 if ((line = malloc(MAX_LINE_LEN + 1)) == NULL) { |
566 mp_msg(MSGT_CODECCFG,MSGL_FATAL,MSGTR_CantGetMemoryForLine, strerror(errno)); | |
567 return 0; | |
568 } | |
569 read_nextline = 1; | |
297 | 570 |
31077 | 571 /* |
572 * this only catches release lines at the start of | |
573 * codecs.conf, before audiocodecs and videocodecs. | |
574 */ | |
575 while ((tmp = get_token(1, 1)) == RET_EOL) | |
576 /* NOTHING */; | |
577 if (tmp == RET_EOF) | |
578 goto out; | |
579 if (!strcmp(token[0], "release")) { | |
580 if (get_token(1, 2) < 0) | |
581 goto err_out_parse_error; | |
582 tmp = atoi(token[0]); | |
583 if (tmp < CODEC_CFG_MIN) | |
584 goto err_out_release_num; | |
31406
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
585 codecs_conf_release = tmp; |
31077 | 586 while ((tmp = get_token(1, 1)) == RET_EOL) |
587 /* NOTHING */; | |
588 if (tmp == RET_EOF) | |
589 goto out; | |
590 } else | |
591 goto err_out_release_num; | |
6200
e604be87613d
codecs.conf versioning - patch by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6103
diff
changeset
|
592 |
31077 | 593 /* |
594 * check if the next block starts with 'audiocodec' or | |
595 * with 'videocodec' | |
596 */ | |
597 if (!strcmp(token[0], "audiocodec") || !strcmp(token[0], "videocodec")) | |
598 goto loop_enter; | |
599 goto err_out_parse_error; | |
328 | 600 |
31077 | 601 while ((tmp = get_token(1, 1)) != RET_EOF) { |
602 if (tmp == RET_EOL) | |
603 continue; | |
604 if (!strcmp(token[0], "audiocodec") || | |
605 !strcmp(token[0], "videocodec")) { | |
606 if (!validate_codec(codec, codec_type)) | |
607 goto err_out_not_valid; | |
608 loop_enter: | |
609 if (*token[0] == 'v') { | |
610 codec_type = TYPE_VIDEO; | |
611 nr_codecsp = &nr_vcodecs; | |
612 codecsp = &video_codecs; | |
613 } else if (*token[0] == 'a') { | |
614 codec_type = TYPE_AUDIO; | |
615 nr_codecsp = &nr_acodecs; | |
616 codecsp = &audio_codecs; | |
361 | 617 #ifdef DEBUG |
31077 | 618 } else { |
619 mp_msg(MSGT_CODECCFG,MSGL_ERR,"picsba\n"); | |
620 goto err_out; | |
361 | 621 #endif |
31077 | 622 } |
623 if (!(*codecsp = realloc(*codecsp, | |
624 sizeof(codecs_t) * (*nr_codecsp + 2)))) { | |
625 mp_msg(MSGT_CODECCFG,MSGL_FATAL,MSGTR_CantReallocCodecsp, strerror(errno)); | |
626 goto err_out; | |
627 } | |
628 codec=*codecsp + *nr_codecsp; | |
629 ++*nr_codecsp; | |
630 memset(codec,0,sizeof(codecs_t)); | |
631 memset(codec->fourcc, 0xff, sizeof(codec->fourcc)); | |
632 memset(codec->outfmt, 0xff, sizeof(codec->outfmt)); | |
633 memset(codec->infmt, 0xff, sizeof(codec->infmt)); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
634 |
31077 | 635 if (get_token(1, 1) < 0) |
636 goto err_out_parse_error; | |
637 for (i = 0; i < *nr_codecsp - 1; i++) { | |
638 if(( (*codecsp)[i].name!=NULL) && | |
639 (!strcmp(token[0], (*codecsp)[i].name)) ) { | |
640 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecNameNotUnique, token[0]); | |
641 goto err_out_print_linenum; | |
642 } | |
643 } | |
644 if (!(codec->name = strdup(token[0]))) { | |
645 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CantStrdupName, strerror(errno)); | |
646 goto err_out; | |
647 } | |
648 } else if (!strcmp(token[0], "info")) { | |
649 if (codec->info || get_token(1, 1) < 0) | |
650 goto err_out_parse_error; | |
651 if (!(codec->info = strdup(token[0]))) { | |
652 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CantStrdupInfo, strerror(errno)); | |
653 goto err_out; | |
654 } | |
655 } else if (!strcmp(token[0], "comment")) { | |
656 if (get_token(1, 1) < 0) | |
657 goto err_out_parse_error; | |
658 add_comment(token[0], &codec->comment); | |
659 } else if (!strcmp(token[0], "fourcc")) { | |
660 if (get_token(1, 2) < 0) | |
661 goto err_out_parse_error; | |
662 if (!add_to_fourcc(token[0], token[1], | |
663 codec->fourcc, | |
664 codec->fourccmap)) | |
665 goto err_out_print_linenum; | |
666 } else if (!strcmp(token[0], "format")) { | |
667 if (get_token(1, 2) < 0) | |
668 goto err_out_parse_error; | |
669 if (!add_to_format(token[0], token[1], | |
670 codec->fourcc,codec->fourccmap)) | |
671 goto err_out_print_linenum; | |
672 } else if (!strcmp(token[0], "driver")) { | |
673 if (get_token(1, 1) < 0) | |
674 goto err_out_parse_error; | |
675 if (!(codec->drv = strdup(token[0]))) { | |
676 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CantStrdupDriver, strerror(errno)); | |
677 goto err_out; | |
678 } | |
679 } else if (!strcmp(token[0], "dll")) { | |
680 if (get_token(1, 1) < 0) | |
681 goto err_out_parse_error; | |
682 if (!(codec->dll = strdup(token[0]))) { | |
683 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CantStrdupDLL, strerror(errno)); | |
684 goto err_out; | |
685 } | |
686 } else if (!strcmp(token[0], "guid")) { | |
687 if (get_token(11, 11) < 0) | |
688 goto err_out_parse_error; | |
689 codec->guid.f1=strtoul(token[0],&endptr,0); | |
690 if ((*endptr != ',' || *(endptr + 1) != '\0') && | |
691 *endptr != '\0') | |
692 goto err_out_parse_error; | |
693 codec->guid.f2=strtoul(token[1],&endptr,0); | |
694 if ((*endptr != ',' || *(endptr + 1) != '\0') && | |
695 *endptr != '\0') | |
696 goto err_out_parse_error; | |
697 codec->guid.f3=strtoul(token[2],&endptr,0); | |
698 if ((*endptr != ',' || *(endptr + 1) != '\0') && | |
699 *endptr != '\0') | |
700 goto err_out_parse_error; | |
701 for (i = 0; i < 8; i++) { | |
702 codec->guid.f4[i]=strtoul(token[i + 3],&endptr,0); | |
703 if ((*endptr != ',' || *(endptr + 1) != '\0') && | |
704 *endptr != '\0') | |
705 goto err_out_parse_error; | |
706 } | |
707 } else if (!strcmp(token[0], "out")) { | |
708 if (get_token(1, 2) < 0) | |
709 goto err_out_parse_error; | |
710 if (!add_to_inout(token[0], token[1], codec->outfmt, | |
711 codec->outflags)) | |
712 goto err_out_print_linenum; | |
713 } else if (!strcmp(token[0], "in")) { | |
714 if (get_token(1, 2) < 0) | |
715 goto err_out_parse_error; | |
716 if (!add_to_inout(token[0], token[1], codec->infmt, | |
717 codec->inflags)) | |
718 goto err_out_print_linenum; | |
719 } else if (!strcmp(token[0], "flags")) { | |
720 if (get_token(1, 1) < 0) | |
721 goto err_out_parse_error; | |
722 if (!strcmp(token[0], "seekable")) | |
723 codec->flags |= CODECS_FLAG_SEEKABLE; | |
724 else | |
725 if (!strcmp(token[0], "align16")) | |
726 codec->flags |= CODECS_FLAG_ALIGN16; | |
727 else | |
728 goto err_out_parse_error; | |
729 } else if (!strcmp(token[0], "status")) { | |
730 if (get_token(1, 1) < 0) | |
731 goto err_out_parse_error; | |
732 if (!strcasecmp(token[0], "working")) | |
733 codec->status = CODECS_STATUS_WORKING; | |
734 else if (!strcasecmp(token[0], "crashing")) | |
735 codec->status = CODECS_STATUS_NOT_WORKING; | |
736 else if (!strcasecmp(token[0], "untested")) | |
737 codec->status = CODECS_STATUS_UNTESTED; | |
738 else if (!strcasecmp(token[0], "buggy")) | |
739 codec->status = CODECS_STATUS_PROBLEMS; | |
740 else | |
741 goto err_out_parse_error; | |
742 } else if (!strcmp(token[0], "cpuflags")) { | |
743 if (get_token(1, 1) < 0) | |
744 goto err_out_parse_error; | |
745 if (!(codec->cpuflags = get_cpuflags(token[0]))) | |
746 goto err_out_parse_error; | |
747 } else | |
748 goto err_out_parse_error; | |
749 } | |
750 if (!validate_codec(codec, codec_type)) | |
751 goto err_out_not_valid; | |
752 mp_msg(MSGT_CODECCFG,MSGL_INFO,MSGTR_AudioVideoCodecTotals, nr_acodecs, nr_vcodecs); | |
753 if(video_codecs) video_codecs[nr_vcodecs].name = NULL; | |
754 if(audio_codecs) audio_codecs[nr_acodecs].name = NULL; | |
297 | 755 out: |
31077 | 756 free(line); |
757 line=NULL; | |
758 fclose(fp); | |
759 return 1; | |
3798
d1e3ad5bcd8f
fixed few segfaults, make parse_codec_cfg() return int
iive
parents:
3787
diff
changeset
|
760 |
328 | 761 err_out_parse_error: |
31077 | 762 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_ParseError); |
361 | 763 err_out_print_linenum: |
31077 | 764 PRINT_LINENUM; |
297 | 765 err_out: |
31077 | 766 codecs_uninit_free(); |
3798
d1e3ad5bcd8f
fixed few segfaults, make parse_codec_cfg() return int
iive
parents:
3787
diff
changeset
|
767 |
31077 | 768 free(line); |
769 line=NULL; | |
770 line_num = 0; | |
771 fclose(fp); | |
772 return 0; | |
328 | 773 err_out_not_valid: |
31077 | 774 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_CodecDefinitionIncorrect); |
775 goto err_out_print_linenum; | |
6200
e604be87613d
codecs.conf versioning - patch by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6103
diff
changeset
|
776 err_out_release_num: |
31077 | 777 mp_msg(MSGT_CODECCFG,MSGL_ERR,MSGTR_OutdatedCodecsConf); |
778 goto err_out_print_linenum; | |
297 | 779 } |
780 | |
13807
b014091b4417
Memory Free function Fix, based on patch by Wei Jiang <jiangw98@yahoo.com>
faust3
parents:
13619
diff
changeset
|
781 static void codecs_free(codecs_t* codecs,int count) { |
31077 | 782 int i; |
783 for ( i = 0; i < count; i++) | |
784 if ( codecs[i].name ) { | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
785 free(codecs[i].name); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
786 free(codecs[i].info); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
787 free(codecs[i].comment); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
788 free(codecs[i].dll); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
789 free(codecs[i].drv); |
31077 | 790 } |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32394
diff
changeset
|
791 free(codecs); |
13807
b014091b4417
Memory Free function Fix, based on patch by Wei Jiang <jiangw98@yahoo.com>
faust3
parents:
13619
diff
changeset
|
792 } |
b014091b4417
Memory Free function Fix, based on patch by Wei Jiang <jiangw98@yahoo.com>
faust3
parents:
13619
diff
changeset
|
793 |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
17120
diff
changeset
|
794 void codecs_uninit_free(void) { |
31077 | 795 if (video_codecs) |
796 codecs_free(video_codecs,nr_vcodecs); | |
797 video_codecs=NULL; | |
798 if (audio_codecs) | |
799 codecs_free(audio_codecs,nr_acodecs); | |
800 audio_codecs=NULL; | |
13807
b014091b4417
Memory Free function Fix, based on patch by Wei Jiang <jiangw98@yahoo.com>
faust3
parents:
13619
diff
changeset
|
801 } |
b014091b4417
Memory Free function Fix, based on patch by Wei Jiang <jiangw98@yahoo.com>
faust3
parents:
13619
diff
changeset
|
802 |
332 | 803 codecs_t *find_audio_codec(unsigned int fourcc, unsigned int *fourccmap, |
31077 | 804 codecs_t *start, int force) |
328 | 805 { |
31077 | 806 return find_codec(fourcc, fourccmap, start, 1, force); |
328 | 807 } |
808 | |
332 | 809 codecs_t *find_video_codec(unsigned int fourcc, unsigned int *fourccmap, |
31077 | 810 codecs_t *start, int force) |
328 | 811 { |
31077 | 812 return find_codec(fourcc, fourccmap, start, 0, force); |
328 | 813 } |
814 | |
332 | 815 codecs_t* find_codec(unsigned int fourcc,unsigned int *fourccmap, |
31077 | 816 codecs_t *start, int audioflag, int force) |
328 | 817 { |
31077 | 818 int i, j; |
819 codecs_t *c; | |
328 | 820 |
628 | 821 #if 0 |
31077 | 822 if (start) { |
823 for (/* NOTHING */; start->name; start++) { | |
824 for (j = 0; j < CODECS_MAX_FOURCC; j++) { | |
825 if (start->fourcc[j] == fourcc) { | |
826 if (fourccmap) | |
827 *fourccmap = start->fourccmap[j]; | |
828 return start; | |
829 } | |
830 } | |
831 } | |
832 } else | |
628 | 833 #endif |
31077 | 834 { |
835 if (audioflag) { | |
836 i = nr_acodecs; | |
837 c = audio_codecs; | |
838 } else { | |
839 i = nr_vcodecs; | |
840 c = video_codecs; | |
841 } | |
842 if(!i) return NULL; | |
843 for (/* NOTHING */; i--; c++) { | |
844 if(start && c<=start) continue; | |
845 for (j = 0; j < CODECS_MAX_FOURCC; j++) { | |
846 // FIXME: do NOT hardwire 'null' name here: | |
847 if (c->fourcc[j]==fourcc || !strcmp(c->drv,"null")) { | |
848 if (fourccmap) | |
849 *fourccmap = c->fourccmap[j]; | |
850 return c; | |
851 } | |
852 } | |
853 if (force) return c; | |
854 } | |
855 } | |
856 return NULL; | |
303 | 857 } |
858 | |
25661
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
859 void stringset_init(stringset_t *set) { |
31077 | 860 *set = calloc(1, sizeof(char *)); |
25661
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
861 } |
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
862 |
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
863 void stringset_free(stringset_t *set) { |
31077 | 864 int count = 0; |
865 while ((*set)[count]) free((*set)[count++]); | |
866 free(*set); | |
867 *set = NULL; | |
7505 | 868 } |
869 | |
25661
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
870 void stringset_add(stringset_t *set, const char *str) { |
31077 | 871 int count = 0; |
872 while ((*set)[count]) count++; | |
873 count++; | |
874 *set = realloc(*set, sizeof(char *) * (count + 1)); | |
875 (*set)[count - 1] = strdup(str); | |
876 (*set)[count] = NULL; | |
25661
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
877 } |
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
878 |
293aeec83153
Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with
reimar
parents:
25247
diff
changeset
|
879 int stringset_test(stringset_t *set, const char *str) { |
31077 | 880 stringset_t s; |
881 for (s = *set; *s; s++) | |
882 if (strcmp(*s, str) == 0) | |
883 return 1; | |
884 return 0; | |
5325
9c326f199060
tagging selected codec to avoid trying the same codec several times
arpi
parents:
5284
diff
changeset
|
885 } |
9c326f199060
tagging selected codec to avoid trying the same codec several times
arpi
parents:
5284
diff
changeset
|
886 |
1983 | 887 void list_codecs(int audioflag){ |
31077 | 888 int i; |
889 codecs_t *c; | |
1983 | 890 |
31077 | 891 if (audioflag) { |
892 i = nr_acodecs; | |
893 c = audio_codecs; | |
894 mp_msg(MSGT_CODECCFG,MSGL_INFO,"ac: afm: status: info: [lib/dll]\n"); | |
895 } else { | |
896 i = nr_vcodecs; | |
897 c = video_codecs; | |
898 mp_msg(MSGT_CODECCFG,MSGL_INFO,"vc: vfm: status: info: [lib/dll]\n"); | |
899 } | |
900 if(!i) return; | |
901 for (/* NOTHING */; i--; c++) { | |
902 char* s="unknown "; | |
903 switch(c->status){ | |
904 case CODECS_STATUS_WORKING: s="working ";break; | |
905 case CODECS_STATUS_PROBLEMS: s="problems";break; | |
906 case CODECS_STATUS_NOT_WORKING: s="crashing";break; | |
907 case CODECS_STATUS_UNTESTED: s="untested";break; | |
908 } | |
909 if(c->dll) | |
910 mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s [%s]\n",c->name,c->drv,s,c->info,c->dll); | |
911 else | |
912 mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s\n",c->name,c->drv,s,c->info); | |
913 } | |
1983 | 914 } |
915 | |
916 | |
607 | 917 #ifdef CODECS2HTML |
31408 | 918 static void wrapline(FILE *f2,char *s){ |
607 | 919 int c; |
920 if(!s){ | |
921 fprintf(f2,"-"); | |
922 return; | |
923 } | |
924 while((c=*s++)){ | |
925 if(c==',') fprintf(f2,"<br>"); else fputc(c,f2); | |
926 } | |
927 } | |
928 | |
31409 | 929 static void parsehtml(FILE *f1,FILE *f2,codecs_t *codec){ |
31077 | 930 int c,d; |
931 while((c=fgetc(f1))>=0){ | |
932 if(c!='%'){ | |
933 fputc(c,f2); | |
934 continue; | |
935 } | |
936 d=fgetc(f1); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
937 |
31077 | 938 switch(d){ |
939 case '.': | |
940 return; // end of section | |
941 case 'n': | |
942 wrapline(f2,codec->name); break; | |
943 case 'i': | |
944 wrapline(f2,codec->info); break; | |
945 case 'c': | |
946 wrapline(f2,codec->comment); break; | |
947 case 'd': | |
948 wrapline(f2,codec->dll); break; | |
949 case 'D': | |
950 fprintf(f2,"%c",!strcmp(codec->drv,"dshow")?'+':'-'); break; | |
951 case 'F': | |
952 for(d=0;d<CODECS_MAX_FOURCC;d++) | |
953 if(!d || codec->fourcc[d]!=0xFFFFFFFF) | |
954 fprintf(f2,"%s%.4s",d?"<br>":"",(codec->fourcc[d]==0xFFFFFFFF || codec->fourcc[d]<0x20202020)?!d?"-":"":(char*) &codec->fourcc[d]); | |
955 break; | |
956 case 'f': | |
957 for(d=0;d<CODECS_MAX_FOURCC;d++) | |
958 if(codec->fourcc[d]!=0xFFFFFFFF) | |
959 fprintf(f2,"%s0x%X",d?"<br>":"",codec->fourcc[d]); | |
960 break; | |
961 case 'Y': | |
962 for(d=0;d<CODECS_MAX_OUTFMT;d++) | |
963 if(codec->outfmt[d]!=0xFFFFFFFF){ | |
964 for (c=0; fmt_table[c].name; c++) | |
965 if(fmt_table[c].num==codec->outfmt[d]) break; | |
966 if(fmt_table[c].name) | |
967 fprintf(f2,"%s%s",d?"<br>":"",fmt_table[c].name); | |
968 } | |
969 break; | |
970 default: | |
971 fputc(c,f2); | |
972 fputc(d,f2); | |
607 | 973 } |
31077 | 974 } |
607 | 975 } |
976 | |
977 void skiphtml(FILE *f1){ | |
31077 | 978 int c,d; |
979 while((c=fgetc(f1))>=0){ | |
980 if(c!='%'){ | |
981 continue; | |
607 | 982 } |
31077 | 983 d=fgetc(f1); |
984 if(d=='.') return; // end of section | |
985 } | |
607 | 986 } |
987 | |
29115
1e78a310487e
Change type of first argument of the print_int_array function from int to
diego
parents:
28747
diff
changeset
|
988 static void print_int_array(const unsigned int* a, int size) |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
989 { |
31077 | 990 printf("{ "); |
991 while (size--) | |
992 if(abs(*a)<256) | |
993 printf("%d%s", *a++, size?", ":""); | |
994 else | |
995 printf("0x%X%s", *a++, size?", ":""); | |
996 printf(" }"); | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
997 } |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
998 |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
999 static void print_char_array(const unsigned char* a, int size) |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1000 { |
31077 | 1001 printf("{ "); |
1002 while (size--) | |
1003 if((*a)<10) | |
1004 printf("%d%s", *a++, size?", ":""); | |
1005 else | |
1006 printf("0x%02x%s", *a++, size?", ":""); | |
1007 printf(" }"); | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1008 } |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1009 |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1010 static void print_string(const char* s) |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1011 { |
31077 | 1012 if (!s) printf("NULL"); |
1013 else printf("\"%s\"", s); | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1014 } |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1015 |
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1016 int main(int argc, char* argv[]) |
607 | 1017 { |
31077 | 1018 codecs_t *cl; |
1019 FILE *f1; | |
1020 FILE *f2; | |
1021 int c,d,i; | |
1022 int pos; | |
1023 int section=-1; | |
1024 int nr_codecs; | |
1025 int win32=-1; | |
1026 int dshow=-1; | |
1027 int win32ex=-1; | |
607 | 1028 |
31077 | 1029 /* |
1030 * Take path to codecs.conf from command line, or fall back on | |
1031 * etc/codecs.conf | |
1032 */ | |
1033 if (!(nr_codecs = parse_codec_cfg((argc>1)?argv[1]:"etc/codecs.conf"))) | |
1034 exit(1); | |
31406
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
1035 if (codecs_conf_release < CODEC_CFG_MIN) |
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
1036 exit(1); |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1037 |
31077 | 1038 if (argc > 1) { |
1039 int i, j; | |
1040 const char* nm[2]; | |
1041 codecs_t* cod[2]; | |
1042 int nr[2]; | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1043 |
31077 | 1044 nm[0] = "builtin_video_codecs"; |
1045 cod[0] = video_codecs; | |
1046 nr[0] = nr_vcodecs; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1047 |
31077 | 1048 nm[1] = "builtin_audio_codecs"; |
1049 cod[1] = audio_codecs; | |
1050 nr[1] = nr_acodecs; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1051 |
31077 | 1052 printf("/* GENERATED FROM %s, DO NOT EDIT! */\n\n",argv[1]); |
31407 | 1053 printf("#include <stddef.h>\n"); |
1054 printf("#include \"codec-cfg.h\"\n\n"); | |
31406
0fd1b3f1fe69
Auto-update CODEC_CFG_MIN value to release value in etc/codecs.conf.
reimar
parents:
31159
diff
changeset
|
1055 printf("#define CODEC_CFG_MIN %i\n\n", codecs_conf_release); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1056 |
31077 | 1057 for (i=0; i<2; i++) { |
1058 printf("const codecs_t %s[] = {\n", nm[i]); | |
1059 for (j = 0; j < nr[i]; j++) { | |
1060 printf("{"); | |
8467
3ca9cc46df5c
Fallback to builtin (generated from etc/codecs.conf at compile time)
arpi
parents:
8211
diff
changeset
|
1061 |
31077 | 1062 print_int_array(cod[i][j].fourcc, CODECS_MAX_FOURCC); |
1063 printf(", /* fourcc */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1064 |
31077 | 1065 print_int_array(cod[i][j].fourccmap, CODECS_MAX_FOURCC); |
1066 printf(", /* fourccmap */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1067 |
31077 | 1068 print_int_array(cod[i][j].outfmt, CODECS_MAX_OUTFMT); |
1069 printf(", /* outfmt */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1070 |
31077 | 1071 print_char_array(cod[i][j].outflags, CODECS_MAX_OUTFMT); |
1072 printf(", /* outflags */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1073 |
31077 | 1074 print_int_array(cod[i][j].infmt, CODECS_MAX_INFMT); |
1075 printf(", /* infmt */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1076 |
31077 | 1077 print_char_array(cod[i][j].inflags, CODECS_MAX_INFMT); |
1078 printf(", /* inflags */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1079 |
31077 | 1080 print_string(cod[i][j].name); printf(", /* name */\n"); |
1081 print_string(cod[i][j].info); printf(", /* info */\n"); | |
1082 print_string(cod[i][j].comment); printf(", /* comment */\n"); | |
1083 print_string(cod[i][j].dll); printf(", /* dll */\n"); | |
1084 print_string(cod[i][j].drv); printf(", /* drv */\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1085 |
31077 | 1086 printf("{ 0x%08lx, %hu, %hu,", |
1087 cod[i][j].guid.f1, | |
1088 cod[i][j].guid.f2, | |
1089 cod[i][j].guid.f3); | |
1090 print_char_array(cod[i][j].guid.f4, sizeof(cod[i][j].guid.f4)); | |
1091 printf(" }, /* GUID */\n"); | |
1092 printf("%hd /* flags */, %hd /* status */, %hd /* cpuflags */ }\n", | |
1093 cod[i][j].flags, | |
1094 cod[i][j].status, | |
1095 cod[i][j].cpuflags); | |
1096 if (j < nr[i]) printf(",\n"); | |
607 | 1097 } |
31077 | 1098 printf("};\n\n"); |
1099 } | |
1100 exit(0); | |
1101 } | |
1102 | |
1103 f1=fopen("DOCS/tech/codecs-in.html","rb"); if(!f1) exit(1); | |
1104 f2=fopen("DOCS/codecs-status.html","wb"); if(!f2) exit(1); | |
1105 | |
1106 while((c=fgetc(f1))>=0){ | |
1107 if(c!='%'){ | |
1108 fputc(c,f2); | |
1109 continue; | |
1110 } | |
1111 d=fgetc(f1); | |
1112 if(d>='0' && d<='9'){ | |
1113 // begin section | |
1114 section=d-'0'; | |
1115 //printf("BEGIN %d\n",section); | |
1116 if(section>=5){ | |
1117 // audio | |
1118 cl = audio_codecs; | |
1119 nr_codecs = nr_acodecs; | |
1120 dshow=7;win32=4; | |
1121 } else { | |
1122 // video | |
1123 cl = video_codecs; | |
1124 nr_codecs = nr_vcodecs; | |
1125 dshow=4;win32=2;win32ex=6; | |
1126 } | |
1127 pos=ftell(f1); | |
1128 for(i=0;i<nr_codecs;i++){ | |
1129 fseek(f1,pos,SEEK_SET); | |
1130 switch(section){ | |
1131 case 0: | |
1132 case 5: | |
1133 if(cl[i].status==CODECS_STATUS_WORKING) | |
1134 // if(!(!strcmp(cl[i].drv,"vfw") || !strcmp(cl[i].drv,"dshow") || !strcmp(cl[i].drv,"vfwex") || !strcmp(cl[i].drv,"acm"))) | |
31409 | 1135 parsehtml(f1,f2,&cl[i]); |
31077 | 1136 break; |
8211 | 1137 #if 0 |
31077 | 1138 case 1: |
1139 case 6: | |
1140 if(cl[i].status==CODECS_STATUS_WORKING) | |
1141 if((!strcmp(cl[i].drv,"vfw") || !strcmp(cl[i].drv,"dshow") || !strcmp(cl[i].drv,"vfwex") || !strcmp(cl[i].drv,"acm"))) | |
31409 | 1142 parsehtml(f1,f2,&cl[i]); |
31077 | 1143 break; |
1144 #endif | |
1145 case 2: | |
1146 case 7: | |
1147 if(cl[i].status==CODECS_STATUS_PROBLEMS) | |
31409 | 1148 parsehtml(f1,f2,&cl[i]); |
31077 | 1149 break; |
1150 case 3: | |
1151 case 8: | |
1152 if(cl[i].status==CODECS_STATUS_NOT_WORKING) | |
31409 | 1153 parsehtml(f1,f2,&cl[i]); |
31077 | 1154 break; |
1155 case 4: | |
1156 case 9: | |
1157 if(cl[i].status==CODECS_STATUS_UNTESTED) | |
31409 | 1158 parsehtml(f1,f2,&cl[i]); |
31077 | 1159 break; |
1160 default: | |
1161 printf("Warning! unimplemented section: %d\n",section); | |
607 | 1162 } |
31077 | 1163 } |
1164 fseek(f1,pos,SEEK_SET); | |
1165 skiphtml(f1); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1166 |
31077 | 1167 continue; |
607 | 1168 } |
31077 | 1169 fputc(c,f2); |
1170 fputc(d,f2); | |
1171 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1172 |
31077 | 1173 fclose(f2); |
1174 fclose(f1); | |
1175 return 0; | |
607 | 1176 } |
1177 | |
1178 #endif | |
1179 | |
297 | 1180 #ifdef TESTING |
1181 int main(void) | |
1182 { | |
31077 | 1183 codecs_t *c; |
1184 int i,j, nr_codecs, state; | |
297 | 1185 |
31077 | 1186 if (!(parse_codec_cfg("etc/codecs.conf"))) |
1187 return 0; | |
1188 if (!video_codecs) | |
1189 printf("no videoconfig.\n"); | |
1190 if (!audio_codecs) | |
1191 printf("no audioconfig.\n"); | |
328 | 1192 |
31077 | 1193 printf("videocodecs:\n"); |
1194 c = video_codecs; | |
1195 nr_codecs = nr_vcodecs; | |
1196 state = 0; | |
328 | 1197 next: |
31077 | 1198 if (c) { |
1199 printf("number of %scodecs: %d\n", state==0?"video":"audio", | |
1200 nr_codecs); | |
1201 for(i=0;i<nr_codecs;i++, c++){ | |
1202 printf("\n============== %scodec %02d ===============\n", | |
1203 state==0?"video":"audio",i); | |
1204 printf("name='%s'\n",c->name); | |
1205 printf("info='%s'\n",c->info); | |
1206 printf("comment='%s'\n",c->comment); | |
1207 printf("dll='%s'\n",c->dll); | |
1208 /* printf("flags=%X driver=%d status=%d cpuflags=%d\n", | |
1209 c->flags, c->driver, c->status, c->cpuflags); */ | |
1210 printf("flags=%X status=%d cpuflags=%d\n", | |
1211 c->flags, c->status, c->cpuflags); | |
300 | 1212 |
31077 | 1213 for(j=0;j<CODECS_MAX_FOURCC;j++){ |
1214 if(c->fourcc[j]!=0xFFFFFFFF){ | |
1215 printf("fourcc %02d: %08X (%.4s) ===> %08X (%.4s)\n",j,c->fourcc[j],(char *) &c->fourcc[j],c->fourccmap[j],(char *) &c->fourccmap[j]); | |
1216 } | |
1217 } | |
328 | 1218 |
31077 | 1219 for(j=0;j<CODECS_MAX_OUTFMT;j++){ |
1220 if(c->outfmt[j]!=0xFFFFFFFF){ | |
1221 printf("outfmt %02d: %08X (%.4s) flags: %d\n",j,c->outfmt[j],(char *) &c->outfmt[j],c->outflags[j]); | |
1222 } | |
1223 } | |
300 | 1224 |
31077 | 1225 for(j=0;j<CODECS_MAX_INFMT;j++){ |
1226 if(c->infmt[j]!=0xFFFFFFFF){ | |
1227 printf("infmt %02d: %08X (%.4s) flags: %d\n",j,c->infmt[j],(char *) &c->infmt[j],c->inflags[j]); | |
1228 } | |
1229 } | |
4676 | 1230 |
31077 | 1231 printf("GUID: %08lX %04X %04X",c->guid.f1,c->guid.f2,c->guid.f3); |
1232 for(j=0;j<8;j++) printf(" %02X",c->guid.f4[j]); | |
1233 printf("\n"); | |
300 | 1234 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29115
diff
changeset
|
1235 |
31077 | 1236 } |
1237 } | |
1238 if (!state) { | |
1239 printf("audiocodecs:\n"); | |
1240 c = audio_codecs; | |
1241 nr_codecs = nr_acodecs; | |
1242 state = 1; | |
1243 goto next; | |
1244 } | |
1245 return 0; | |
297 | 1246 } |
1247 | |
1248 #endif |