comparison libmpdemux/demux_avi.c @ 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 0f1b5b68af32
children 76e81f47bce2
comparison
equal deleted inserted replaced
29870:eeb60773d668 29871:a90c7676bf0e
104 unsigned char* fcc=(unsigned char*)(&id); 104 unsigned char* fcc=(unsigned char*)(&id);
105 return strchr(valid, fcc[0]) && strchr(valid, fcc[1]) && 105 return strchr(valid, fcc[0]) && strchr(valid, fcc[1]) &&
106 strchr(valid, fcc[2]) && strchr(valid, fcc[3]); 106 strchr(valid, fcc[2]) && strchr(valid, fcc[3]);
107 } 107 }
108 108
109 static int valid_stream_id(unsigned int id) {
110 unsigned char* fcc=(unsigned char*)(&id);
111 return fcc[0] >= '0' && fcc[0] <= '9' && fcc[1] >= '0' && fcc[1] <= '9' &&
112 ((fcc[2] == 'w' && fcc[3] == 'b') || (fcc[2] == 'd' && fcc[3] == 'c'));
113 }
114
109 static int choose_chunk_len(unsigned int len1,unsigned int len2){ 115 static int choose_chunk_len(unsigned int len1,unsigned int len2){
110 // len1 has a bit more priority than len2. len1!=len2 116 // len1 has a bit more priority than len2. len1!=len2
111 // Note: this is a first-idea-logic, may be wrong. comments welcomed. 117 // Note: this is a first-idea-logic, may be wrong. comments welcomed.
112 118
113 // prefer small frames rather than 0 119 // prefer small frames rather than 0
216 off_t pos; 222 off_t pos;
217 223
218 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; 224 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
219 225
220 if(idx->dwFlags&AVIIF_LIST){ 226 if(idx->dwFlags&AVIIF_LIST){
227 if (!valid_stream_id(idx->ckid))
221 // LIST 228 // LIST
222 continue; 229 continue;
230 if (!priv->warned_unaligned)
231 mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n");
232 priv->warned_unaligned = 1;
223 } 233 }
224 if(!demux_avi_select_stream(demux,idx->ckid)){ 234 if(!demux_avi_select_stream(demux,idx->ckid)){
225 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); 235 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid);
226 continue; // skip this chunk 236 continue; // skip this chunk
227 } 237 }
315 if(priv->idx_size>0 && idx_pos<priv->idx_size){ 325 if(priv->idx_size>0 && idx_pos<priv->idx_size){
316 off_t pos; 326 off_t pos;
317 idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos]; 327 idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos];
318 328
319 if(idx->dwFlags&AVIIF_LIST){ 329 if(idx->dwFlags&AVIIF_LIST){
330 if (!valid_stream_id(idx->ckid))
320 // LIST 331 // LIST
321 continue; 332 continue;
333 if (!priv->warned_unaligned)
334 mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n");
335 priv->warned_unaligned = 1;
322 } 336 }
323 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){ 337 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){
324 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); 338 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid);
325 continue; // skip this chunk 339 continue; // skip this chunk
326 } 340 }
435 priv->audio_block_no=0; 449 priv->audio_block_no=0;
436 priv->audio_block_size=0; 450 priv->audio_block_size=0;
437 priv->isodml = 0; 451 priv->isodml = 0;
438 priv->suidx_size = 0; 452 priv->suidx_size = 0;
439 priv->suidx = NULL; 453 priv->suidx = NULL;
454 priv->warned_unaligned = 0;
440 455
441 demuxer->priv=(void*)priv; 456 demuxer->priv=(void*)priv;
442 457
443 //---- AVI header: 458 //---- AVI header:
444 read_avi_header(demuxer,(demuxer->stream->flags & STREAM_SEEK_BW)?index_mode:-2); 459 read_avi_header(demuxer,(demuxer->stream->flags & STREAM_SEEK_BW)?index_mode:-2);