[vlc-commits] ogg: find the length of an opus stream
Ludovic Fauvet
git at videolan.org
Fri Sep 7 00:42:28 CEST 2012
vlc/vlc-2.0 | branch: master | Ludovic Fauvet <etix at videolan.org> | Thu Sep 6 12:38:49 2012 +0200| [6cb68abc190a4179f47e837c393ef46f6d11c2fd] | committer: Rafaël Carré
ogg: find the length of an opus stream
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
(cherry picked from commit bc6a86c077196e8a48230f37e43a9167cadf97ef)
Signed-off-by: Rafaël Carré <funman at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=6cb68abc190a4179f47e837c393ef46f6d11c2fd
---
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 9b15998..288c98c 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,
@@ -1957,7 +1957,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;
@@ -1981,6 +1982,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;
More information about the vlc-commits
mailing list