[vlc-commits] demux: libavi: force chunk type check
Francois Cartegnie
git at videolan.org
Tue Nov 21 18:32:58 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at 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 *** */
More information about the vlc-commits
mailing list