Commit 934d64c3 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: ogg: implement speex backward duration fixing (fix #11283)

Because all pages except last are -1
parent f9c5295c
...@@ -411,6 +411,7 @@ static int Demux( demux_t * p_demux ) ...@@ -411,6 +411,7 @@ static int Demux( demux_t * p_demux )
// PASS 0 // PASS 0
if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS || if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
p_stream->fmt.i_codec == VLC_CODEC_VORBIS || p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
p_stream->fmt.i_cat == VIDEO_ES ) p_stream->fmt.i_cat == VIDEO_ES )
{ {
assert( p_stream->p_prepcr_blocks == NULL ); assert( p_stream->p_prepcr_blocks == NULL );
...@@ -483,6 +484,10 @@ static int Demux( demux_t * p_demux ) ...@@ -483,6 +484,10 @@ static int Demux( demux_t * p_demux )
switch( p_stream->fmt.i_codec ) switch( p_stream->fmt.i_codec )
{ {
case VLC_CODEC_SPEEX:
p_block->i_nb_samples = p_stream->special.speex.i_framesize *
p_stream->special.speex.i_framesperpacket;
break;
case VLC_CODEC_OPUS: case VLC_CODEC_OPUS:
i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet ); i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
p_block->i_nb_samples = i_duration; p_block->i_nb_samples = i_duration;
...@@ -510,6 +515,7 @@ static int Demux( demux_t * p_demux ) ...@@ -510,6 +515,7 @@ static int Demux( demux_t * p_demux )
block_t *p_block = p_stream->p_prepcr_blocks[i]; block_t *p_block = p_stream->p_prepcr_blocks[i];
switch( p_stream->fmt.i_codec ) switch( p_stream->fmt.i_codec )
{ {
case VLC_CODEC_SPEEX:
case VLC_CODEC_OPUS: case VLC_CODEC_OPUS:
case VLC_CODEC_VORBIS: case VLC_CODEC_VORBIS:
pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate; pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
...@@ -921,6 +927,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream, ...@@ -921,6 +927,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
p_stream->fmt.i_codec == VLC_CODEC_KATE || p_stream->fmt.i_codec == VLC_CODEC_KATE ||
p_stream->fmt.i_codec == VLC_CODEC_VP8 || p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
p_stream->fmt.i_codec == VLC_CODEC_DIRAC || p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
(p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) ) (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
{ {
p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream, p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
...@@ -981,6 +988,16 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream, ...@@ -981,6 +988,16 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
p_stream->i_pcr += p_ogg->i_nzpcr_offset; p_stream->i_pcr += p_ogg->i_nzpcr_offset;
} }
#endif #endif
else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
p_stream->i_previous_granulepos > 0 )
{
i_duration = p_stream->special.speex.i_framesize *
p_stream->special.speex.i_framesperpacket;
p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
p_stream->i_previous_granulepos, false );
p_stream->i_pcr += p_ogg->i_nzpcr_offset;
}
else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
p_stream->i_previous_granulepos > 0 && p_stream->i_previous_granulepos > 0 &&
( i_duration = ( i_duration =
...@@ -1494,9 +1511,11 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -1494,9 +1511,11 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
{ {
if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) ) if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
msg_Dbg( p_demux, "found speex header, channels: %i, " msg_Dbg( p_demux, "found speex header, channels: %i, "
"rate: %i, bitrate: %i", "rate: %i, bitrate: %i, frames: %i group %i",
p_stream->fmt.audio.i_channels, p_stream->fmt.audio.i_channels,
(int)p_stream->f_rate, p_stream->fmt.i_bitrate ); (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
p_stream->special.speex.i_framesize,
p_stream->special.speex.i_framesperpacket );
else else
{ {
msg_Dbg( p_demux, "found invalid Speex header" ); msg_Dbg( p_demux, "found invalid Speex header" );
...@@ -2538,9 +2557,11 @@ static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream, ...@@ -2538,9 +2557,11 @@ static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 ); p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
fill_channels_info(&p_stream->fmt.audio); fill_channels_info(&p_stream->fmt.audio);
p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
oggpack_adv( &opb, 32 ); /* frame_size */ p_stream->special.speex.i_framesize =
oggpack_read( &opb, 32 ); /* frame_size */
oggpack_adv( &opb, 32 ); /* vbr */ oggpack_adv( &opb, 32 ); /* vbr */
oggpack_adv( &opb, 32 ); /* frames_per_packet */ p_stream->special.speex.i_framesperpacket =
oggpack_read( &opb, 32 ); /* frames_per_packet */
p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */ p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
return true; return true;
} }
......
...@@ -140,6 +140,11 @@ typedef struct logical_stream_s ...@@ -140,6 +140,11 @@ typedef struct logical_stream_s
{ {
bool b_interlaced; bool b_interlaced;
} dirac; } dirac;
struct
{
int32_t i_framesize;
int32_t i_framesperpacket;
} speex;
} special; } special;
} logical_stream_t; } logical_stream_t;
......
...@@ -729,6 +729,14 @@ int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream, ...@@ -729,6 +729,14 @@ int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
i_timestamp = i_granule * CLOCK_FREQ / p_stream->f_rate; i_timestamp = i_granule * CLOCK_FREQ / p_stream->f_rate;
break; break;
} }
case VLC_CODEC_SPEEX:
{
if ( b_presentation )
i_granule -= p_stream->special.speex.i_framesize *
p_stream->special.speex.i_framesperpacket;
i_timestamp = i_granule * CLOCK_FREQ / p_stream->f_rate;
break;
}
} }
return i_timestamp; return i_timestamp;
......
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