[vlc-commits] demux: ogg: implement speex backward duration fixing (fix #11283)

Francois Cartegnie git at videolan.org
Wed Apr 23 13:19:14 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Apr 23 13:14:26 2014 +0200| [934d64c39cf021504f63e53fa36292dbc8fa9175] | committer: Francois Cartegnie

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

Because all pages except last are -1

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=934d64c39cf021504f63e53fa36292dbc8fa9175
---

 modules/demux/ogg.c     |   29 +++++++++++++++++++++++++----
 modules/demux/ogg.h     |    5 +++++
 modules/demux/oggseek.c |    8 ++++++++
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 36ec242..b6de5df 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -411,6 +411,7 @@ static int Demux( demux_t * p_demux )
             // PASS 0
             if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
                  p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
+                 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
                  p_stream->fmt.i_cat == VIDEO_ES )
             {
                 assert( p_stream->p_prepcr_blocks == NULL );
@@ -483,6 +484,10 @@ static int Demux( demux_t * p_demux )
 
                 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:
                     i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
                     p_block->i_nb_samples = i_duration;
@@ -510,6 +515,7 @@ static int Demux( demux_t * p_demux )
                 block_t *p_block = p_stream->p_prepcr_blocks[i];
                 switch( p_stream->fmt.i_codec )
                 {
+                case VLC_CODEC_SPEEX:
                 case VLC_CODEC_OPUS:
                 case VLC_CODEC_VORBIS:
                     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,
             p_stream->fmt.i_codec == VLC_CODEC_KATE ||
             p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
             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->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,
             p_stream->i_pcr += p_ogg->i_nzpcr_offset;
         }
 #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 &&
                  p_stream->i_previous_granulepos > 0 &&
                  ( i_duration =
@@ -1494,9 +1511,11 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                 {
                     if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
                         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,
-                                (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
                     {
                         msg_Dbg( p_demux, "found invalid Speex header" );
@@ -2538,9 +2557,11 @@ static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
     fill_channels_info(&p_stream->fmt.audio);
     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 ); /* 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 */
     return true;
 }
diff --git a/modules/demux/ogg.h b/modules/demux/ogg.h
index 71cf096..dda4684 100644
--- a/modules/demux/ogg.h
+++ b/modules/demux/ogg.h
@@ -140,6 +140,11 @@ typedef struct logical_stream_s
         {
             bool b_interlaced;
         } dirac;
+        struct
+        {
+            int32_t i_framesize;
+            int32_t i_framesperpacket;
+        } speex;
     } special;
 
 } logical_stream_t;
diff --git a/modules/demux/oggseek.c b/modules/demux/oggseek.c
index 738a73f..8ed3344 100644
--- a/modules/demux/oggseek.c
+++ b/modules/demux/oggseek.c
@@ -729,6 +729,14 @@ int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
         i_timestamp = i_granule * CLOCK_FREQ / p_stream->f_rate;
         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;



More information about the vlc-commits mailing list