diff options
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | codec-cfg.c | 468 | ||||
-rw-r--r-- | codec-cfg.h | 44 | ||||
-rw-r--r-- | codecs.conf | 175 |
4 files changed, 693 insertions, 1 deletions
@@ -17,6 +17,8 @@ PRG = mplayer PRG_HQ = mplayerHQ PRG_AVIP = aviparse PRG_TV = tvision +PRG_CFG = codec-cfg + prefix = /usr/local BINDIR = ${prefix}/bin # BINDIR = /usr/local/bin @@ -30,7 +32,7 @@ VO_LIBS = -Llibvo -lvo $(X_LIBS) # .PHONY: all clean -all: $(PRG) +all: $(PRG) $(PRG_CFG) # $(PRG_AVIP) .c.o: @@ -74,6 +76,9 @@ $(PRG_AVIP): .depend aviparse.o $(OBJS) loader/libloader.a $(COMMONLIBS) $(PRG_TV): .depend tvision.o $(OBJS) $(COMMONLIBS) $(CC) $(CFLAGS) -o $(PRG_TV) tvision.o $(OBJS) -lm $(TERMCAP_LIB) $(VO_LIBS) +$(PRG_CFG): codec-cfg.c codec-cfg.h + $(CC) $(CFLAGS) codec-cfg.c -o $(PRG_CFG) -DTESTING + install: $(PRG) install -g $(GROUP) -o $(OWNER) -m $(PERM) -s $(PRG) $(BINDIR) install -D -m 644 DOCS/mplayer.1 $(prefix)/man/man1/mplayer.1 diff --git a/codec-cfg.c b/codec-cfg.c new file mode 100644 index 0000000000..ddf6c6de7b --- /dev/null +++ b/codec-cfg.c @@ -0,0 +1,468 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <assert.h> +#include <string.h> + +#include "libvo/video_out.h" +#include "codec-cfg.h" + +#define MALLOC_ADD 10 + +#define MAX_LINE_LEN 1000 + +#define STATE_MASK ((1<<7)-1) + +#define GOT_NAME (1<<0) +#define GOT_INFO (1<<1) +#define GOT_FOURCC (1<<2) +#define GOT_FORMAT (1<<3) +#define GOT_DRIVER (1<<4) +#define GOT_DLL (1<<5) +#define GOT_OUT (1<<6) + +#define RET_EOF -1 +#define RET_EOL -2 +#define RET_OK 0 + +FILE *fp; +int line_num = 0; +int line_pos; /* line pos */ +int firstdef = 1; +char *line; +char *token; + +int nr_codecs = 0; + +int get_token(void) +{ + static int read_nextline = 1; + + if (read_nextline) { + if (!fgets(line, MAX_LINE_LEN, fp)) + goto ret_eof; + line_pos = 0; + ++line_num; + read_nextline = 0; + } + while (isspace(line[line_pos])) + ++line_pos; + if (line[line_pos] == '\0' || line[line_pos] == '#' || + line[line_pos] == ';') { + read_nextline = 1; + goto ret_eol; + } + token = line + line_pos; + if (line[line_pos] == '"') { + token++; + for (/* NOTHING */; line[++line_pos] != '"' && line[line_pos];) + /* NOTHING */; + if (!line[line_pos]) { + read_nextline = 1; + goto ret_eol; + } + } else { + for (/* NOTHING */; !isspace(line[line_pos]); line_pos++) + /* NOTHING */; + } + line[line_pos] = '\0'; + line_pos++; +#ifdef DEBUG + printf("get_token ok\n"); +#endif + return RET_OK; +ret_eof: +#ifdef DEBUG + printf("get_token EOF\n"); +#endif + token = NULL; + return RET_EOF; +ret_eol: +#ifdef DEBUG + printf("get_token EOL\n"); +#endif + token = NULL; + return RET_EOL; +} + +int add_to_fourcc(char *s, char *alias, unsigned int *fourcc, + unsigned int *map) +{ + int i; + char **aliasp; + + /* find first unused slot */ + for (i = 0; i < CODECS_MAX_FOURCC && fourcc[i] != 0xffffffff; i++) + /* NOTHING */; + if (i == CODECS_MAX_FOURCC) { + printf("too many fourcc...\n"); + return 0; + } +#if 1 + if (alias) { + do { + fourcc[i] = *((unsigned int *) s); + map[i] = *((unsigned int *) alias); + s += 4; + i++; + } while (*(s++) == ','); + } else { + do { + fourcc[i] = *((unsigned int *) s); + map[i] = *((unsigned int *) s); + s += 4; + i++; + } while (*(s++) == ','); + } +#else + if (alias) + aliasp = &alias; + else + aliasp = &s; + do { + fourcc[i] = *((unsigned int *) s); + map[i++] = *((unsigned int *) (*aliasp)); + s += 4; + } while (*(s++) == ','); +#endif + if (*(--s) != '\0') + return 0; + return 1; +} + +int add_to_format(char *s, unsigned int *format) +{ + return 1; +} + +short get_flags(char *s) +{ + if (!s) + return 0; + return 1; +} + +int add_to_out(char *sfmt, char *sflags, unsigned int *outfmt, + unsigned char *outflags) +{ + static char *fmtstr[] = { + "YUY2", + "YV12", + "RGB8", + "RGB15", + "RGB16", + "RGB24", + "RGB32", + "BGR8", + "BGR15", + "BGR16", + "BGR24", + "BGR32", + NULL + }; + static unsigned int fmtnum[] = { + IMGFMT_YUY2, + IMGFMT_YV12, + IMGFMT_RGB|8, + IMGFMT_RGB|15, + IMGFMT_RGB|16, + IMGFMT_RGB|24, + IMGFMT_RGB|32, + IMGFMT_BGR|8, + IMGFMT_BGR|15, + IMGFMT_BGR|16, + IMGFMT_BGR|24, + IMGFMT_BGR|32 + }; + int i, j; + unsigned char flags; + + for (i = 0; i < CODECS_MAX_OUTFMT && outfmt[i] != 0xffffffff; i++) + /* NOTHING */; + if (i == CODECS_MAX_FOURCC) { + printf("too many out...\n"); + return 0; + } + + flags = get_flags(sflags); + + do { + for (j = 0; fmtstr[i] != NULL; j++) + if (!strncmp(sfmt, fmtstr[j], strlen(fmtstr[j]))) + break; + if (fmtstr[j] == NULL) + return 0; + outfmt[i] = fmtnum[j]; + outflags[i] = flags; + sfmt+=strlen(fmtstr[j]); + } while (*(sfmt++) == ','); + if (*(--sfmt) != '\0') + return 0; + return 1; +} + +short get_driver(char *s) +{ + return 0; +} + +#define DEBUG + +codecs_t *parse_codec_cfg(char *cfgfile) +{ +#define PRINT_LINENUM printf("%s(%d): ", cfgfile, line_num) +#define GET_MEM\ + do {\ + if (!(codecs = (codecs_t *) realloc(codecs,\ + sizeof(codecs_t) * (nr_codecs + 1)))) {\ + perror("parse_codec_cfg: can't realloc 'codecs'");\ + goto err_out;\ + }\ + } while (0) + + codecs_t *codecs = NULL; + int free_slots = 0; + int tmp, i; + int state = 0; + char *param1; + +#ifdef DEBUG + assert(cfgfile != NULL); +#endif + + printf("Reading codec config file: %s\n", cfgfile); + + if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { + perror("parse_codec_cfg: can't get memory for 'line'"); + return NULL; + } + + if ((fp = fopen(cfgfile, "r")) == NULL) { + printf("parse_codec_cfg: can't open '%s': %s\n", cfgfile, strerror(errno)); + free(line); + return NULL; + } + line_pos = 0; + line[0] = '\0'; /* forces get_token to read next line */ + + for (;;) { + tmp = get_token(); + if (tmp == RET_EOF) + goto eof_out; + if (tmp == RET_EOL) + continue; + if (!strcmp(token, "audiocodec") || !strcmp(token, "videocodec")) { + if (codecs) { +// tmp = ~state & STATE_MASK; +// if (tmp != GOT_FOURCC && tmp != GOT_FORMAT) +// goto parse_error_out; + nr_codecs++; + } + PRINT_LINENUM; + GET_MEM; + state = 0; + codecs[nr_codecs].comment = NULL; + memset(codecs[nr_codecs].fourcc, 0xff, + sizeof(codecs[nr_codecs].fourcc) ); +/* + memset(codecs[nr_codecs].fourccmap, 0xff, + sizeof(codecs[nr_codecs].fourccmap) * + CODECS_MAX_FOURCC); +*/ + memset(codecs[nr_codecs].outfmt, 0xff, + sizeof(codecs[nr_codecs].outfmt) ); + if (*token == 'a') { /* audiocodec */ + printf("audio"); + codecs[nr_codecs].flags |= CODECS_FLAG_AUDIO; + } else if (*token == 'v') { /* videocodec */ + printf("video"); + codecs[nr_codecs].flags &= !CODECS_FLAG_AUDIO; + } else { + printf("itt valami nagyon el van baszva\n"); + goto err_out; + } + if (get_token() < 0) + goto parse_error_out; + codecs[nr_codecs].name = strdup(token); + state |= GOT_NAME; + printf(" %s\n", codecs[nr_codecs].name); + } else if (!strcmp(token, "info")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("info"); + if (state & GOT_INFO || get_token() < 0) + goto parse_error_out; + codecs[nr_codecs].info = strdup(token); + state |= GOT_INFO; + printf(" %s\n", codecs[nr_codecs].info); + } else if (!strcmp(token, "comment")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("comment"); + if (get_token() < 0) + goto parse_error_out; +#if 1 + if (!codecs[nr_codecs].comment) + codecs[nr_codecs].comment = strdup(token); + printf(" %s\n", codecs[nr_codecs].comment); +#else + add_comment(token, &codecs[nr_codecs].comment); + printf(" FIXMEEEEEEEEEEEEEEE\n"); +#endif + } else if (!strcmp(token, "fourcc")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("fourcc"); + if (codecs[nr_codecs].flags & CODECS_FLAG_AUDIO) { + printf("\n'fourcc' in audiocodec definition!\n"); + goto err_out; + } + if (get_token() < 0) + goto parse_error_out; + param1 = strdup(token); + get_token(); + if (!add_to_fourcc(param1, token, + codecs[nr_codecs].fourcc, + codecs[nr_codecs].fourccmap)) + goto err_out; + state |= GOT_FOURCC; + printf(" %s: %s\n", param1, token); + free(param1); + } else if (!strcmp(token, "format")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("format"); + if (!(codecs[nr_codecs].flags & CODECS_FLAG_AUDIO)) { + printf("\n'format' in videocodec definition!\n"); + goto err_out; + } + if (get_token() < 0) + goto parse_error_out; + if (!add_to_format(token, codecs[nr_codecs].fourcc)) + goto err_out; + state |= GOT_FORMAT; + printf(" %s\n", token); + } else if (!strcmp(token, "driver")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("driver"); + if (get_token() < 0) + goto parse_error_out; + if ((codecs[nr_codecs].driver = get_driver(token)) == -1) + goto err_out; + printf(" %s\n", token); + } else if (!strcmp(token, "dll")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("dll"); + if (get_token() < 0) + goto parse_error_out; + codecs[nr_codecs].dll = strdup(token); + printf(" %s\n", codecs[nr_codecs].dll); + } else if (!strcmp(token, "guid")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("guid"); + if (get_token() < 0) + goto parse_error_out; + sscanf(token, "%ld,", &codecs[nr_codecs].guid.f1); + if (get_token() < 0) + goto parse_error_out; + sscanf(token, "%d,", &tmp); + codecs[nr_codecs].guid.f2 = tmp; + if (get_token() < 0) + goto parse_error_out; + sscanf(token, "%d,", &tmp); + codecs[nr_codecs].guid.f3 = tmp; + for (i = 0; i < 7; i++) { + if (get_token() < 0) + goto parse_error_out; + sscanf(token, "%d,", &tmp); + codecs[nr_codecs].guid.f4[i] = tmp; + } + if (get_token() < 0) + goto parse_error_out; + sscanf(token, "%d", &tmp); + codecs[nr_codecs].guid.f4[7] = tmp; + printf(" %s\n", token); + } else if (!strcmp(token, "out")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("out"); + if (get_token() < 0) + goto parse_error_out; + param1 = strdup(token); + get_token(); + if (!add_to_out(param1, token, codecs[nr_codecs].outfmt, + codecs[nr_codecs].outflags)) + goto err_out; + printf(" %s: %s\n", param1, token); + free(param1); + } else if (!strcmp(token, "flags")) { + if (!(state & GOT_NAME)) + goto parse_error_out; + PRINT_LINENUM; + printf("flags"); + if (get_token() < 0) + goto parse_error_out; + printf(" %s\n", token); + } else + goto parse_error_out; + } +out: + free(line); + fclose(fp); + return codecs; +parse_error_out: + PRINT_LINENUM; + printf("parse error\n"); +err_out: + printf("\nOops\n"); + if (codecs) + free(codecs); + codecs = NULL; + goto out; +eof_out: + /* FIXME teljes az utolso config?? */ + goto out; +} + +#ifdef TESTING +int main(void) +{ + codecs_t *codecs; + int i,j; + + codecs = parse_codec_cfg("codecs.conf"); + + printf("total %d codecs parsed\n",nr_codecs); + for(i=0;i<nr_codecs;i++){ + codecs_t *c=&codecs[i]; + printf("\n============== codec %02d ===============\n",i); + printf("name='%s'\n",c->name); + printf("info='%s'\n",c->info); + printf("comment='%s'\n",c->comment); + printf("dll='%s'\n",c->dll); + printf("flags=%X driver=%d\n",c->flags,c->driver); + for(j=0;j<CODECS_MAX_FOURCC;j++){ + if(c->fourcc[j]!=0xFFFFFFFF){ + printf("fourcc %02d: %08X (%.4s) ===> %08X (%.4s)\n",j,c->fourcc[j],&c->fourcc[j],c->fourccmap[j],&c->fourccmap[j]); + } + } + } + + return 0; +} + +#endif diff --git a/codec-cfg.h b/codec-cfg.h new file mode 100644 index 0000000000..90261cc5c5 --- /dev/null +++ b/codec-cfg.h @@ -0,0 +1,44 @@ +#ifndef __CODEC_CFG_H +#define __CODEC_CFG_H + +//#include <inttypes.h> + +#ifndef IMGFMT_YV12 +#define IMGFMT_YV12 0x32315659 +#define IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y') +#define IMGFMT_RGB_MASK 0xFFFFFF00 +#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) +#define IMGFMT_BGR_MASK 0xFFFFFF00 +#define IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8)) +#endif + +#define CODECS_MAX_FOURCC 16 +#define CODECS_MAX_OUTFMT 16 + +#define CODECS_FLAG_AUDIO (1<<0) + +#warning nem kellene ket typedef GUID-nak... +typedef struct { + long f1; + short f2; + short f3; + char f4[8]; +} GUID; + +typedef struct { + char *name; + char *info; + char *comment; + unsigned int fourcc[CODECS_MAX_FOURCC]; + unsigned int fourccmap[CODECS_MAX_FOURCC]; + short driver; + short flags; + char *dll; + GUID guid; + unsigned int outfmt[CODECS_MAX_OUTFMT]; + unsigned char outflags[CODECS_MAX_OUTFMT]; +} codecs_t; + +codecs_t *parse_codec_cfg(char *cfgfile); + +#endif diff --git a/codecs.conf b/codecs.conf new file mode 100644 index 0000000000..5defd8c576 --- /dev/null +++ b/codecs.conf @@ -0,0 +1,175 @@ +; Example codecs config file. +; It is not functional yet! until we finish config loader, +; mplayer will use codecs.c!!! + +videocodec mpeg4 + info "Microsoft MPEG-4 v1/v2" + comment "No postprocessing" + fourcc MPG4,mpg4 + fourcc MP42,mp42 + driver vfw + dll "mpg4c32.dll" + out YUY2 noflip,yuvhack + out RGB32,RGB24,RGB15 + +videocodec divx + info "DivX ;-) (MS MPEG-4 v3)" + comment "DivX rulez ;-)" + fourcc MP43,mp43 div3 ; fourcc mapping to div3 + fourcc DIV5,div5 div3 + fourcc DIV6,div6 div4 + fourcc DIV3,div3,DIV4,div3 + driver vfw + dll "divxc32.dll" + out YUY2 noflip,yuvhack + out RGB32,RGB24,RGB15 + +videocodec divxds + info "DivX ;-) (MS MPEG-4 v3)" + comment "DivX rulez ;-)" + fourcc MP43,mp43 div3 ; fourcc mapping to div3 + fourcc DIV5,div5 div3 + fourcc DIV6,div6 div4 + fourcc DIV3,div3,DIV4,div3 + driver dshow + dll "divx_c32.ax" + guid 0x82CCd3E0, 0xF71A, 0x11D0, 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa + out YUY2 noflip + out RGB32,RGB24,RGB16,RGB15 noflip + +videocodec odivx + info "OpenDivX (MPEG-4 v2)" + fourcc DIVX,divx + fourcc DIV1,div1 divx + driver odivx + out YV12 noflip + +videocodec indeo5 + info "Intel Indeo 5" + fourcc IV50,iv50 + driver vfw + dll "ir50_32.dll" + out YUY2 noflip + out RGB32,RGB24,RGB15 noflip + +videocodec indeo4 + info "Intel Indeo 4.1" + comment "upside-down" + fourcc IV41,iv41 + driver vfw + dll "ir41_32.dll" + out RGB24,RGB15 flip + +videocodec indeo3 + info "Intel Indeo 3.1/3.2" + comment "upside-down" + fourcc IV31,iv31 + fourcc IV32,iv32 + driver vfw + dll "ir32_32.dll" + out RGB24,RGB15 flip + +videocodec cvid + info "Cinepak Video" + fourcc cvid + driver vfw + dll "msvidc32.dll" + out YUY2 noflip + out RGB24,RGB15 noflip + +videocodec cram + info "CRAM" + fourcc cram,CRAM + driver vfw + dll "msvidc32.dll" + out RGB24,RGB15 noflip + +videocodec vcr2 + info "ATI VCR-2" + fourcc VCR2 + driver vfw + dll "ativcr2.dll" + out YUY2 noflip + out RGB32,RGB24,RGB15 noflip + +videocodec i263 + info "I263" + comment "not tested" + fourcc I263,i263 + driver vfw + dll "i263_32.drv" + out RGB32,RGB24,RGB15 noflip + +videocodec mjpeg + info "Motion JPEG" + fourcc MJPG + driver vfw + dll "mcmjpg32.dll" +; dll "m3jpeg32.dll" + out YUY2 noflip + out RGB32,RGB24,RGB15 noflip + +videocodec wmv1 + info "Windows Media Video 7" + fourcc WMV1 + driver dshow + dll "wmvds32.ax" + guid 0x4facbba1, 0xffd8, 0x4cd7, 0x82, 0x28, 0x61, 0xe2, 0xf6, 0x5c, 0xb1, 0xae + out YUY2 noflip + out RGB32,RGB24,RGB16,RGB15 noflip + +audiocodec divx + info "DivX audio (WMA)" + format 0x160 + format 0x161 + driver acm + dll "divxa32.acm" + +audiocodec msadpcm + info "MS ADPCM" + format 0x2 + driver acm + dll "msadp32.acm" + +audiocodec mp3acm + info "MPEG layer-3" + comment "Optimized to Intel MMX/SSE" + format 0x55 + driver acm + dll "l3codeca.acm" + flags seekable + +audiocodec mp3 + info "MPEG layer-2,3" + comment "Optimized to AMD 3Dnow!" + format 0x50 + format 0x55 + driver mp3lib + flags seekable + +audiocodec imaadpcm + info "IMA ADPCM" + format 0x11 + driver acm + dll "imaadp32.acm" + +audiocodec msgsmacm + info "MS GSM" + format 0x31 + format 0x32 + driver acm + dll "msgsm32.acm" + +audiocodec msgsm + info "MS GSM" + format 0x31 + format 0x32 + driver msgsm + +audiocodec voxware + info "VoxWare" + format 0x75 + driver dshow + dll "voxmsdec.ax" + guid 0x73f7a062, 0x8829, 0x11d1, 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d + |