[vlc-commits] demux: xiph: support old ffmpeg vorbis headers (fix #8832)

Francois Cartegnie git at videolan.org
Tue Nov 5 15:25:41 CET 2013


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Nov  5 22:38:04 2013 +0900| [e347b8f495e7d8c82896ee372f9966a1c73b0a7e] | committer: Francois Cartegnie

demux: xiph: support old ffmpeg vorbis headers (fix #8832)

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

 modules/demux/xiph.h |   90 +++++++++++++++++++++++++++++++++++++-------------
 modules/mux/ogg.c    |    2 +-
 2 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/modules/demux/xiph.h b/modules/demux/xiph.h
index b19c643..885662e 100644
--- a/modules/demux/xiph.h
+++ b/modules/demux/xiph.h
@@ -24,45 +24,89 @@
 #include <assert.h>
 #define XIPH_MAX_HEADER_COUNT (256)
 
-static inline unsigned int xiph_CountHeaders( const void *extra )
+/* Temp ffmpeg vorbis format */
+static inline bool xiph_IsOldFormat( const void *extra, unsigned int i_extra )
 {
-    return *( (const uint8_t*) extra ) + 1;
+    if ( i_extra >= 6 && GetWBE( extra ) == 30 )
+        return true;
+    else
+        return false;
 }
 
-static inline int xiph_SplitHeaders(unsigned packet_size[], void *packet[], unsigned *packet_count,
-                                    unsigned extra_size, void *extra)
+static inline unsigned int xiph_CountHeaders( const void *extra, unsigned int i_extra )
 {
-    uint8_t *current = extra;
+    const uint8_t *p_extra = (uint8_t*) extra;
+    if ( !i_extra ) return 0;
+    if ( xiph_IsOldFormat( extra, i_extra ) )
+    {
+        /* Check headers count */
+        unsigned int overall_len = 6;
+        for ( int i=0; i<3; i++ )
+        {
+            uint16_t i_size = GetWBE( extra );
+            p_extra += 2 + i_size;
+            if ( overall_len > i_extra - i_size )
+                return 0;
+            overall_len += i_size;
+        }
+        return 3;
+    }
+    else
+    {
+        return *p_extra + 1;
+    }
+}
+
+static inline int xiph_SplitHeaders(unsigned packet_size[], void * packet[], unsigned *packet_count,
+                                    unsigned extra_size, const void *extra)
+{
+    const uint8_t *current = extra;
     const uint8_t *end = &current[extra_size];
     if (extra_size < 1)
         return VLC_EGENERIC;
 
     /* Parse the packet count and their sizes */
-    const unsigned count = xiph_CountHeaders( current++ );
+    const unsigned count = xiph_CountHeaders( current++, extra_size );
     if (packet_count)
         *packet_count = count;
-    unsigned size = 0;
-    for (unsigned i = 0; i < count - 1; i++) {
-        packet_size[i] = 0;
-        for (;;) {
-            if (current >= end)
+
+    if ( xiph_IsOldFormat( extra, extra_size ) )
+    {
+        uint8_t *p_extra = (uint8_t*) extra;
+        unsigned int overall_len = count << 1;
+        for ( unsigned int i=0; i < count; i++ ) {
+            packet_size[i] = GetWBE( p_extra );
+            packet[i] = p_extra + 2;
+            p_extra += packet_size[i] + 2;
+            if (overall_len > extra_size - packet_size[i])
                 return VLC_EGENERIC;
-            packet_size[i] += *current;
-            if (*current++ != 255)
-                break;
+            overall_len += packet_size[i];
         }
-        size += packet_size[i];
     }
-    if (end - current < size)
-        return VLC_EGENERIC;
-    packet_size[count - 1] = end - current - size;
-
-    for (unsigned i = 0; i < count; i++)
-        if (packet_size[i] > 0) {
-            packet[i] = current;
-            current += packet_size[i];
+    else
+    {
+        unsigned size = 0;
+        for (unsigned i = 0; i < count - 1; i++) {
+            packet_size[i] = 0;
+            for (;;) {
+                if (current >= end)
+                    return VLC_EGENERIC;
+                packet_size[i] += *current;
+                if (*current++ != 255)
+                    break;
+            }
+            size += packet_size[i];
         }
+        if (end - current < size)
+            return VLC_EGENERIC;
+        packet_size[count - 1] = end - current - size;
 
+        for (unsigned i = 0; i < count; i++)
+            if (packet_size[i] > 0) {
+                packet[i] = (void *) current;
+                current += packet_size[i];
+            }
+    }
     return VLC_SUCCESS;
 }
 
diff --git a/modules/mux/ogg.c b/modules/mux/ogg.c
index fa4f0c5..f4f5d9b 100644
--- a/modules/mux/ogg.c
+++ b/modules/mux/ogg.c
@@ -814,7 +814,7 @@ static void OggGetSkeletonFisbone( uint8_t **pp_buffer, long *pi_size,
 
     /* preroll */
     if ( p_input->p_fmt->p_extra )
-        SetDWLE( &(*pp_buffer)[44], xiph_CountHeaders( p_input->p_fmt->p_extra ) );
+        SetDWLE( &(*pp_buffer)[44], xiph_CountHeaders( p_input->p_fmt->p_extra, p_input->p_fmt->i_extra ) );
 
     psz_header = *pp_buffer + FISBONE_BASE_SIZE;
     memcpy( psz_header, headers.psz_content_type, strlen( headers.psz_content_type ) );



More information about the vlc-commits mailing list