[vlc-commits] ogg: Fix theora length computing.
Hugo Beauzée-Luyssen
git at videolan.org
Tue Sep 4 00:04:09 CEST 2012
vlc/vlc-2.0 | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Wed Aug 8 22:48:32 2012 +0300| [9fd30bf5f0321119adbdf1add47b9cfa42ed6d3a] | committer: Jean-Baptiste Kempf
ogg: Fix theora length computing.
Fix #1859 #6983
(cherry picked from commit e80525ad5743f2117ac89327c88c98516946f26f)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=9fd30bf5f0321119adbdf1add47b9cfa42ed6d3a
---
modules/demux/ogg.c | 51 +++++++++++++++++++++++++++++++++++++--------------
modules/demux/ogg.h | 3 +++
2 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 5b0c59f..d4f4c97 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -136,13 +136,13 @@ 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 );
/* Logical bitstream headers */
-static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
+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_ReadKateHeader( logical_stream_t *, ogg_packet * );
static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
-static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
+static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
/*****************************************************************************
@@ -178,6 +178,8 @@ static int Open( vlc_object_t * p_this )
p_sys->i_bos = 0;
p_sys->i_eos = 0;
+ p_sys->i_length = -1;
+
/* Initialize the Ogg physical bitstream parser */
ogg_sync_init( &p_sys->oy );
p_sys->b_page_waiting = false;
@@ -306,7 +308,7 @@ static int Demux( demux_t * p_demux )
oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "\x80theora", 7 ) )
{
- Ogg_ReadTheoraHeader( p_stream, &oggpacket );
+ Ogg_ReadTheoraHeader( p_demux, p_stream, &oggpacket );
p_stream->i_secondary_header_packets = 0;
}
else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
@@ -464,8 +466,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
ogg_stream_reset( &p_stream->os );
}
ogg_sync_reset( &p_sys->oy );
- /* XXX The break/return is missing on purpose as
- * demux_vaControlHelper will do the last part of the job */
+ return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
+ 1, i_query, args );
+ case DEMUX_GET_LENGTH:
+ if ( p_sys->i_length < 0 )
+ return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
+ 1, i_query, args );
+ pi64 = (int64_t*)va_arg( args, int64_t * );
+ *pi64 = p_sys->i_length * 1000000;
+ return VLC_SUCCESS;
+
default:
return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
@@ -1026,7 +1036,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "\x80theora", 7 ) )
{
- Ogg_ReadTheoraHeader( p_stream, &oggpacket );
+ Ogg_ReadTheoraHeader( p_demux, p_stream, &oggpacket );
msg_Dbg( p_demux,
"found theora header, bitrate: %i, rate: %f",
@@ -1071,8 +1081,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "Annodex", 7 ) )
{
- Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
- &oggpacket );
+ Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
/* kill annodex track */
free( p_stream );
p_ogg->i_streams--;
@@ -1081,8 +1090,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "AnxData", 7 ) )
{
- Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
- &oggpacket );
+ Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
}
/* Check for Kate header */
else if( oggpacket.bytes >= 8 &&
@@ -1611,7 +1619,7 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8
p_demux->info.i_update |= INPUT_UPDATE_META;
}
-static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
+static void Ogg_ReadTheoraHeader( demux_t *p_demux, logical_stream_t *p_stream,
ogg_packet *p_oggpacket )
{
bs_t bitstream;
@@ -1676,6 +1684,21 @@ static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
{
p_stream->i_keyframe_offset = 1;
}
+ 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 / ((float)i_fps_numerator /
+ (float)i_fps_denominator);
+ }
+ }
p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
}
@@ -1851,7 +1874,7 @@ static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
}
}
-static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
+static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
logical_stream_t *p_stream,
ogg_packet *p_oggpacket )
{
@@ -1865,7 +1888,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
uint64_t timebase_numerator;
uint64_t timebase_denominator;
- Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
+ Ogg_ReadTheoraHeader( p_demux, p_stream, p_oggpacket );
oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
@@ -1900,7 +1923,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
content_type_string );
}
- msg_Dbg( p_this, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
+ msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
granule_rate_numerator, granule_rate_denominator,
p_stream->i_secondary_header_packets, content_type_string );
diff --git a/modules/demux/ogg.h b/modules/demux/ogg.h
index 6dae0a4..8c1d72b 100644
--- a/modules/demux/ogg.h
+++ b/modules/demux/ogg.h
@@ -137,4 +137,7 @@ struct demux_sys_t
/* */
int i_attachments;
input_attachment_t **attachments;
+
+ /* Length, if available. */
+ int64_t i_length;
};
More information about the vlc-commits
mailing list