[vlc-commits] ogg: Fix borken stream resets.
Timothy B. Terriberry
git at videolan.org
Thu Feb 28 09:16:54 CET 2013
vlc/vlc-2.0 | branch: master | Timothy B. Terriberry <tterribe at xiph.org> | Tue Feb 26 18:36:02 2013 -0800| [1e604e1f26edad8cea2ecab42913a982409d81c9] | committer: Jean-Baptiste Kempf
ogg: Fix borken stream resets.
Commit 78a8771f attempted to reset the ogg_stream_state in
find_last_frame(), but it tries to do so using a non-existent page
and then leaks memory (due to using ogg_stream_init() instead of
ogg_stream_reset()). Its caller, Ogg_GetLastPacket(), then tries
to restore the contents of the current packet, but its call to
ogg_stream_pageseek() will immediately fail, leaving the dangling
packet pointers untouched.
Instead, just back up the whole stream state and restore it on
exit. This fixes both problems.
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
(cherry picked from commit d6aeeebe0c7ec9f4defe1751454bc3c1943d84e1)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=1e604e1f26edad8cea2ecab42913a982409d81c9
---
modules/demux/ogg.c | 16 +++++-----------
modules/demux/oggseek.c | 13 ++++++++++---
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 29b65bc..8a041c6 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -135,7 +135,7 @@ static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *
/* */
static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers );
-static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream, ogg_packet *p_oggpacket, double f_rate );
+static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream, double f_rate );
/* Logical bitstream headers */
static void Ogg_ReadTheoraHeader( demux_t *, logical_stream_t *, ogg_packet * );
@@ -1827,15 +1827,9 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8
}
static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream,
- ogg_packet *p_oggpacket, double f_rate )
+ double f_rate )
{
int64_t last_packet = 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 );
-
return ( last_packet >= 0 ) ? last_packet / f_rate : -1;
}
@@ -1907,7 +1901,7 @@ static void Ogg_ReadTheoraHeader( demux_t *p_demux, logical_stream_t *p_stream,
}
if ( p_demux->p_sys->i_length < 0 )
{
- int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+ int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
if ( last_packet >= 0 )
p_demux->p_sys->i_length = last_packet;
}
@@ -1938,7 +1932,7 @@ static void Ogg_ReadVorbisHeader( demux_t *p_demux, logical_stream_t *p_stream,
if ( p_demux->p_sys->i_length < 0 )
{
- int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+ int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
if ( last_packet >= 0 )
p_demux->p_sys->i_length = last_packet;
}
@@ -1997,7 +1991,7 @@ static void Ogg_ReadOpusHeader( demux_t *p_demux,
if ( p_demux->p_sys->i_length < 0 )
{
- int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+ int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
if ( last_packet >= 0 )
p_demux->p_sys->i_length = last_packet;
}
diff --git a/modules/demux/oggseek.c b/modules/demux/oggseek.c
index 42d08ee..e22f66f 100644
--- a/modules/demux/oggseek.c
+++ b/modules/demux/oggseek.c
@@ -696,6 +696,14 @@ 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;
+ ogg_stream_state os;
+
+ /* Backup the stream state. We get called during header processing, and our
+ * caller expects its header packet to remain valid after the call. If we
+ * let find_last_frame() reuse the same stream state, then it will
+ * invalidate the pointers in that packet. */
+ memcpy(&os, &p_stream->os, sizeof(os));
+ ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
i_frame = find_last_frame ( p_demux, p_stream );
@@ -708,9 +716,8 @@ static int64_t get_last_frame ( demux_t *p_demux, logical_stream_t *p_stream )
seek_byte( p_demux, 0 );
/* Reset stream states */
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_sys->current_page );
+ ogg_stream_clear( &p_stream->os );
+ memcpy( &p_stream->os, &os, sizeof(os) );
return i_frame;
}
More information about the vlc-commits
mailing list