changeset 6056:f980563afdbc

big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
author arpi
date Sun, 12 May 2002 01:51:09 +0000
parents 3ca1f8cf7bfc
children 31e465fda59c
files libmpdemux/aviheader.c libmpdemux/aviheader.h libmpdemux/demux_avi.c
diffstat 3 files changed, 66 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/aviheader.c	Sun May 12 01:41:24 2002 +0000
+++ b/libmpdemux/aviheader.c	Sun May 12 01:51:09 2002 +0000
@@ -39,22 +39,28 @@
 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 @@
     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 @@
       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 @@
         }
       } 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 @@
       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 @@
       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 @@
   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 @@
     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 @@
       }
 
     // 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(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 @@
     }
 #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;
--- a/libmpdemux/aviheader.h	Sun May 12 01:41:24 2002 +0000
+++ b/libmpdemux/aviheader.h	Sun May 12 01:51:09 2002 +0000
@@ -89,10 +89,10 @@
   // 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;
--- a/libmpdemux/demux_avi.c	Sun May 12 01:41:24 2002 +0000
+++ b/libmpdemux/demux_avi.c	Sun May 12 01:51:09 2002 +0000
@@ -46,6 +46,7 @@
   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 @@
   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 @@
       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 @@
     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 @@
                        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 @@
       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 @@
 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 @@
       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 @@
   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 @@
   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 @@
   // 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,