Commit e347b8f4 authored by Francois Cartegnie's avatar Francois Cartegnie

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

parent dcffc924
...@@ -24,45 +24,89 @@ ...@@ -24,45 +24,89 @@
#include <assert.h> #include <assert.h>
#define XIPH_MAX_HEADER_COUNT (256) #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, static inline unsigned int xiph_CountHeaders( const void *extra, unsigned int i_extra )
unsigned extra_size, void *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]; const uint8_t *end = &current[extra_size];
if (extra_size < 1) if (extra_size < 1)
return VLC_EGENERIC; return VLC_EGENERIC;
/* Parse the packet count and their sizes */ /* Parse the packet count and their sizes */
const unsigned count = xiph_CountHeaders( current++ ); const unsigned count = xiph_CountHeaders( current++, extra_size );
if (packet_count) if (packet_count)
*packet_count = count; *packet_count = count;
unsigned size = 0;
for (unsigned i = 0; i < count - 1; i++) { if ( xiph_IsOldFormat( extra, extra_size ) )
packet_size[i] = 0; {
for (;;) { uint8_t *p_extra = (uint8_t*) extra;
if (current >= end) 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; return VLC_EGENERIC;
packet_size[i] += *current; overall_len += packet_size[i];
if (*current++ != 255)
break;
} }
size += packet_size[i];
} }
if (end - current < size) else
return VLC_EGENERIC; {
packet_size[count - 1] = end - current - size; unsigned size = 0;
for (unsigned i = 0; i < count - 1; i++) {
for (unsigned i = 0; i < count; i++) packet_size[i] = 0;
if (packet_size[i] > 0) { for (;;) {
packet[i] = current; if (current >= end)
current += packet_size[i]; 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; return VLC_SUCCESS;
} }
......
...@@ -814,7 +814,7 @@ static void OggGetSkeletonFisbone( uint8_t **pp_buffer, long *pi_size, ...@@ -814,7 +814,7 @@ static void OggGetSkeletonFisbone( uint8_t **pp_buffer, long *pi_size,
/* preroll */ /* preroll */
if ( p_input->p_fmt->p_extra ) 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; psz_header = *pp_buffer + FISBONE_BASE_SIZE;
memcpy( psz_header, headers.psz_content_type, strlen( headers.psz_content_type ) ); memcpy( psz_header, headers.psz_content_type, strlen( headers.psz_content_type ) );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment