aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-02-05 22:37:43 +0000
committerGravatar arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-02-05 22:37:43 +0000
commita3735cb42d9a5f8ec5f25d496fc2375d3ec1b0d8 (patch)
treed828dde85423d428b6f8698b631cd950a2b35e5f
parent14495f48ab5e10c862388394f6e8ebd6cf44d4ec (diff)
avi-fix v0.1: simple tool to fix chunk sizes in a RIFF AVI file
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11925 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--TOOLS/avi-fix.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/TOOLS/avi-fix.c b/TOOLS/avi-fix.c
new file mode 100644
index 0000000000..45bb4c8fa8
--- /dev/null
+++ b/TOOLS/avi-fix.c
@@ -0,0 +1,136 @@
+// avi-fix v0.1 (C) A'rpi, license GPL
+// simple tool to fix chunk sizes in a RIFF AVI file
+// it doesn't check/fix index, use mencoder -forceidx -oac copy -ovc copy to fix index!
+
+#include <stdio.h>
+#include <stdlib.h>
+//#include <string.h>
+
+#define FCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
+
+static inline xx(unsigned char c){
+ if(c>=32 && c<128) return c;
+ return '?';
+}
+
+static inline unsigned int getid(FILE* f){
+ unsigned int id;
+ id=fgetc(f);
+ id=(id<<8)|fgetc(f);
+ id=(id<<8)|fgetc(f);
+ id=(id<<8)|fgetc(f);
+ return id;
+}
+
+int main(int argc,char* argv[]){
+//FILE* f=fopen("edgar.avi","rb"); // readonly (report errors)
+//FILE* f=fopen("edgar.avi","rb+"); // fix mode (fix chunk sizes)
+unsigned int lastgood=0;
+unsigned int fixat=0;
+unsigned int offset=0;
+int fix_flag=0;
+FILE* f;
+
+if(argc<=1){
+ printf("Usage: %s [-fix] badfile.avi\n",argv[0]);
+ exit(1);
+}
+
+if(!strcmp(argv[1],"-fix")){
+ fix_flag=1;
+ f=fopen(argv[argc-1],"rb+");
+} else
+ f=fopen(argv[argc-1],"rb");
+
+if(!f){
+ perror("error");
+ printf("couldnt open '%s'\n",argv[argc-1]);
+ exit(2);
+}
+
+while(1){
+ unsigned int id,len;
+again:
+ id=fgetc(f);
+ id=(id<<8)|fgetc(f);
+ id=(id<<8)|fgetc(f);
+faszom:
+ if(feof(f)) break;
+// if(!lastgood && feof(f)) break;
+ id=(id<<8)|fgetc(f);
+// lastgood=ftell(f);
+ printf("%08X: %c%c%c%c\n",(int)ftell(f)-4,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+ switch(id){
+ case FCC('R','I','F','F'):
+ fread(&len,4,1,f); // filesize
+ id=getid(f); // AVI
+ printf("RIFF header, filesize=0x%X format=%c%c%c%c\n",len,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+ break;
+ case FCC('L','I','S','T'):
+ fread(&len,4,1,f); // size
+ id=getid(f); // AVI
+ printf("LIST size=0x%X format=%c%c%c%c\n",len,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+ //case FCC('h','d','r','l'):
+ //case FCC('s','t','r','l'):
+ //case FCC('o','d','m','l'):
+ //case FCC('m','o','v','i'):
+ break;
+ // legal chunk IDs:
+ case FCC('a','v','i','h'): // avi header
+ case FCC('s','t','r','h'): // stream header
+ case FCC('s','t','r','f'): // stream format
+ case FCC('J','U','N','K'): // official shit
+ // index:
+ case FCC('i','d','x','1'): // main index??
+ case FCC('d','m','l','h'): // opendml header
+ case FCC('i','n','d','x'): // opendml main index??
+ case FCC('i','x','0','0'): // opendml sub index??
+ case FCC('i','x','0','1'): // opendml sub index??
+ // data:
+ case FCC('0','1','w','b'): // audio track #1
+ case FCC('0','2','w','b'): // audio track #2
+ case FCC('0','3','w','b'): // audio track #3
+ case FCC('0','0','d','b'): // uncompressed video
+ case FCC('0','0','d','c'): // compressed video
+ case FCC('0','0','_','_'): // A-V interleaved (type2 DV file)
+ // info:
+ case FCC('I','S','F','T'): // INFO: software
+ case FCC('I','S','R','C'): // INFO: source
+ case FCC('I','N','A','M'): // INFO: name
+ case FCC('I','S','B','J'): // INFO: subject
+ case FCC('I','A','R','T'): // INFO: artist
+ case FCC('I','C','O','P'): // INFO: copyright
+ case FCC('I','C','M','T'): // INFO: comment
+ lastgood=ftell(f);
+ if(fixat && fix_flag){
+ // fix last chunk's size field:
+ fseek(f,fixat,SEEK_SET);
+ len=lastgood-fixat-8;
+ printf("Correct len to 0x%X\n",len);
+ fwrite(&len,4,1,f);
+ fseek(f,lastgood,SEEK_SET);
+ fixat=0;
+ }
+ fread(&len,4,1,f); // size
+ printf("ID ok, chunk len=0x%X\n",len);
+ len+=len&1; // align at 2
+ fseek(f,len,SEEK_CUR); // skip data
+ break;
+ default:
+ if(!lastgood){
+ ++offset;
+ printf("invalid ID, trying %d byte offset\n",offset);
+ goto faszom; // try again @ next post
+ }
+ printf("invalid ID, parsing next chunk's data at 0x%X\n",lastgood);
+ fseek(f,lastgood,SEEK_SET);
+ fixat=lastgood;
+ lastgood=0;
+ goto again;
+ }
+ offset=0;
+}
+
+
+}
+