[vlc-commits] flac: STREAMINFO is not necessarily the first METADATA_BLOCK

Rafaël Carré git at videolan.org
Sat Jun 22 11:14:38 CEST 2013


vlc | branch: master | Rafaël Carré <funman at videolan.org> | Sat Jun 22 11:07:25 2013 +0200| [6647ae7c650bee66fdc9a286af222966ab15dfef] | committer: Rafaël Carré

flac: STREAMINFO is not necessarily the first METADATA_BLOCK

Close: #8830

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6647ae7c650bee66fdc9a286af222966ab15dfef
---

 modules/demux/flac.c |   79 ++++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 34 deletions(-)

diff --git a/modules/demux/flac.c b/modules/demux/flac.c
index 2740f96..f4d7ee5 100644
--- a/modules/demux/flac.c
+++ b/modules/demux/flac.c
@@ -436,47 +436,26 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
     int     i_peek;
     const uint8_t *p_peek;
     bool b_last;
-    int i_sample_rate;
+    int i_sample_rate = 0;
     int64_t i_sample_count;
-    seekpoint_t *s;
-
-    /* Read STREAMINFO */
-    i_peek = stream_Peek( p_demux->s, &p_peek, 8 );
-    if( (p_peek[4] & 0x7F) != META_STREAMINFO )
-    {
-        msg_Err( p_demux, "this isn't a STREAMINFO metadata block" );
-        return VLC_EGENERIC;
-    }
-    if( Get24bBE(&p_peek[5]) != (STREAMINFO_SIZE - 4) )
-    {
-        msg_Err( p_demux, "invalid size for a STREAMINFO metadata block" );
-        return VLC_EGENERIC;
-    }
 
-    *pi_streaminfo = 4 + STREAMINFO_SIZE;
-    *pp_streaminfo = malloc( 4 + STREAMINFO_SIZE );
-    if( *pp_streaminfo == NULL )
-        return VLC_EGENERIC;
-
-    if( stream_Read( p_demux->s, *pp_streaminfo, 4+STREAMINFO_SIZE ) != 4+STREAMINFO_SIZE )
-    {
-        msg_Err( p_demux, "failed to read STREAMINFO metadata block" );
-        free( *pp_streaminfo );
-        return VLC_EGENERIC;
-    }
-
-    /* */
-    ParseStreamInfo( &i_sample_rate, &i_sample_count, *pp_streaminfo );
-    if( i_sample_rate > 0 )
-        p_sys->i_length = i_sample_count * INT64_C(1000000)/i_sample_rate;
+    *pp_streaminfo = NULL;
 
     /* Be sure we have seekpoint 0 */
-    s = vlc_seekpoint_New();
+    seekpoint_t *s = vlc_seekpoint_New();
     s->i_time_offset = 0;
     s->i_byte_offset = 0;
     TAB_APPEND( p_sys->i_seekpoint, p_sys->seekpoint, s );
 
-    b_last = (*pp_streaminfo)[4]&0x80;
+    static const uint8_t marker[4] = { 'f', 'L', 'a', 'C' };
+    uint8_t header[4];
+    if( stream_Read( p_demux->s, header, 4) < 4)
+        return VLC_EGENERIC;
+
+    if (memcmp(header, marker, 4))
+        return VLC_EGENERIC;
+
+    b_last = 0;
     while( !b_last )
     {
         int i_len;
@@ -489,7 +468,36 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
         i_type = p_peek[0]&0x7f;
         i_len  = Get24bBE( &p_peek[1] );
 
-        if( i_type == META_SEEKTABLE )
+        if( i_type == META_STREAMINFO )
+        {
+            if( i_len != (STREAMINFO_SIZE - 4) ) {
+                msg_Err( p_demux, "invalid size %d for a STREAMINFO metadata block", i_len );
+                return VLC_EGENERIC;
+            }
+            i_peek = stream_Peek( p_demux->s, &p_peek, STREAMINFO_SIZE);
+            if( i_peek == STREAMINFO_SIZE)
+
+            free(*pp_streaminfo);
+            *pi_streaminfo = STREAMINFO_SIZE + 4;
+            *pp_streaminfo = malloc( STREAMINFO_SIZE + 4 );
+            if( *pp_streaminfo == NULL )
+                return VLC_EGENERIC;
+
+            if( stream_Read( p_demux->s, &(*pp_streaminfo)[4], STREAMINFO_SIZE ) != STREAMINFO_SIZE )
+            {
+                msg_Err( p_demux, "failed to read STREAMINFO metadata block" );
+                free( *pp_streaminfo );
+                return VLC_EGENERIC;
+            }
+
+            memcpy(*pp_streaminfo, marker, 4);
+
+            /* */
+            ParseStreamInfo( &i_sample_rate, &i_sample_count, *pp_streaminfo );
+            if( i_sample_rate > 0 )
+                p_sys->i_length = i_sample_count * INT64_C(1000000)/i_sample_rate;
+        }
+        else if( i_type == META_SEEKTABLE )
         {
             i_peek = stream_Peek( p_demux->s, &p_peek, 4+i_len );
             if( i_peek == 4+i_len )
@@ -515,6 +523,9 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
     /* */
     p_sys->i_data_pos = stream_Tell( p_demux->s );
 
+    if (!*pp_streaminfo)
+        return VLC_EGENERIC;
+
     return VLC_SUCCESS;
 }
 static void ParseStreamInfo( int *pi_rate, int64_t *pi_count, uint8_t *p_data )



More information about the vlc-commits mailing list