Mercurial > mplayer.hg
changeset 15886:e44fe4cf44f9
avi subtitle stream dumper
author | ranma |
---|---|
date | Sat, 02 Jul 2005 15:22:49 +0000 |
parents | b2f434649dec |
children | a03d9116fc25 |
files | TOOLS/avisubdump.c |
diffstat | 1 files changed, 199 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/avisubdump.c Sat Jul 02 15:22:49 2005 +0000 @@ -0,0 +1,199 @@ +/* + * avisubdump + * + * avi vobsub subtitle stream dumper (c) 2004 Tobias Diedrich + * Licensed under GNU GPLv2 or (at your option) any later version. + * + * Compile with "make avisubdump" + */ + +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> + +#define FCC(a,b,c,d) (((a))|((b)<<8)|((c)<<16)|((d)<<24)) + +#define FCC_RIFF FCC('R','I','F','F') +#define FCC_LIST FCC('L','I','S','T') +#define FCC_strh FCC('s','t','r','h') +#define FCC_txts FCC('t','x','t','s') +#define FCC_GAB2 FCC('G','A','B','2') + +#define GAB_LANGUAGE 0 +#define GAB_ENTRY 1 +#define GAB_LANGUAGE_UNICODE 2 +#define GAB_ENTRY_UNICODE 3 +#define GAB_RAWTEXTSUBTITLE 4 + +static char *subfile; + +static unsigned int getle16(FILE* f){ + unsigned int res; + + res = fgetc(f); + res |= fgetc(f) << 8; + + return res; +} + +static unsigned int getle(FILE* f){ + unsigned int res; + + res = fgetc(f); + res |= fgetc(f) << 8; + res |= fgetc(f) << 16; + res |= fgetc(f) << 24; + + return res; +} + +static void skip(FILE *f, int len) +{ + if (f != stdin) { + fseek(f,len,SEEK_CUR); + } else { + void *buf = malloc(len); + fread(buf,len,1,f); + free(buf); + } +} + +static int stream_id(unsigned int id) +{ + char c1,c2; + c1 = (char)(id & 0xff); + c2 = (char)((id >> 8) & 0xff); + if (c1 >= '0' && c1 <= '9' && + c2 >= '0' && c2 <= '9') { + c1 -= '0'; + c2 -= '0'; + return c1*10+c2; + } + return -1; +} + +static int dumpsub_gab2(FILE *f, int size) { + int ret = 0; + + while (ret + 6 <= size) { + unsigned int len, id; + char *buf; + int i, fd; + + id = getle16(f); ret += 2; + len = getle(f); ret += 4; + if (ret + len > size) break; + + buf = malloc(len); + ret += fread(buf, 1, len, f); + + switch (id) { + case GAB_LANGUAGE_UNICODE: + for (i=0; i<len; i++) buf[i] = buf[i*2]; + case GAB_LANGUAGE: + fprintf(stderr, "LANGUAGE: %s\n", buf); + break; + case GAB_ENTRY_UNICODE: + for (i=0; i<len; i++) buf[i] = buf[i*2]; + case GAB_ENTRY: + fprintf(stderr, "ENTRY: %s\n", buf); + break; + case GAB_RAWTEXTSUBTITLE: + printf("%s", buf); + fd = open(subfile, O_CREAT|O_APPEND|O_WRONLY, 0644); + write(fd, buf, len); + close(fd); + fprintf(stderr, "Dumped subtitles to %s.\n", subfile); + break; + default: + fprintf(stderr, "Unknown type %d, len %d\n", id, len); + break; + } + free(buf); + } + + return ret; +} + +static void dump(FILE *f) { + unsigned int id, len; + int stream = 0; + int substream = -2; + + while (1) { + id = getle(f); + len = getle(f); + + if(feof(f)) break; + + if (id == FCC_RIFF || + id == FCC_LIST) { + getle(f); + continue; + } else if (id == FCC_strh) { + id = getle(f); len -= 4; + fprintf(stderr, "Stream %d is %c%c%c%c", + stream, + id, + id >> 8, + id >> 16, + id >> 24); + if (id == FCC_txts) { + substream = stream; + fprintf(stderr, " (subtitle stream)"); + } + fprintf(stderr, ".\n"); + stream++; + } else if (stream_id(id) == substream) { + unsigned int subid; + subid = getle(f); len -= 4; + if (subid != FCC_GAB2) { + fprintf(stderr, + "Unknown subtitle chunk %c%c%c%c (%08x).\n", + id, id >> 8, id >> 16, id >> 24, subid); + } else { + skip(f,1); len -= 1; + len -= dumpsub_gab2(f, len); + } + } + len+=len&1; + skip(f,len); + } +} + +int main(int argc,char* argv[]) +{ + FILE* f; + int i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s <avi>\n", argv[0]); + exit(1); + } + + f=fopen(argv[argc-1],"rb"); + + if (!f) { + fprintf(stderr, "Could not open '%s': %s\n", + argv[argc-1], strerror(errno)); + exit(-errno); + } + + subfile = malloc(strlen(argv[1]) + 4); + strcpy(subfile, argv[1]); + for (i=strlen(subfile); i>0 && subfile[i] != '.'; i--); + subfile[i] = 0; + strcat(subfile, ".ssa"); + + dump(f); + + free(subfile); + + return 0; +} +