Commit 6cb68abc authored by Ludovic Fauvet's avatar Ludovic Fauvet Committed by Rafaël Carré

ogg: find the length of an opus stream

Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
(cherry picked from commit bc6a86c077196e8a48230f37e43a9167cadf97ef)
Signed-off-by: default avatarRafaël Carré <funman@videolan.org>
parent ae71018b
...@@ -140,7 +140,7 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8 ...@@ -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_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( demux_t *, 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( 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 ) ...@@ -1113,7 +1113,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 8 && else if( oggpacket.bytes >= 8 &&
! memcmp( oggpacket.packet, "OpusHead", 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, " msg_Dbg( p_demux, "found opus header, channels: %i, "
"pre-skip: %i", "pre-skip: %i",
p_stream->fmt.audio.i_channels, p_stream->fmt.audio.i_channels,
...@@ -1957,7 +1957,8 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream, ...@@ -1957,7 +1957,8 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); 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 ) ogg_packet *p_oggpacket )
{ {
oggpack_buffer opb; oggpack_buffer opb;
...@@ -1981,6 +1982,21 @@ static void Ogg_ReadOpusHeader( logical_stream_t *p_stream, ...@@ -1981,6 +1982,21 @@ static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
oggpack_adv( &opb, 8 ); /* version_id */ oggpack_adv( &opb, 8 ); /* version_id */
p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 ); p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
p_stream->i_pre_skip = oggpack_read( &opb, 16 ); 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, static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
......
...@@ -690,10 +690,11 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t ...@@ -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; int64_t i_frame;
i_frame = find_last_frame ( p_demux, p_stream ); 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 ...@@ -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 ); seek_byte( p_demux, 0 );
/* Reset stream states */ /* 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_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; return i_frame;
} }
...@@ -722,15 +724,16 @@ static int64_t find_last_theora_frame ( demux_t *p_demux, logical_stream_t *p_st ...@@ -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 oggseek_get_last_frame ( demux_t *p_demux, logical_stream_t *p_stream )
{ {
int64_t i_frame = -1; 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; if ( i_frame < 0 ) return -1;
return i_frame; return i_frame;
......
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