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 shouldn't 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 ) {
741 if( (codecs[i]).name )
742 free((codecs[i]).name);
743 if( (codecs[i]).info )
744 free((codecs[i]).info);
745 if( (codecs[i]).comment )
746 free((codecs[i]).comment);
747 if( (codecs[i]).dll )
748 free((codecs[i]).dll);
749 if( (codecs[i]).drv )
750 free((codecs[i]).drv);
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 select_codec(char* codecname,int audioflag){
824 // printf("select_codec('%s')\n",codecname);
833 for (/* NOTHING */; i--; c++)
834 if(!strcmp(c->name,codecname))
835 c->flags|=CODECS_FLAG_SELECTED;
838 void codecs_reset_selection(int audioflag){
849 for (/* NOTHING */; i--; c++)
850 c->flags&=(~CODECS_FLAG_SELECTED);
853 void list_codecs(int audioflag){
860 mp_msg(MSGT_CODECCFG,MSGL_INFO,"ac: afm: status: info: [lib/dll]\n");
864 mp_msg(MSGT_CODECCFG,MSGL_INFO,"vc: vfm: status: info: [lib/dll]\n");
867 for (/* NOTHING */; i--; c++) {
870 case CODECS_STATUS_WORKING: s="working ";break;
871 case CODECS_STATUS_PROBLEMS: s="problems";break;
872 case CODECS_STATUS_NOT_WORKING: s="crashing";break;
873 case CODECS_STATUS_UNTESTED: s="untested";break;
876 mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s [%s]\n",c->name,c->drv,s,c->info,c->dll);
878 mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s\n",c->name,c->drv,s,c->info);
888 * Fake out GUI references when building the codecs2html utility.
891 void gtkMessageBox( int type,char * str ) { return; }
895 void wrapline(FILE *f2,char *s){
902 if(c==',') fprintf(f2,"<br>"); else fputc(c,f2);
906 void parsehtml(FILE *f1,FILE *f2,codecs_t *codec,int section,int dshow){
908 while((c=fgetc(f1))>=0){
917 return; // end of section
919 wrapline(f2,codec->name); break;
921 wrapline(f2,codec->info); break;
923 wrapline(f2,codec->comment); break;
925 wrapline(f2,codec->dll); break;
927 fprintf(f2,"%c",!strcmp(codec->drv,"dshow")?'+':'-'); break;
929 for(d=0;d<CODECS_MAX_FOURCC;d++)
930 if(!d || codec->fourcc[d]!=0xFFFFFFFF)
931 fprintf(f2,"%s%.4s",d?"<br>":"",(codec->fourcc[d]==0xFFFFFFFF || codec->fourcc[d]<0x20202020)?!d?"-":"":(char*) &codec->fourcc[d]);
934 for(d=0;d<CODECS_MAX_FOURCC;d++)
935 if(codec->fourcc[d]!=0xFFFFFFFF)
936 fprintf(f2,"%s0x%X",d?"<br>":"",codec->fourcc[d]);
939 for(d=0;d<CODECS_MAX_OUTFMT;d++)
940 if(codec->outfmt[d]!=0xFFFFFFFF){
941 for (c=0; fmt_table[c].name; c++)
942 if(fmt_table[c].num==codec->outfmt[d]) break;
943 if(fmt_table[c].name)
944 fprintf(f2,"%s%s",d?"<br>":"",fmt_table[c].name);
955 void skiphtml(FILE *f1){
957 while((c=fgetc(f1))>=0){
962 if(d=='.') return; // end of section
966 static void print_int_array(const int* a, int size)
971 printf("%d%s", *a++, size?", ":"");
973 printf("0x%X%s", *a++, size?", ":"");
977 static void print_char_array(const unsigned char* a, int size)
982 printf("%d%s", *a++, size?", ":"");
984 printf("0x%02x%s", *a++, size?", ":"");
988 static void print_string(const char* s)
990 if (!s) printf("NULL");
991 else printf("\"%s\"", s);
994 int main(int argc, char* argv[])
1008 * Take path to codecs.conf from command line, or fall back on
1011 if (!(nr_codecs = parse_codec_cfg((argc>1)?argv[1]:"etc/codecs.conf")))
1020 nm[0] = "builtin_video_codecs";
1021 cod[0] = video_codecs;
1024 nm[1] = "builtin_audio_codecs";
1025 cod[1] = audio_codecs;
1028 printf("/* GENERATED FROM %s, DO NOT EDIT! */\n\n",argv[1]);
1030 for (i=0; i<2; i++) {
1031 printf("codecs_t %s[] = {\n", nm[i]);
1032 for (j = 0; j < nr[i]; j++) {
1035 print_int_array(cod[i][j].fourcc, CODECS_MAX_FOURCC);
1036 printf(", /* fourcc */\n");
1038 print_int_array(cod[i][j].fourccmap, CODECS_MAX_FOURCC);
1039 printf(", /* fourccmap */\n");
1041 print_int_array(cod[i][j].outfmt, CODECS_MAX_OUTFMT);
1042 printf(", /* outfmt */\n");
1044 print_char_array(cod[i][j].outflags, CODECS_MAX_OUTFMT);
1045 printf(", /* outflags */\n");
1047 print_int_array(cod[i][j].infmt, CODECS_MAX_INFMT);
1048 printf(", /* infmt */\n");
1050 print_char_array(cod[i][j].inflags, CODECS_MAX_INFMT);
1051 printf(", /* inflags */\n");
1053 print_string(cod[i][j].name); printf(", /* name */\n");
1054 print_string(cod[i][j].info); printf(", /* info */\n");
1055 print_string(cod[i][j].comment); printf(", /* comment */\n");
1056 print_string(cod[i][j].dll); printf(", /* dll */\n");
1057 print_string(cod[i][j].drv); printf(", /* drv */\n");
1059 printf("{ 0x%08lx, %hu, %hu,",
1063 print_char_array(cod[i][j].guid.f4, sizeof(cod[i][j].guid.f4));
1064 printf(" }, /* GUID */\n");
1065 printf("%hd /* flags */, %hd /* status */, %hd /* cpuflags */ }\n",
1068 cod[i][j].cpuflags);
1069 if (j < nr[i]) printf(",\n");
1076 f1=fopen("DOCS/tech/codecs-in.html","rb"); if(!f1) exit(1);
1077 f2=fopen("DOCS/codecs-status.html","wb"); if(!f2) exit(1);
1079 while((c=fgetc(f1))>=0){
1085 if(d>='0' && d<='9'){
1088 //printf("BEGIN %d\n",section);
1092 nr_codecs = nr_acodecs;
1097 nr_codecs = nr_vcodecs;
1098 dshow=4;win32=2;win32ex=6;
1101 for(i=0;i<nr_codecs;i++){
1102 fseek(f1,pos,SEEK_SET);
1106 if(cl[i].status==CODECS_STATUS_WORKING)
1107 // if(!(!strcmp(cl[i].drv,"vfw") || !strcmp(cl[i].drv,"dshow") || !strcmp(cl[i].drv,"vfwex") || !strcmp(cl[i].drv,"acm")))
1108 parsehtml(f1,f2,&cl[i],section,dshow);
1113 if(cl[i].status==CODECS_STATUS_WORKING)
1114 if((!strcmp(cl[i].drv,"vfw") || !strcmp(cl[i].drv,"dshow") || !strcmp(cl[i].drv,"vfwex") || !strcmp(cl[i].drv,"acm")))
1115 parsehtml(f1,f2,&cl[i],section,dshow);
1120 if(cl[i].status==CODECS_STATUS_PROBLEMS)
1121 parsehtml(f1,f2,&cl[i],section,dshow);
1125 if(cl[i].status==CODECS_STATUS_NOT_WORKING)
1126 parsehtml(f1,f2,&cl[i],section,dshow);
1130 if(cl[i].status==CODECS_STATUS_UNTESTED)
1131 parsehtml(f1,f2,&cl[i],section,dshow);
1134 printf("Warning! unimplemented section: %d\n",section);
1137 fseek(f1,pos,SEEK_SET);
1139 //void parsehtml(FILE *f1,FILE *f2,codecs_t *codec,int section,int dshow){
1158 int i,j, nr_codecs, state;
1160 if (!(parse_codec_cfg("etc/codecs.conf")))
1163 printf("no videoconfig.\n");
1165 printf("no audioconfig.\n");
1167 printf("videocodecs:\n");
1169 nr_codecs = nr_vcodecs;
1173 printf("number of %scodecs: %d\n", state==0?"video":"audio",
1175 for(i=0;i<nr_codecs;i++, c++){
1176 printf("\n============== %scodec %02d ===============\n",
1177 state==0?"video":"audio",i);
1178 printf("name='%s'\n",c->name);
1179 printf("info='%s'\n",c->info);
1180 printf("comment='%s'\n",c->comment);
1181 printf("dll='%s'\n",c->dll);
1182 printf("flags=%X driver=%d status=%d cpuflags=%d\n",
1183 c->flags, c->driver, c->status, c->cpuflags);
1185 for(j=0;j<CODECS_MAX_FOURCC;j++){
1186 if(c->fourcc[j]!=0xFFFFFFFF){
1187 printf("fourcc %02d: %08X (%.4s) ===> %08X (%.4s)\n",j,c->fourcc[j],(char *) &c->fourcc[j],c->fourccmap[j],(char *) &c->fourccmap[j]);
1191 for(j=0;j<CODECS_MAX_OUTFMT;j++){
1192 if(c->outfmt[j]!=0xFFFFFFFF){
1193 printf("outfmt %02d: %08X (%.4s) flags: %d\n",j,c->outfmt[j],(char *) &c->outfmt[j],c->outflags[j]);
1197 for(j=0;j<CODECS_MAX_INFMT;j++){
1198 if(c->infmt[j]!=0xFFFFFFFF){
1199 printf("infmt %02d: %08X (%.4s) flags: %d\n",j,c->infmt[j],(char *) &c->infmt[j],c->inflags[j]);
1203 printf("GUID: %08lX %04X %04X",c->guid.f1,c->guid.f2,c->guid.f3);
1204 for(j=0;j<8;j++) printf(" %02X",c->guid.f4[j]);
1211 printf("audiocodecs:\n");
1213 nr_codecs = nr_acodecs;