]> git.sesse.net Git - vlc/blobdiff - modules/demux/ogg.c
Use _WIN32 rather than WIN32 (same for WIN64)
[vlc] / modules / demux / ogg.c
index c26fbd92f2c7ec57d240770784dca67ac0ef0d34..b5750c3d1f536686101685945efadcc013901118 100644 (file)
@@ -40,8 +40,7 @@
 #include <vlc_codecs.h>
 #include <vlc_bits.h>
 #include "xiph.h"
-#include "vorbis.h"
-#include "kate_categories.h"
+#include "xiph_metadata.h"
 #include "ogg.h"
 #include "oggseek.h"
 
@@ -135,7 +134,7 @@ 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 );
-static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream, ogg_packet *p_oggpacket, double f_rate );
+static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream, double f_rate );
 
 /* Logical bitstream headers */
 static void Ogg_ReadTheoraHeader( demux_t *, logical_stream_t *, ogg_packet * );
@@ -156,7 +155,6 @@ static int Open( vlc_object_t * p_this )
     demux_sys_t    *p_sys;
     const uint8_t  *p_peek;
 
-
     /* Check if we are dealing with an ogg stream */
     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
     if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
@@ -164,30 +162,21 @@ static int Open( vlc_object_t * p_this )
         return VLC_EGENERIC;
     }
 
-    /* Set exported functions */
-    p_demux->pf_demux = Demux;
-    p_demux->pf_control = Control;
-    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
+    /* */
+    p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
     if( !p_sys )
         return VLC_ENOMEM;
 
-    memset( p_sys, 0, sizeof( demux_sys_t ) );
-    p_sys->i_bitrate = 0;
-    p_sys->pp_stream = NULL;
-    p_sys->p_old_stream = NULL;
-
-    /* Begnning of stream, tell the demux to look for elementary streams. */
-    p_sys->i_bos = 0;
-    p_sys->i_eos = 0;
-
     p_sys->i_length = -1;
 
+    /* Set exported functions */
+    p_demux->pf_demux = Demux;
+    p_demux->pf_control = Control;
+
     /* Initialize the Ogg physical bitstream parser */
     ogg_sync_init( &p_sys->oy );
-    p_sys->b_page_waiting = false;
 
     /* */
-    p_sys->p_meta = NULL;
     TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
 
     return VLC_SUCCESS;
@@ -431,6 +420,22 @@ static int Demux( demux_t * p_demux )
     return 1;
 }
 
+static void Ogg_ResetStreamHelper( demux_sys_t *p_sys )
+{
+    for( int i = 0; i < p_sys->i_streams; i++ )
+    {
+        logical_stream_t *p_stream = p_sys->pp_stream[i];
+
+        /* we'll trash all the data until we find the next pcr */
+        p_stream->b_reinit = true;
+        p_stream->i_pcr = -1;
+        p_stream->i_interpolated_pcr = -1;
+        p_stream->i_previous_granulepos = -1;
+        ogg_stream_reset( &p_stream->os );
+    }
+    ogg_sync_reset( &p_sys->oy );
+}
+
 /*****************************************************************************
  * Control:
  *****************************************************************************/
@@ -440,7 +445,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     vlc_meta_t *p_meta;
     int64_t *pi64;
     bool *pb_bool;
-    int i;
 
     switch( i_query )
     {
@@ -488,18 +492,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 return VLC_EGENERIC;
             }
 
-            for( i = 0; i < p_sys->i_streams; i++ )
-            {
-                logical_stream_t *p_stream = p_sys->pp_stream[i];
-
-                /* we'll trash all the data until we find the next pcr */
-                p_stream->b_reinit = true;
-                p_stream->i_pcr = -1;
-                p_stream->i_interpolated_pcr = -1;
-                p_stream->i_previous_granulepos = -1;
-                ogg_stream_reset( &p_stream->os );
-            }
-            ogg_sync_reset( &p_sys->oy );
+            Ogg_ResetStreamHelper( p_sys );
             return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
                                           1, i_query, args );
         case DEMUX_GET_LENGTH:
@@ -543,7 +536,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             const int i_seekpoint = (int)va_arg( args, int );
             if( i_seekpoint > p_sys->i_seekpoints )
                 return VLC_EGENERIC;
-            return VLC_EGENERIC;// Seek( p_demux, p_sys->pp_seekpoints[i_seekpoint]->i_time_offset );
+            if( p_sys->i_bos > 0 )
+            {
+                return VLC_EGENERIC;
+            }
+
+            Ogg_ResetStreamHelper( p_sys );
+            int64_t i_block = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset * p_sys->i_bitrate / INT64_C(8000000);
+            if( stream_Seek( p_demux->s, i_block ) )
+                return VLC_EGENERIC;
+            return VLC_SUCCESS;
         }
 
         default:
@@ -712,12 +714,14 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         case VLC_CODEC_VORBIS:
         case VLC_CODEC_SPEEX:
         case VLC_CODEC_THEORA:
-            if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
+            if( p_stream->i_packets_backup == 3 )
+                p_stream->b_force_backup = false;
             b_xiph = true;
             break;
 
         case VLC_CODEC_OPUS:
-            if( p_stream->i_packets_backup == 2 ) p_stream->b_force_backup = 0;
+            if( p_stream->i_packets_backup == 2 )
+                p_stream->b_force_backup = false;
             b_xiph = true;
             break;
 
@@ -725,11 +729,11 @@ static void Ogg_DecodePacket( demux_t *p_demux,
             if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
             {
                 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
-                p_stream->b_force_backup = 0;
+                p_stream->b_force_backup = false;
             }
             else if( p_stream->fmt.audio.i_rate )
             {
-                p_stream->b_force_backup = 0;
+                p_stream->b_force_backup = false;
                 if( p_oggpacket->bytes >= 9 )
                 {
                     p_oggpacket->packet += 9;
@@ -740,12 +744,13 @@ static void Ogg_DecodePacket( demux_t *p_demux,
             break;
 
         case VLC_CODEC_KATE:
-            if( p_stream->i_packets_backup == p_stream->i_kate_num_headers ) p_stream->b_force_backup = 0;
+            if( p_stream->i_packets_backup == p_stream->i_kate_num_headers )
+                p_stream->b_force_backup = false;
             b_xiph = true;
             break;
 
         default:
-            p_stream->b_force_backup = 0;
+            p_stream->b_force_backup = false;
             b_xiph = false;
             break;
         }
@@ -1168,7 +1173,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                     /* Grrrr!!!! Did they really have to put all the
                      * important info in the second header packet!!!
                      * (STREAMINFO metadata is in the following packet) */
-                    p_stream->b_force_backup = 1;
+                    p_stream->b_force_backup = true;
 
                     p_stream->fmt.i_cat = AUDIO_ES;
                     p_stream->fmt.i_codec = VLC_CODEC_FLAC;
@@ -1185,7 +1190,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                              oggpacket.packet[5], oggpacket.packet[6],
                              i_packets );
 
-                    p_stream->b_force_backup = 1;
+                    p_stream->b_force_backup = true;
 
                     p_stream->fmt.i_cat = AUDIO_ES;
                     p_stream->fmt.i_codec = VLC_CODEC_FLAC;
@@ -1481,7 +1486,7 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                         /* We need to get rid of the header packet */
                         ogg_stream_packetout( &p_stream->os, &oggpacket );
 
-                        msg_Dbg( p_demux, "found text subtitles header" );
+                        msg_Dbg( p_demux, "found text subtitle header" );
                         p_stream->fmt.i_cat = SPU_ES;
                         p_stream->fmt.i_codec = VLC_CODEC_SUBT;
                         p_stream->f_rate = 1000; /* granulepos is in millisec */
@@ -1820,9 +1825,21 @@ static void Ogg_ExtractXiphMeta( demux_t *p_demux, const void *p_headers, unsign
 
     /* TODO how to handle multiple comments properly ? */
     if( i_count >= 2 && pi_size[1] > i_skip )
+    {
+        int i_cover_score = 0;
+        int i_cover_idx = 0;
         vorbis_ParseComment( &p_ogg->p_meta, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip,
                              &p_ogg->i_attachments, &p_ogg->attachments,
+                             &i_cover_score, &i_cover_idx,
                              &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints );
+        if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
+        {
+            char psz_url[128];
+            snprintf( psz_url, sizeof(psz_url), "attachment://%s",
+                p_ogg->attachments[i_cover_idx]->psz_name );
+            vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
+        }
+    }
 
     if( p_ogg->i_seekpoints > 1 )
     {
@@ -1872,15 +1889,9 @@ static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8
 }
 
 static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream,
-                                  ogg_packet *p_oggpacket, double f_rate )
+                                  double f_rate )
 {
     int64_t last_packet = 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 );
-
     return ( last_packet >= 0 ) ? last_packet / f_rate : -1;
 }
 
@@ -1902,7 +1913,7 @@ static void Ogg_ReadTheoraHeader( demux_t *p_demux, logical_stream_t *p_stream,
     /* Signal that we want to keep a backup of the theora
      * stream headers. They will be used when switching between
      * audio streams. */
-    p_stream->b_force_backup = 1;
+    p_stream->b_force_backup = true;
 
     /* Cheat and get additionnal info ;) */
     bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
@@ -1952,7 +1963,7 @@ static void Ogg_ReadTheoraHeader( demux_t *p_demux, logical_stream_t *p_stream,
     }
     if ( p_demux->p_sys->i_length < 0 )
     {
-        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
         if ( last_packet >= 0 )
             p_demux->p_sys->i_length = last_packet;
     }
@@ -1970,7 +1981,7 @@ static void Ogg_ReadVorbisHeader( demux_t *p_demux, logical_stream_t *p_stream,
     /* Signal that we want to keep a backup of the vorbis
      * stream headers. They will be used when switching between
      * audio streams. */
-    p_stream->b_force_backup = 1;
+    p_stream->b_force_backup = true;
 
     /* Cheat and get additionnal info ;) */
     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
@@ -1983,7 +1994,7 @@ static void Ogg_ReadVorbisHeader( demux_t *p_demux, logical_stream_t *p_stream,
 
     if ( p_demux->p_sys->i_length < 0 )
     {
-        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
         if ( last_packet >= 0 )
             p_demux->p_sys->i_length = last_packet;
     }
@@ -2000,7 +2011,7 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
     /* Signal that we want to keep a backup of the speex
      * stream headers. They will be used when switching between
      * audio streams. */
-    p_stream->b_force_backup = 1;
+    p_stream->b_force_backup = true;
 
     /* Cheat and get additionnal info ;) */
     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
@@ -2026,7 +2037,7 @@ static void Ogg_ReadOpusHeader( demux_t *p_demux,
     /* Signal that we want to keep a backup of the opus
      * stream headers. They will be used when switching between
      * audio streams. */
-    p_stream->b_force_backup = 1;
+    p_stream->b_force_backup = true;
 
     /* All OggOpus streams are timestamped at 48kHz and
      * can be played at 48kHz. */
@@ -2042,7 +2053,7 @@ static void Ogg_ReadOpusHeader( demux_t *p_demux,
 
     if ( p_demux->p_sys->i_length < 0 )
     {
-        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_oggpacket, p_stream->f_rate );
+        int64_t last_packet = Ogg_GetLastPacket( p_demux, p_stream, p_stream->f_rate );
         if ( last_packet >= 0 )
             p_demux->p_sys->i_length = last_packet;
     }
@@ -2098,7 +2109,7 @@ static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
     /* Signal that we want to keep a backup of the kate
      * stream headers. They will be used when switching between
      * kate streams. */
-    p_stream->b_force_backup = 1;
+    p_stream->b_force_backup = true;
 
     /* Cheat and get additionnal info ;) */
     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
@@ -2167,6 +2178,11 @@ static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
         minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
         timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
         timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
+
+        msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
+                          "Timebase  %"PRId64" / %"PRId64,
+                          major_version, minor_version,
+                          timebase_numerator, timebase_denominator );
     }
     else if( p_oggpacket->bytes >= 42 &&
              !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
@@ -2214,28 +2230,28 @@ static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
             p_stream->fmt.i_cat = AUDIO_ES;
             p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
 
-            p_stream->b_force_backup = 1;
+            p_stream->b_force_backup = true;
         }
         else if( !strncmp(content_type_string, "audio/x-speex", 13) )
         {
             p_stream->fmt.i_cat = AUDIO_ES;
             p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
 
-            p_stream->b_force_backup = 1;
+            p_stream->b_force_backup = true;
         }
         else if( !strncmp(content_type_string, "video/x-theora", 14) )
         {
             p_stream->fmt.i_cat = VIDEO_ES;
             p_stream->fmt.i_codec = VLC_CODEC_THEORA;
 
-            p_stream->b_force_backup = 1;
+            p_stream->b_force_backup = true;
         }
         else if( !strncmp(content_type_string, "video/x-xvid", 12) )
         {
             p_stream->fmt.i_cat = VIDEO_ES;
             p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
 
-            p_stream->b_force_backup = 1;
+            p_stream->b_force_backup = true;
         }
         else if( !strncmp(content_type_string, "video/mpeg", 10) )
         {
@@ -2294,7 +2310,7 @@ static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
 
     /* Backing up stream headers is not required -- seqhdrs are repeated
      * thoughout the stream at suitable decoding start points */
-    p_stream->b_force_backup = 0;
+    p_stream->b_force_backup = false;
 
     /* read in useful bits from sequence header */
     bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );