[vlc-commits] ogg: Fix theora length computing.

Hugo Beauzée-Luyssen git at videolan.org
Tue Sep 4 00:04:09 CEST 2012


vlc/vlc-2.0 | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Wed Aug  8 22:48:32 2012 +0300| [9fd30bf5f0321119adbdf1add47b9cfa42ed6d3a] | committer: Jean-Baptiste Kempf

ogg: Fix theora length computing.

Fix #1859 #6983
(cherry picked from commit e80525ad5743f2117ac89327c88c98516946f26f)

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=9fd30bf5f0321119adbdf1add47b9cfa42ed6d3a
---

 modules/demux/ogg.c |   51 +++++++++++++++++++++++++++++++++++++--------------
 modules/demux/ogg.h |    3 +++
 2 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 5b0c59f..d4f4c97 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -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 );
 
 /* 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 * );
 
 /*****************************************************************************
@@ -178,6 +178,8 @@ static int Open( vlc_object_t * p_this )
     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;
@@ -306,7 +308,7 @@ static int Demux( demux_t * p_demux )
                         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 &&
@@ -464,8 +466,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 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,
@@ -1026,7 +1036,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                 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",
@@ -1071,8 +1081,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                 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--;
@@ -1081,8 +1090,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                 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 &&
@@ -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;
 }
 
-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;
@@ -1676,6 +1684,21 @@ static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
     {
         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;
 }
@@ -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,
                                    ogg_packet *p_oggpacket )
 {
@@ -1865,7 +1888,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
         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 */
@@ -1900,7 +1923,7 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
                         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 );
 
diff --git a/modules/demux/ogg.h b/modules/demux/ogg.h
index 6dae0a4..8c1d72b 100644
--- a/modules/demux/ogg.h
+++ b/modules/demux/ogg.h
@@ -137,4 +137,7 @@ struct demux_sys_t
     /* */
     int                i_attachments;
     input_attachment_t **attachments;
+
+    /* Length, if available. */
+    int64_t i_length;
 };



More information about the vlc-commits mailing list