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 * );
/*****************************************************************************
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;
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 &&
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,
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",
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--;
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 &&
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;
{
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;
}
}
}
-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 )
{
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 */
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 );