Mercurial > mplayer.hg
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); |