summaryrefslogtreecommitdiffstats
path: root/aviparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'aviparse.c')
-rw-r--r--aviparse.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/aviparse.c b/aviparse.c
new file mode 100644
index 0000000000..2fd34e9033
--- /dev/null
+++ b/aviparse.c
@@ -0,0 +1,336 @@
+// AVI Parser tool v0.1 (C) 2000. by A'rpi/ESP-team
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <signal.h>
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/cdrom.h>
+
+#include "config.h"
+
+#include "loader.h"
+#include "wine/avifmt.h"
+//#include "libvo/video_out.h"
+
+#include "linux/timer.h"
+#include "linux/shmem.h"
+
+#include "help_avp.h"
+
+#define DEBUG if(0)
+
+//static int show_packets=0;
+
+typedef struct {
+ // file:
+ MainAVIHeader avih;
+ unsigned int movi_start;
+ unsigned int movi_end;
+ // index:
+ AVIINDEXENTRY* idx;
+ int idx_size;
+ int idx_pos;
+// int a_idx;
+// int v_idx;
+ // video:
+ AVIStreamHeader video;
+ char *video_codec;
+ BITMAPINFOHEADER bih; // in format
+ BITMAPINFOHEADER o_bih; // out format
+ HIC hic;
+ void *our_out_buffer;
+ char yuv_supported; // 1 if codec support YUY2 output format
+ char yuv_hack_needed; // requires for divx & mpeg4
+ // audio:
+ AVIStreamHeader audio;
+ char *audio_codec;
+ char wf_ext[64]; // in format
+ WAVEFORMATEX wf; // out format
+ HACMSTREAM srcstream;
+ int audio_minsize;
+} avi_header_t;
+
+avi_header_t avi_header;
+
+#include "aviprint.c"
+//#include "codecs.c"
+
+//**************************************************************************//
+#include "stream.c"
+//#include "demuxer.c"
+//#include "demux_avi.c"
+
+static stream_t* stream=NULL;
+
+//**************************************************************************//
+
+extern int errno;
+static int play_in_bg=0;
+
+void exit_player(){
+// int tmp;
+ // restore terminal:
+ getch2_disable();
+ printf("\n\n");
+ if(play_in_bg) system("xsetroot -solid \\#000000");
+ exit(1);
+}
+
+void exit_sighandler(int x){
+ printf("\nmpgplay2 interrupted by signal %d\n",x);
+ exit_player();
+}
+
+
+int main(int argc,char* argv[]){
+char* filename=NULL; //"MI2-Trailer.avi";
+int i;
+//int seek_to_sec=0;
+int seek_to_byte=0;
+int f; // filedes
+int has_audio=1;
+//int audio_format=0;
+//int alsa=0;
+//int audio_buffer_size=-1;
+int audio_id=-1;
+//int video_id=-1;
+//float default_max_pts_correction=0.01f;
+//int delay_corrected=0;
+//float force_fps=0;
+//float default_fps=25;
+//float audio_delay=0;
+int stream_type;
+//int elementary_stream=0;
+int vcd_track=0;
+#ifdef VCD_CACHE
+int vcd_cache_size=128;
+#endif
+//char* video_driver="mga"; // default
+//int out_fmt=0;
+int idx_filepos=0;
+FILE *audiofile=NULL;
+FILE *videofile=NULL;
+char *audiofile_name=NULL;
+char *videofile_name=NULL;
+
+ printf("%s",banner_text);
+
+for(i=1;i<argc;i++){
+ if(strcmp(argv[i],"-afile")==0) audiofile_name=argv[++i]; else
+ if(strcmp(argv[i],"-vfile")==0) videofile_name=argv[++i]; else
+// if(strcmp(argv[i],"-sb")==0) seek_to_byte=strtol(argv[++i],NULL,0); else
+ if(strcmp(argv[i],"-aid")==0) audio_id=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-vid")==0) video_id=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-afm")==0) audio_format=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-vcd")==0) vcd_track=strtol(argv[++i],NULL,0); else
+ if(strcmp(argv[i],"-h")==0) break; else
+ if(strcmp(argv[i],"--help")==0) break; else
+ { if(filename){ printf("invalid option: %s\n",filename);exit(1);}
+ filename=argv[i];
+ }
+}
+
+if(!filename){
+ if(vcd_track) filename="/dev/cdrom";
+// else
+// filename="/4/Film/Joan of Arc [Hun DivX]/Joan of Arc - CD2.avi";
+ { printf("%s",help_text); exit(0);}
+}
+
+
+if(vcd_track){
+//============ Open VideoCD track ==============
+ f=open(filename,O_RDONLY);
+ if(f<0){ printf("Device not found!\n");return 1; }
+ vcd_read_toc(f);
+ if(!vcd_seek_to_track(f,vcd_track)){ printf("Error selecting VCD track!\n");return 1;}
+ seek_to_byte+=VCD_SECTOR_DATA*vcd_get_msf();
+ stream_type=STREAMTYPE_VCD;
+#ifdef VCD_CACHE
+ vcd_cache_init(vcd_cache_size);
+#endif
+} else {
+//============ Open plain FILE ============
+ f=open(filename,O_RDONLY);
+ if(f<0){ printf("File not found!\n");return 1; }
+ stream_type=STREAMTYPE_FILE;
+}
+
+//============ Open & Sync stream and detect file format ===============
+
+stream=new_stream(f,stream_type);
+//=============== Read AVI header:
+{ //---- RIFF header:
+ int id=stream_read_dword_le(stream); // "RIFF"
+ if(id!=mmioFOURCC('R','I','F','F')){ printf("Not RIFF format file!\n");return 1; }
+ stream_read_dword_le(stream); //filesize
+ id=stream_read_dword_le(stream); // "AVI "
+ if(id!=formtypeAVI){ printf("Not AVI file!\n");return 1; }
+}
+//---- AVI header:
+avi_header.idx_size=0;
+while(1){
+ int id=stream_read_dword_le(stream);
+ int chunksize,size2;
+ static int last_fccType=0;
+ //
+ if(stream_eof(stream)) break;
+ //
+ if(id==mmioFOURCC('L','I','S','T')){
+ int len=stream_read_dword_le(stream)-4; // list size
+ id=stream_read_dword_le(stream); // list type
+ printf("LIST %.4s len=%d\n",&id,len);
+ if(id==listtypeAVIMOVIE){
+ // found MOVI header
+ avi_header.movi_start=stream_tell(stream);
+ avi_header.movi_end=avi_header.movi_start+len;
+// printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+ len=(len+1)&(~1);
+ stream_skip(stream,len);
+ }
+ continue;
+ }
+ size2=stream_read_dword_le(stream);
+ printf("CHUNK %.4s len=%d\n",&id,size2);
+ chunksize=(size2+1)&(~1);
+ switch(id){
+ case ckidAVIMAINHDR: // read 'avih'
+ stream_read(stream,(char*) &avi_header.avih,sizeof(avi_header.avih));
+ chunksize-=sizeof(avi_header.avih);
+ print_avih(&avi_header.avih);
+ break;
+ case ckidSTREAMHEADER: { // read 'strh'
+ AVIStreamHeader h;
+ stream_read(stream,(char*) &h,sizeof(h));
+ chunksize-=sizeof(h);
+ if(h.fccType==streamtypeVIDEO) memcpy(&avi_header.video,&h,sizeof(h));else
+ if(h.fccType==streamtypeAUDIO) memcpy(&avi_header.audio,&h,sizeof(h));
+ last_fccType=h.fccType;
+ print_strh(&h);
+ break; }
+ case ckidSTREAMFORMAT: { // read 'strf'
+ if(last_fccType==streamtypeVIDEO){
+ stream_read(stream,(char*) &avi_header.bih,sizeof(avi_header.bih));
+ chunksize-=sizeof(avi_header.bih);
+// init_video_codec();
+// init_video_out();
+ } else
+ if(last_fccType==streamtypeAUDIO){
+ int z=(chunksize<64)?chunksize:64;
+ printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
+ stream_read(stream,(char*) &avi_header.wf_ext,z);
+ chunksize-=z;
+ print_wave_header((WAVEFORMATEX*)&avi_header.wf_ext);
+// init_audio_codec();
+// init_audio_out();
+ }
+ break;
+ }
+ case ckidAVINEWINDEX: {
+ avi_header.idx_size=size2>>4;
+// printf("Reading INDEX block, %d chunks for %d frames\n",
+// avi_header.idx_size,avi_header.avih.dwTotalFrames);
+ avi_header.idx=malloc(avi_header.idx_size<<4);
+ idx_filepos=stream_tell(stream);
+ stream_read(stream,(char*)avi_header.idx,avi_header.idx_size<<4);
+ chunksize-=avi_header.idx_size<<4;
+ print_index();
+ break;
+ }
+ }
+ if(chunksize>0) stream_skip(stream,chunksize); else
+ if(chunksize<0) printf("WARNING!!! chunksize=%d (id=%.4s)\n",chunksize,&id);
+
+}
+
+printf("----------------------------------------------------------------------\n");
+printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+if(avi_header.idx_size<=0){ printf("No index block found!\n");return 0;}
+printf("Index block at 0x%X, %d entries for %d frames\n",idx_filepos,
+ avi_header.idx_size,avi_header.avih.dwTotalFrames );
+
+stream_reset(stream);
+stream_seek(stream,avi_header.movi_start);
+avi_header.idx_pos=0;
+
+if(audiofile_name) audiofile=fopen(audiofile_name,"wb");
+if(videofile_name) videofile=fopen(videofile_name,"wb");
+
+for(i=0;i<avi_header.idx_size;i++){
+#if 0
+ printf("%.4s %4X %08X %d ",
+ &avi_header.idx[i].ckid,
+ avi_header.idx[i].dwFlags,
+ avi_header.idx[i].dwChunkOffset,
+ avi_header.idx[i].dwChunkLength
+ );fflush(stdout);
+#endif
+ if(avi_header.idx[i].ckid&AVIIF_LIST){
+// printf("LIST\n");
+ } else {
+ int id,size;
+ stream_seek(stream,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4);
+ id=stream_read_dword_le(stream);
+ size=stream_read_dword_le(stream);
+ if(id!=avi_header.idx[i].ckid){
+ printf("ChunkID mismatch! raw=%.4s (0x%X) idx=%.4s (0x%X)\n",
+ &id,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4,
+ &avi_header.idx[i].ckid,idx_filepos+16*i
+ );
+ continue;
+ }
+ if(size!=avi_header.idx[i].dwChunkLength){
+ printf("ChunkSize mismatch! raw=%d (0x%X) idx=%d (0x%X)\n",
+ size,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4,
+ avi_header.idx[i].dwChunkLength,idx_filepos+16*i
+ );
+ continue;
+ }
+
+ if(id!=mmioFOURCC('J','U','N','K'))
+ if(TWOCCFromFOURCC(id)==cktypeWAVEbytes){
+ // audio
+ int aid=StreamFromFOURCC(id);
+ if(audio_id==-1) audio_id=aid;
+ if(audio_id==aid){
+ if(audiofile){
+ void* mem=malloc(size);
+ stream_read(stream,mem,size);
+ fwrite(mem,size,1,audiofile);
+ free(mem);
+ }
+ } else {
+ printf("Invalid audio stream id: %d (%.4s)\n",aid,&id);
+ }
+ } else
+ if(LOWORD(id)==aviTWOCC('0','0')){
+ // video
+ if(videofile){
+ void* mem=malloc(size);
+ stream_read(stream,mem,size);
+ fwrite(&size,4,1,videofile);
+ fwrite(mem,size,1,videofile);
+ free(mem);
+ }
+ } else {
+ // unknown
+ printf("Unknown chunk: %.4s (%X)\n",&id,id);
+ }
+
+ } // LIST or CHUNK
+
+}
+
+return 0;
+}
+