Mercurial > mplayer.hg
view aviparse.c @ 434:50955d1a56c1
bih fix for mpegs
author | arpi_esp |
---|---|
date | Sun, 15 Apr 2001 14:46:07 +0000 |
parents | 3b5f5d1c5041 |
children |
line wrap: on
line source
// 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; }