]> git.sesse.net Git - vlc/blobdiff - modules/demux/ogg.c
+ modules/misc/freetype.c: fixed a couple of typos
[vlc] / modules / demux / ogg.c
index 9f1430bb4492b50e49ea2357d857f7fd2cb084b7..35e72e010e84b8ab5a92d57f1b1597d570040f6e 100644 (file)
@@ -2,15 +2,15 @@
  * ogg.c : ogg stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ogg.c,v 1.41 2003/10/23 16:48:45 gbazin Exp $
+ * $Id: ogg.c,v 1.44 2003/11/18 00:57:04 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -39,7 +39,7 @@
 #define OGG_BLOCK_SIZE 4096
 
 /*****************************************************************************
- * Definitions of structures and functions used by this plugins 
+ * Definitions of structures and functions used by this plugins
  *****************************************************************************/
 typedef struct logical_stream_s
 {
@@ -96,9 +96,10 @@ struct demux_sys_t
      * the sub-streams */
     mtime_t i_pcr;
     int     b_reinit;
+    int     i_prev_sync_state;
 
     /* stream state */
-    int     b_eos;
+    int     i_eos;
 };
 
 /* OggDS headers for the new header format (used in ogm files) */
@@ -107,7 +108,7 @@ typedef struct stream_header_video
     ogg_int32_t width;
     ogg_int32_t height;
 } stream_header_video;
-        
+
 typedef struct stream_header_audio
 {
     ogg_int16_t channels;
@@ -251,7 +252,7 @@ static void Ogg_ElemStreamStop( input_thread_t *p_input,
  ****************************************************************************/
 static int Ogg_Check( input_thread_t *p_input )
 {
-    u8 *p_peek;
+    uint8_t *p_peek;
     int i_size = input_Peek( p_input, &p_peek, 4 );
 
     /* Check for the Ogg capture pattern */
@@ -361,6 +362,52 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
           if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
           break;
 
+        case VLC_FOURCC( 'f','l','a','c' ):
+          if( p_stream->i_packets_backup == 2 )
+          {
+#ifdef HAVE_OGGPACKB
+              oggpack_buffer opb;
+              char title[sizeof("Stream") + 10];
+              input_info_category_t *p_cat;
+
+              sprintf( title, "Stream %d", p_stream->i_serial_no );
+              p_cat = input_InfoCategory( p_input, title );
+              input_AddInfo( p_cat, _("Type"), _("Audio") );
+              input_AddInfo( p_cat, _("Codec"), _("Flac") );
+
+              /* Parse the STREAMINFO metadata */
+              oggpackB_readinit(&opb, p_oggpacket->packet, p_oggpacket->bytes);
+              oggpackB_adv( &opb, 1 );
+              if( oggpackB_read( &opb, 7 ) == 0 )
+              {
+                  if( oggpackB_read( &opb, 24 ) >= 34 /*size STREAMINFO*/ )
+                  {
+                      oggpackB_adv( &opb, 80 );
+                      p_stream->f_rate = oggpackB_read( &opb, 20 );
+                      p_stream->i_channels = oggpackB_read( &opb, 3 ) + 1;
+
+                      input_AddInfo( p_cat, _("Sample Rate"), "%d",
+                                     (int)p_stream->f_rate );
+                      input_AddInfo( p_cat, _("Channels"), "%d",
+                                     p_stream->i_channels );
+                      msg_Dbg( p_input, "Flac header, channels: %i, rate: %i",
+                               p_stream->i_channels, (int)p_stream->f_rate );
+                  }
+                  else
+                  {
+                      msg_Dbg( p_input, "FLAC STREAMINFO metadata too short" );
+                  }
+              }
+              else
+              {
+                  /* This ain't a STREAMINFO metadata */
+                  msg_Dbg( p_input, "Invalid FLAC STREAMINFO metadata" );
+              }
+#endif
+              p_stream->b_force_backup = 0;
+          }
+          break;
+
         default:
           p_stream->b_force_backup = 0;
           break;
@@ -400,7 +447,8 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
 
     /* Convert the pcr into a pts */
     if( p_stream->i_fourcc == VLC_FOURCC( 'v','o','r','b' ) ||
-        p_stream->i_fourcc == VLC_FOURCC( 's','p','x',' ' ) )
+        p_stream->i_fourcc == VLC_FOURCC( 's','p','x',' ' ) ||
+        p_stream->i_fourcc == VLC_FOURCC( 'f','l','a','c' ) )
     {
         if( p_stream->i_pcr >= 0 )
         {
@@ -487,6 +535,7 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
 
     if( p_stream->i_fourcc != VLC_FOURCC( 'v','o','r','b' ) &&
         p_stream->i_fourcc != VLC_FOURCC( 's','p','x',' ' ) &&
+        p_stream->i_fourcc != VLC_FOURCC( 'f','l','a','c' ) &&
         p_stream->i_fourcc != VLC_FOURCC( 't','a','r','k' ) &&
         p_stream->i_fourcc != VLC_FOURCC( 't','h','e','o' ) )
     {
@@ -597,8 +646,8 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                         p_cat = input_InfoCategory( p_input, title );
                         input_AddInfo( p_cat, _("Type"), _("Audio") );
                         input_AddInfo( p_cat, _("Codec"), _("Vorbis") );
-                        input_AddInfo( p_cat, _("Sample Rate"), "%f",
-                                       p_stream->f_rate );
+                        input_AddInfo( p_cat, _("Sample Rate"), "%d",
+                                       (int)p_stream->f_rate );
                         input_AddInfo( p_cat, _("Channels"), "%d",
                                        p_stream->i_channels );
                         input_AddInfo( p_cat, _("Bit Rate"), "%d",
@@ -636,8 +685,8 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                         p_cat = input_InfoCategory( p_input, title );
                         input_AddInfo( p_cat, _("Type"), _("Audio") );
                         input_AddInfo( p_cat, _("Codec"), _("Speex") );
-                        input_AddInfo( p_cat, _("Sample Rate"), "%f",
-                                       p_stream->f_rate );
+                        input_AddInfo( p_cat, _("Sample Rate"), "%d",
+                                       (int)p_stream->f_rate );
                         input_AddInfo( p_cat, _("Channels"), "%d",
                                        p_stream->i_channels );
                         input_AddInfo( p_cat, _("Bit Rate"), "%d",
@@ -648,6 +697,21 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                                  (int)p_stream->f_rate, p_stream->i_bitrate );
                     }
                 }
+                /* Check for Flac header */
+                else if( oggpacket.bytes >= 4 &&
+                    ! strncmp( &oggpacket.packet[0], "fLaC", 4 ) )
+                {
+                    msg_Dbg( p_input, "found Flac header" );
+
+                    /* 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->i_cat = AUDIO_ES;
+                    p_stream->i_fourcc = VLC_FOURCC( 'f','l','a','c' );
+                    p_stream->i_bitrate = 0;
+                }
                 /* Check for Theora header */
                 else if( oggpacket.bytes >= 7 &&
                          ! strncmp( &oggpacket.packet[1], "theora", 6 ) )
@@ -712,7 +776,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                         p_cat = input_InfoCategory( p_input, title );
                         input_AddInfo( p_cat, _("Type"), _("Video") );
                         input_AddInfo( p_cat, _("Codec"), _("Theora") );
-                        input_AddInfo( p_cat, _("Frame Rate"), "%f",
+                        input_AddInfo( p_cat, _("Frame Rate"), "%.2f",
                                        p_stream->f_rate );
                         input_AddInfo( p_cat, _("Bit Rate"), "%d",
                                        p_stream->i_bitrate );
@@ -751,8 +815,8 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                         p_cat = input_InfoCategory( p_input, title );
                         input_AddInfo( p_cat, _("Type"), _("Video") );
                         input_AddInfo( p_cat, _("Codec"), _("tarkin") );
-                        input_AddInfo( p_cat, _("Sample Rate"), "%f",
-                                       p_stream->f_rate );
+                        input_AddInfo( p_cat, _("Sample Rate"), "%d",
+                                       (int)p_stream->f_rate );
                         input_AddInfo( p_cat, _("Bit Rate"), "%d",
                                        p_stream->i_bitrate );
                     }
@@ -817,7 +881,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                             input_AddInfo( p_cat, _("Type"), _("Video") );
                             input_AddInfo( p_cat, _("Codec"), "%.4s",
                                            (char *)&p_stream->i_fourcc );
-                            input_AddInfo( p_cat, _("Frame Rate"), "%f",
+                            input_AddInfo( p_cat, _("Frame Rate"), "%.2f",
                                            p_stream->f_rate );
                             input_AddInfo( p_cat, _("Bit Count"), "%d",
                                            p_stream->p_bih->biBitCount );
@@ -910,7 +974,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                             sprintf( title, "Stream %d", p_ogg->i_streams );
                             p_cat = input_InfoCategory( p_input, title );
                             input_AddInfo( p_cat, _("Type"), _("Audio") );
-                            input_AddInfo( p_cat, _("Codec"), "%.4s", 
+                            input_AddInfo( p_cat, _("Codec"), "%.4s",
                                            (char *)&p_stream->i_fourcc );
                             input_AddInfo( p_cat, _("Sample Rate"), "%d",
                                            p_stream->p_wf->nSamplesPerSec );
@@ -933,7 +997,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                     }
                 }
                 else if( (*oggpacket.packet & PACKET_TYPE_BITS )
-                         == PACKET_TYPE_HEADER && 
+                         == PACKET_TYPE_HEADER &&
                          oggpacket.bytes >= (int)sizeof(stream_header)+1 )
                 {
                     stream_header *st = (stream_header *)(oggpacket.packet+1);
@@ -992,7 +1056,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                             input_AddInfo( p_cat, _("Type"), _("Video") );
                             input_AddInfo( p_cat, _("Codec"), "%.4s",
                                            (char *)&p_stream->i_fourcc );
-                            input_AddInfo( p_cat, _("Frame Rate"), "%f",
+                            input_AddInfo( p_cat, _("Frame Rate"), "%.2f",
                                            p_stream->f_rate );
                             input_AddInfo( p_cat, _("Bit Count"), "%d",
                                            p_stream->p_bih->biBitCount );
@@ -1083,7 +1147,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                             sprintf( title, "Stream %d", p_ogg->i_streams );
                             p_cat = input_InfoCategory( p_input, title );
                             input_AddInfo( p_cat, _("Type"), _("Audio") );
-                            input_AddInfo( p_cat, _("Codec"), "%.4s", 
+                            input_AddInfo( p_cat, _("Codec"), "%.4s",
                                            (char *)&p_stream->i_fourcc );
                             input_AddInfo( p_cat, _("Sample Rate"), "%d",
                                            p_stream->p_wf->nSamplesPerSec );
@@ -1209,7 +1273,9 @@ static int Activate( vlc_object_t * p_this )
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
     /* Begnning of stream, tell the demux to look for elementary streams. */
-    p_ogg->b_eos = VLC_TRUE;
+    p_ogg->i_eos = 0;
+
+    p_ogg->i_prev_sync_state = SYNCHRO_REINIT;
 
     return 0;
 
@@ -1386,7 +1452,7 @@ static void Ogg_EndOfStream( input_thread_t *p_input, demux_sys_t *p_ogg )
 static void Deactivate( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
-    demux_sys_t *p_ogg = (demux_sys_t *)p_input->p_demux_data  ; 
+    demux_sys_t *p_ogg = (demux_sys_t *)p_input->p_demux_data  ;
 
     if( p_ogg )
     {
@@ -1411,10 +1477,16 @@ static int Demux( input_thread_t * p_input )
     ogg_packet  oggpacket;
     int         i_stream;
 
-    if( p_ogg->b_eos )
+    if( p_ogg->i_eos == p_ogg->i_streams )
     {
+        if( p_ogg->i_eos )
+        {
+            msg_Dbg( p_input, "end of a group of logical streams" );
+            Ogg_EndOfStream( p_input, p_ogg );
+        }
+
         if( Ogg_BeginningOfStream( p_input, p_ogg ) != VLC_SUCCESS ) return 0;
-        p_ogg->b_eos = VLC_FALSE;
+        p_ogg->i_eos = 0;
 
         msg_Dbg( p_input, "beginning of a group of logical streams" );
 
@@ -1485,8 +1557,12 @@ static int Demux( input_thread_t * p_input )
             p_stream->i_pcr = -1;
             p_stream->i_interpolated_pcr = -1;
         }
+        if( p_ogg->i_prev_sync_state != SYNCHRO_REINIT )
+            ogg_sync_reset( &p_ogg->oy );
     }
 
+    p_ogg->i_prev_sync_state =
+        p_input->stream.p_selected_program->i_synchro_state;
 
     /*
      * Demux an ogg page from the stream
@@ -1497,14 +1573,8 @@ static int Demux( input_thread_t * p_input )
     }
 
     /* Test for End of Stream */
-    if( ogg_page_eos( &oggpage ) )
-    {
-        msg_Dbg( p_input, "end of a group of logical streams" );
+    if( ogg_page_eos( &oggpage ) ) p_ogg->i_eos++;
 
-        Ogg_EndOfStream( p_input, p_ogg );
-        p_ogg->b_eos = VLC_TRUE;
-        return 1;
-    }
 
     for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
     {
@@ -1536,12 +1606,18 @@ static int Demux( input_thread_t * p_input )
 
                 /* An Ogg/vorbis packet contains an end date granulepos */
                 if( p_stream->i_fourcc == VLC_FOURCC( 'v','o','r','b' ) ||
-                    p_stream->i_fourcc == VLC_FOURCC( 's','p','x',' ' ) )
+                    p_stream->i_fourcc == VLC_FOURCC( 's','p','x',' ' ) ||
+                    p_stream->i_fourcc == VLC_FOURCC( 'f','l','a','c' ) )
                 {
                     if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
                     {
                         Ogg_DecodePacket( p_input, p_stream, &oggpacket );
                     }
+                    else
+                    {
+                        input_ClockManageRef( p_input,
+                            p_input->stream.p_selected_program, p_ogg->i_pcr );
+                    }
                     continue;
                 }
             }