Mercurial > mplayer.hg
comparison libmpdemux/demux_avi.c @ 2438:561a7b13220a
better logic to choose valid info at broken index
author | arpi |
---|---|
date | Wed, 24 Oct 2001 00:25:52 +0000 |
parents | 4f3e8c8ea32f |
children | 022a7e7fec2d |
comparison
equal
deleted
inserted
replaced
2437:de434f02dee6 | 2438:561a7b13220a |
---|---|
46 if(id!=mmioFOURCC('J','U','N','K')){ | 46 if(id!=mmioFOURCC('J','U','N','K')){ |
47 // unknown | 47 // unknown |
48 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Unknown chunk: %.4s (%X)\n",(char *) &id,id); | 48 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Unknown chunk: %.4s (%X)\n",(char *) &id,id); |
49 } | 49 } |
50 return NULL; | 50 return NULL; |
51 } | |
52 | |
53 static int valid_fourcc(unsigned int id){ | |
54 unsigned char* fcc=(unsigned char*)(&id); | |
55 #define FCC_CHR_CHECK(x) (x<48 || x>=96) | |
56 if(FCC_CHR_CHECK(fcc[0])) return 0; | |
57 if(FCC_CHR_CHECK(fcc[1])) return 0; | |
58 if(FCC_CHR_CHECK(fcc[2])) return 0; | |
59 if(FCC_CHR_CHECK(fcc[3])) return 0; | |
60 return 1; | |
61 #undef FCC_CHR_CHECK | |
62 } | |
63 | |
64 static int choose_chunk_len(unsigned int len1,unsigned int len2){ | |
65 // len1 has a bit more priority than len2. len1!=len2 | |
66 // Note: this is a first-idea-logic, may be wrong. comments welcomed. | |
67 | |
68 // prefer small frames rather than 0 | |
69 if(!len1) return (len2>0x80000) ? len1 : len2; | |
70 if(!len2) return (len1>0x100000) ? len2 : len1; | |
71 | |
72 // choose the smaller value: | |
73 return (len1<len2)? len1 : len2; | |
51 } | 74 } |
52 | 75 |
53 static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos,int flags){ | 76 static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos,int flags){ |
54 avi_priv_t *priv=demux->priv; | 77 avi_priv_t *priv=demux->priv; |
55 int skip; | 78 int skip; |
183 id=stream_read_dword_le(demux->stream); | 206 id=stream_read_dword_le(demux->stream); |
184 if(stream_eof(demux->stream)) return 0; // EOF! | 207 if(stream_eof(demux->stream)) return 0; // EOF! |
185 | 208 |
186 if(id!=idx->ckid){ | 209 if(id!=idx->ckid){ |
187 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); | 210 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
188 id=idx->ckid; | 211 if(valid_fourcc(idx->ckid)) |
189 // continue; | 212 id=idx->ckid; // use index if valid |
213 else | |
214 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
190 } | 215 } |
191 len=stream_read_dword_le(demux->stream); | 216 len=stream_read_dword_le(demux->stream); |
192 // if((len&(~1))!=(idx->dwChunkLength&(~1))){ | 217 // if((len&(~1))!=(idx->dwChunkLength&(~1))){ |
193 // if((len)!=(idx->dwChunkLength)){ | 218 // if((len)!=(idx->dwChunkLength)){ |
194 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | 219 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ |
195 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); | 220 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); |
196 len=idx->dwChunkLength; | 221 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
197 // continue; | 222 len=choose_chunk_len(idx->dwChunkLength,len); |
198 } | 223 } |
199 if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; | 224 if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; |
200 } else { | 225 } else { |
201 demux->filepos=stream_tell(demux->stream); | 226 demux->filepos=stream_tell(demux->stream); |
202 if(demux->filepos>=demux->movi_end){ | 227 if(demux->filepos>=demux->movi_end){ |
274 | 299 |
275 if(stream_eof(demux->stream)) return 0; | 300 if(stream_eof(demux->stream)) return 0; |
276 | 301 |
277 if(id!=idx->ckid){ | 302 if(id!=idx->ckid){ |
278 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); | 303 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
279 id=idx->ckid; | 304 if(valid_fourcc(idx->ckid)) |
280 // continue; | 305 id=idx->ckid; // use index if valid |
306 else | |
307 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
281 } | 308 } |
282 len=stream_read_dword_le(demux->stream); | 309 len=stream_read_dword_le(demux->stream); |
283 // if((len&(~1))!=(idx->dwChunkLength&(~1))){ | 310 // if((len&(~1))!=(idx->dwChunkLength&(~1))){ |
284 // if((len)!=(idx->dwChunkLength)){ | 311 // if((len)!=(idx->dwChunkLength)){ |
285 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | 312 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ |
286 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); | 313 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); |
287 len=idx->dwChunkLength; | 314 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
288 // continue; | 315 len=choose_chunk_len(idx->dwChunkLength,len); |
289 } | 316 } |
290 if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; | 317 if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; |
291 } else return 0; | 318 } else return 0; |
292 ret=demux_avi_read_packet(demux,id,len,idx_pos,flags); | 319 ret=demux_avi_read_packet(demux,id,len,idx_pos,flags); |
293 // if(!ret && priv->skip_video_frames<=0) | 320 // if(!ret && priv->skip_video_frames<=0) |