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)