3 * by Szabolcs Berecz <szabi@inf.elte.hu>
6 * to compile test application:
7 * cc -I. -DTESTING -o codec-cfg-test codec-cfg.c mp_msg.o osdep/getch2.o -ltermcap
8 * to compile CODECS2HTML:
9 * gcc -DCODECS2HTML -o codecs2html codec-cfg.c mp_msg.o
11 * TODO: implement informat in CODECS2HTML too
32 #define mp_msg(t, l, m, args...) fprintf(stderr, m, ##args)
34 #define mp_msg(t, l, ...) fprintf(stderr, __VA_ARGS__)
41 #include "libmpdemux/aviheader.h"
43 #include "libmpcodecs/img_format.h"
44 #include "codec-cfg.h"
47 #include "codecs.conf.h"
50 #define PRINT_LINENUM mp_msg(MSGT_CODECCFG,MSGL_ERR," at line %d\n", line_num)
52 #define MAX_NR_TOKEN 16
54 #define MAX_LINE_LEN 1000
62 char * codecs_file
= NULL
;
64 static int add_to_fourcc(char *s
, char *alias
, unsigned int *fourcc
,
70 /* find first unused slot */
71 for (i
= 0; i
< CODECS_MAX_FOURCC
&& fourcc
[i
] != 0xffffffff; i
++)
73 freeslots
= CODECS_MAX_FOURCC
- i
;
75 goto err_out_too_many
;
78 tmp
= mmioFOURCC(s
[0], s
[1], s
[2], s
[3]);
79 for (j
= 0; j
< i
; j
++)
81 goto err_out_duplicated
;
83 map
[i
] = alias
? mmioFOURCC(alias
[0], alias
[1], alias
[2], alias
[3]) : tmp
;
86 } while ((*(s
++) == ',') && --freeslots
);
89 goto err_out_too_many
;
91 goto err_out_parse_error
;
94 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_DuplicateFourcc
);
97 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_TooManyFourccs
);
100 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_ParseError
);
104 static int add_to_format(char *s
, char *alias
,unsigned int *fourcc
, unsigned int *fourccmap
)
109 /* find first unused slot */
110 for (i
= 0; i
< CODECS_MAX_FOURCC
&& fourcc
[i
] != 0xffffffff; i
++)
112 if (i
== CODECS_MAX_FOURCC
) {
113 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_TooManyFourccs
);
117 fourcc
[i
]=strtoul(s
,&endptr
,0);
118 if (*endptr
!= '\0') {
119 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_ParseErrorFIDNotNumber
);
124 fourccmap
[i
]=strtoul(alias
,&endptr
,0);
125 if (*endptr
!= '\0') {
126 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_ParseErrorFIDAliasNotNumber
);
130 fourccmap
[i
]=fourcc
[i
];
132 for (j
= 0; j
< i
; j
++)
133 if (fourcc
[j
] == fourcc
[i
]) {
134 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_DuplicateFID
);
143 const unsigned int num
;
145 {"YV12", IMGFMT_YV12
},
146 {"I420", IMGFMT_I420
},
147 {"IYUV", IMGFMT_IYUV
},
148 {"NV12", IMGFMT_NV12
},
149 {"NV21", IMGFMT_NV21
},
150 {"YVU9", IMGFMT_YVU9
},
151 {"IF09", IMGFMT_IF09
},
152 {"444P", IMGFMT_444P
},
153 {"422P", IMGFMT_422P
},
154 {"411P", IMGFMT_411P
},
155 {"Y800", IMGFMT_Y800
},
158 {"YUY2", IMGFMT_YUY2
},
159 {"UYVY", IMGFMT_UYVY
},
160 {"YVYU", IMGFMT_YVYU
},
162 {"RGB4", IMGFMT_RGB
|4},
163 {"RGB8", IMGFMT_RGB
|8},
164 {"RGB15", IMGFMT_RGB
|15},
165 {"RGB16", IMGFMT_RGB
|16},
166 {"RGB24", IMGFMT_RGB
|24},
167 {"RGB32", IMGFMT_RGB
|32},
168 {"BGR4", IMGFMT_BGR
|4},
169 {"BGR8", IMGFMT_BGR
|8},
170 {"BGR15", IMGFMT_BGR
|15},
171 {"BGR16", IMGFMT_BGR
|16},
172 {"BGR24", IMGFMT_BGR
|24},
173 {"BGR32", IMGFMT_BGR
|32},
174 {"RGB1", IMGFMT_RGB
|1},
175 {"BGR1", IMGFMT_BGR
|1},
177 {"MPES", IMGFMT_MPEGPES
},
178 {"ZRMJPEGNI", IMGFMT_ZRMJPEGNI
},
179 {"ZRMJPEGIT", IMGFMT_ZRMJPEGIT
},
180 {"ZRMJPEGIB", IMGFMT_ZRMJPEGIB
},
182 {"IDCT_MPEG2",IMGFMT_XVMC_IDCT_MPEG2
},
183 {"MOCO_MPEG2",IMGFMT_XVMC_MOCO_MPEG2
},
189 static int add_to_inout(char *sfmt
, char *sflags
, unsigned int *outfmt
,
190 unsigned char *outflags
)
193 static char *flagstr
[] = {
205 for (i
= 0; i
< CODECS_MAX_OUTFMT
&& outfmt
[i
] != 0xffffffff; i
++)
207 freeslots
= CODECS_MAX_OUTFMT
- i
;
209 goto err_out_too_many
;
214 for (j
= 0; flagstr
[j
] != NULL
; j
++)
215 if (!strncmp(sflags
, flagstr
[j
],
218 if (flagstr
[j
] == NULL
)
219 goto err_out_parse_error
;
221 sflags
+=strlen(flagstr
[j
]);
222 } while (*(sflags
++) == ',');
224 if (*(--sflags
) != '\0')
225 goto err_out_parse_error
;
229 for (j
= 0; fmt_table
[j
].name
!= NULL
; j
++)
230 if (!strncmp(sfmt
, fmt_table
[j
].name
, strlen(fmt_table
[j
].name
)))
232 if (fmt_table
[j
].name
== NULL
)
233 goto err_out_parse_error
;
234 outfmt
[i
] = fmt_table
[j
].num
;
237 sfmt
+=strlen(fmt_table
[j
].name
);
238 } while ((*(sfmt
++) == ',') && --freeslots
);
241 goto err_out_too_many
;
243 if (*(--sfmt
) != '\0')
244 goto err_out_parse_error
;
248 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_TooManyOut
);
251 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_ParseError
);
256 static short get_driver(char *s
,int audioflag
)
258 static char *audiodrv
[] = {
284 static char *videodrv
[] = {
314 char **drv
=audioflag
?audiodrv
:videodrv
;
317 for(i
=0;drv
[i
];i
++) if(!strcmp(s
,drv
[i
])) return i
;
323 static int validate_codec(codecs_t
*c
, int type
)
326 char *tmp_name
= c
->name
;
328 for (i
= 0; i
< strlen(tmp_name
) && isalnum(tmp_name
[i
]); i
++)
331 if (i
< strlen(tmp_name
)) {
332 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_InvalidCodecName
, c
->name
);
337 c
->info
= strdup(c
->name
);
340 if (c
->fourcc
[0] == 0xffffffff) {
341 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecLacksFourcc
, c
->name
);
347 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecLacksDriver
, c
->name
);
352 #warning codec->driver == 4;... <- this should not be put in here...
353 #warning Where are they defined ????????????
354 if (!c
->dll
&& (c
->driver
== 4 ||
355 (c
->driver
== 2 && type
== TYPE_VIDEO
))) {
356 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecNeedsDLL
, c
->name
);
359 #warning Can guid.f1 be 0? How does one know that it was not given?
360 // if (!(codec->flags & CODECS_FLAG_AUDIO) && codec->driver == 4)
362 if (type
== TYPE_VIDEO
)
363 if (c
->outfmt
[0] == 0xffffffff) {
364 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecNeedsOutfmt
, c
->name
);
371 static int add_comment(char *s
, char **d
)
381 if (!(*d
= realloc(*d
, pos
+ strlen(s
) + 1))) {
382 mp_msg(MSGT_CODECCFG
,MSGL_FATAL
,MSGTR_CantAllocateComment
);
389 static short get_cpuflags(char *s
)
391 static char *flagstr
[] = {
401 for (i
= 0; flagstr
[i
]; i
++)
402 if (!strncmp(s
, flagstr
[i
], strlen(flagstr
[i
])))
405 goto err_out_parse_error
;
407 s
+= strlen(flagstr
[i
]);
408 } while (*(s
++) == ',');
411 goto err_out_parse_error
;
419 static int line_num
= 0;
421 static char *token
[MAX_NR_TOKEN
];
422 static int read_nextline
= 1;
424 static int get_token(int min
, int max
)
430 if (max
>= MAX_NR_TOKEN
) {
431 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_GetTokenMaxNotLessThanMAX_NR_TOKEN
);
435 memset(token
, 0x00, sizeof(*token
) * max
);
438 if (!fgets(line
, MAX_LINE_LEN
, fp
))
444 for (i
= 0; i
< max
; i
++) {
445 while (isspace(line
[line_pos
]))
447 if (line
[line_pos
] == '\0' || line
[line_pos
] == '#' ||
448 line
[line_pos
] == ';') {
454 token
[i
] = line
+ line_pos
;
456 if (c
== '"' || c
== '\'') {
458 while (line
[++line_pos
] != c
&& line
[line_pos
])
461 for (/* NOTHING */; !isspace(line
[line_pos
]) &&
462 line
[line_pos
]; line_pos
++)
465 if (!line
[line_pos
]) {
471 line
[line_pos
] = '\0';
483 static codecs_t
*video_codecs
=NULL
;
484 static codecs_t
*audio_codecs
=NULL
;
485 static int nr_vcodecs
= 0;
486 static int nr_acodecs
= 0;
488 int parse_codec_cfg(const char *cfgfile
)
490 codecs_t
*codec
= NULL
; // current codec
491 codecs_t
**codecsp
= NULL
;// points to audio_codecs or to video_codecs
492 char *endptr
; // strtoul()...
494 int codec_type
; /* TYPE_VIDEO/TYPE_AUDIO */
497 // in case we call it a second time
498 codecs_uninit_free();
507 video_codecs
= builtin_video_codecs
;
508 audio_codecs
= builtin_audio_codecs
;
509 nr_vcodecs
= sizeof(builtin_video_codecs
)/sizeof(codecs_t
);
510 nr_acodecs
= sizeof(builtin_audio_codecs
)/sizeof(codecs_t
);
515 mp_msg(MSGT_CODECCFG
,MSGL_V
,MSGTR_ReadingFile
, cfgfile
);
517 if ((fp
= fopen(cfgfile
, "r")) == NULL
) {
518 mp_msg(MSGT_CODECCFG
,MSGL_V
,MSGTR_CantOpenFileError
, cfgfile
, strerror(errno
));
522 if ((line
= malloc(MAX_LINE_LEN
+ 1)) == NULL
) {
523 mp_msg(MSGT_CODECCFG
,MSGL_FATAL
,MSGTR_CantGetMemoryForLine
, strerror(errno
));
529 * this only catches release lines at the start of
530 * codecs.conf, before audiocodecs and videocodecs.
532 while ((tmp
= get_token(1, 1)) == RET_EOL
)
536 if (!strcmp(token
[0], "release")) {
537 if (get_token(1, 2) < 0)
538 goto err_out_parse_error
;
539 tmp
= atoi(token
[0]);
540 if (tmp
< CODEC_CFG_MIN
)
541 goto err_out_release_num
;
542 while ((tmp
= get_token(1, 1)) == RET_EOL
)
547 goto err_out_release_num
;
550 * check if the next block starts with 'audiocodec' or
553 if (!strcmp(token
[0], "audiocodec") || !strcmp(token
[0], "videocodec"))
555 goto err_out_parse_error
;
557 while ((tmp
= get_token(1, 1)) != RET_EOF
) {
560 if (!strcmp(token
[0], "audiocodec") ||
561 !strcmp(token
[0], "videocodec")) {
562 if (!validate_codec(codec
, codec_type
))
563 goto err_out_not_valid
;
565 if (*token
[0] == 'v') {
566 codec_type
= TYPE_VIDEO
;
567 nr_codecsp
= &nr_vcodecs
;
568 codecsp
= &video_codecs
;
569 } else if (*token
[0] == 'a') {
570 codec_type
= TYPE_AUDIO
;
571 nr_codecsp
= &nr_acodecs
;
572 codecsp
= &audio_codecs
;
575 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,"picsba\n");
579 if (!(*codecsp
= realloc(*codecsp
,
580 sizeof(codecs_t
) * (*nr_codecsp
+ 2)))) {
581 mp_msg(MSGT_CODECCFG
,MSGL_FATAL
,MSGTR_CantReallocCodecsp
, strerror(errno
));
584 codec
=*codecsp
+ *nr_codecsp
;
586 memset(codec
,0,sizeof(codecs_t
));
587 memset(codec
->fourcc
, 0xff, sizeof(codec
->fourcc
));
588 memset(codec
->outfmt
, 0xff, sizeof(codec
->outfmt
));
589 memset(codec
->infmt
, 0xff, sizeof(codec
->infmt
));
591 if (get_token(1, 1) < 0)
592 goto err_out_parse_error
;
593 for (i
= 0; i
< *nr_codecsp
- 1; i
++) {
594 if(( (*codecsp
)[i
].name
!=NULL
) &&
595 (!strcmp(token
[0], (*codecsp
)[i
].name
)) ) {
596 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecNameNotUnique
, token
[0]);
597 goto err_out_print_linenum
;
600 if (!(codec
->name
= strdup(token
[0]))) {
601 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CantStrdupName
, strerror(errno
));
604 } else if (!strcmp(token
[0], "info")) {
605 if (codec
->info
|| get_token(1, 1) < 0)
606 goto err_out_parse_error
;
607 if (!(codec
->info
= strdup(token
[0]))) {
608 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CantStrdupInfo
, strerror(errno
));
611 } else if (!strcmp(token
[0], "comment")) {
612 if (get_token(1, 1) < 0)
613 goto err_out_parse_error
;
614 add_comment(token
[0], &codec
->comment
);
615 } else if (!strcmp(token
[0], "fourcc")) {
616 if (get_token(1, 2) < 0)
617 goto err_out_parse_error
;
618 if (!add_to_fourcc(token
[0], token
[1],
621 goto err_out_print_linenum
;
622 } else if (!strcmp(token
[0], "format")) {
623 if (get_token(1, 2) < 0)
624 goto err_out_parse_error
;
625 if (!add_to_format(token
[0], token
[1],
626 codec
->fourcc
,codec
->fourccmap
))
627 goto err_out_print_linenum
;
628 } else if (!strcmp(token
[0], "driver")) {
629 if (get_token(1, 1) < 0)
630 goto err_out_parse_error
;
631 if (!(codec
->drv
= strdup(token
[0]))) {
632 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CantStrdupDriver
, strerror(errno
));
635 } else if (!strcmp(token
[0], "dll")) {
636 if (get_token(1, 1) < 0)
637 goto err_out_parse_error
;
638 if (!(codec
->dll
= strdup(token
[0]))) {
639 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CantStrdupDLL
, strerror(errno
));
642 } else if (!strcmp(token
[0], "guid")) {
643 if (get_token(11, 11) < 0)
644 goto err_out_parse_error
;
645 codec
->guid
.f1
=strtoul(token
[0],&endptr
,0);
646 if ((*endptr
!= ',' || *(endptr
+ 1) != '\0') &&
648 goto err_out_parse_error
;
649 codec
->guid
.f2
=strtoul(token
[1],&endptr
,0);
650 if ((*endptr
!= ',' || *(endptr
+ 1) != '\0') &&
652 goto err_out_parse_error
;
653 codec
->guid
.f3
=strtoul(token
[2],&endptr
,0);
654 if ((*endptr
!= ',' || *(endptr
+ 1) != '\0') &&
656 goto err_out_parse_error
;
657 for (i
= 0; i
< 8; i
++) {
658 codec
->guid
.f4
[i
]=strtoul(token
[i
+ 3],&endptr
,0);
659 if ((*endptr
!= ',' || *(endptr
+ 1) != '\0') &&
661 goto err_out_parse_error
;
663 } else if (!strcmp(token
[0], "out")) {
664 if (get_token(1, 2) < 0)
665 goto err_out_parse_error
;
666 if (!add_to_inout(token
[0], token
[1], codec
->outfmt
,
668 goto err_out_print_linenum
;
669 } else if (!strcmp(token
[0], "in")) {
670 if (get_token(1, 2) < 0)
671 goto err_out_parse_error
;
672 if (!add_to_inout(token
[0], token
[1], codec
->infmt
,
674 goto err_out_print_linenum
;
675 } else if (!strcmp(token
[0], "flags")) {
676 if (get_token(1, 1) < 0)
677 goto err_out_parse_error
;
678 if (!strcmp(token
[0], "seekable"))
679 codec
->flags
|= CODECS_FLAG_SEEKABLE
;
681 if (!strcmp(token
[0], "align16"))
682 codec
->flags
|= CODECS_FLAG_ALIGN16
;
684 goto err_out_parse_error
;
685 } else if (!strcmp(token
[0], "status")) {
686 if (get_token(1, 1) < 0)
687 goto err_out_parse_error
;
688 if (!strcasecmp(token
[0], "working"))
689 codec
->status
= CODECS_STATUS_WORKING
;
690 else if (!strcasecmp(token
[0], "crashing"))
691 codec
->status
= CODECS_STATUS_NOT_WORKING
;
692 else if (!strcasecmp(token
[0], "untested"))
693 codec
->status
= CODECS_STATUS_UNTESTED
;
694 else if (!strcasecmp(token
[0], "buggy"))
695 codec
->status
= CODECS_STATUS_PROBLEMS
;
697 goto err_out_parse_error
;
698 } else if (!strcmp(token
[0], "cpuflags")) {
699 if (get_token(1, 1) < 0)
700 goto err_out_parse_error
;
701 if (!(codec
->cpuflags
= get_cpuflags(token
[0])))
702 goto err_out_parse_error
;
704 goto err_out_parse_error
;
706 if (!validate_codec(codec
, codec_type
))
707 goto err_out_not_valid
;
708 mp_msg(MSGT_CODECCFG
,MSGL_INFO
,MSGTR_AudioVideoCodecTotals
, nr_acodecs
, nr_vcodecs
);
709 if(video_codecs
) video_codecs
[nr_vcodecs
].name
= NULL
;
710 if(audio_codecs
) audio_codecs
[nr_acodecs
].name
= NULL
;
718 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_ParseError
);
719 err_out_print_linenum
:
722 codecs_uninit_free();
730 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_CodecDefinitionIncorrect
);
731 goto err_out_print_linenum
;
733 mp_msg(MSGT_CODECCFG
,MSGL_ERR
,MSGTR_OutdatedCodecsConf
);
734 goto err_out_print_linenum
;
737 static void codecs_free(codecs_t
* codecs
,int count
) {
739 for ( i
= 0; i
< count
; i
++)
740 if ( codecs
[i
].name
) {
742 free(codecs
[i
].name
);
744 free(codecs
[i
].info
);
745 if( codecs
[i
].comment
)
746 free(codecs
[i
].comment
);
756 void codecs_uninit_free(void) {
758 codecs_free(video_codecs
,nr_vcodecs
);
761 codecs_free(audio_codecs
,nr_acodecs
);
765 codecs_t
*find_audio_codec(unsigned int fourcc
, unsigned int *fourccmap
,
766 codecs_t
*start
, int force
)
768 return find_codec(fourcc
, fourccmap
, start
, 1, force
);
771 codecs_t
*find_video_codec(unsigned int fourcc
, unsigned int *fourccmap
,
772 codecs_t
*start
, int force
)
774 return find_codec(fourcc
, fourccmap
, start
, 0, force
);
777 codecs_t
* find_codec(unsigned int fourcc
,unsigned int *fourccmap
,
778 codecs_t
*start
, int audioflag
, int force
)
785 for (/* NOTHING */; start
->name
; start
++) {
786 for (j
= 0; j
< CODECS_MAX_FOURCC
; j
++) {
787 if (start
->fourcc
[j
] == fourcc
) {
789 *fourccmap
= start
->fourccmap
[j
];
805 for (/* NOTHING */; i
--; c
++) {
806 if(start
&& c
<=start
) continue;
807 for (j
= 0; j
< CODECS_MAX_FOURCC
; j
++) {
808 // FIXME: do NOT hardwire 'null' name here:
809 if (c
->fourcc
[j
]==fourcc
|| !strcmp(c
->drv
,"null")) {
811 *fourccmap
= c
->fourccmap
[j
];
821 void stringset_init(stringset_t
*set
) {
822 *set
= calloc(1, sizeof(char *));
825 void stringset_free(stringset_t
*set
) {
827 while ((*set
)[count
]) free((*set
)[count
++]);
832 void stringset_add(stringset_t
*set
, const char *str
) {
834 while ((*set
)[count
]) count
++;
836 *set
= realloc(*set
, sizeof(char *) * (count
+ 1));
837 (*set
)[count
- 1] = strdup(str
);
838 (*set
)[count
] = NULL
;
841 int stringset_test(stringset_t
*set
, const char *str
) {
843 for (s
= *set
; *s
; s
++)
844 if (strcmp(*s
, str
) == 0)
849 void list_codecs(int audioflag
){
856 mp_msg(MSGT_CODECCFG
,MSGL_INFO
,"ac: afm: status: info: [lib/dll]\n");
860 mp_msg(MSGT_CODECCFG
,MSGL_INFO
,"vc: vfm: status: info: [lib/dll]\n");
863 for (/* NOTHING */; i
--; c
++) {
866 case CODECS_STATUS_WORKING
: s
="working ";break;
867 case CODECS_STATUS_PROBLEMS
: s
="problems";break;
868 case CODECS_STATUS_NOT_WORKING
: s
="crashing";break;
869 case CODECS_STATUS_UNTESTED
: s
="untested";break;
872 mp_msg(MSGT_CODECCFG
,MSGL_INFO
,"%-11s %-9s %s %s [%s]\n",c
->name
,c
->drv
,s
,c
->info
,c
->dll
);
874 mp_msg(MSGT_CODECCFG
,MSGL_INFO
,"%-11s %-9s %s %s\n",c
->name
,c
->drv
,s
,c
->info
);
884 * Fake out GUI references when building the codecs2html utility.
887 void gtkMessageBox( int type
,char * str
) { return; }
891 void wrapline(FILE *f2
,char *s
){
898 if(c
==',') fprintf(f2
,"<br>"); else fputc(c
,f2
);
902 void parsehtml(FILE *f1
,FILE *f2
,codecs_t
*codec
,int section
,int dshow
){
904 while((c
=fgetc(f1
))>=0){
913 return; // end of section
915 wrapline(f2
,codec
->name
); break;
917 wrapline(f2
,codec
->info
); break;
919 wrapline(f2
,codec
->comment
); break;
921 wrapline(f2
,codec
->dll
); break;
923 fprintf(f2
,"%c",!strcmp(codec
->drv
,"dshow")?'+':'-'); break;
925 for(d
=0;d
<CODECS_MAX_FOURCC
;d
++)
926 if(!d
|| codec
->fourcc
[d
]!=0xFFFFFFFF)
927 fprintf(f2
,"%s%.4s",d
?"<br>":"",(codec
->fourcc
[d
]==0xFFFFFFFF || codec
->fourcc
[d
]<0x20202020)?!d
?"-":"":(char*) &codec
->fourcc
[d
]);
930 for(d
=0;d
<CODECS_MAX_FOURCC
;d
++)
931 if(codec
->fourcc
[d
]!=0xFFFFFFFF)
932 fprintf(f2
,"%s0x%X",d
?"<br>":"",codec
->fourcc
[d
]);
935 for(d
=0;d
<CODECS_MAX_OUTFMT
;d
++)
936 if(codec
->outfmt
[d
]!=0xFFFFFFFF){
937 for (c
=0; fmt_table
[c
].name
; c
++)
938 if(fmt_table
[c
].num
==codec
->outfmt
[d
]) break;
939 if(fmt_table
[c
].name
)
940 fprintf(f2
,"%s%s",d
?"<br>":"",fmt_table
[c
].name
);
951 void skiphtml(FILE *f1
){
953 while((c
=fgetc(f1
))>=0){
958 if(d
=='.') return; // end of section
962 static void print_int_array(const int* a
, int size
)
967 printf("%d%s", *a
++, size
?", ":"");
969 printf("0x%X%s", *a
++, size
?", ":"");
973 static void print_char_array(const unsigned char* a
, int size
)
978 printf("%d%s", *a
++, size
?", ":"");
980 printf("0x%02x%s", *a
++, size
?", ":"");
984 static void print_string(const char* s
)
986 if (!s
) printf("NULL");
987 else printf("\"%s\"", s
);
990 int main(int argc
, char* argv
[])
1004 * Take path to codecs.conf from command line, or fall back on
1007 if (!(nr_codecs
= parse_codec_cfg((argc
>1)?argv
[1]:"etc/codecs.conf")))
1016 nm
[0] = "builtin_video_codecs";
1017 cod
[0] = video_codecs
;
1020 nm
[1] = "builtin_audio_codecs";
1021 cod
[1] = audio_codecs
;
1024 printf("/* GENERATED FROM %s, DO NOT EDIT! */\n\n",argv
[1]);
1025 printf("#include <stddef.h>\n",argv
[1]);
1026 printf("#include \"codec-cfg.h\"\n\n",argv
[1]);
1028 for (i
=0; i
<2; i
++) {
1029 printf("const codecs_t %s[] = {\n", nm
[i
]);
1030 for (j
= 0; j
< nr
[i
]; j
++) {
1033 print_int_array(cod
[i
][j
].fourcc
, CODECS_MAX_FOURCC
);
1034 printf(", /* fourcc */\n");
1036 print_int_array(cod
[i
][j
].fourccmap
, CODECS_MAX_FOURCC
);
1037 printf(", /* fourccmap */\n");
1039 print_int_array(cod
[i
][j
].outfmt
, CODECS_MAX_OUTFMT
);
1040 printf(", /* outfmt */\n");
1042 print_char_array(cod
[i
][j
].outflags
, CODECS_MAX_OUTFMT
);
1043 printf(", /* outflags */\n");
1045 print_int_array(cod
[i
][j
].infmt
, CODECS_MAX_INFMT
);
1046 printf(", /* infmt */\n");
1048 print_char_array(cod
[i
][j
].inflags
, CODECS_MAX_INFMT
);
1049 printf(", /* inflags */\n");
1051 print_string(cod
[i
][j
].name
); printf(", /* name */\n");
1052 print_string(cod
[i
][j
].info
); printf(", /* info */\n");
1053 print_string(cod
[i
][j
].comment
); printf(", /* comment */\n");
1054 print_string(cod
[i
][j
].dll
); printf(", /* dll */\n");
1055 print_string(cod
[i
][j
].drv
); printf(", /* drv */\n");
1057 printf("{ 0x%08lx, %hu, %hu,",
1061 print_char_array(cod
[i
][j
].guid
.f4
, sizeof(cod
[i
][j
].guid
.f4
));
1062 printf(" }, /* GUID */\n");
1063 printf("%hd /* flags */, %hd /* status */, %hd /* cpuflags */ }\n",
1066 cod
[i
][j
].cpuflags
);
1067 if (j
< nr
[i
]) printf(",\n");
1074 f1
=fopen("DOCS/tech/codecs-in.html","rb"); if(!f1
) exit(1);
1075 f2
=fopen("DOCS/codecs-status.html","wb"); if(!f2
) exit(1);
1077 while((c
=fgetc(f1
))>=0){
1083 if(d
>='0' && d
<='9'){
1086 //printf("BEGIN %d\n",section);
1090 nr_codecs
= nr_acodecs
;
1095 nr_codecs
= nr_vcodecs
;
1096 dshow
=4;win32
=2;win32ex
=6;
1099 for(i
=0;i
<nr_codecs
;i
++){
1100 fseek(f1
,pos
,SEEK_SET
);
1104 if(cl
[i
].status
==CODECS_STATUS_WORKING
)
1105 // if(!(!strcmp(cl[i].drv,"vfw") || !strcmp(cl[i].drv,"dshow") || !strcmp(cl[i].drv,"vfwex") || !strcmp(cl[i].drv,"acm")))
1106 parsehtml(f1
,f2
,&cl
[i
],section
,dshow
);
1111 if(cl
[i
].status
==CODECS_STATUS_WORKING
)
1112 if((!strcmp(cl
[i
].drv
,"vfw") || !strcmp(cl
[i
].drv
,"dshow") || !strcmp(cl
[i
].drv
,"vfwex") || !strcmp(cl
[i
].drv
,"acm")))
1113 parsehtml(f1
,f2
,&cl
[i
],section
,dshow
);
1118 if(cl
[i
].status
==CODECS_STATUS_PROBLEMS
)
1119 parsehtml(f1
,f2
,&cl
[i
],section
,dshow
);
1123 if(cl
[i
].status
==CODECS_STATUS_NOT_WORKING
)
1124 parsehtml(f1
,f2
,&cl
[i
],section
,dshow
);
1128 if(cl
[i
].status
==CODECS_STATUS_UNTESTED
)
1129 parsehtml(f1
,f2
,&cl
[i
],section
,dshow
);
1132 printf("Warning! unimplemented section: %d\n",section
);
1135 fseek(f1
,pos
,SEEK_SET
);
1137 //void parsehtml(FILE *f1,FILE *f2,codecs_t *codec,int section,int dshow){
1156 int i
,j
, nr_codecs
, state
;
1158 if (!(parse_codec_cfg("etc/codecs.conf")))
1161 printf("no videoconfig.\n");
1163 printf("no audioconfig.\n");
1165 printf("videocodecs:\n");
1167 nr_codecs
= nr_vcodecs
;
1171 printf("number of %scodecs: %d\n", state
==0?"video":"audio",
1173 for(i
=0;i
<nr_codecs
;i
++, c
++){
1174 printf("\n============== %scodec %02d ===============\n",
1175 state
==0?"video":"audio",i
);
1176 printf("name='%s'\n",c
->name
);
1177 printf("info='%s'\n",c
->info
);
1178 printf("comment='%s'\n",c
->comment
);
1179 printf("dll='%s'\n",c
->dll
);
1180 printf("flags=%X driver=%d status=%d cpuflags=%d\n",
1181 c
->flags
, c
->driver
, c
->status
, c
->cpuflags
);
1183 for(j
=0;j
<CODECS_MAX_FOURCC
;j
++){
1184 if(c
->fourcc
[j
]!=0xFFFFFFFF){
1185 printf("fourcc %02d: %08X (%.4s) ===> %08X (%.4s)\n",j
,c
->fourcc
[j
],(char *) &c
->fourcc
[j
],c
->fourccmap
[j
],(char *) &c
->fourccmap
[j
]);
1189 for(j
=0;j
<CODECS_MAX_OUTFMT
;j
++){
1190 if(c
->outfmt
[j
]!=0xFFFFFFFF){
1191 printf("outfmt %02d: %08X (%.4s) flags: %d\n",j
,c
->outfmt
[j
],(char *) &c
->outfmt
[j
],c
->outflags
[j
]);
1195 for(j
=0;j
<CODECS_MAX_INFMT
;j
++){
1196 if(c
->infmt
[j
]!=0xFFFFFFFF){
1197 printf("infmt %02d: %08X (%.4s) flags: %d\n",j
,c
->infmt
[j
],(char *) &c
->infmt
[j
],c
->inflags
[j
]);
1201 printf("GUID: %08lX %04X %04X",c
->guid
.f1
,c
->guid
.f2
,c
->guid
.f3
);
1202 for(j
=0;j
<8;j
++) printf(" %02X",c
->guid
.f4
[j
]);
1209 printf("audiocodecs:\n");
1211 nr_codecs
= nr_acodecs
;