vlc | branch: master | Francois Cartegnie <fcvlc...@free.fr> | Tue Nov 21 15:57:26 2017 +0100| [2be0155e2895ad45d6f8bae3e1e8ef712182a57c] | committer: Francois Cartegnie
demux: libavi: force chunk type check avi breakable since 2002 by mutating single chunks as LIST > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2be0155e2895ad45d6f8bae3e1e8ef712182a57c --- modules/demux/avi/avi.c | 66 +++++++++++++++++++++++----------------------- modules/demux/avi/libavi.c | 63 +++++++++++++++++++------------------------ modules/demux/avi/libavi.h | 12 ++++----- 3 files changed, 66 insertions(+), 75 deletions(-) diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c index a769a07a75..4193e38bf2 100644 --- a/modules/demux/avi/avi.c +++ b/modules/demux/avi/avi.c @@ -350,17 +350,17 @@ static int Open( vlc_object_t * p_this ) return VLC_EGENERIC; } - if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF ) > 1 ) + if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF, true ) > 1 ) { unsigned int i_count = - AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF ); + AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF, true ); msg_Warn( p_demux, "multiple riff -> OpenDML ?" ); for( unsigned i = 1; i < i_count; i++ ) { avi_chunk_list_t *p_sysx; - p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i ); + p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i, true ); if( p_sysx->i_type == AVIFOURCC_AVIX ) { msg_Warn( p_demux, "detected OpenDML file" ); @@ -370,11 +370,11 @@ static int Open( vlc_object_t * p_this ) } } - p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0 ); - p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 ); - p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 ); + p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true ); + p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0, true ); + p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true ); if( !p_movi ) - p_movi = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_movi, 0 ); + p_movi = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_movi, 0, true ); if( !p_hdrl || !p_movi ) { @@ -382,12 +382,12 @@ static int Open( vlc_object_t * p_this ) goto error; } - if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0 ) ) ) + if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0, false ) ) ) { msg_Err( p_demux, "invalid file: cannot find avih chunk" ); goto error; } - i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl ); + i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl, true ); if( p_avih->i_streams != i_track ) { msg_Warn( p_demux, @@ -426,16 +426,16 @@ static int Open( vlc_object_t * p_this ) if( unlikely( !tk ) ) goto error; - avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i ); - avi_chunk_strh_t *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 ); - avi_chunk_STRING_t *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0 ); + avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i, true ); + avi_chunk_strh_t *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0, false ); + avi_chunk_STRING_t *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0, false ); avi_chunk_strf_auds_t *p_auds = NULL; avi_chunk_strf_vids_t *p_vids = NULL; tk->b_eof = false; tk->b_activated = true; - p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 ); + p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0, false ); p_auds = (avi_chunk_strf_auds_t*)p_vids; if( p_strl == NULL || p_strh == NULL || p_vids == NULL ) @@ -515,11 +515,11 @@ static int Open( vlc_object_t * p_this ) tk->fmt.audio.i_bitspersample = p_auds->p_wf->wBitsPerSample; tk->fmt.b_packetized = !tk->i_blocksize; - avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0 ); + avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0, true ); if( p_info ) { int i_chunk = AVIFOURCC_IAS1 + ((i - 1) << 24); - avi_chunk_STRING_t *p_lang = AVI_ChunkFind( p_info, i_chunk, 0 ); + avi_chunk_STRING_t *p_lang = AVI_ChunkFind( p_info, i_chunk, 0, false ); if( p_lang != NULL && p_lang->p_str != NULL ) tk->fmt.psz_language = FromACP( p_lang->p_str ); } @@ -651,7 +651,7 @@ static int Open( vlc_object_t * p_this ) tk->fmt.video.i_height = (unsigned int)(-(int)p_vids->p_bih->biHeight); - avi_chunk_vprp_t *p_vprp = AVI_ChunkFind( p_strl, AVIFOURCC_vprp, 0 ); + avi_chunk_vprp_t *p_vprp = AVI_ChunkFind( p_strl, AVIFOURCC_vprp, 0, false ); if( p_vprp ) { uint32_t i_frame_aspect_ratio = p_vprp->i_frame_aspect_ratio; @@ -848,8 +848,8 @@ aviindex: { continue; } - p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i ); - p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 ); + p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i, true ); + p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0, false ); if( p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM && tk->i_rate == p_auds->p_wf->nSamplesPerSec ) @@ -1512,7 +1512,7 @@ static int Seek( demux_t *p_demux, mtime_t i_date, int i_percent, bool b_accurat /* Check and lazy load indexes if it was not done (not fastseekable) */ if ( !p_sys->b_indexloaded && ( p_sys->i_avih_flags & AVIF_HASINDEX ) ) { - avi_chunk_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0 ); + avi_chunk_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true ); if (unlikely( !p_riff )) return VLC_EGENERIC; @@ -2370,8 +2370,8 @@ static int AVI_IndexFind_idx1( demux_t *p_demux, { demux_sys_t *p_sys = p_demux->p_sys; - avi_chunk_list_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0); - avi_chunk_idx1_t *p_idx1 = AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0); + avi_chunk_list_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true); + avi_chunk_idx1_t *p_idx1 = AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0, false); if( !p_idx1 ) { @@ -2385,7 +2385,7 @@ static int AVI_IndexFind_idx1( demux_t *p_demux, * checking the offset of the first packet is not enough as some files * has unused chunk at the beginning of the movi content. */ - avi_chunk_list_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0); + avi_chunk_list_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true ); uint64_t i_first_pos = UINT64_MAX; for( unsigned i = 0; i < __MIN( p_idx1->i_entry_count, 100 ); i++ ) { @@ -2532,8 +2532,8 @@ static void AVI_IndexLoad_indx( demux_t *p_demux, avi_chunk_list_t *p_riff; avi_chunk_list_t *p_hdrl; - p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0); - p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 ); + p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true); + p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0, true ); for( unsigned i_stream = 0; i_stream < p_sys->i_track; i_stream++ ) { @@ -2541,8 +2541,8 @@ static void AVI_IndexLoad_indx( demux_t *p_demux, avi_chunk_indx_t *p_indx; #define p_stream p_sys->track[i_stream] - p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream ); - p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0 ); + p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream, true ); + p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0, false ); if( !p_indx ) { @@ -2654,8 +2654,8 @@ static void AVI_IndexCreate( demux_t *p_demux ) mtime_t i_dialog_update; vlc_dialog_id *p_dialog_id = NULL; - p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0); - p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0); + p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true ); + p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true ); if( !p_movi ) { @@ -2726,7 +2726,7 @@ static void AVI_IndexCreate( demux_t *p_demux ) { avi_chunk_list_t *p_sysx; p_sysx = AVI_ChunkFind( &p_sys->ck_root, - AVIFOURCC_RIFF, 1 ); + AVIFOURCC_RIFF, 1, true ); msg_Dbg( p_demux, "looking for new RIFF chunk" ); if( vlc_stream_Seek( p_demux->s, @@ -2790,7 +2790,7 @@ static void AVI_MetaLoad( demux_t *p_demux, p_avih->i_flags&AVIF_TRUSTCKTYPE ? " TRUST_CKTYPE" : "" ); vlc_meta_SetSetting( p_meta, buffer ); - avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0 ); + avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0, true ); if( !p_info ) return; @@ -2813,7 +2813,7 @@ static void AVI_MetaLoad( demux_t *p_demux, }; for( int i = 0; p_dsc[i].i_id != 0; i++ ) { - avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_dsc[i].i_id, 0 ); + avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_dsc[i].i_id, 0, false ); if( !p_strz || !p_strz->p_str ) continue; char *psz_value = FromACP( p_strz->p_str ); @@ -2837,7 +2837,7 @@ static void AVI_MetaLoad( demux_t *p_demux, for( int i = 0; p_extra[i] != 0; i++ ) { - avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_extra[i], 0 ); + avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_extra[i], 0, false ); if( !p_strz || !p_strz->p_str ) continue; char *psz_value = FromACP( p_strz->p_str ); @@ -2901,7 +2901,7 @@ static void AVI_ExtractSubtitle( demux_t *p_demux, if( !p_sys->b_seekable ) goto exit; - p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0 ); + p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0, false ); avi_chunk_t ck; int64_t i_position; unsigned i_size; diff --git a/modules/demux/avi/libavi.c b/modules/demux/avi/libavi.c index 8a9e844165..e529348b57 100644 --- a/modules/demux/avi/libavi.c +++ b/modules/demux/avi/libavi.c @@ -230,7 +230,7 @@ static int AVI_ChunkRead_list( stream_t *s, avi_chunk_t *p_container ) /* Allow to append indexes after starting playback */ int AVI_ChunkFetchIndexes( stream_t *s, avi_chunk_t *p_riff ) { - avi_chunk_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 ); + avi_chunk_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true ); if ( !p_movi ) return VLC_EGENERIC; @@ -413,7 +413,7 @@ static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk ) msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( VLC_EGENERIC ); } - if( !( p_strh = AVI_ChunkFind( p_chk->common.p_father, AVIFOURCC_strh, 0 ) ) ) + if( !( p_strh = AVI_ChunkFind( p_chk->common.p_father, AVIFOURCC_strh, 0, false ) ) ) { msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( p_chk->common.i_chunk_size > 0 ? VLC_EGENERIC : AVI_ZEROSIZED_CHUNK ); @@ -1168,57 +1168,48 @@ void AVI_ChunkFreeRoot( stream_t *s, } -int AVI_ChunkCount_( avi_chunk_t *p_chk, vlc_fourcc_t i_fourcc ) +int AVI_ChunkCount_( avi_chunk_t *p_chk, vlc_fourcc_t i_fourcc, bool b_list ) { - int i_count; - avi_chunk_t *p_child; - if( !p_chk ) - { return 0; - } - i_count = 0; - p_child = p_chk->common.p_first; - while( p_child ) + int i_count = 0; + for( avi_chunk_t *p_child = p_chk->common.p_first; + p_child; p_child = p_child->common.p_next ) { - if( p_child->common.i_chunk_fourcc == i_fourcc || - ( p_child->common.i_chunk_fourcc == AVIFOURCC_LIST && - p_child->list.i_type == i_fourcc ) ) - { - i_count++; - } - p_child = p_child->common.p_next; + if( b_list && p_child->list.i_type == 0 ) + continue; + + if( p_child->common.i_chunk_fourcc != i_fourcc && + p_child->list.i_type != i_fourcc ) + continue; + + i_count++; } + return i_count; } void *AVI_ChunkFind_( avi_chunk_t *p_chk, - vlc_fourcc_t i_fourcc, int i_number ) + vlc_fourcc_t i_fourcc, int i_number, bool b_list ) { - avi_chunk_t *p_child; if( !p_chk ) - { return NULL; - } - p_child = p_chk->common.p_first; - while( p_child ) + for( avi_chunk_t *p_child = p_chk->common.p_first; + p_child; p_child = p_child->common.p_next ) { - if( p_child->common.i_chunk_fourcc == i_fourcc || - ( p_child->common.i_chunk_fourcc == AVIFOURCC_LIST && - p_child->list.i_type == i_fourcc ) ) - { - if( i_number == 0 ) - { - /* We found it */ - return p_child; - } + if( b_list && p_child->list.i_type == 0 ) + continue; - i_number--; - } - p_child = p_child->common.p_next; + if( p_child->common.i_chunk_fourcc != i_fourcc && + p_child->list.i_type != i_fourcc ) + continue; + + if( i_number-- == 0 ) + return p_child; /* We found it */ } + return NULL; } diff --git a/modules/demux/avi/libavi.h b/modules/demux/avi/libavi.h index 5092996412..5fda4435ef 100644 --- a/modules/demux/avi/libavi.h +++ b/modules/demux/avi/libavi.h @@ -254,17 +254,17 @@ int AVI_ChunkRead( stream_t *, avi_chunk_t *p_father ); void AVI_ChunkClean( stream_t *, avi_chunk_t * ); -int AVI_ChunkCount_( avi_chunk_t *, vlc_fourcc_t ); -void *AVI_ChunkFind_ ( avi_chunk_t *, vlc_fourcc_t, int ); +int AVI_ChunkCount_( avi_chunk_t *, vlc_fourcc_t, bool ); +void *AVI_ChunkFind_ ( avi_chunk_t *, vlc_fourcc_t, int, bool ); int AVI_ChunkReadRoot( stream_t *, avi_chunk_t *p_root ); void AVI_ChunkFreeRoot( stream_t *, avi_chunk_t *p_chk ); int AVI_ChunkFetchIndexes( stream_t *, avi_chunk_t *p_riff ); -#define AVI_ChunkCount( p_chk, i_fourcc ) \ - AVI_ChunkCount_( AVI_CHUNK(p_chk), i_fourcc ) -#define AVI_ChunkFind( p_chk, i_fourcc, i_number ) \ - AVI_ChunkFind_( AVI_CHUNK(p_chk), i_fourcc, i_number ) +#define AVI_ChunkCount( p_chk, i_fourcc, b_list ) \ + AVI_ChunkCount_( AVI_CHUNK(p_chk), i_fourcc, b_list ) +#define AVI_ChunkFind( p_chk, i_fourcc, i_number, b_list ) \ + AVI_ChunkFind_( AVI_CHUNK(p_chk), i_fourcc, i_number, b_list ) /* *** avi stuff *** */ _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits