changeset 29871:a90c7676bf0e

Try to detect broken files with unaligned chunks. This patch hopefully makes them playable as long as they have and index without breaking any other files. Fixes http://samples.mplayerhq.hu/avi/invalid_unaligned.avi with native demuxer.
author reimar
date Mon, 16 Nov 2009 10:41:06 +0000
parents eeb60773d668
children 76e81f47bce2
files libmpdemux/aviheader.h libmpdemux/demux_avi.c
diffstat 2 files changed, 16 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/aviheader.h	Sat Nov 14 12:46:14 2009 +0000
+++ b/libmpdemux/aviheader.h	Mon Nov 16 10:41:06 2009 +0000
@@ -367,6 +367,7 @@
   avisuperindex_chunk *suidx;
   int suidx_size;
   int isodml;
+  int warned_unaligned;
 } avi_priv_t;
 
 #define AVI_PRIV ((avi_priv_t*)(demuxer->priv))
--- a/libmpdemux/demux_avi.c	Sat Nov 14 12:46:14 2009 +0000
+++ b/libmpdemux/demux_avi.c	Mon Nov 16 10:41:06 2009 +0000
@@ -106,6 +106,12 @@
            strchr(valid, fcc[2]) && strchr(valid, fcc[3]);
 }
 
+static int valid_stream_id(unsigned int id) {
+    unsigned char* fcc=(unsigned char*)(&id);
+    return fcc[0] >= '0' && fcc[0] <= '9' && fcc[1] >= '0' && fcc[1] <= '9' &&
+           ((fcc[2] == 'w' && fcc[3] == 'b') || (fcc[2] == 'd' && fcc[3] == 'c'));
+}
+
 static int choose_chunk_len(unsigned int len1,unsigned int len2){
     // len1 has a bit more priority than len2. len1!=len2
     // Note: this is a first-idea-logic, may be wrong. comments welcomed.
@@ -218,8 +224,12 @@
     idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
 
     if(idx->dwFlags&AVIIF_LIST){
+      if (!valid_stream_id(idx->ckid))
       // LIST
       continue;
+      if (!priv->warned_unaligned)
+        mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n");
+      priv->warned_unaligned = 1;
     }
     if(!demux_avi_select_stream(demux,idx->ckid)){
       mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X)  \n",(char *)&idx->ckid,(unsigned int)idx->ckid);
@@ -317,8 +327,12 @@
     idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos];
 
     if(idx->dwFlags&AVIIF_LIST){
+      if (!valid_stream_id(idx->ckid))
       // LIST
       continue;
+      if (!priv->warned_unaligned)
+        mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n");
+      priv->warned_unaligned = 1;
     }
     if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){
       mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X)  \n",(char *)&idx->ckid,(unsigned int)idx->ckid);
@@ -437,6 +451,7 @@
   priv->isodml = 0;
   priv->suidx_size = 0;
   priv->suidx = NULL;
+  priv->warned_unaligned = 0;
 
   demuxer->priv=(void*)priv;