vlc | branch: master | Ludovic Fauvet <[email protected]> | Thu Sep 6 12:38:49 2012 +0200| [bc6a86c077196e8a48230f37e43a9167cadf97ef] | committer: Jean-Baptiste Kempf
ogg: find the length of an opus stream Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bc6a86c077196e8a48230f37e43a9167cadf97ef --- modules/demux/ogg.c | 22 +++++++++++++++++++--- modules/demux/oggseek.c | 17 ++++++++++------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c index 18b43de..3830e89 100644 --- a/modules/demux/ogg.c +++ b/modules/demux/ogg.c @@ -140,7 +140,7 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8 static void Ogg_ReadTheoraHeader( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * ); static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * ); -static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * ); +static void Ogg_ReadOpusHeader( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * ); static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * ); @@ -1113,7 +1113,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) else if( oggpacket.bytes >= 8 && ! memcmp( oggpacket.packet, "OpusHead", 8 ) ) { - Ogg_ReadOpusHeader( p_stream, &oggpacket ); + Ogg_ReadOpusHeader( p_demux, p_stream, &oggpacket ); msg_Dbg( p_demux, "found opus header, channels: %i, " "pre-skip: %i", p_stream->fmt.audio.i_channels, @@ -1958,7 +1958,8 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream, p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); } -static void Ogg_ReadOpusHeader( logical_stream_t *p_stream, +static void Ogg_ReadOpusHeader( demux_t *p_demux, + logical_stream_t *p_stream, ogg_packet *p_oggpacket ) { oggpack_buffer opb; @@ -1982,6 +1983,21 @@ static void Ogg_ReadOpusHeader( logical_stream_t *p_stream, oggpack_adv( &opb, 8 ); /* version_id */ p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 ); p_stream->i_pre_skip = oggpack_read( &opb, 16 ); + + if ( p_demux->p_sys->i_length < 0 ) + { + int64_t last_frame = oggseek_get_last_frame( p_demux, p_stream ); + /* + * Since there's quite a good chance that ogg_stream_packetout was called, + * the given p_oggpacket may point to invalid data. Fill it with some valid ones + */ + ogg_stream_packetpeek( &p_stream->os, p_oggpacket ); + + if ( last_frame >= 0 ) + { + p_demux->p_sys->i_length = last_frame / p_stream->f_rate; + } + } } static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream, diff --git a/modules/demux/oggseek.c b/modules/demux/oggseek.c index c67f8e0..49d8bde 100644 --- a/modules/demux/oggseek.c +++ b/modules/demux/oggseek.c @@ -690,10 +690,11 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t } -/* get highest frame in theora stream */ +/* get highest frame in theora and opus streams */ -static int64_t find_last_theora_frame ( demux_t *p_demux, logical_stream_t *p_stream ) +static int64_t get_last_frame ( demux_t *p_demux, logical_stream_t *p_stream ) { + demux_sys_t *p_sys = p_demux->p_sys; int64_t i_frame; i_frame = find_last_frame ( p_demux, p_stream ); @@ -706,9 +707,10 @@ static int64_t find_last_theora_frame ( demux_t *p_demux, logical_stream_t *p_st seek_byte( p_demux, 0 ); /* Reset stream states */ - p_stream->i_serial_no = ogg_page_serialno( &p_demux->p_sys->current_page ); + p_sys->i_streams = 0; + p_stream->i_serial_no = ogg_page_serialno( &p_sys->current_page ); ogg_stream_init( &p_stream->os, p_stream->i_serial_no ); - ogg_stream_pagein( &p_stream->os, &p_demux->p_sys->current_page ); + ogg_stream_pagein( &p_stream->os, &p_sys->current_page ); return i_frame; } @@ -722,15 +724,16 @@ static int64_t find_last_theora_frame ( demux_t *p_demux, logical_stream_t *p_st -/* return highest frame number for p_stream (which must be a theora or dirac video stream) */ +/* return highest frame number for p_stream (which must be a theora, dirac or opus stream) */ int64_t oggseek_get_last_frame ( demux_t *p_demux, logical_stream_t *p_stream ) { int64_t i_frame = -1; - if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA ) + if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA || + p_stream->fmt.i_codec == VLC_CODEC_OPUS ) { - i_frame = find_last_theora_frame ( p_demux, p_stream ); + i_frame = get_last_frame ( p_demux, p_stream ); if ( i_frame < 0 ) return -1; return i_frame; _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
