Mercurial > mplayer.hg
changeset 1485:b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
author | arpi |
---|---|
date | Sat, 11 Aug 2001 20:37:33 +0000 |
parents | 14af3106c359 |
children | a70e494144cf |
files | asf.h asfheader.c aviheader.c aviheader.h aviprint.c dec_audio.c demux_asf.c demux_avi.c demuxer.c demuxer.h mplayer.c seek.c |
diffstat | 12 files changed, 304 insertions(+), 253 deletions(-) [+] |
line wrap: on
line diff
--- a/asf.h Sat Aug 11 17:05:35 2001 +0000 +++ b/asf.h Sat Aug 11 20:37:33 2001 +0000 @@ -156,12 +156,36 @@ (h)->comment_size = le2me_16((h)->comment_size); \ (h)->rating_size = le2me_16((h)->rating_size); \ } +#define le2me_BITMAPINFOHEADER(h) { \ + (h)->biSize = le2me_32((h)->biSize); \ + (h)->biWidth = le2me_32((h)->biWidth); \ + (h)->biHeight = le2me_32((h)->biHeight); \ + (h)->biPlanes = le2me_16((h)->biPlanes); \ + (h)->biBitCount = le2me_16((h)->biBitCount); \ + (h)->biCompression = le2me_32((h)->biCompression); \ + (h)->biSizeImage = le2me_32((h)->biSizeImage); \ + (h)->biXPelsPerMeter = le2me_32((h)->biXPelsPerMeter); \ + (h)->biYPelsPerMeter = le2me_32((h)->biYPelsPerMeter); \ + (h)->biClrUsed = le2me_32((h)->biClrUsed); \ + (h)->biClrImportant = le2me_32((h)->biClrImportant); \ +} +#define le2me_WAVEFORMATEX(h) { \ + (h)->wFormatTag = le2me_16((h)->wFormatTag); \ + (h)->nChannels = le2me_16((h)->nChannels); \ + (h)->nSamplesPerSec = le2me_32((h)->nSamplesPerSec); \ + (h)->nAvgBytesPerSec = le2me_32((h)->nAvgBytesPerSec); \ + (h)->nBlockAlign = le2me_16((h)->nBlockAlign); \ + (h)->wBitsPerSample = le2me_16((h)->wBitsPerSample); \ + (h)->cbSize = le2me_16((h)->cbSize); \ +} #else #define le2me_ASF_obj_header_t(h) /**/ #define le2me_ASF_header_t(h) /**/ #define le2me_ASF_stream_header_t(h) /**/ #define le2me_ASF_file_header_t(h) /**/ #define le2me_ASF_content_description_t(h) /**/ +#define le2me_BITMAPINFOHEADER(h) /**/ +#define le2me_WAVEFORMATEX(h) /**/ #endif
--- a/asfheader.c Sat Aug 11 17:05:35 2001 +0000 +++ b/asfheader.c Sat Aug 11 20:37:33 2001 +0000 @@ -16,7 +16,7 @@ #include "codec-cfg.h" #include "stheader.h" -#include "aviheader.h" +//#include "aviheader.h" #include "asf.h" #ifdef ARCH_X86
--- a/aviheader.c Sat Aug 11 17:05:35 2001 +0000 +++ b/aviheader.c Sat Aug 11 20:37:33 2001 +0000 @@ -1,9 +1,10 @@ -#include "config.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include "config.h" + extern int verbose; // defined in mplayer.c #include "stream.h" @@ -35,9 +36,10 @@ int stream_id=-1; int idxfix_videostream=0; int idxfix_divx=0; +avi_priv_t* priv=demuxer->priv; //---- AVI header: -demuxer->idx_size=0; +priv->idx_size=0; while(1){ int id=stream_read_dword_le(demuxer->stream); int chunksize,size2; @@ -137,15 +139,15 @@ } case ckidAVINEWINDEX: if(index_mode){ int i; - demuxer->idx_size=size2>>4; + priv->idx_size=size2>>4; if(verbose>=1) printf("Reading INDEX block, %d chunks for %ld frames\n", - demuxer->idx_size,avih.dwTotalFrames); - demuxer->idx=malloc(demuxer->idx_size<<4); - stream_read(demuxer->stream,(char*)demuxer->idx,demuxer->idx_size<<4); - for (i = 0; i < demuxer->idx_size; i++) // swap index to machine endian - le2me_AVIINDEXENTRY((AVIINDEXENTRY*)demuxer->idx + i); - chunksize-=demuxer->idx_size<<4; - if(verbose>=2) print_index(demuxer->idx,demuxer->idx_size); + priv->idx_size,avih.dwTotalFrames); + priv->idx=malloc(priv->idx_size<<4); + stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4); + for (i = 0; i < priv->idx_size; i++) // swap index to machine endian + le2me_AVIINDEXENTRY((AVIINDEXENTRY*)priv->idx + i); + chunksize-=priv->idx_size<<4; + if(verbose>=2) print_index(priv->idx,priv->idx_size); break; } } @@ -154,14 +156,14 @@ } -if(index_mode>=2 || (demuxer->idx_size==0 && index_mode==1)){ +if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){ // build index for file: stream_reset(demuxer->stream); stream_seek(demuxer->stream,demuxer->movi_start); - demuxer->idx_pos=0; - demuxer->idx_size=0; - demuxer->idx=NULL; + priv->idx_pos=0; + priv->idx_size=0; + priv->idx=NULL; while(1){ int id,len,skip; @@ -178,13 +180,13 @@ if(stream_eof(demuxer->stream)) break; if(!id || avi_stream_id(id)==100) goto skip_chunk; // bad ID (or padding?) - if(demuxer->idx_pos<=demuxer->idx_size){ -// demuxer->idx_size+=32; - demuxer->idx_size+=1024; // +16kB - demuxer->idx=realloc(demuxer->idx,demuxer->idx_size*sizeof(AVIINDEXENTRY)); - if(!demuxer->idx){demuxer->idx_pos=0; break;} // error! + if(priv->idx_pos<=priv->idx_size){ +// priv->idx_size+=32; + priv->idx_size+=1024; // +16kB + priv->idx=realloc(priv->idx,priv->idx_size*sizeof(AVIINDEXENTRY)); + if(!priv->idx){priv->idx_pos=0; break;} // error! } - idx=&((AVIINDEXENTRY *)demuxer->idx)[demuxer->idx_pos++]; + idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; idx->ckid=id; idx->dwFlags=AVIIF_KEYFRAME; // FIXME idx->dwChunkOffset=demuxer->filepos; @@ -212,11 +214,12 @@ skip=(len+1)&(~1); // total bytes in this chunk stream_seek(demuxer->stream,8+demuxer->filepos+skip); } - demuxer->idx_size=demuxer->idx_pos; - printf("AVI: Generated index table for %d chunks!\n",demuxer->idx_size); + priv->idx_size=priv->idx_pos; + printf("AVI: Generated index table for %d chunks!\n",priv->idx_size); } } #undef MIN +
--- a/aviheader.h Sat Aug 11 17:05:35 2001 +0000 +++ b/aviheader.h Sat Aug 11 20:37:33 2001 +0000 @@ -1,7 +1,7 @@ #ifndef _aviheader_h #define _aviheader_h -#include "config.h" /* get correct definition WORDS_BIGENDIAN */ +//#include "config.h" /* get correct definition WORDS_BIGENDIAN */ #include "bswap.h" /* @@ -83,3 +83,24 @@ #endif + + +typedef struct { + // index stuff: + void* idx; + int idx_size; + int idx_pos; + int idx_pos_a; + int idx_pos_v; + int idx_offset; // ennyit kell hozzaadni az index offset ertekekhez + // interleaved PTS stuff: + int skip_video_frames; + float avi_audio_pts; + float avi_video_pts; + float pts_correction; + unsigned int pts_corr_bytes; + unsigned char pts_corrected; + unsigned char pts_has_video; +} avi_priv_t; + +#define AVI_PRIV ((avi_priv_t*)(demuxer->priv))
--- a/aviprint.c Sat Aug 11 17:05:35 2001 +0000 +++ b/aviprint.c Sat Aug 11 20:37:33 2001 +0000 @@ -79,14 +79,23 @@ void print_index(AVIINDEXENTRY *idx,int idx_size){ int i; + unsigned int pos[256]; + unsigned int num[256]; + for(i=0;i<256;i++) num[i]=pos[i]=0; for(i=0;i<idx_size;i++){ - printf("%5d: %.4s %4X %08X %ld\n",i, + int id=avi_stream_id(idx[i].ckid); + if(id<0 || id>255) id=255; + printf("%5d: %.4s %4X %08X len:%6ld pos:%7d->%7.3f %7d->%7.3f\n",i, (char *)&idx[i].ckid, (unsigned int)idx[i].dwFlags, (unsigned int)idx[i].dwChunkOffset, // idx[i].dwChunkOffset+demuxer->movi_start, - idx[i].dwChunkLength + idx[i].dwChunkLength, + pos[id],(float)pos[id]/18747.0f, + num[id],(float)num[id]/23.976f ); + pos[id]+=idx[i].dwChunkLength; + ++num[id]; } }
--- a/dec_audio.c Sat Aug 11 17:05:35 2001 +0000 +++ b/dec_audio.c Sat Aug 11 20:37:33 2001 +0000 @@ -282,6 +282,7 @@ switch(sh_audio->codec->driver){ case AFM_MPEG: // MPEG layer 2 or 3 len=MP3_DecodeFrame(buf,-1); +// len=MP3_DecodeFrame(buf,3); break; case AFM_PCM: // AVI PCM len=demux_read_data(sh_audio->ds,buf,minlen);
--- a/demux_asf.c Sat Aug 11 17:05:35 2001 +0000 +++ b/demux_asf.c Sat Aug 11 20:37:33 2001 +0000 @@ -37,13 +37,6 @@ // based on asf file-format doc by Eugene [http://divx.euro.ru] -//static float avi_pts_frametime=1.0f/25.0f; -//static float avi_audio_pts=0; -//static float avi_video_pts=0; - -//static int skip_video_frames=0; - - static void asf_descrambling(unsigned char *src,int len){ unsigned char *dst=malloc(len); unsigned char *s2=src;
--- a/demux_avi.c Sat Aug 11 17:05:35 2001 +0000 +++ b/demux_avi.c Sat Aug 11 20:37:33 2001 +0000 @@ -1,4 +1,4 @@ -// AVI file parser for DEMUXER v2.6 by A'rpi/ESP-team +// AVI file parser for DEMUXER v2.9 by A'rpi/ESP-team #include <stdio.h> #include <stdlib.h> @@ -16,11 +16,7 @@ #include "codec-cfg.h" #include "stheader.h" -//static float avi_pts_frametime=1.0f/25.0f; -float avi_audio_pts=0; -float avi_video_pts=0; -//float avi_video_ftime=0.04; -int skip_video_frames=0; +#include "aviheader.h" // Select ds from ID demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){ @@ -58,12 +54,9 @@ return NULL; } -static float pts_correction=0.0; -static int pts_corrected=0; -static int pts_has_video=0; -static unsigned int pts_corr_bytes=0; static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos,int flags){ + avi_priv_t *priv=demux->priv; int skip; float pts=0; demux_stream_t *ds=demux_avi_select_stream(demux,id); @@ -72,50 +65,50 @@ if(ds==demux->audio){ - if(pts_corrected==0){ -// printf("\rYYY-A A: %5.3f V: %5.3f \n",avi_audio_pts,avi_video_pts); - if(pts_has_video){ + if(priv->pts_corrected==0){ +// printf("\rYYY-A A: %5.3f V: %5.3f \n",priv->avi_audio_pts,priv->avi_video_pts); + if(priv->pts_has_video){ // we have video pts now - float delay=(float)pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec; - printf("XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",avi_audio_pts,pts_corr_bytes,delay); - //pts_correction=-avi_audio_pts+delay; - pts_correction=delay-avi_audio_pts; - avi_audio_pts+=pts_correction; - pts_corrected=1; + float delay=(float)priv->pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec; + printf("XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",priv->avi_audio_pts,priv->pts_corr_bytes,delay); + //priv->pts_correction=-priv->avi_audio_pts+delay; + priv->pts_correction=delay-priv->avi_audio_pts; + priv->avi_audio_pts+=priv->pts_correction; + priv->pts_corrected=1; } else - pts_corr_bytes+=len; + priv->pts_corr_bytes+=len; } - pts=avi_audio_pts; //+pts_correction; - avi_audio_pts=0; + pts=priv->avi_audio_pts; //+priv->pts_correction; + priv->avi_audio_pts=0; } else if(ds==demux->video){ // video - if(skip_video_frames>0){ + if(priv->skip_video_frames>0){ // drop frame (seeking) - --skip_video_frames; + --priv->skip_video_frames; ds=NULL; } else { - pts=avi_video_pts; + pts=priv->avi_video_pts; } // ezt a 2 sort lehet hogy fell kell majd cserelni: - //avi_video_pts+=avi_pts_frametime; - //avi_video_pts+=(float)avi_header.video.dwScale/(float)avi_header.video.dwRate; - //avi_video_pts+=((sh_video_t*)ds->sh)->frametime; + //priv->avi_video_pts+=avi_pts_frametime; + //priv->avi_video_pts+=(float)avi_header.video.dwScale/(float)avi_header.video.dwRate; + //priv->avi_video_pts+=((sh_video_t*)ds->sh)->frametime; // FIXME!!! #if 1 // printf("ds=0x%X\n",ds); // printf("packno=%d\n",ds->pack_no); // printf("### pack_no=%d\n",demux->video->pack_no+demux->video->packs); - avi_video_pts = (demux->video->pack_no+demux->video->packs) * + priv->avi_video_pts = (demux->video->pack_no+demux->video->packs) * (float)((sh_video_t*)demux->video->sh)->video.dwScale / (float)((sh_video_t*)demux->video->sh)->video.dwRate; #else - avi_video_pts+=(float)((sh_video_t*)(demux->video->sh))->video.dwScale/(float)((sh_video_t*)(demux->video->sh))->video.dwRate; -// avi_video_pts+=avi_video_ftime; + priv->avi_video_pts+=(float)((sh_video_t*)(demux->video->sh))->video.dwScale/(float)((sh_video_t*)(demux->video->sh))->video.dwRate; +// priv->avi_video_pts+=avi_video_ftime; #endif -// printf("\rYYY-V A: %5.3f V: %5.3f \n",avi_audio_pts,avi_video_pts); - avi_audio_pts=avi_video_pts+pts_correction; - pts_has_video=1; +// printf("\rYYY-V A: %5.3f V: %5.3f \n",priv->avi_audio_pts,priv->avi_video_pts); + priv->avi_audio_pts=priv->avi_video_pts+priv->pts_correction; + priv->pts_has_video=1; } @@ -134,13 +127,11 @@ return ds?1:0; } -//static int num_elementary_packets100=0; -//static int num_elementary_packets101=0; - // return value: // 0 = EOF or no stream found // 1 = successfully read a packet int demux_avi_fill_buffer(demuxer_t *demux){ +avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; int max_packs=128; @@ -157,14 +148,14 @@ } if(stream_eof(demux->stream)) return 0; #endif - if(demux->idx_size>0 && demux->idx_pos<demux->idx_size){ + if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){ unsigned int pos; - //if(demux->idx_pos<0) printf("Fatal! idx_pos=%d\n",demux->idx_pos); + //if(priv->idx_pos<0) printf("Fatal! idx_pos=%d\n",priv->idx_pos); - idx=&((AVIINDEXENTRY *)demux->idx)[demux->idx_pos++]; + idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; - //printf("[%d]",demux->idx_pos);fflush(stdout); + //printf("[%d]",priv->idx_pos);fflush(stdout); //stream_seek(demux->stream,idx.dwChunkOffset); //printf("IDX pos=%X idx.pos=%X idx.size=%X idx.flags=%X\n",demux->filepos, @@ -178,7 +169,7 @@ continue; // skip this chunk } - pos=idx->dwChunkOffset+demux->idx_offset; + pos=idx->dwChunkOffset+priv->idx_offset; if(pos<demux->movi_start || pos>=demux->movi_end){ printf("ChunkOffset out of range! idx=0x%X \n",pos); continue; @@ -222,8 +213,8 @@ continue; } } - ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,flags); - if(!ret && skip_video_frames<=0) + ret=demux_avi_read_packet(demux,id,len,priv->idx_pos-1,flags); + if(!ret && priv->skip_video_frames<=0) if(--max_packs==0){ demux->stream->eof=1; printf("demux: file doesn't contain the selected audio or video stream\n"); @@ -238,6 +229,7 @@ // 0 = EOF or no stream found // 1 = successfully read a packet int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){ +avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; int max_packs=128; @@ -249,14 +241,14 @@ int idx_pos=0; demux->filepos=stream_tell(demux->stream); - if(ds==demux->video) idx_pos=demux->idx_pos_v++; else - if(ds==demux->audio) idx_pos=demux->idx_pos_a++; else - idx_pos=demux->idx_pos++; + if(ds==demux->video) idx_pos=priv->idx_pos_v++; else + if(ds==demux->audio) idx_pos=priv->idx_pos_a++; else + idx_pos=priv->idx_pos++; - if(demux->idx_size>0 && idx_pos<demux->idx_size){ + if(priv->idx_size>0 && idx_pos<priv->idx_size){ unsigned int pos; - idx=&((AVIINDEXENTRY *)demux->idx)[idx_pos]; -// idx=&demux->idx[idx_pos]; + idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos]; +// idx=&priv->idx[idx_pos]; if(idx->dwFlags&AVIIF_LIST){ // LIST @@ -267,7 +259,7 @@ continue; // skip this chunk } - pos=idx->dwChunkOffset+demux->idx_offset; + pos=idx->dwChunkOffset+priv->idx_offset; if(pos<demux->movi_start || pos>=demux->movi_end){ printf("ChunkOffset out of range! current=0x%X idx=0x%X \n",demux->filepos,pos); continue; @@ -299,7 +291,7 @@ if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; } else return 0; ret=demux_avi_read_packet(demux,id,len,idx_pos,flags); - if(!ret && skip_video_frames<=0) + if(!ret && priv->skip_video_frames<=0) if(--max_packs==0){ demux->stream->eof=1; printf("demux: file doesn't contain the selected audio or video stream\n"); @@ -314,13 +306,14 @@ // 0 = EOF or no stream found // 1 = successfully read a packet int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){ +avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; int ret=0; int *fpos=NULL; - if(ds==demux->video) fpos=&demux->idx_pos_v; else - if(ds==demux->audio) fpos=&demux->idx_pos_a; else + if(ds==demux->video) fpos=&priv->idx_pos_v; else + if(ds==demux->audio) fpos=&priv->idx_pos_a; else return 0; stream_seek(demux->stream,fpos[0]); @@ -343,7 +336,7 @@ if(ds==demux_avi_select_stream(demux,id)){ // read it! - ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,0); + ret=demux_avi_read_packet(demux,id,len,priv->idx_pos-1,0); } else { // skip it! int skip=(len+1)&(~1); // total bytes in this chunk @@ -355,9 +348,130 @@ return 1; } -extern float initial_pts_delay; +extern int audio_id; +extern int video_id; +extern int index_mode; // -1=untouched 0=don't use index 1=use (geneate) index +extern int force_ni; +extern int pts_from_bps; + +demuxer_t* demux_open_avi(demuxer_t* demuxer){ + demux_stream_t *d_audio=demuxer->audio; + demux_stream_t *d_video=demuxer->video; + sh_audio_t *sh_audio=NULL; + sh_video_t *sh_video=NULL; + avi_priv_t* priv=malloc(sizeof(avi_priv_t)); + + // priv struct: + priv->avi_audio_pts=priv->avi_video_pts=0.0f; + priv->pts_correction=0.0f; + priv->skip_video_frames=0; + priv->pts_corr_bytes=0; + priv->pts_has_video=priv->pts_corrected=0; + demuxer->priv=(void*)priv; + + //---- AVI header: + read_avi_header(demuxer,(demuxer->stream->type!=STREAMTYPE_STREAM)?index_mode:-2); + stream_reset(demuxer->stream); + stream_seek(demuxer->stream,demuxer->movi_start); + priv->idx_pos=0; + priv->idx_pos_a=0; + priv->idx_pos_v=0; + if(priv->idx_size>0){ + // decide index format: + if(((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start) + priv->idx_offset=demuxer->movi_start-4; + else + priv->idx_offset=0; + if(verbose) printf("AVI index offset: %d\n",priv->idx_offset); + } +// demuxer->endpos=avi_header.movi_end; + + if(priv->idx_size>0){ + // check that file is non-interleaved: + int i; + int a_pos=-1; + int v_pos=-1; + for(i=0;i<priv->idx_size;i++){ + AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)priv->idx)[i]; + demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); + int pos=idx->dwChunkOffset+priv->idx_offset; + if(a_pos==-1 && ds==demuxer->audio){ + a_pos=pos; + if(v_pos!=-1) break; + } + if(v_pos==-1 && ds==demuxer->video){ + v_pos=pos; + if(a_pos!=-1) break; + } + } + if(v_pos==-1){ + fprintf(stderr,"AVI_NI: missing video stream!? contact the author, it may be a bug :(\n"); + return NULL; +// GUI_MSG( mplErrorAVINI ) +// exit(1); + } + if(a_pos==-1){ + printf("AVI_NI: No audio stream found -> nosound\n"); + sh_audio=NULL; + } else { + if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB + printf("%s NON-INTERLEAVED AVI file-format!\n",force_ni?"Forced":"Detected"); + demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!! + pts_from_bps=1; // force BPS sync! + } + } + } else { + // no index + if(force_ni){ + printf("Using NON-INTERLEAVED Broken AVI file-format!\n"); + demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!! + priv->idx_pos_a= + priv->idx_pos_v=demuxer->movi_start; + pts_from_bps=1; // force BPS sync! + } + } + if(!ds_fill_buffer(d_video)){ + fprintf(stderr,"AVI: missing video stream!? contact the author, it may be a bug :(\n"); + return NULL; +// GUI_MSG( mplAVIErrorMissingVideoStream ) +// exit(1); + } + sh_video=d_video->sh;sh_video->ds=d_video; + if(audio_id!=-2){ + if(verbose) printf("AVI: Searching for audio stream (id:%d)\n",d_audio->id); + if(!ds_fill_buffer(d_audio)){ + printf("AVI: No Audio stream found... ->nosound\n"); + sh_audio=NULL; + } else { + sh_audio=d_audio->sh;sh_audio->ds=d_audio; + sh_audio->format=sh_audio->wf->wFormatTag; + } + } + // calc. FPS: + sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; + sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; + // calculating video bitrate: + sh_video->i_bps=demuxer->movi_end-demuxer->movi_start-priv->idx_size*8; + if(sh_audio) sh_video->i_bps-=sh_audio->audio.dwLength; + if(verbose) printf("AVI video length=%d\n",sh_video->i_bps); + sh_video->i_bps=((float)sh_video->i_bps/(float)sh_video->video.dwLength)*sh_video->fps; + printf("VIDEO: [%.4s] %ldx%ld %dbpp %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n", + (char *)&sh_video->bih->biCompression, + sh_video->bih->biWidth, + sh_video->bih->biHeight, + sh_video->bih->biBitCount, + sh_video->fps, + sh_video->i_bps*0.008f, + sh_video->i_bps/1024.0f ); + + return demuxer; + +} + +//extern float initial_pts_delay; void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){ + avi_priv_t *priv=demuxer->priv; demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; sh_audio_t *sh_audio=d_audio->sh; @@ -370,40 +484,40 @@ int video_chunk_pos=d_video->pos; int i; - skip_video_frames=0; - avi_audio_pts=0; + priv->skip_video_frames=0; + priv->avi_audio_pts=0; // ------------ STEP 1: find nearest video keyframe chunk ------------ // find nearest video keyframe chunk pos: if(rel_seek_frames>0){ // seek forward - while(video_chunk_pos<demuxer->idx_size){ - int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid; + while(video_chunk_pos<priv->idx_size){ + int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid; if(avi_stream_id(id)==d_video->id){ // video frame - if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; + if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; } ++video_chunk_pos; } } else { // seek backward while(video_chunk_pos>=0){ - int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid; + int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid; if(avi_stream_id(id)==d_video->id){ // video frame - if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; + if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; } --video_chunk_pos; } } - demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=video_chunk_pos; + priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=video_chunk_pos; // re-calc video pts: d_video->pack_no=0; for(i=0;i<video_chunk_pos;i++){ - int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid; + int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; if(avi_stream_id(id)==d_video->id) ++d_video->pack_no; } sh_video->num_frames=d_video->pack_no; - avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; + priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; d_video->pos=video_chunk_pos; // ------------ STEP 2: seek audio, find the right chunk & pos ------------ @@ -419,28 +533,28 @@ int skip_audio_bytes=0; int curr_audio_pos=-1; int audio_chunk_pos=-1; - int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:demuxer->idx_size; + int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size; if(sh_audio->audio.dwSampleSize){ // constant rate audio stream #if 0 int align; - curr_audio_pos=(avi_video_pts) * sh_audio->wf->nAvgBytesPerSec; + curr_audio_pos=(priv->avi_video_pts) * sh_audio->wf->nAvgBytesPerSec; if(curr_audio_pos<0)curr_audio_pos=0; align=sh_audio->audio.dwSampleSize; if(sh_audio->wf->nBlockAlign>align) align=sh_audio->wf->nBlockAlign; curr_audio_pos/=align; curr_audio_pos*=align; #else - curr_audio_pos=(avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; + curr_audio_pos=(priv->avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; curr_audio_pos*=sh_audio->audio.dwSampleSize; #endif // find audio chunk pos: for(i=0;i<chunk_max;i++){ - int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid; + int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; if(avi_stream_id(id)==d_audio->id){ - len=((AVIINDEXENTRY *)demuxer->idx)[i].dwChunkLength; + len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; audio_chunk_pos=i; ++d_audio->pack_no; if(d_audio->dpos<=curr_audio_pos && curr_audio_pos<(d_audio->dpos+len)){ //if(verbose)printf("break;\n"); @@ -453,14 +567,14 @@ } else { // VBR audio - int chunks=(avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; + int chunks=(priv->avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; audio_chunk_pos=0; // find audio chunk pos: - for(i=0;i<demuxer->idx_size && chunks>0;i++){ - int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid; + for(i=0;i<priv->idx_size && chunks>0;i++){ + int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; if(avi_stream_id(id)==d_audio->id){ - len=((AVIINDEXENTRY *)demuxer->idx)[i].dwChunkLength; + len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; if(i>chunk_max){ skip_audio_bytes+=len; } else { @@ -474,7 +588,7 @@ //if(audio_chunk_pos>chunk_max) audio_chunk_pos=chunk_max; // printf("VBR seek: %5.3f -> chunk_no %d -> chunk_idx %d + skip %d \n", -// avi_video_pts, audio_chunk_pos, ); +// priv->avi_video_pts, audio_chunk_pos, ); } @@ -493,25 +607,25 @@ if(demuxer->type==DEMUXER_TYPE_AVI){ // interleaved stream: if(audio_chunk_pos<video_chunk_pos){ - // calc skip_video_frames & adjust video pts counter: + // calc priv->skip_video_frames & adjust video pts counter: for(i=audio_chunk_pos;i<video_chunk_pos;i++){ - int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid; - if(avi_stream_id(id)==d_video->id) ++skip_video_frames; + int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; + if(avi_stream_id(id)==d_video->id) ++priv->skip_video_frames; } // requires for correct audio pts calculation (demuxer): - avi_video_pts-=skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; - demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=audio_chunk_pos; + priv->avi_video_pts-=priv->skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; + priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=audio_chunk_pos; } } else { // non-interleaved stream: - demuxer->idx_pos_a=audio_chunk_pos; - demuxer->idx_pos_v=video_chunk_pos; - demuxer->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos; + priv->idx_pos_a=audio_chunk_pos; + priv->idx_pos_v=video_chunk_pos; + priv->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos; } if(verbose) printf("SEEK: idx=%d (a:%d v:%d) v.skip=%d a.skip=%d/%4.3f \n", - demuxer->idx_pos,audio_chunk_pos,video_chunk_pos, - skip_video_frames,skip_audio_bytes,skip_audio_secs); + priv->idx_pos,audio_chunk_pos,video_chunk_pos, + priv->skip_video_frames,skip_audio_bytes,skip_audio_secs); if(skip_audio_bytes){ demux_read_data(d_audio,NULL,skip_audio_bytes);
--- a/demuxer.c Sat Aug 11 17:05:35 2001 +0000 +++ b/demuxer.c Sat Aug 11 20:37:33 2001 +0000 @@ -294,7 +294,6 @@ // commandline options, flags: extern int seek_to_byte; -extern int index_mode; // -1=untouched 0=don't use index 1=use (geneate) index extern int force_ni; extern int pts_from_bps; @@ -391,8 +390,8 @@ printf("Detected MPEG-ES file format!\n"); } } -#ifdef MOV //=============== Try to open as MOV file: ================= +#if 0 if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){ stream_reset(stream); demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id); @@ -416,110 +415,19 @@ d_video=demuxer->video; //d_dvdsub=demuxer->sub; +demuxer->file_format=file_format; + switch(file_format){ case DEMUXER_TYPE_AVI: { - //---- AVI header: - read_avi_header(demuxer,(stream->type!=STREAMTYPE_STREAM)?index_mode:-2); - stream_reset(demuxer->stream); - stream_seek(demuxer->stream,demuxer->movi_start); - demuxer->idx_pos=0; - demuxer->idx_pos_a=0; - demuxer->idx_pos_v=0; - if(demuxer->idx_size>0){ - // decide index format: - if(((AVIINDEXENTRY *)demuxer->idx)[0].dwChunkOffset<demuxer->movi_start) - demuxer->idx_offset=demuxer->movi_start-4; - else - demuxer->idx_offset=0; - if(verbose) printf("AVI index offset: %d\n",demuxer->idx_offset); - } -// demuxer->endpos=avi_header.movi_end; - - if(demuxer->idx_size>0){ - // check that file is non-interleaved: - int i; - int a_pos=-1; - int v_pos=-1; - for(i=0;i<demuxer->idx_size;i++){ - AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)demuxer->idx)[i]; - demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); - int pos=idx->dwChunkOffset+demuxer->idx_offset; - if(a_pos==-1 && ds==demuxer->audio){ - a_pos=pos; - if(v_pos!=-1) break; - } - if(v_pos==-1 && ds==demuxer->video){ - v_pos=pos; - if(a_pos!=-1) break; - } - } - if(v_pos==-1){ - fprintf(stderr,"AVI_NI: missing video stream!? contact the author, it may be a bug :(\n"); - return NULL; -// GUI_MSG( mplErrorAVINI ) -// exit(1); - } - if(a_pos==-1){ - printf("AVI_NI: No audio stream found -> nosound\n"); - sh_audio=NULL; - } else { - if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB - printf("%s NON-INTERLEAVED AVI file-format!\n",force_ni?"Forced":"Detected"); - demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!! - pts_from_bps=1; // force BPS sync! - } - } - } else { - // no index - if(force_ni){ - printf("Using NON-INTERLEAVED Broken AVI file-format!\n"); - demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!! - demuxer->idx_pos_a= - demuxer->idx_pos_v=demuxer->movi_start; - pts_from_bps=1; // force BPS sync! - } - } - if(!ds_fill_buffer(d_video)){ - fprintf(stderr,"AVI: missing video stream!? contact the author, it may be a bug :(\n"); - return NULL; -// GUI_MSG( mplAVIErrorMissingVideoStream ) -// exit(1); - } - sh_video=d_video->sh;sh_video->ds=d_video; - if(audio_id!=-2){ - if(verbose) printf("AVI: Searching for audio stream (id:%d)\n",d_audio->id); - if(!ds_fill_buffer(d_audio)){ - printf("AVI: No Audio stream found... ->nosound\n"); - sh_audio=NULL; - } else { - sh_audio=d_audio->sh;sh_audio->ds=d_audio; - sh_audio->format=sh_audio->wf->wFormatTag; - } - } - // calc. FPS: - sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; - sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; - // calculating video bitrate: - sh_video->i_bps=demuxer->movi_end-demuxer->movi_start-demuxer->idx_size*8; - if(sh_audio) sh_video->i_bps-=sh_audio->audio.dwLength; - if(verbose) printf("AVI video length=%d\n",sh_video->i_bps); - sh_video->i_bps=((float)sh_video->i_bps/(float)sh_video->video.dwLength)*sh_video->fps; - printf("VIDEO: [%.4s] %ldx%ld %dbpp %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n", - (char *)&sh_video->bih->biCompression, - sh_video->bih->biWidth, - sh_video->bih->biHeight, - sh_video->bih->biBitCount, - sh_video->fps, - sh_video->i_bps*0.008f, - sh_video->i_bps/1024.0f ); - break; + return demux_open_avi(demuxer); +// break; } case DEMUXER_TYPE_ASF: { //---- ASF header: read_asf_header(demuxer); stream_reset(demuxer->stream); stream_seek(demuxer->stream,demuxer->movi_start); - demuxer->idx_pos=0; +// demuxer->idx_pos=0; // demuxer->endpos=avi_header.movi_end; if(!ds_fill_buffer(d_video)){ printf("ASF: no video stream found!\n"); @@ -575,6 +483,5 @@ } } // switch(file_format) -demuxer->file_format=file_format; return demuxer; }
--- a/demuxer.h Sat Aug 11 17:05:35 2001 +0000 +++ b/demuxer.h Sat Aug 11 20:37:33 2001 +0000 @@ -22,7 +22,7 @@ typedef struct demux_packet_st { int len; float pts; - off_t pos; // pozicio indexben (AVI) ill. fileban (MPG) + off_t pos; // position in index (AVI) or file (MPG) unsigned char* buffer; int flags; // keyframe, etc struct demux_packet_st* next; @@ -59,30 +59,19 @@ off_t filepos; // input stream current pos. int type; // demuxer type: mpeg PS, mpeg ES, avi, avi-ni, avi-nini, asf int file_format; // file format: mpeg/avi/asf -// int time_src;// time source (pts/file/bps) off_t movi_start; off_t movi_end; // - demux_stream_t *audio; - demux_stream_t *video; - demux_stream_t *sub; - - // index: -// AVIINDEXENTRY* idx; -// FIXME: off_t??? - void* idx; - int idx_size; - int idx_pos; - int idx_pos_a; - int idx_pos_v; - int idx_offset; // ennyit kell hozzaadni az index offset ertekekhez + demux_stream_t *audio; // audio buffer/demuxer + demux_stream_t *video; // video buffer/demuxer + demux_stream_t *sub; // dvd subtitle buffer/demuxer // stream headers: -// sh_audio_t* a_streams[256]; -// sh_video_t* v_streams[256]; - void* a_streams[256]; - void* v_streams[256]; - char s_streams[32]; // dvd subtitles + void* a_streams[256]; // audio streams (sh_audio_t) + void* v_streams[256]; // video sterams (sh_video_t) + char s_streams[32]; // dvd subtitles (flag) + + void* priv; // fileformat-dependent data } demuxer_t; inline static demux_packet_t* new_demux_packet(int len){
--- a/mplayer.c Sat Aug 11 17:05:35 2001 +0000 +++ b/mplayer.c Sat Aug 11 20:37:33 2001 +0000 @@ -150,11 +150,6 @@ extern int asf_packetsize; // for seeking -extern float avi_audio_pts; -extern float avi_video_pts; -extern float avi_video_ftime; -extern int skip_video_frames; - void read_avi_header(demuxer_t *demuxer,int index_mode); demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id); @@ -1362,7 +1357,7 @@ else // VBR: a_pts=d_audio->pack_no*(float)sh_audio->audio.dwScale/(float)sh_audio->audio.dwRate; v_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; - if(verbose)printf("%5.3f|",v_pts-d_video->pts); +// if(verbose)printf("%5.3f|",v_pts-d_video->pts); } else { if(!delay_corrected && d_audio->pts){ // float x=d_audio->pts-d_video->pts-(delay);
--- a/seek.c Sat Aug 11 17:05:35 2001 +0000 +++ b/seek.c Sat Aug 11 20:37:33 2001 +0000 @@ -22,11 +22,6 @@ //extern int asf_packetsize; // for seeking -//extern float avi_audio_pts; -//extern float avi_video_pts; -//extern float avi_video_ftime; -//extern int skip_video_frames; -//extern int seek_to_byte; //extern char* current_module; // for debugging // flags: @@ -44,10 +39,10 @@ sh_video_t *sh_video=d_video->sh; // float skip_audio_secs=0; -if(demuxer->file_format==DEMUXER_TYPE_AVI && demuxer->idx_size<=0){ - printf("Can't seek in raw .AVI streams! (index required, try with the -idx switch!) \n"); - return 0; -} +//if(demuxer->file_format==DEMUXER_TYPE_AVI && demuxer->idx_size<=0){ +// printf("Can't seek in raw .AVI streams! (index required, try with the -idx switch!) \n"); +// return 0; +//} // current_module="seek";