$OpenBSD: patch-modules_demux_ogg_c,v 1.7 2008/09/04 22:58:23 brad Exp $ --- modules/demux/ogg.c.orig Tue Jul 8 16:59:23 2008 +++ modules/demux/ogg.c Tue Sep 2 02:07:40 2008 @@ -105,20 +105,21 @@ struct demux_sys_t }; /* OggDS headers for the new header format (used in ogm files) */ -typedef struct stream_header_video +typedef struct { ogg_int32_t width; ogg_int32_t height; -} stream_header_video; +} stream_header_video_t; -typedef struct stream_header_audio +typedef struct { ogg_int16_t channels; + ogg_int16_t padding; ogg_int16_t blockalign; ogg_int32_t avgbytespersec; -} stream_header_audio; +} stream_header_audio_t; -typedef struct stream_header +typedef struct { char streamtype[8]; char subtype[4]; @@ -131,15 +132,16 @@ typedef struct stream_header ogg_int32_t buffersize; ogg_int16_t bits_per_sample; + ogg_int16_t padding; union { /* Video specific */ - stream_header_video video; + stream_header_video_t video; /* Audio specific */ - stream_header_audio audio; + stream_header_audio_t audio; } sh; -} stream_header; +} stream_header_t; #define OGG_BLOCK_SIZE 4096 @@ -193,6 +195,8 @@ static int Open( vlc_object_t * p_this ) p_demux->pf_demux = Demux; p_demux->pf_control = Control; p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; memset( p_sys, 0, sizeof( demux_sys_t ) ); p_sys->i_bitrate = 0; @@ -506,7 +510,7 @@ static void Ogg_DecodePacket( demux_t *p_demux, if( p_stream->b_force_backup ) { - uint8_t *p_extra; + uint8_t *p_sav; vlc_bool_t b_store_size = VLC_TRUE; p_stream->i_packets_backup++; @@ -543,27 +547,34 @@ static void Ogg_DecodePacket( demux_t *p_demux, /* Backup the ogg packet (likely an header packet) */ p_stream->p_headers = - realloc( p_stream->p_headers, p_stream->i_headers + + realloc( p_sav = p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes + (b_store_size ? 2 : 0) ); - p_extra = p_stream->p_headers + p_stream->i_headers; - if( b_store_size ) + if( p_stream->p_headers ) { - *(p_extra++) = p_oggpacket->bytes >> 8; - *(p_extra++) = p_oggpacket->bytes & 0xFF; - } - memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes ); - p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0); + uint8_t *p_extra = p_stream->p_headers + p_stream->i_headers; + if( b_store_size ) + { + *(p_extra++) = p_oggpacket->bytes >> 8; + *(p_extra++) = p_oggpacket->bytes & 0xFF; + } + memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes ); + p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0); - if( !p_stream->b_force_backup ) + if( !p_stream->b_force_backup ) + { + /* Last header received, commit changes */ + p_stream->fmt.i_extra = p_stream->i_headers; + p_stream->fmt.p_extra = + realloc( p_stream->fmt.p_extra, p_stream->i_headers ); + memcpy( p_stream->fmt.p_extra, p_stream->p_headers, + p_stream->i_headers ); + es_out_Control( p_demux->out, ES_OUT_SET_FMT, + p_stream->p_es, &p_stream->fmt ); + } + } + else { - /* Last header received, commit changes */ - p_stream->fmt.i_extra = p_stream->i_headers; - p_stream->fmt.p_extra = - realloc( p_stream->fmt.p_extra, p_stream->i_headers ); - memcpy( p_stream->fmt.p_extra, p_stream->p_headers, - p_stream->i_headers ); - es_out_Control( p_demux->out, ES_OUT_SET_FMT, - p_stream->p_es, &p_stream->fmt ); + p_stream->p_headers = p_sav; } b_selected = VLC_FALSE; /* Discard the header packet */ @@ -728,8 +739,6 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ogg_page oggpage; int i_stream; -#define p_stream p_ogg->pp_stream[p_ogg->i_streams - 1] - while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS ) { if( ogg_page_bos( &oggpage ) ) @@ -739,12 +748,15 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) * We found the beginning of our first logical stream. */ while( ogg_page_bos( &oggpage ) ) { - p_ogg->i_streams++; - p_ogg->pp_stream = - realloc( p_ogg->pp_stream, p_ogg->i_streams * - sizeof(logical_stream_t *) ); + logical_stream_t **pp_sav = p_ogg->pp_stream; + logical_stream_t *p_stream; p_stream = malloc( sizeof(logical_stream_t) ); + if( !p_stream ) + return VLC_ENOMEM; + + TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream ); + memset( p_stream, 0, sizeof(logical_stream_t) ); p_stream->p_headers = 0; p_stream->secondary_header_packets = 0; @@ -916,12 +928,15 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) p_stream->fmt.i_cat = AUDIO_ES; i_extra_size = GetWLE((oggpacket.packet+140)); - if( i_extra_size ) + if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 ) { p_stream->fmt.i_extra = i_extra_size; p_stream->fmt.p_extra = malloc( i_extra_size ); - memcpy( p_stream->fmt.p_extra, - oggpacket.packet + 142, i_extra_size ); + if( p_stream->fmt.p_extra ) + memcpy( p_stream->fmt.p_extra, + oggpacket.packet + 142, i_extra_size ); + else + p_stream->fmt.i_extra = 0; } i_format_tag = GetWLE((oggpacket.packet+124)); @@ -966,15 +981,27 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) p_ogg->i_streams--; } } - else if( (*oggpacket.packet & PACKET_TYPE_BITS ) - == PACKET_TYPE_HEADER && - oggpacket.bytes >= (int)sizeof(stream_header)+1 ) + else if( (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER && + oggpacket.bytes >= 56+1 ) { - stream_header *st = (stream_header *)(oggpacket.packet+1); + stream_header_t tmp; + stream_header_t *st = &tmp; + memcpy( st->streamtype, &oggpacket.packet[1+0], 8 ); + memcpy( st->subtype, &oggpacket.packet[1+8], 4 ); + st->size = GetDWLE( &oggpacket.packet[1+12] ); + st->time_unit = GetQWLE( &oggpacket.packet[1+16] ); + st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] ); + st->default_len = GetDWLE( &oggpacket.packet[1+32] ); + st->buffersize = GetDWLE( &oggpacket.packet[1+36] ); + st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2) + /* Check for video header (new format) */ if( !strncmp( st->streamtype, "video", 5 ) ) { + st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] ); + st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] ); + p_stream->fmt.i_cat = VIDEO_ES; /* We need to get rid of the header packet */ @@ -987,16 +1014,13 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) (char *)&p_stream->fmt.i_codec ); p_stream->fmt.video.i_frame_rate = 10000000; - p_stream->fmt.video.i_frame_rate_base = - GetQWLE(&st->time_unit); - p_stream->f_rate = 10000000.0 / - GetQWLE(&st->time_unit); - p_stream->fmt.video.i_bits_per_pixel = - GetWLE(&st->bits_per_sample); - p_stream->fmt.video.i_width = - GetDWLE(&st->sh.video.width); - p_stream->fmt.video.i_height = - GetDWLE(&st->sh.video.height); + p_stream->fmt.video.i_frame_rate_base = st->time_unit; + if( st->time_unit <= 0 ) + st->time_unit = 400000; + p_stream->f_rate = 10000000.0 / st->time_unit; + p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample; + p_stream->fmt.video.i_width = st->sh.video.width; + p_stream->fmt.video.i_height = st->sh.video.height; msg_Dbg( p_demux, "fps: %f, width:%i; height:%i, bitcount:%i", @@ -1009,36 +1033,42 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) else if( !strncmp( st->streamtype, "audio", 5 ) ) { char p_buffer[5]; + unsigned int i_extra_size; int i_format_tag; + st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] ); + st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] ); + st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] ); + p_stream->fmt.i_cat = AUDIO_ES; /* We need to get rid of the header packet */ ogg_stream_packetout( &p_stream->os, &oggpacket ); - p_stream->fmt.i_extra = GetQWLE(&st->size) - - sizeof(stream_header); - if( p_stream->fmt.i_extra ) + i_extra_size = st->size - 56; + + if( i_extra_size > 0 && + i_extra_size < oggpacket.bytes - 1 - 56 ) { - p_stream->fmt.p_extra = - malloc( p_stream->fmt.i_extra ); - memcpy( p_stream->fmt.p_extra, st + 1, - p_stream->fmt.i_extra ); + p_stream->fmt.i_extra = i_extra_size; + p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra ); + if( p_stream->fmt.p_extra ) + memcpy( p_stream->fmt.p_extra, st + 1, + p_stream->fmt.i_extra ); + else + p_stream->fmt.i_extra = 0; } memcpy( p_buffer, st->subtype, 4 ); p_buffer[4] = '\0'; i_format_tag = strtol(p_buffer,NULL,16); - p_stream->fmt.audio.i_channels = - GetWLE(&st->sh.audio.channels); - p_stream->f_rate = p_stream->fmt.audio.i_rate = - GetQWLE(&st->samples_per_unit); - p_stream->fmt.i_bitrate = - GetDWLE(&st->sh.audio.avgbytespersec) * 8; - p_stream->fmt.audio.i_blockalign = - GetWLE(&st->sh.audio.blockalign); - p_stream->fmt.audio.i_bitspersample = - GetWLE(&st->bits_per_sample); + p_stream->fmt.audio.i_channels = st->sh.audio.channels; + if( st->time_unit <= 0 ) + st->time_unit = 10000000; + p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit; + p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8; + p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign; + p_stream->fmt.audio.i_bitspersample = st->bits_per_sample; wf_tag_to_fourcc( i_format_tag, &p_stream->fmt.i_codec, 0 ); @@ -1116,7 +1146,6 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) return VLC_SUCCESS; } } -#undef p_stream return VLC_EGENERIC; } @@ -1374,7 +1403,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_thi uint8_t *p = memchr( &p_oggpacket->packet[42], '\r', p_oggpacket->bytes - 1 ); if( p && p[0] == '\r' && p[1] == '\n' ) - sscanf( (char*)(&p_oggpacket->packet[42]), "%1024s\r\n", + sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n", content_type_string ); }