From febea59322289ec7d45aa8bb8128703ba65ea726 Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Thu, 26 Mar 2015 23:13:41 +0100 Subject: [PATCH] demux: ts: rewrite/split IOD parsing Fixes read overflows. --- modules/demux/Makefile.am | 1 + modules/demux/mpeg4_iod.c | 401 ++++++++++++++++++++++++++++++++++++++ modules/demux/mpeg4_iod.h | 54 +++++ modules/demux/ts.c | 269 +------------------------ 4 files changed, 458 insertions(+), 267 deletions(-) create mode 100644 modules/demux/mpeg4_iod.c create mode 100644 modules/demux/mpeg4_iod.h diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am index 78dc9156ef..cd8a5bdef1 100644 --- a/modules/demux/Makefile.am +++ b/modules/demux/Makefile.am @@ -227,6 +227,7 @@ libplaylist_plugin_la_SOURCES = \ demux_LTLIBRARIES += libplaylist_plugin.la libts_plugin_la_SOURCES = demux/ts.c \ + demux/mpeg4_iod.c demux/mpeg4_iod.h \ mux/mpeg/csa.c mux/mpeg/dvbpsi_compat.h \ mux/mpeg/streams.h mux/mpeg/tables.c mux/mpeg/tables.h \ mux/mpeg/tsutil.c mux/mpeg/tsutil.h \ diff --git a/modules/demux/mpeg4_iod.c b/modules/demux/mpeg4_iod.c new file mode 100644 index 0000000000..b8276562db --- /dev/null +++ b/modules/demux/mpeg4_iod.c @@ -0,0 +1,401 @@ +/***************************************************************************** + * mpeg4_iod.c: ISO 14496-1 IOD and parsers + ***************************************************************************** + * Copyright (C) 2004-2015 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "mpeg4_iod.h" + +//#define IOD_DEBUG 1 +static void iod_debug( vlc_object_t *p_object, const char *format, ... ) +{ +#ifdef IOD_DEBUG + va_list ap; + va_start(ap, format); + msg_GenericVa( p_object, VLC_MSG_DBG, format, ap ); + va_end(ap); +#else + VLC_UNUSED(format); + VLC_UNUSED(p_object); +#endif +} + +/***************************************************************************** + * MP4 specific functions (IOD parser) + *****************************************************************************/ +static unsigned IODDescriptorLength( unsigned *pi_data, const uint8_t **pp_data ) +{ + unsigned int i_b; + unsigned int i_len = 0; + + if(*pi_data == 0) + return 0; + + do + { + i_b = **pp_data; + (*pp_data)++; + (*pi_data)--; + i_len = ( i_len << 7 ) + ( i_b&0x7f ); + + } while( i_b&0x80 && *pi_data > 0 ); + + if (i_len > *pi_data) + i_len = *pi_data; + + return i_len; +} + +static unsigned IODGetBytes( unsigned *pi_data, const uint8_t **pp_data, size_t bytes ) +{ + unsigned res = 0; + while( *pi_data > 0 && bytes-- ) + { + res <<= 8; + res |= **pp_data; + (*pp_data)++; + (*pi_data)--; + } + + return res; +} + +static char* IODGetURL( unsigned *pi_data, const uint8_t **pp_data ) +{ + unsigned len = IODGetBytes( pi_data, pp_data, 1 ); + if (len > *pi_data) + len = *pi_data; + char *url = strndup( (char*)*pp_data, len ); + *pp_data += len; + *pi_data -= len; + return url; +} + +#define IODTag_ObjectDescr 0x01 +#define IODTag_InitialObjectDescr 0x02 +#define IODTag_ESDescr 0x03 +#define IODTag_DecConfigDescr 0x04 +#define IODTag_DecSpecificDescr 0x05 +#define IODTag_SLDescr 0x06 + +/* Unified pointer for read helper */ +typedef union +{ + iod_descriptor_t *p_iod; + es_mpeg4_descriptor_t *es_descr; + decoder_config_descriptor_t *p_dec_config; +} iod_read_params_t; + +static uint8_t IOD_Desc_Read( vlc_object_t *, unsigned *, const uint8_t **, uint8_t, uint8_t, iod_read_params_t params ); + +static bool IOD_SLDesc_Read( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data, + iod_read_params_t params ) +{ + VLC_UNUSED(p_object); + VLC_UNUSED(i_data); + VLC_UNUSED(p_data); + VLC_UNUSED(params); + return true; +} + +static bool IOD_DecSpecificDesc_Read( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data, + iod_read_params_t params ) +{ + VLC_UNUSED(p_object); + decoder_config_descriptor_t *p_dec_config = params.p_dec_config; + + p_dec_config->p_extra = malloc( i_data ); + if( p_dec_config->p_extra ) + { + p_dec_config->i_extra = i_data; + memcpy( p_dec_config->p_extra, p_data, p_dec_config->i_extra ); + } + + return !!p_dec_config->i_extra; +} + +static bool IOD_DecConfigDesc_Read( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data, + iod_read_params_t params ) +{ + decoder_config_descriptor_t *p_dec_config = params.p_dec_config; + + if( i_data < 13 ) + return false; + + p_dec_config->i_objectTypeIndication = IODGetBytes( &i_data, &p_data, 1 ); + uint8_t i_flags = IODGetBytes( &i_data, &p_data, 1 ); + p_dec_config->i_streamType = i_flags >> 2; + + IODGetBytes( &i_data, &p_data, 3 ); /* bufferSizeDB */ + IODGetBytes( &i_data, &p_data, 4 ); /* maxBitrate */ + IODGetBytes( &i_data, &p_data, 4 ); /* avgBitrate */ + + /* DecoderSpecificDescr */ + IOD_Desc_Read( p_object, &i_data, &p_data, + IODTag_DecSpecificDescr, 1, params ); + + iod_debug( p_object, " * read decoder objecttype: %x streamtype:%x extra: %u", + p_dec_config->i_objectTypeIndication, p_dec_config->i_streamType, p_dec_config->i_extra ); + /* ProfileLevelIndicator [0..255] */ + return true; +} + +static bool IOD_ESDesc_Read( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data, + iod_read_params_t params ) +{ + es_mpeg4_descriptor_t *es_descr = params.es_descr; + + if ( i_data < 3 ) + return false; + es_descr->i_es_id = IODGetBytes( &i_data, &p_data, 2 ); + uint8_t i_flags = IODGetBytes( &i_data, &p_data, 1 ); + + if( ( i_flags >> 7 )&0x01 ) + { + if ( i_data < 2 ) + return false; + IODGetBytes( &i_data, &p_data, 2 ); /* dependOn_es_id */ + } + + if( (i_flags >> 6) & 0x01 ) + es_descr->psz_url = IODGetURL( &i_data, &p_data ); + + if( ( i_flags >> 5 )&0x01 ) + { + if ( i_data < 2 ) + return false; + IODGetBytes( &i_data, &p_data, 2 ); /* OCR_es_id */ + } + + iod_debug( p_object, " * read ES Descriptor for es id %"PRIx16, es_descr->i_es_id ); + + /* DecoderConfigDescr */ + params.p_dec_config = &es_descr->dec_descr; + if ( 1 != IOD_Desc_Read( p_object, &i_data, &p_data, + IODTag_DecConfigDescr, 1, params ) ) + return false; + + /* SLDescr */ + IOD_Desc_Read( p_object, &i_data, &p_data, IODTag_SLDescr, 1, params ); + + /* IPI / IP / IPMP ... */ + + es_descr->b_ok = true; + + return true; +} + +static bool IOD_InitialObjectDesc_Read( vlc_object_t *p_object, unsigned i_data, + const uint8_t *p_data, iod_read_params_t params ) +{ + iod_descriptor_t *p_iod = params.p_iod; + if( i_data < 3 + 5 + 2 ) + return false; + + uint16_t i_object_descriptor_id = ( IODGetBytes( &i_data, &p_data, 1 ) << 2 ); + uint8_t i_flags = IODGetBytes( &i_data, &p_data, 1 ); + i_object_descriptor_id |= i_flags >> 6; + + iod_debug( p_object, " * ObjectDescriptorID: %"PRIu16, i_object_descriptor_id ); + iod_debug( p_object, " * includeInlineProfileLevel flag: 0x%"PRIx8, ( i_flags >> 4 )&0x01 ); + if ( (i_flags >> 5) & 0x01 ) + { + p_iod->psz_url = IODGetURL( &i_data, &p_data ); + iod_debug( p_object, " * URL: %s", p_iod->psz_url ); + return true; /* leaves out unparsed remaining extdescr */ + } + + if( i_data < 5 + 2 ) /* at least one ES desc */ + return false; + + /* Profile Level Indication */ + IODGetBytes( &i_data, &p_data, 1 ); /* OD */ + IODGetBytes( &i_data, &p_data, 1 ); /* scene */ + IODGetBytes( &i_data, &p_data, 1 ); /* audio */ + IODGetBytes( &i_data, &p_data, 1 ); /* visual */ + IODGetBytes( &i_data, &p_data, 1 ); /* graphics */ + + /* Now read */ + /* 1..255 ESdescr */ + uint8_t i_desc_count = IOD_Desc_Read( p_object, &i_data, &p_data, + IODTag_ESDescr, ES_DESCRIPTOR_COUNT, params ); + if( i_desc_count == 0 ) + { + iod_debug( p_object, " * missing ES Descriptor" ); + return false; + } + + /* 0..255 OCIdescr */ + /* 0..255 IPMPdescpointer */ + /* 0..255 IPMPdesc */ + /* 0..1 IPMPtoollistdesc */ + /* 0..255 Extensiondescr */ + + return true; +} + +static uint8_t IOD_Desc_Read( vlc_object_t *p_object, unsigned *pi_data, const uint8_t **pp_data, + uint8_t i_target_tag, uint8_t i_max_desc, iod_read_params_t params ) +{ + uint8_t i_read_count = 0; + + for (unsigned i = 0; *pi_data > 2 && i < i_max_desc; i++) + { + const uint8_t i_tag = IODGetBytes( pi_data, pp_data, 1 ); + const unsigned i_length = IODDescriptorLength( pi_data, pp_data ); + if( i_target_tag != i_tag || i_length > *pi_data ) + break; + + unsigned i_descriptor_data = i_length; + const uint8_t *p_descriptor_data = *pp_data; + + iod_debug( p_object, " Reading descriptor 0x%"PRIx8": found tag 0x%"PRIx8" left %d", + i_target_tag, i_tag, *pi_data ); + switch( i_tag ) + { + case IODTag_InitialObjectDescr: + { + /* iod_descriptor_t *p_iod = (iod_descriptor_t *) param; */ + if ( !IOD_InitialObjectDesc_Read( p_object, i_descriptor_data, + p_descriptor_data, params ) ) + {}; + break; + } + + case IODTag_ESDescr: /**/ + { + iod_descriptor_t *p_iod = params.p_iod; + params.es_descr = &p_iod->es_descr[i_read_count]; + if ( !IOD_ESDesc_Read( p_object, i_descriptor_data, + p_descriptor_data, params ) ) + {}; + break; + } + + case IODTag_DecConfigDescr: + { + if ( !IOD_DecConfigDesc_Read( p_object, i_descriptor_data, + p_descriptor_data, params ) ) + {}; + break; + } + + case IODTag_DecSpecificDescr: + { + if ( !IOD_DecSpecificDesc_Read( p_object, i_descriptor_data, + p_descriptor_data, params ) ) + {}; + break; + } + + case IODTag_SLDescr: + { + if ( !IOD_SLDesc_Read( p_object, i_descriptor_data, + p_descriptor_data, params ) ) + {}; + break; + } + + default: + iod_debug( p_object, "trying to read unsupported descriptor" ); + break; + } + + *pp_data += i_length; + *pi_data -= i_length; + + i_read_count++; + } + + return i_read_count; +} + +iod_descriptor_t *IODNew( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data ) +{ + if( i_data < 4 ) + return NULL; + + uint8_t i_iod_scope = IODGetBytes( &i_data, &p_data, 1 ); /* scope */ + uint8_t i_iod_label = IODGetBytes( &i_data, &p_data, 1 ); + if( i_iod_label == 0x02 ) /* old vlc's buggy implementation of the IOD_descriptor */ + { + i_iod_label = i_iod_scope; + i_iod_scope = 0x10; /* Add the missing front iod scope byte */ + i_data++; p_data--; /* next byte must be tag */ + } + + iod_debug( p_object, " * iod label:0x%"PRIx8" scope:0x%"PRIx8, + i_iod_label, i_iod_scope ); + + if( i_iod_scope != 0x10 && i_iod_scope != 0x11 ) /* Uniqueness in program or transport */ + { + iod_debug( p_object, " * can't handle reserved scope 0x%"PRIx8, i_iod_scope ); + return NULL; + } + + /* Initial Object Descriptor must follow */ + iod_descriptor_t *p_iod = calloc( 1, sizeof( iod_descriptor_t ) ); + if( !p_iod ) + return NULL; + + /* IOD_InitialObjectDescrTag Parsing */ + iod_read_params_t params; + params.p_iod = p_iod; + if ( 1 != IOD_Desc_Read( p_object, &i_data, &p_data, + IODTag_InitialObjectDescr, 1, params ) ) + { + iod_debug( p_object, " cannot read InitialObjectDescr" ); + free( p_iod ); + return NULL; + } + + return p_iod; +} + +void IODFree( iod_descriptor_t *p_iod ) +{ + if( p_iod->psz_url ) + { + free( p_iod->psz_url ); + free( p_iod ); + return; + } + + for( int i = 0; i < 255; i++ ) + { +#define es_descr p_iod->es_descr[i] + if( es_descr.b_ok ) + { + if( es_descr.psz_url ) + free( es_descr.psz_url ); + else + free( es_descr.dec_descr.p_extra ); + } +#undef es_descr + } + free( p_iod ); +} diff --git a/modules/demux/mpeg4_iod.h b/modules/demux/mpeg4_iod.h new file mode 100644 index 0000000000..af47b2b40f --- /dev/null +++ b/modules/demux/mpeg4_iod.h @@ -0,0 +1,54 @@ +/***************************************************************************** + * mpeg4_iod.h: ISO 14496-1 IOD and parsers + ***************************************************************************** + * Copyright (C) 2004-2015 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#define ES_DESCRIPTOR_COUNT 255 + +typedef struct +{ + uint8_t i_objectTypeIndication; + uint8_t i_streamType; + + unsigned i_extra; + uint8_t *p_extra; + +} decoder_config_descriptor_t; + +typedef struct +{ + bool b_ok; + uint16_t i_es_id; + + char *psz_url; + + decoder_config_descriptor_t dec_descr; + +} es_mpeg4_descriptor_t; + +typedef struct +{ + /* IOD */ + char *psz_url; + + es_mpeg4_descriptor_t es_descr[ES_DESCRIPTOR_COUNT]; + +} iod_descriptor_t; + +iod_descriptor_t *IODNew( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data ); +void IODFree( iod_descriptor_t *p_iod ); diff --git a/modules/demux/ts.c b/modules/demux/ts.c index 051bdde1e3..2e36f05ba6 100644 --- a/modules/demux/ts.c +++ b/modules/demux/ts.c @@ -70,18 +70,7 @@ #include "opus.h" -#undef TS_DEBUG -VLC_FORMAT(1, 2) static void ts_debug(const char *format, ...) -{ -#ifdef TS_DEBUG - va_list ap; - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -#else - (void)format; -#endif -} +#include "mpeg4_iod.h" #ifdef HAVE_ARIBB24 #include @@ -204,37 +193,6 @@ static const char *const ppsz_teletext_type[] = { typedef struct ts_pid_t ts_pid_t; -typedef struct -{ - uint8_t i_objectTypeIndication; - uint8_t i_streamType; - - unsigned i_extra; - uint8_t *p_extra; - -} decoder_config_descriptor_t; - -typedef struct -{ - bool b_ok; - uint16_t i_es_id; - - char *psz_url; - - decoder_config_descriptor_t dec_descr; - -} es_mpeg4_descriptor_t; - -#define ES_DESCRIPTOR_COUNT 255 -typedef struct -{ - /* IOD */ - char *psz_url; - - es_mpeg4_descriptor_t es_descr[ES_DESCRIPTOR_COUNT]; - -} iod_descriptor_t; - typedef struct { int i_version; @@ -521,8 +479,6 @@ static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * ); static void PCRFixHandle( demux_t *, ts_pmt_t *, block_t * ); static int64_t TimeStampWrapAround( ts_pmt_t *, int64_t ); -static void IODFree( iod_descriptor_t * ); - #define TS_USER_PMT_NUMBER (0) static int UserPmt( demux_t *p_demux, const char * ); @@ -3400,227 +3356,6 @@ static void PIDFillFormat( es_format_t *fmt, int i_stream_type ) fmt->b_packetized = false; } -/***************************************************************************** - * MP4 specific functions (IOD parser) - *****************************************************************************/ -static unsigned IODDescriptorLength( unsigned *pi_data, uint8_t **pp_data ) -{ - unsigned int i_b; - unsigned int i_len = 0; - do - { - i_b = **pp_data; - (*pp_data)++; - (*pi_data)--; - i_len = ( i_len << 7 ) + ( i_b&0x7f ); - - } while( i_b&0x80 && *pi_data > 0 ); - - if (i_len > *pi_data) - i_len = *pi_data; - - return i_len; -} - -static unsigned IODGetBytes( unsigned *pi_data, uint8_t **pp_data, size_t bytes ) -{ - unsigned res = 0; - while( *pi_data > 0 && bytes-- ) - { - res <<= 8; - res |= **pp_data; - (*pp_data)++; - (*pi_data)--; - } - - return res; -} - -static char* IODGetURL( unsigned *pi_data, uint8_t **pp_data ) -{ - unsigned len = IODGetBytes( pi_data, pp_data, 1 ); - if (len > *pi_data) - len = *pi_data; - char *url = strndup( (char*)*pp_data, len ); - *pp_data += len; - *pi_data -= len; - return url; -} - -static iod_descriptor_t *IODNew( unsigned i_data, uint8_t *p_data ) -{ - uint8_t i_iod_tag, i_iod_label, byte1, byte2, byte3; - - iod_descriptor_t *p_iod = calloc( 1, sizeof( iod_descriptor_t ) ); - if( !p_iod ) - return NULL; - - if( i_data < 3 ) - { - return p_iod; - } - - byte1 = IODGetBytes( &i_data, &p_data, 1 ); - byte2 = IODGetBytes( &i_data, &p_data, 1 ); - byte3 = IODGetBytes( &i_data, &p_data, 1 ); - if( byte2 == 0x02 ) //old vlc's buggy implementation of the IOD_descriptor - { - i_iod_label = byte1; - i_iod_tag = byte2; - } - else //correct implementation of the IOD_descriptor - { - i_iod_label = byte2; - i_iod_tag = byte3; - } - - ts_debug( "\n* iod label:%d tag:0x%x", i_iod_label, i_iod_tag ); - - if( i_iod_tag != 0x02 ) - { - ts_debug( "\n ERR: tag %02x != 0x02", i_iod_tag ); - return p_iod; - } - - IODDescriptorLength( &i_data, &p_data ); - - uint16_t i_od_id = ( IODGetBytes( &i_data, &p_data, 1 ) << 2 ); - uint8_t i_flags = IODGetBytes( &i_data, &p_data, 1 ); - i_od_id |= i_flags >> 6; - ts_debug( "\n* od_id:%d", i_od_id ); - ts_debug( "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 ); - if ((i_flags >> 5) & 0x01) - { - p_iod->psz_url = IODGetURL( &i_data, &p_data ); - ts_debug( "\n* url string:%s", p_iod->psz_url ); - ts_debug( "\n*****************************\n" ); - return p_iod; - } - else - { - p_iod->psz_url = NULL; - } - - /* Profile Level Indication */ - IODGetBytes( &i_data, &p_data, 1 ); /* OD */ - IODGetBytes( &i_data, &p_data, 1 ); /* scene */ - IODGetBytes( &i_data, &p_data, 1 ); /* audio */ - IODGetBytes( &i_data, &p_data, 1 ); /* visual */ - IODGetBytes( &i_data, &p_data, 1 ); /* graphics */ - - unsigned i_length = 0; - unsigned i_data_sav = i_data; - uint8_t *p_data_sav = p_data; - for (unsigned i = 0; i_data > 0 && i < ES_DESCRIPTOR_COUNT; i++) - { - es_mpeg4_descriptor_t *es_descr = &p_iod->es_descr[i]; - - p_data = p_data_sav + i_length; - i_data = i_data_sav - i_length; - - uint8_t i_tag = IODGetBytes( &i_data, &p_data, 1 ); - i_length = IODDescriptorLength( &i_data, &p_data ); - - i_data_sav = i_data; - p_data_sav = p_data; - - i_data = i_length; - - if ( i_tag != 0x03 ) - { - ts_debug( "\n* - OD tag:0x%x Unsupported", i_tag ); - continue; - } - - es_descr->i_es_id = IODGetBytes( &i_data, &p_data, 2 ); - uint8_t i_flags = IODGetBytes( &i_data, &p_data, 1 ); - bool b_streamDependenceFlag = ( i_flags >> 7 )&0x01; - if( b_streamDependenceFlag ) - IODGetBytes( &i_data, &p_data, 2 ); /* dependOn_es_id */ - - if( (i_flags >> 6) & 0x01 ) - es_descr->psz_url = IODGetURL( &i_data, &p_data ); - - bool b_OCRStreamFlag = ( i_flags >> 5 )&0x01; - if( b_OCRStreamFlag ) - IODGetBytes( &i_data, &p_data, 2 ); /* OCR_es_id */ - - if( IODGetBytes( &i_data, &p_data, 1 ) != 0x04 ) - { - ts_debug( "\n* ERR missing DecoderConfigDescr" ); - continue; - } - unsigned i_config_desc_length = IODDescriptorLength( &i_data, &p_data ); /* DecoderConfigDescr_length */ - decoder_config_descriptor_t *dec_descr = &es_descr->dec_descr; - dec_descr->i_objectTypeIndication = IODGetBytes( &i_data, &p_data, 1 ); - i_flags = IODGetBytes( &i_data, &p_data, 1 ); - dec_descr->i_streamType = i_flags >> 2; - - IODGetBytes( &i_data, &p_data, 3); /* bufferSizeDB */ - IODGetBytes( &i_data, &p_data, 4); /* maxBitrate */ - IODGetBytes( &i_data, &p_data, 4 ); /* avgBitrate */ - - if( i_config_desc_length > 13 && IODGetBytes( &i_data, &p_data, 1 ) == 0x05 ) - { - dec_descr->i_extra = IODDescriptorLength( &i_data, &p_data ); - if( dec_descr->i_extra > 0 ) - { - dec_descr->p_extra = xmalloc( dec_descr->i_extra ); - memcpy(dec_descr->p_extra, p_data, dec_descr->i_extra); - p_data += dec_descr->i_extra; - i_data -= dec_descr->i_extra; - } - } - else - { - dec_descr->i_extra = 0; - dec_descr->p_extra = NULL; - } - - if( IODGetBytes( &i_data, &p_data, 1 ) != 0x06 ) - { - ts_debug( "\n* ERR missing SLConfigDescr" ); - continue; - } - IODDescriptorLength( &i_data, &p_data ); /* SLConfigDescr_length */ - switch( IODGetBytes( &i_data, &p_data, 1 ) /* predefined */ ) - { - default: - ts_debug( "\n* ERR unsupported SLConfigDescr predefined" ); - case 0x01: - // FIXME - break; - } - es_descr->b_ok = true; - } - - return p_iod; -} - -static void IODFree( iod_descriptor_t *p_iod ) -{ - if( p_iod->psz_url ) - { - free( p_iod->psz_url ); - free( p_iod ); - return; - } - - for( int i = 0; i < 255; i++ ) - { -#define es_descr p_iod->es_descr[i] - if( es_descr.b_ok ) - { - if( es_descr.psz_url ) - free( es_descr.psz_url ); - else - free( es_descr.dec_descr.p_extra ); - } -#undef es_descr - } - free( p_iod ); -} - /**************************************************************************** **************************************************************************** ** libdvbpsi callbacks @@ -5301,7 +5036,7 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt ) { case 0x1d: /* We have found an IOD descriptor */ msg_Dbg( p_demux, " * PMT descriptor : IOD (0x1d)" ); - p_pmt->iod = IODNew( p_dr->i_length, p_dr->p_data ); + p_pmt->iod = IODNew( VLC_OBJECT(p_demux), p_dr->i_length, p_dr->p_data ); break; case 0x9: -- 2.39.2