1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-19 05:15:12 +00:00

big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6057 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
arpi 2002-05-12 01:51:09 +00:00
parent db43a6edeb
commit fbba89f83b
3 changed files with 66 additions and 39 deletions

View File

@ -39,22 +39,28 @@ priv->idx_size=0;
priv->audio_streams=0;
while(1){
int id=stream_read_dword_le(demuxer->stream);
int chunksize,size2;
unsigned chunksize,size2;
static int last_fccType=0;
char* hdr=NULL;
//
if(stream_eof(demuxer->stream)) break;
//
if(id==mmioFOURCC('L','I','S','T')){
int len=stream_read_dword_le(demuxer->stream)-4; // list size
id=stream_read_dword_le(demuxer->stream); // list type
mp_msg(MSGT_HEADER,MSGL_DBG2,"LIST %.4s len=%d\n",(char *) &id,len);
list_end=stream_tell(demuxer->stream)+((len+1)&(~1));
unsigned len=stream_read_dword_le(demuxer->stream); // list size
id=stream_read_dword_le(demuxer->stream); // list type
mp_msg(MSGT_HEADER,MSGL_DBG2,"LIST %.4s len=%u\n",(char *) &id,len);
if(len >= 4) {
len -= 4;
list_end=stream_tell(demuxer->stream)+((len+1)&(~1));
} else {
mp_msg(MSGT_HEADER,MSGL_WARN,"** empty list?!\n");
list_end = 0;
}
mp_msg(MSGT_HEADER,MSGL_V,"list_end=0x%X\n",(int)list_end);
if(id==listtypeAVIMOVIE){
// found MOVI header
if(!demuxer->movi_start) demuxer->movi_start=stream_tell(demuxer->stream);
demuxer->movi_end=demuxer->movi_start+len;
demuxer->movi_end=stream_tell(demuxer->stream)+len;
mp_msg(MSGT_HEADER,MSGL_V,"Found movie at 0x%X - 0x%X\n",(int)demuxer->movi_start,(int)demuxer->movi_end);
if(demuxer->stream->end_pos) demuxer->movi_end=demuxer->stream->end_pos;
if(index_mode==-2 || index_mode==2 || index_mode==0)
@ -65,7 +71,7 @@ while(1){
continue;
}
size2=stream_read_dword_le(demuxer->stream);
mp_msg(MSGT_HEADER,MSGL_DBG2,"CHUNK %.4s len=%d\n",(char *) &id,size2);
mp_msg(MSGT_HEADER,MSGL_DBG2,"CHUNK %.4s len=%u\n",(char *) &id,size2);
chunksize=(size2+1)&(~1);
switch(id){
@ -173,7 +179,7 @@ while(1){
if(last_fccType==streamtypeVIDEO){
sh_video->bih=calloc((chunksize<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):chunksize,1);
// sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
mp_msg(MSGT_HEADER,MSGL_V,"found 'bih', %d bytes of %d\n",chunksize,sizeof(BITMAPINFOHEADER));
mp_msg(MSGT_HEADER,MSGL_V,"found 'bih', %u bytes of %d\n",chunksize,sizeof(BITMAPINFOHEADER));
stream_read(demuxer->stream,(char*) sh_video->bih,chunksize);
le2me_BITMAPINFOHEADER(sh_video->bih); // swap to machine endian
// fixup MS-RLE header (seems to be broken for <256 color files)
@ -212,7 +218,7 @@ while(1){
}
} else
if(last_fccType==streamtypeAUDIO){
int wf_size = chunksize<sizeof(WAVEFORMATEX)?sizeof(WAVEFORMATEX):chunksize;
unsigned wf_size = chunksize<sizeof(WAVEFORMATEX)?sizeof(WAVEFORMATEX):chunksize;
sh_audio->wf=calloc(wf_size,1);
// sh_audio->wf=malloc(chunksize); memset(sh_audio->wf,0,chunksize);
mp_msg(MSGT_HEADER,MSGL_V,"found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
@ -245,9 +251,21 @@ while(1){
if(verbose>=2) print_index(priv->idx,priv->idx_size);
break;
}
/* added May 2002 */
case mmioFOURCC('R','I','F','F'): {
char riff_type[4];
mp_msg(MSGT_HEADER, MSGL_V, "additional RIFF header...\n");
stream_read(demuxer->stream, riff_type, sizeof riff_type);
if (strncmp(riff_type, "AVIX", sizeof riff_type))
mp_msg(MSGT_HEADER, MSGL_WARN,
"** warning: this is no extended AVI header..\n");
chunksize = 0;
list_end = 0; /* a new list will follow */
break; }
}
if(hdr){
mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s size=%d\n",hdr,size2);
mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s size=%u\n",hdr,size2);
if(size2==3)
chunksize=1; // empty
else {
@ -269,7 +287,7 @@ while(1){
list_end=0;
} else
if(chunksize>0) stream_skip(demuxer->stream,chunksize); else
if(chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%d (id=%.4s)\n",chunksize,(char *) &id);
if((int)chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%u (id=%.4s)\n",chunksize,(char *) &id);
}
@ -283,15 +301,17 @@ if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
priv->idx=NULL;
while(1){
int id,len,skip;
int id;
unsigned len;
off_t skip;
AVIINDEXENTRY* idx;
unsigned int c;
demuxer->filepos=stream_tell(demuxer->stream);
if(demuxer->filepos>=demuxer->movi_end && demuxer->movi_start<demuxer->movi_end) break;
id=stream_read_dword_le(demuxer->stream);
len=stream_read_dword_le(demuxer->stream);
if(id==mmioFOURCC('L','I','S','T')){
id=stream_read_dword_le(demuxer->stream); // list type
if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){
id=stream_read_dword_le(demuxer->stream); // list or RIFF type
continue;
}
if(stream_eof(demuxer->stream)) break;
@ -306,7 +326,7 @@ if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
idx->ckid=id;
idx->dwFlags=AVIIF_KEYFRAME; // FIXME
idx->dwChunkOffset=demuxer->filepos;
idx->dwChunkOffset=(unsigned long)demuxer->filepos;
idx->dwChunkLength=len;
c=stream_read_dword(demuxer->stream);
@ -321,8 +341,8 @@ if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
}
// update status line:
{ static int lastpos;
int pos;
{ static off_t lastpos;
off_t pos;
off_t len=demuxer->movi_end-demuxer->movi_start;
if(len){
pos=100*(demuxer->filepos-demuxer->movi_start)/len; // %
@ -331,11 +351,11 @@ if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
}
if(pos!=lastpos){
lastpos=pos;
mp_msg(MSGT_HEADER,MSGL_STATUS,"Generating Index: %3d %s \r",
pos, len?"%":"MB");
mp_msg(MSGT_HEADER,MSGL_STATUS,"Generating Index: %3lu %s \r",
(unsigned long)pos, len?"%":"MB");
}
}
mp_dbg(MSGT_HEADER,MSGL_DBG2,"%08X %08X %.4s %08X %X\n",(int)demuxer->filepos,id,(char *) &id,(int)c,(unsigned int) idx->dwFlags);
mp_dbg(MSGT_HEADER,MSGL_DBG2,"%08X %08X %.4s %08X %X\n",(unsigned int)demuxer->filepos,id,(char *) &id,(int)c,(unsigned int) idx->dwFlags);
#if 0
{ unsigned char tmp[64];
int i;
@ -346,7 +366,7 @@ if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
}
#endif
skip_chunk:
skip=(len+1)&(~1); // total bytes in this chunk
skip=(len+1)&(~1UL); // total bytes in this chunk
stream_seek(demuxer->stream,8+demuxer->filepos+skip);
}
priv->idx_size=priv->idx_pos;

View File

@ -89,10 +89,10 @@ 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
off_t idx_pos;
off_t idx_pos_a;
off_t idx_pos_v;
off_t idx_offset; // ennyit kell hozzaadni az index offset ertekekhez
// interleaved PTS stuff:
int skip_video_frames;
int audio_streams;

View File

@ -46,6 +46,7 @@ demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){
if(id!=mmioFOURCC('J','U','N','K')){
// unknown
mp_msg(MSGT_DEMUX,MSGL_DBG2,"Unknown chunk: %.4s (%X)\n",(char *) &id,id);
//abort();
}
return NULL;
}
@ -173,7 +174,7 @@ do{
if(stream_eof(demux->stream)) return 0;
#endif
if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){
unsigned int pos;
off_t pos;
//if(priv->idx_pos<0) printf("Fatal! idx_pos=%d\n",priv->idx_pos);
@ -193,7 +194,7 @@ do{
continue; // skip this chunk
}
pos=idx->dwChunkOffset+priv->idx_offset;
pos = priv->idx_offset + (unsigned long)idx->dwChunkOffset;
if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start)){
mp_msg(MSGT_DEMUX,MSGL_V,"ChunkOffset out of range! idx=0x%X \n",pos);
continue;
@ -234,8 +235,8 @@ do{
len=stream_read_dword_le(demux->stream);
if(stream_eof(demux->stream)) return 0; // EOF!
if(id==mmioFOURCC('L','I','S','T')){
id=stream_read_dword_le(demux->stream); // list type
if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){
id=stream_read_dword_le(demux->stream); // list or RIFF type
continue;
}
}
@ -272,7 +273,7 @@ do{
idx_pos=priv->idx_pos++;
if(priv->idx_size>0 && idx_pos<priv->idx_size){
unsigned int pos;
off_t pos;
idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos];
// idx=&priv->idx[idx_pos];
@ -285,7 +286,7 @@ do{
continue; // skip this chunk
}
pos=idx->dwChunkOffset+priv->idx_offset;
pos = priv->idx_offset+(unsigned long)idx->dwChunkOffset;
if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start)){
mp_msg(MSGT_DEMUX,MSGL_V,"ChunkOffset out of range! current=0x%X idx=0x%X \n",demux->filepos,pos);
continue;
@ -338,7 +339,7 @@ avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
int ret=0;
int *fpos=NULL;
off_t *fpos=NULL;
if(ds==demux->video) fpos=&priv->idx_pos_v; else
if(ds==demux->audio) fpos=&priv->idx_pos_a; else
@ -362,6 +363,12 @@ do{
continue;
}
if(id==mmioFOURCC('R','I','F','F')){
printf("additional RIFF header...\n");
id=stream_read_dword_le(demux->stream); // "AVIX"
continue;
}
if(ds==demux_avi_select_stream(demux,id)){
// read it!
ret=demux_avi_read_packet(demux,id,len,priv->idx_pos-1,0);
@ -420,13 +427,13 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer){
if(priv->idx_size>1){
// decide index format:
#if 1
if(((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start ||
((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset<demuxer->movi_start)
if((unsigned long)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start ||
(unsigned long)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset<demuxer->movi_start)
priv->idx_offset=demuxer->movi_start-4;
else
priv->idx_offset=0;
#else
if(((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start)
if((unsigned long)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start)
priv->idx_offset=demuxer->movi_start-4;
else
priv->idx_offset=0;
@ -441,12 +448,12 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer){
if(priv->idx_size>0){
// check that file is non-interleaved:
int i;
int a_pos=-1;
int v_pos=-1;
off_t a_pos=-1;
off_t 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;
off_t pos = priv->idx_offset + (unsigned long)idx->dwChunkOffset;
if(a_pos==-1 && ds==demuxer->audio){
a_pos=pos;
if(v_pos!=-1) break;
@ -504,7 +511,7 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer){
// 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;
mp_msg(MSGT_DEMUX,MSGL_V,"AVI video length=%d\n",sh_video->i_bps);
mp_msg(MSGT_DEMUX,MSGL_V,"AVI video length=%lu\n",(unsigned long)sh_video->i_bps);
sh_video->i_bps=((float)sh_video->i_bps/(float)sh_video->video.dwLength)*sh_video->fps;
mp_msg(MSGT_DEMUX,MSGL_INFO,"VIDEO: [%.4s] %ldx%ld %dbpp %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n",
(char *)&sh_video->bih->biCompression,