int AVI_ChunkRead( stream_t *s, avi_chunk_t *p_chk, avi_chunk_t *p_father ) { int i_index; if( !p_chk ) { msg_Warn( (vlc_object_t*)s, "cannot read null chunk" ); return VLC_EGENERIC; } if( AVI_ChunkReadCommon( s, p_chk ) ) { msg_Warn( (vlc_object_t*)s, "cannot read one chunk" ); return VLC_EGENERIC; } if( p_chk->common.i_chunk_fourcc == VLC_FOURCC( 0, 0, 0, 0 ) ) { msg_Warn( (vlc_object_t*)s, "found null fourcc chunk (corrupted file?)" ); return AVI_ZERO_FOURCC; } p_chk->common.p_father = p_father; i_index = AVI_ChunkFunctionFind( p_chk->common.i_chunk_fourcc ); if( AVI_Chunk_Function[i_index].AVI_ChunkRead_function ) { int i_return = AVI_Chunk_Function[i_index].AVI_ChunkRead_function( s, p_chk ); if ( i_return == AVI_STRD_ZERO_CHUNK || i_return == AVI_ZERO_FOURCC ) { if ( !p_father ) return VLC_EGENERIC; return AVI_NextChunk( s, p_father ); } return i_return; } else if( ( ((char*)&p_chk->common.i_chunk_fourcc)[0] == 'i' && ((char*)&p_chk->common.i_chunk_fourcc)[1] == 'x' ) || ( ((char*)&p_chk->common.i_chunk_fourcc)[2] == 'i' && ((char*)&p_chk->common.i_chunk_fourcc)[3] == 'x' ) ) { p_chk->common.i_chunk_fourcc = AVIFOURCC_indx; return AVI_ChunkRead_indx( s, p_chk ); } msg_Warn( (vlc_object_t*)s, "unknown chunk: %4.4s (not loaded)", (char*)&p_chk->common.i_chunk_fourcc ); return AVI_NextChunk( s, p_chk ); }
static int AVI_ChunkRead_nothing( stream_t *s, avi_chunk_t *p_chk ) { return AVI_NextChunk( s, p_chk ); }
/**************************************************************************** * * Functions to read chunks * ****************************************************************************/ static int AVI_ChunkRead_list( stream_t *s, avi_chunk_t *p_container ) { avi_chunk_t *p_chk; const uint8_t *p_peek; bool b_seekable; if( p_container->common.i_chunk_size > 0 && p_container->common.i_chunk_size < 8 ) { /* empty box */ msg_Warn( (vlc_object_t*)s, "empty list chunk" ); return VLC_EGENERIC; } if( stream_Peek( s, &p_peek, 12 ) < 12 ) { msg_Warn( (vlc_object_t*)s, "cannot peek while reading list chunk" ); return VLC_EGENERIC; } stream_Control( s, STREAM_CAN_FASTSEEK, &b_seekable ); p_container->list.i_type = GetFOURCC( p_peek + 8 ); /* XXX fixed for on2 hack */ if( p_container->common.i_chunk_fourcc == AVIFOURCC_ON2 && p_container->list.i_type == AVIFOURCC_ON2f ) { p_container->common.i_chunk_fourcc = AVIFOURCC_RIFF; p_container->list.i_type = AVIFOURCC_AVI; } if( p_container->common.i_chunk_fourcc == AVIFOURCC_LIST && p_container->list.i_type == AVIFOURCC_movi ) { msg_Dbg( (vlc_object_t*)s, "skipping movi chunk" ); if( b_seekable ) { return AVI_NextChunk( s, p_container ); } return VLC_SUCCESS; /* point at begining of LIST-movi */ } if( stream_Read( s, NULL, 12 ) != 12 ) { msg_Warn( (vlc_object_t*)s, "cannot enter chunk" ); return VLC_EGENERIC; } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "found LIST chunk: \'%4.4s\'", (char*)&p_container->list.i_type ); #endif msg_Dbg( (vlc_object_t*)s, "<list \'%4.4s\'>", (char*)&p_container->list.i_type ); for( ; ; ) { p_chk = malloc( sizeof( avi_chunk_t ) ); memset( p_chk, 0, sizeof( avi_chunk_t ) ); if( !p_container->common.p_first ) { p_container->common.p_first = p_chk; } else { p_container->common.p_last->common.p_next = p_chk; } p_container->common.p_last = p_chk; if( AVI_ChunkRead( s, p_chk, p_container ) ) { break; } if( p_chk->common.p_father->common.i_chunk_size > 0 && ( stream_Tell( s ) > (off_t)p_chk->common.p_father->common.i_chunk_pos + (off_t)__EVEN( p_chk->common.p_father->common.i_chunk_size ) ) ) { break; } /* If we can't seek then stop when we 've found LIST-movi */ if( p_chk->common.i_chunk_fourcc == AVIFOURCC_LIST && p_chk->list.i_type == AVIFOURCC_movi && ( !b_seekable || p_chk->common.i_chunk_size == 0 ) ) { break; } } msg_Dbg( (vlc_object_t*)s, "</list \'%4.4s\'>", (char*)&p_container->list.i_type ); return VLC_SUCCESS; }