Commit 9fd30bf5 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen Committed by Jean-Baptiste Kempf

ogg: Fix theora length computing.

Fix #1859 #6983
(cherry picked from commit e80525ad5743f2117ac89327c88c98516946f26f)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 5c46f9de
...@@ -136,13 +136,13 @@ static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t * ...@@ -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 ); static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers );
/* Logical bitstream 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_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
static void Ogg_ReadSpeexHeader( 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( logical_stream_t *, ogg_packet * );
static void Ogg_ReadKateHeader( 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_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 * ); static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
/***************************************************************************** /*****************************************************************************
...@@ -178,6 +178,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -178,6 +178,8 @@ static int Open( vlc_object_t * p_this )
p_sys->i_bos = 0; p_sys->i_bos = 0;
p_sys->i_eos = 0; p_sys->i_eos = 0;
p_sys->i_length = -1;
/* Initialize the Ogg physical bitstream parser */ /* Initialize the Ogg physical bitstream parser */
ogg_sync_init( &p_sys->oy ); ogg_sync_init( &p_sys->oy );
p_sys->b_page_waiting = false; p_sys->b_page_waiting = false;
...@@ -306,7 +308,7 @@ static int Demux( demux_t * p_demux ) ...@@ -306,7 +308,7 @@ static int Demux( demux_t * p_demux )
oggpacket.bytes >= 7 && oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "\x80theora", 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; p_stream->i_secondary_header_packets = 0;
} }
else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS && 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 ) ...@@ -464,8 +466,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
ogg_stream_reset( &p_stream->os ); ogg_stream_reset( &p_stream->os );
} }
ogg_sync_reset( &p_sys->oy ); ogg_sync_reset( &p_sys->oy );
/* XXX The break/return is missing on purpose as return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
* demux_vaControlHelper will do the last part of the job */ 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: default:
return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate, return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
...@@ -1026,7 +1036,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -1026,7 +1036,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 && else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "\x80theora", 7 ) ) ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
{ {
Ogg_ReadTheoraHeader( p_stream, &oggpacket ); Ogg_ReadTheoraHeader( p_demux, p_stream, &oggpacket );
msg_Dbg( p_demux, msg_Dbg( p_demux,
"found theora header, bitrate: %i, rate: %f", "found theora header, bitrate: %i, rate: %f",
...@@ -1071,8 +1081,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -1071,8 +1081,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 && else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "Annodex", 7 ) ) ! memcmp( oggpacket.packet, "Annodex", 7 ) )
{ {
Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream, Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
&oggpacket );
/* kill annodex track */ /* kill annodex track */
free( p_stream ); free( p_stream );
p_ogg->i_streams--; p_ogg->i_streams--;
...@@ -1081,8 +1090,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -1081,8 +1090,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 7 && else if( oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "AnxData", 7 ) ) ! memcmp( oggpacket.packet, "AnxData", 7 ) )
{ {
Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream, Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
&oggpacket );
} }
/* Check for Kate header */ /* Check for Kate header */
else if( oggpacket.bytes >= 8 && else if( oggpacket.bytes >= 8 &&
...@@ -1611,7 +1619,7 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8 ...@@ -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; 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 ) ogg_packet *p_oggpacket )
{ {
bs_t bitstream; bs_t bitstream;
...@@ -1676,6 +1684,21 @@ static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream, ...@@ -1676,6 +1684,21 @@ static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
{ {
p_stream->i_keyframe_offset = 1; 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; p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
} }
...@@ -1851,7 +1874,7 @@ static void Ogg_ReadKateHeader( logical_stream_t *p_stream, ...@@ -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, logical_stream_t *p_stream,
ogg_packet *p_oggpacket ) ogg_packet *p_oggpacket )
{ {
...@@ -1865,7 +1888,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this, ...@@ -1865,7 +1888,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
uint64_t timebase_numerator; uint64_t timebase_numerator;
uint64_t timebase_denominator; 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_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */ oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
...@@ -1900,7 +1923,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this, ...@@ -1900,7 +1923,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
content_type_string ); 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, granule_rate_numerator, granule_rate_denominator,
p_stream->i_secondary_header_packets, content_type_string ); p_stream->i_secondary_header_packets, content_type_string );
......
...@@ -137,4 +137,7 @@ struct demux_sys_t ...@@ -137,4 +137,7 @@ struct demux_sys_t
/* */ /* */
int i_attachments; int i_attachments;
input_attachment_t **attachments; input_attachment_t **attachments;
/* Length, if available. */
int64_t i_length;
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment