ogg.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:51k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * ogg.c : ogg stream demux module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2003 VideoLAN
  5.  * $Id: ogg.c 8567 2004-08-29 12:27:49Z gbazin $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  8.  *          Andre Pang <Andre.Pang@csiro.au> (Annodex support)
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <vlc/vlc.h>
  28. #include <vlc/input.h>
  29. #include <ogg/ogg.h>
  30. #include "codecs.h"
  31. #include "vlc_bits.h"
  32. /*****************************************************************************
  33.  * Module descriptor
  34.  *****************************************************************************/
  35. static int  Open ( vlc_object_t * );
  36. static void Close( vlc_object_t * );
  37. vlc_module_begin();
  38.     set_description( _("Ogg stream demuxer" ) );
  39.     set_capability( "demux2", 50 );
  40.     set_callbacks( Open, Close );
  41.     add_shortcut( "ogg" );
  42. vlc_module_end();
  43. /*****************************************************************************
  44.  * Definitions of structures and functions used by this plugins
  45.  *****************************************************************************/
  46. typedef struct logical_stream_s
  47. {
  48.     ogg_stream_state os;                        /* logical stream of packets */
  49.     es_format_t      fmt;
  50.     es_out_id_t      *p_es;
  51.     double           f_rate;
  52.     int              i_serial_no;
  53.     /* the header of some logical streams (eg vorbis) contain essential
  54.      * data for the decoder. We back them up here in case we need to re-feed
  55.      * them to the decoder. */
  56.     int              b_force_backup;
  57.     int              i_packets_backup;
  58.     uint8_t          *p_headers;
  59.     int              i_headers;
  60.     /* program clock reference (in units of 90kHz) derived from the previous
  61.      * granulepos */
  62.     mtime_t          i_pcr;
  63.     mtime_t          i_interpolated_pcr;
  64.     mtime_t          i_previous_pcr;
  65.     /* Misc */
  66.     int b_reinit;
  67.     int i_theora_keyframe_granule_shift;
  68.     /* for Annodex logical bitstreams */
  69.     int secondary_header_packets;
  70. } logical_stream_t;
  71. struct demux_sys_t
  72. {
  73.     ogg_sync_state oy;        /* sync and verify incoming physical bitstream */
  74.     int i_streams;                           /* number of logical bitstreams */
  75.     logical_stream_t **pp_stream;  /* pointer to an array of logical streams */
  76.     /* program clock reference (in units of 90kHz) derived from the pcr of
  77.      * the sub-streams */
  78.     mtime_t i_pcr;
  79.     /* stream state */
  80.     int     i_eos;
  81.     /* bitrate */
  82.     int     i_bitrate;
  83. };
  84. /* OggDS headers for the new header format (used in ogm files) */
  85. typedef struct stream_header_video
  86. {
  87.     ogg_int32_t width;
  88.     ogg_int32_t height;
  89. } stream_header_video;
  90. typedef struct stream_header_audio
  91. {
  92.     ogg_int16_t channels;
  93.     ogg_int16_t blockalign;
  94.     ogg_int32_t avgbytespersec;
  95. } stream_header_audio;
  96. typedef struct stream_header
  97. {
  98.     char        streamtype[8];
  99.     char        subtype[4];
  100.     ogg_int32_t size;                               /* size of the structure */
  101.     ogg_int64_t time_unit;                              /* in reference time */
  102.     ogg_int64_t samples_per_unit;
  103.     ogg_int32_t default_len;                                /* in media time */
  104.     ogg_int32_t buffersize;
  105.     ogg_int16_t bits_per_sample;
  106.     union
  107.     {
  108.         /* Video specific */
  109.         stream_header_video video;
  110.         /* Audio specific */
  111.         stream_header_audio audio;
  112.     } sh;
  113. } stream_header;
  114. #define OGG_BLOCK_SIZE 4096
  115. /* Some defines from OggDS */
  116. #define PACKET_TYPE_HEADER   0x01
  117. #define PACKET_TYPE_BITS     0x07
  118. #define PACKET_LEN_BITS01    0xc0
  119. #define PACKET_LEN_BITS2     0x02
  120. #define PACKET_IS_SYNCPOINT  0x08
  121. /*****************************************************************************
  122.  * Local prototypes
  123.  *****************************************************************************/
  124. static int  Demux  ( demux_t * );
  125. static int  Control( demux_t *, int, va_list );
  126. /* Bitstream manipulation */
  127. static int  Ogg_ReadPage     ( demux_t *, ogg_page * );
  128. static void Ogg_UpdatePCR    ( logical_stream_t *, ogg_packet * );
  129. static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
  130. static int Ogg_BeginningOfStream( demux_t *p_demux );
  131. static int Ogg_FindLogicalStreams( demux_t *p_demux );
  132. static void Ogg_EndOfStream( demux_t *p_demux );
  133. /* Logical bitstream headers */
  134. static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
  135. static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
  136. static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
  137. static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
  138. static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
  139. /*****************************************************************************
  140.  * Open: initializes ogg demux structures
  141.  *****************************************************************************/
  142. static int Open( vlc_object_t * p_this )
  143. {
  144.     demux_t *p_demux = (demux_t *)p_this;
  145.     demux_sys_t    *p_sys;
  146.     uint8_t        *p_peek;
  147.     /* Check if we are dealing with an ogg stream */
  148.     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
  149.     {
  150.         msg_Err( p_demux, "cannot peek" );
  151.         return VLC_EGENERIC;
  152.     }
  153.     if( strcmp( p_demux->psz_demux, "ogg" ) && strncmp( p_peek, "OggS", 4 ) )
  154.     {
  155.         msg_Warn( p_demux, "ogg module discarded (invalid header)" );
  156.         return VLC_EGENERIC;
  157.     }
  158.     /* Set exported functions */
  159.     p_demux->pf_demux = Demux;
  160.     p_demux->pf_control = Control;
  161.     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
  162.     memset( p_sys, 0, sizeof( demux_sys_t ) );
  163.     p_sys->i_bitrate = 0;
  164.     p_sys->pp_stream = NULL;
  165.     /* Begnning of stream, tell the demux to look for elementary streams. */
  166.     p_sys->i_eos = 0;
  167.     /* Initialize the Ogg physical bitstream parser */
  168.     ogg_sync_init( &p_sys->oy );
  169.     return VLC_SUCCESS;
  170. }
  171. /*****************************************************************************
  172.  * Close: frees unused data
  173.  *****************************************************************************/
  174. static void Close( vlc_object_t *p_this )
  175. {
  176.     demux_t *p_demux = (demux_t *)p_this;
  177.     demux_sys_t *p_sys = p_demux->p_sys  ;
  178.     /* Cleanup the bitstream parser */
  179.     ogg_sync_clear( &p_sys->oy );
  180.     Ogg_EndOfStream( p_demux );
  181.     free( p_sys );
  182. }
  183. /*****************************************************************************
  184.  * Demux: reads and demuxes data packets
  185.  *****************************************************************************
  186.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  187.  *****************************************************************************/
  188. static int Demux( demux_t * p_demux )
  189. {
  190.     demux_sys_t *p_sys = p_demux->p_sys;
  191.     ogg_page    oggpage;
  192.     ogg_packet  oggpacket;
  193.     int         i_stream;
  194.     if( p_sys->i_eos == p_sys->i_streams )
  195.     {
  196.         if( p_sys->i_eos )
  197.         {
  198.             msg_Dbg( p_demux, "end of a group of logical streams" );
  199.             Ogg_EndOfStream( p_demux );
  200.         }
  201.         p_sys->i_eos = 0;
  202.         if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS ) return 0;
  203.         msg_Dbg( p_demux, "beginning of a group of logical streams" );
  204.         es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  205.     }
  206.     /*
  207.      * Demux an ogg page from the stream
  208.      */
  209.     if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
  210.     {
  211.         return 0; /* EOF */
  212.     }
  213.     /* Test for End of Stream */
  214.     if( ogg_page_eos( &oggpage ) ) p_sys->i_eos++;
  215.     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
  216.     {
  217.         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
  218.         if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 )
  219.             continue;
  220.         while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
  221.         {
  222.             /* Read info from any secondary header packets, if there are any */
  223.             if( p_stream->secondary_header_packets > 0 )
  224.             {
  225.                 if( p_stream->fmt.i_codec == VLC_FOURCC('t','h','e','o') &&
  226.                         oggpacket.bytes >= 7 &&
  227.                         ! strncmp( &oggpacket.packet[1], "theora", 6 ) )
  228.                 {
  229.                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
  230.                     p_stream->secondary_header_packets = 0;
  231.                 }
  232.                 else if( p_stream->fmt.i_codec == VLC_FOURCC('v','o','r','b') &&
  233.                         oggpacket.bytes >= 7 &&
  234.                         ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) )
  235.                 {
  236.                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
  237.                     p_stream->secondary_header_packets = 0;
  238.                 }
  239.                 else if ( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
  240.                 {
  241.                     p_stream->secondary_header_packets = 0;
  242.                 }
  243.                 p_stream->secondary_header_packets--;
  244.             }
  245.             if( p_stream->b_reinit )
  246.             {
  247.                 /* If synchro is re-initialized we need to drop all the packets
  248.                  * until we find a new dated one. */
  249.                 Ogg_UpdatePCR( p_stream, &oggpacket );
  250.                 if( p_stream->i_pcr >= 0 )
  251.                 {
  252.                     p_stream->b_reinit = 0;
  253.                 }
  254.                 else
  255.                 {
  256.                     p_stream->i_interpolated_pcr = -1;
  257.                     continue;
  258.                 }
  259.                 /* An Ogg/vorbis packet contains an end date granulepos */
  260.                 if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
  261.                     p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
  262.                     p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
  263.                 {
  264.                     if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
  265.                     {
  266.                         Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
  267.                     }
  268.                     else
  269.                     {
  270.                         es_out_Control( p_demux->out, ES_OUT_SET_PCR,
  271.                                         p_stream->i_pcr );
  272.                     }
  273.                     continue;
  274.                 }
  275.             }
  276.             Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
  277.         }
  278.         break;
  279.     }
  280.     i_stream = 0; p_sys->i_pcr = -1;
  281.     for( ; i_stream < p_sys->i_streams; i_stream++ )
  282.     {
  283.         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
  284.         if( p_stream->fmt.i_cat == SPU_ES )
  285.             continue;
  286.         if( p_stream->i_interpolated_pcr < 0 )
  287.             continue;
  288.         if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )
  289.             p_sys->i_pcr = p_stream->i_interpolated_pcr;
  290.     }
  291.     if( p_sys->i_pcr >= 0 )
  292.     {
  293.         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
  294.     }
  295.     return 1;
  296. }
  297. /*****************************************************************************
  298.  * Control:
  299.  *****************************************************************************/
  300. static int Control( demux_t *p_demux, int i_query, va_list args )
  301. {
  302.     demux_sys_t *p_sys  = p_demux->p_sys;
  303.     int64_t *pi64;
  304.     int i;
  305.     switch( i_query )
  306.     {
  307.         case DEMUX_GET_TIME:
  308.             pi64 = (int64_t*)va_arg( args, int64_t * );
  309.             *pi64 = p_sys->i_pcr;
  310.             return VLC_SUCCESS;
  311.         case DEMUX_SET_TIME:
  312.             return VLC_EGENERIC;
  313.         case DEMUX_SET_POSITION:
  314.             for( i = 0; i < p_sys->i_streams; i++ )
  315.             {
  316.                 logical_stream_t *p_stream = p_sys->pp_stream[i];
  317.                 /* we'll trash all the data until we find the next pcr */
  318.                 p_stream->b_reinit = 1;
  319.                 p_stream->i_pcr = -1;
  320.                 p_stream->i_interpolated_pcr = -1;
  321.                 ogg_stream_reset( &p_stream->os );
  322.             }
  323.             ogg_sync_reset( &p_sys->oy );
  324.         default:
  325.             return demux2_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
  326.                                            1, i_query, args );
  327.     }
  328. }
  329. /****************************************************************************
  330.  * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
  331.  ****************************************************************************
  332.  * Returns VLC_SUCCESS if a page has been read. An error might happen if we
  333.  * are at the end of stream.
  334.  ****************************************************************************/
  335. static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
  336. {
  337.     demux_sys_t *p_ogg = p_demux->p_sys  ;
  338.     int i_read = 0;
  339.     byte_t *p_buffer;
  340.     while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
  341.     {
  342.         p_buffer = ogg_sync_buffer( &p_ogg->oy, OGG_BLOCK_SIZE );
  343.         i_read = stream_Read( p_demux->s, p_buffer, OGG_BLOCK_SIZE );
  344.         if( i_read <= 0 )
  345.             return VLC_EGENERIC;
  346.         ogg_sync_wrote( &p_ogg->oy, i_read );
  347.     }
  348.     return VLC_SUCCESS;
  349. }
  350. /****************************************************************************
  351.  * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
  352.  *                current stream.
  353.  ****************************************************************************/
  354. static void Ogg_UpdatePCR( logical_stream_t *p_stream,
  355.                            ogg_packet *p_oggpacket )
  356. {
  357.     /* Convert the granulepos into a pcr */
  358.     if( p_oggpacket->granulepos >= 0 )
  359.     {
  360.         if( p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) )
  361.         {
  362.             p_stream->i_pcr = p_oggpacket->granulepos * I64C(1000000)
  363.                               / p_stream->f_rate;
  364.         }
  365.         else
  366.         {
  367.             ogg_int64_t iframe = p_oggpacket->granulepos >>
  368.               p_stream->i_theora_keyframe_granule_shift;
  369.             ogg_int64_t pframe = p_oggpacket->granulepos -
  370.               ( iframe << p_stream->i_theora_keyframe_granule_shift );
  371.             p_stream->i_pcr = ( iframe + pframe ) * I64C(1000000)
  372.                               / p_stream->f_rate;
  373.         }
  374.         p_stream->i_interpolated_pcr = p_stream->i_pcr;
  375.     }
  376.     else
  377.     {
  378.         p_stream->i_pcr = -1;
  379.         /* no granulepos available, try to interpolate the pcr.
  380.          * If we can't then don't touch the old value. */
  381.         if( p_stream->fmt.i_cat == VIDEO_ES )
  382.             /* 1 frame per packet */
  383.             p_stream->i_interpolated_pcr += (I64C(1000000) / p_stream->f_rate);
  384.         else if( p_stream->fmt.i_bitrate )
  385.             p_stream->i_interpolated_pcr +=
  386.                 ( p_oggpacket->bytes * I64C(1000000) /
  387.                   p_stream->fmt.i_bitrate / 8 );
  388.     }
  389. }
  390. /****************************************************************************
  391.  * Ogg_DecodePacket: Decode an Ogg packet.
  392.  ****************************************************************************/
  393. static void Ogg_DecodePacket( demux_t *p_demux,
  394.                               logical_stream_t *p_stream,
  395.                               ogg_packet *p_oggpacket )
  396. {
  397.     block_t *p_block;
  398.     vlc_bool_t b_selected;
  399.     int i_header_len = 0;
  400.     mtime_t i_pts = -1, i_interpolated_pts;
  401.     /* Sanity check */
  402.     if( !p_oggpacket->bytes )
  403.     {
  404.         msg_Dbg( p_demux, "discarding 0 sized packet" );
  405.         return;
  406.     }
  407.     if( p_oggpacket->bytes >= 7 &&
  408.         ! strncmp ( &p_oggpacket->packet[0], "Annodex", 7 ) )
  409.     {
  410.         /* it's an Annodex packet -- skip it (do nothing) */
  411.         return; 
  412.     }
  413.     else if( p_oggpacket->bytes >= 7 &&
  414.         ! strncmp ( &p_oggpacket->packet[0], "AnxData", 7 ) )
  415.     {
  416.         /* it's an AnxData packet -- skip it (do nothing) */
  417.         return; 
  418.     }
  419.     /* Check the ES is selected */
  420.     es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
  421.                     p_stream->p_es, &b_selected );
  422.     if( p_stream->b_force_backup )
  423.     {
  424.         uint8_t *p_extra;
  425.         vlc_bool_t b_store_size = VLC_TRUE;
  426.         p_stream->i_packets_backup++;
  427.         switch( p_stream->fmt.i_codec )
  428.         {
  429.         case VLC_FOURCC( 'v','o','r','b' ):
  430.         case VLC_FOURCC( 's','p','x',' ' ):
  431.         case VLC_FOURCC( 't','h','e','o' ):
  432.           if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
  433.           break;
  434.         case VLC_FOURCC( 'f','l','a','c' ):
  435.           if( p_stream->i_packets_backup == 2 )
  436.           {
  437.               Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
  438.               p_stream->b_force_backup = 0;
  439.           }
  440.           b_store_size = VLC_FALSE;
  441.           break;
  442.         default:
  443.           p_stream->b_force_backup = 0;
  444.           break;
  445.         }
  446.         /* Backup the ogg packet (likely an header packet) */
  447.         p_stream->p_headers =
  448.             realloc( p_stream->p_headers, p_stream->i_headers +
  449.                      p_oggpacket->bytes + (b_store_size ? 2 : 0) );
  450.         p_extra = p_stream->p_headers + p_stream->i_headers;
  451.         if( b_store_size )
  452.         {
  453.             *(p_extra++) = p_oggpacket->bytes >> 8;
  454.             *(p_extra++) = p_oggpacket->bytes & 0xFF;
  455.         }
  456.         memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes );
  457.         p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0);
  458.         if( !p_stream->b_force_backup )
  459.         {
  460.             /* Last header received, commit changes */
  461.             p_stream->fmt.i_extra = p_stream->i_headers;
  462.             p_stream->fmt.p_extra =
  463.                 realloc( p_stream->fmt.p_extra, p_stream->i_headers );
  464.             memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
  465.                     p_stream->i_headers );
  466.             es_out_Control( p_demux->out, ES_OUT_SET_FMT,
  467.                             p_stream->p_es, &p_stream->fmt );
  468.         }
  469.         b_selected = VLC_FALSE; /* Discard the header packet */
  470.     }
  471.     /* Convert the pcr into a pts */
  472.     if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
  473.         p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
  474.         p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
  475.     {
  476.         if( p_stream->i_pcr >= 0 )
  477.         {
  478.             /* This is for streams where the granulepos of the header packets
  479.              * doesn't match these of the data packets (eg. ogg web radios). */
  480.             if( p_stream->i_previous_pcr == 0 &&
  481.                 p_stream->i_pcr  > 3 * DEFAULT_PTS_DELAY )
  482.             {
  483.                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  484.                 /* Call the pace control */
  485.                 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
  486.                                 p_stream->i_pcr );
  487.             }
  488.             p_stream->i_previous_pcr = p_stream->i_pcr;
  489.             /* The granulepos is the end date of the sample */
  490.             i_pts =  p_stream->i_pcr;
  491.         }
  492.     }
  493.     /* Convert the granulepos into the next pcr */
  494.     i_interpolated_pts = p_stream->i_interpolated_pcr;
  495.     Ogg_UpdatePCR( p_stream, p_oggpacket );
  496.     if( p_stream->i_pcr >= 0 )
  497.     {
  498.         /* This is for streams where the granulepos of the header packets
  499.          * doesn't match these of the data packets (eg. ogg web radios). */
  500.         if( p_stream->i_previous_pcr == 0 &&
  501.             p_stream->i_pcr  > 3 * DEFAULT_PTS_DELAY )
  502.         {
  503.             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  504.             /* Call the pace control */
  505.             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_stream->i_pcr );
  506.         }
  507.     }
  508.     if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
  509.         p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
  510.         p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
  511.         p_stream->i_pcr >= 0 )
  512.     {
  513.         p_stream->i_previous_pcr = p_stream->i_pcr;
  514.         /* The granulepos is the start date of the sample */
  515.         i_pts = p_stream->i_pcr;
  516.     }
  517.     if( !b_selected )
  518.     {
  519.         /* This stream isn't currently selected so we don't need to decode it,
  520.          * but we did need to store its pcr as it might be selected later on */
  521.         return;
  522.     }
  523.     if( !( p_block = block_New( p_demux, p_oggpacket->bytes ) ) ) return;
  524.     /* Normalize PTS */
  525.     if( i_pts == 0 ) i_pts = 1;
  526.     else if( i_pts == -1 && i_interpolated_pts == 0 ) i_pts = 1;
  527.     else if( i_pts == -1 ) i_pts = 0;
  528.     if( p_stream->fmt.i_cat == AUDIO_ES )
  529.         p_block->i_dts = p_block->i_pts = i_pts;
  530.     else if( p_stream->fmt.i_cat == SPU_ES )
  531.     {
  532.         p_block->i_dts = p_block->i_pts = i_pts;
  533.         p_block->i_length = 0;
  534.     }
  535.     else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )
  536.         p_block->i_dts = p_block->i_pts = i_pts;
  537.     else
  538.     {
  539.         p_block->i_dts = i_pts;
  540.         p_block->i_pts = 0;
  541.     }
  542.     if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
  543.         p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
  544.         p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
  545.         p_stream->fmt.i_codec != VLC_FOURCC( 't','a','r','k' ) &&
  546.         p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) &&
  547.         p_stream->fmt.i_codec != VLC_FOURCC( 'c','m','m','l' ) )
  548.     {
  549.         /* We remove the header from the packet */
  550.         i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
  551.         i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
  552.         
  553.         if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ))
  554.         {
  555.             /* But with subtitles we need to retrieve the duration first */
  556.             int i, lenbytes = 0;
  557.         
  558.             if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
  559.             {
  560.                 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
  561.                 {
  562.                     lenbytes = lenbytes << 8;
  563.                     lenbytes += *(p_oggpacket->packet + i_header_len - i);
  564.                 }
  565.             }
  566.             if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
  567.                 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
  568.                   p_oggpacket->packet[i_header_len + 1] != 0 && 
  569.                   p_oggpacket->packet[i_header_len + 1] != 'n' &&
  570.                   p_oggpacket->packet[i_header_len + 1] != 'r' ) )
  571.             {
  572.                 p_block->i_length = (mtime_t)lenbytes * 1000;
  573.             }
  574.         }
  575.         i_header_len++;
  576.         p_block->i_buffer -= i_header_len;
  577.     }
  578.     if( p_stream->fmt.i_codec == VLC_FOURCC( 't','a','r','k' ) )
  579.     {
  580.         /* FIXME: the biggest hack I've ever done */
  581.         msg_Warn( p_demux, "tarkin pts: "I64Fd", granule: "I64Fd,
  582.                   p_block->i_pts, p_block->i_dts );
  583.         msleep(10000);
  584.     }
  585.     memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
  586.             p_oggpacket->bytes - i_header_len );
  587.     es_out_Send( p_demux->out, p_stream->p_es, p_block );
  588. }
  589. /****************************************************************************
  590.  * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
  591.  *                         stream and fill p_ogg.
  592.  *****************************************************************************
  593.  * The initial page of a logical stream is marked as a 'bos' page.
  594.  * Furthermore, the Ogg specification mandates that grouped bitstreams begin
  595.  * together and all of the initial pages must appear before any data pages.
  596.  *
  597.  * On success this function returns VLC_SUCCESS.
  598.  ****************************************************************************/
  599. static int Ogg_FindLogicalStreams( demux_t *p_demux )
  600. {
  601.     demux_sys_t *p_ogg = p_demux->p_sys  ;
  602.     ogg_packet oggpacket;
  603.     ogg_page oggpage;
  604.     int i_stream;
  605. #define p_stream p_ogg->pp_stream[p_ogg->i_streams - 1]
  606.     while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS )
  607.     {
  608.         if( ogg_page_bos( &oggpage ) )
  609.         {
  610.             /* All is wonderful in our fine fine little world.
  611.              * We found the beginning of our first logical stream. */
  612.             while( ogg_page_bos( &oggpage ) )
  613.             {
  614.                 p_ogg->i_streams++;
  615.                 p_ogg->pp_stream =
  616.                     realloc( p_ogg->pp_stream, p_ogg->i_streams *
  617.                              sizeof(logical_stream_t *) );
  618.                 p_stream = malloc( sizeof(logical_stream_t) );
  619.                 memset( p_stream, 0, sizeof(logical_stream_t) );
  620.                 p_stream->p_headers = 0;
  621.                 es_format_Init( &p_stream->fmt, 0, 0 );
  622.                 /* Setup the logical stream */
  623.                 p_stream->i_serial_no = ogg_page_serialno( &oggpage );
  624.                 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
  625.                 /* Extract the initial header from the first page and verify
  626.                  * the codec type of tis Ogg bitstream */
  627.                 if( ogg_stream_pagein( &p_stream->os, &oggpage ) < 0 )
  628.                 {
  629.                     /* error. stream version mismatch perhaps */
  630.                     msg_Err( p_demux, "error reading first page of "
  631.                              "Ogg bitstream data" );
  632.                     return VLC_EGENERIC;
  633.                 }
  634.                 /* FIXME: check return value */
  635.                 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
  636.                 /* Check for Vorbis header */
  637.                 if( oggpacket.bytes >= 7 &&
  638.                     ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) )
  639.                 {
  640.                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
  641.                     msg_Dbg( p_demux, "found vorbis header" );
  642.                 }
  643.                 /* Check for Speex header */
  644.                 else if( oggpacket.bytes >= 7 &&
  645.                     ! strncmp( &oggpacket.packet[0], "Speex", 5 ) )
  646.                 {
  647.                     Ogg_ReadSpeexHeader( p_stream, &oggpacket );
  648.                     msg_Dbg( p_demux, "found speex header, channels: %i, "
  649.                              "rate: %i,  bitrate: %i",
  650.                              p_stream->fmt.audio.i_channels,
  651.                              (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
  652.                 }
  653.                 /* Check for Flac header */
  654.                 else if( oggpacket.bytes >= 4 &&
  655.                     ! strncmp( &oggpacket.packet[0], "fLaC", 4 ) )
  656.                 {
  657.                     msg_Dbg( p_demux, "found FLAC header" );
  658.                     /* Grrrr!!!! Did they really have to put all the
  659.                      * important info in the second header packet!!!
  660.                      * (STREAMINFO metadata is in the following packet) */
  661.                     p_stream->b_force_backup = 1;
  662.                     p_stream->fmt.i_cat = AUDIO_ES;
  663.                     p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );
  664.                 }
  665.                 /* Check for Theora header */
  666.                 else if( oggpacket.bytes >= 7 &&
  667.                          ! strncmp( &oggpacket.packet[1], "theora", 6 ) )
  668.                 {
  669.                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
  670.                     msg_Dbg( p_demux,
  671.                              "found theora header, bitrate: %i, rate: %f",
  672.                              p_stream->fmt.i_bitrate, p_stream->f_rate );
  673.                 }
  674.                 /* Check for Tarkin header */
  675.                 else if( oggpacket.bytes >= 7 &&
  676.                          ! strncmp( &oggpacket.packet[1], "tarkin", 6 ) )
  677.                 {
  678.                     oggpack_buffer opb;
  679.                     msg_Dbg( p_demux, "found tarkin header" );
  680.                     p_stream->fmt.i_cat = VIDEO_ES;
  681.                     p_stream->fmt.i_codec = VLC_FOURCC( 't','a','r','k' );
  682.                     /* Cheat and get additionnal info ;) */
  683.                     oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
  684.                     oggpack_adv( &opb, 88 );
  685.                     oggpack_adv( &opb, 104 );
  686.                     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
  687.                     p_stream->f_rate = 2; /* FIXME */
  688.                     msg_Dbg( p_demux,
  689.                              "found tarkin header, bitrate: %i, rate: %f",
  690.                              p_stream->fmt.i_bitrate, p_stream->f_rate );
  691.                 }
  692.                 /* Check for Annodex header */
  693.                 else if( oggpacket.bytes >= 7 &&
  694.                          ! strncmp( &oggpacket.packet[0], "Annodex", 7 ) )
  695.                 {
  696.                     Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
  697.                                            &oggpacket );
  698.                     /* kill annodex track */
  699.                     free( p_stream );
  700.                     p_ogg->i_streams--;
  701.                 }
  702.                 /* Check for Annodex header */
  703.                 else if( oggpacket.bytes >= 7 &&
  704.                          ! strncmp( &oggpacket.packet[0], "AnxData", 7 ) )
  705.                 {
  706.                     Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
  707.                                            &oggpacket );
  708.                 }
  709.                 else if( oggpacket.bytes >= 142 &&
  710.                          !strncmp( &oggpacket.packet[1],
  711.                                    "Direct Show Samples embedded in Ogg", 35 ))
  712.                 {
  713.                     /* Old header type */
  714.                     /* Check for video header (old format) */
  715.                     if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
  716.                         oggpacket.bytes >= 184 )
  717.                     {
  718.                         p_stream->fmt.i_cat = VIDEO_ES;
  719.                         p_stream->fmt.i_codec =
  720.                             VLC_FOURCC( oggpacket.packet[68],
  721.                                         oggpacket.packet[69],
  722.                                         oggpacket.packet[70],
  723.                                         oggpacket.packet[71] );
  724.                         msg_Dbg( p_demux, "found video header of type: %.4s",
  725.                                  (char *)&p_stream->fmt.i_codec );
  726.                         p_stream->f_rate = 10000000.0 /
  727.                             GetQWLE((oggpacket.packet+164));
  728.                         p_stream->fmt.video.i_bits_per_pixel =
  729.                             GetWLE((oggpacket.packet+182));
  730.                         if( !p_stream->fmt.video.i_bits_per_pixel )
  731.                             /* hack, FIXME */
  732.                             p_stream->fmt.video.i_bits_per_pixel = 24;
  733.                         p_stream->fmt.video.i_width =
  734.                             GetDWLE((oggpacket.packet+176));
  735.                         p_stream->fmt.video.i_height =
  736.                             GetDWLE((oggpacket.packet+180));
  737.                         msg_Dbg( p_demux,
  738.                                  "fps: %f, width:%i; height:%i, bitcount:%i",
  739.                                  p_stream->f_rate,
  740.                                  p_stream->fmt.video.i_width,
  741.                                  p_stream->fmt.video.i_height,
  742.                                  p_stream->fmt.video.i_bits_per_pixel);
  743.                     }
  744.                     /* Check for audio header (old format) */
  745.                     else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
  746.                     {
  747.                         unsigned int i_extra_size;
  748.                         unsigned int i_format_tag;
  749.                         p_stream->fmt.i_cat = AUDIO_ES;
  750.                         i_extra_size = GetWLE((oggpacket.packet+140));
  751.                         if( i_extra_size )
  752.                         {
  753.                             p_stream->fmt.i_extra = i_extra_size;
  754.                             p_stream->fmt.p_extra = malloc( i_extra_size );
  755.                             memcpy( p_stream->fmt.p_extra,
  756.                                     oggpacket.packet + 142, i_extra_size );
  757.                         }
  758.                         i_format_tag = GetWLE((oggpacket.packet+124));
  759.                         p_stream->fmt.audio.i_channels =
  760.                             GetWLE((oggpacket.packet+126));
  761.                         p_stream->f_rate = p_stream->fmt.audio.i_rate =
  762.                             GetDWLE((oggpacket.packet+128));
  763.                         p_stream->fmt.i_bitrate =
  764.                             GetDWLE((oggpacket.packet+132)) * 8;
  765.                         p_stream->fmt.audio.i_blockalign =
  766.                             GetWLE((oggpacket.packet+136));
  767.                         p_stream->fmt.audio.i_bitspersample =
  768.                             GetWLE((oggpacket.packet+138));
  769.                         wf_tag_to_fourcc( i_format_tag,
  770.                                           &p_stream->fmt.i_codec, 0 );
  771.                         if( p_stream->fmt.i_codec ==
  772.                             VLC_FOURCC('u','n','d','f') )
  773.                         {
  774.                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
  775.                                 ( i_format_tag >> 8 ) & 0xff,
  776.                                 i_format_tag & 0xff );
  777.                         }
  778.                         msg_Dbg( p_demux, "found audio header of type: %.4s",
  779.                                  (char *)&p_stream->fmt.i_codec );
  780.                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
  781.                                  "%dbits/sample %dkb/s",
  782.                                  i_format_tag,
  783.                                  p_stream->fmt.audio.i_channels,
  784.                                  p_stream->fmt.audio.i_rate,
  785.                                  p_stream->fmt.audio.i_bitspersample,
  786.                                  p_stream->fmt.i_bitrate / 1024 );
  787.                     }
  788.                     else
  789.                     {
  790.                         msg_Dbg( p_demux, "stream %d has an old header "
  791.                             "but is of an unknown type", p_ogg->i_streams-1 );
  792.                         free( p_stream );
  793.                         p_ogg->i_streams--;
  794.                     }
  795.                 }
  796.                 else if( (*oggpacket.packet & PACKET_TYPE_BITS )
  797.                          == PACKET_TYPE_HEADER &&
  798.                          oggpacket.bytes >= (int)sizeof(stream_header)+1 )
  799.                 {
  800.                     stream_header *st = (stream_header *)(oggpacket.packet+1);
  801.                     /* Check for video header (new format) */
  802.                     if( !strncmp( st->streamtype, "video", 5 ) )
  803.                     {
  804.                         p_stream->fmt.i_cat = VIDEO_ES;
  805.                         /* We need to get rid of the header packet */
  806.                         ogg_stream_packetout( &p_stream->os, &oggpacket );
  807.                         p_stream->fmt.i_codec =
  808.                             VLC_FOURCC( st->subtype[0], st->subtype[1],
  809.                                         st->subtype[2], st->subtype[3] );
  810.                         msg_Dbg( p_demux, "found video header of type: %.4s",
  811.                                  (char *)&p_stream->fmt.i_codec );
  812.                         p_stream->f_rate = 10000000.0 /
  813.                             GetQWLE(&st->time_unit);
  814.                         p_stream->fmt.video.i_bits_per_pixel =
  815.                             GetWLE(&st->bits_per_sample);
  816.                         p_stream->fmt.video.i_width =
  817.                             GetDWLE(&st->sh.video.width);
  818.                         p_stream->fmt.video.i_height =
  819.                             GetDWLE(&st->sh.video.height);
  820.                         msg_Dbg( p_demux,
  821.                                  "fps: %f, width:%i; height:%i, bitcount:%i",
  822.                                  p_stream->f_rate,
  823.                                  p_stream->fmt.video.i_width,
  824.                                  p_stream->fmt.video.i_height,
  825.                                  p_stream->fmt.video.i_bits_per_pixel );
  826.                     }
  827.                     /* Check for audio header (new format) */
  828.                     else if( !strncmp( st->streamtype, "audio", 5 ) )
  829.                     {
  830.                         char p_buffer[5];
  831.                         int i_format_tag;
  832.                         p_stream->fmt.i_cat = AUDIO_ES;
  833.                         /* We need to get rid of the header packet */
  834.                         ogg_stream_packetout( &p_stream->os, &oggpacket );
  835.                         p_stream->fmt.i_extra = GetQWLE(&st->size) -
  836.                             sizeof(stream_header);
  837.                         if( p_stream->fmt.i_extra )
  838.                         {
  839.                             p_stream->fmt.p_extra =
  840.                                 malloc( p_stream->fmt.i_extra );
  841.                             memcpy( p_stream->fmt.p_extra, st + 1,
  842.                                     p_stream->fmt.i_extra );
  843.                         }
  844.                         memcpy( p_buffer, st->subtype, 4 );
  845.                         p_buffer[4] = '';
  846.                         i_format_tag = strtol(p_buffer,NULL,16);
  847.                         p_stream->fmt.audio.i_channels =
  848.                             GetWLE(&st->sh.audio.channels);
  849.                         p_stream->f_rate = p_stream->fmt.audio.i_rate =
  850.                             GetQWLE(&st->samples_per_unit);
  851.                         p_stream->fmt.i_bitrate =
  852.                             GetDWLE(&st->sh.audio.avgbytespersec) * 8;
  853.                         p_stream->fmt.audio.i_blockalign =
  854.                             GetWLE(&st->sh.audio.blockalign);
  855.                         p_stream->fmt.audio.i_bitspersample =
  856.                             GetWLE(&st->bits_per_sample);
  857.                         wf_tag_to_fourcc( i_format_tag,
  858.                                           &p_stream->fmt.i_codec, 0 );
  859.                         if( p_stream->fmt.i_codec ==
  860.                             VLC_FOURCC('u','n','d','f') )
  861.                         {
  862.                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
  863.                                 ( i_format_tag >> 8 ) & 0xff,
  864.                                 i_format_tag & 0xff );
  865.                         }
  866.                         msg_Dbg( p_demux, "found audio header of type: %.4s",
  867.                                  (char *)&p_stream->fmt.i_codec );
  868.                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
  869.                                  "%dbits/sample %dkb/s",
  870.                                  i_format_tag,
  871.                                  p_stream->fmt.audio.i_channels,
  872.                                  p_stream->fmt.audio.i_rate,
  873.                                  p_stream->fmt.audio.i_bitspersample,
  874.                                  p_stream->fmt.i_bitrate / 1024 );
  875.                     }
  876.                     /* Check for text (subtitles) header */
  877.                     else if( !strncmp(st->streamtype, "text", 4) )
  878.                     {
  879.                         /* We need to get rid of the header packet */
  880.                         ogg_stream_packetout( &p_stream->os, &oggpacket );
  881.                         msg_Dbg( p_demux, "found text subtitles header" );
  882.                         p_stream->fmt.i_cat = SPU_ES;
  883.                         p_stream->fmt.i_codec = VLC_FOURCC('s','u','b','t');
  884.                         p_stream->f_rate = 1000; /* granulepos is in milisec */
  885.                     }
  886.                     else
  887.                     {
  888.                         msg_Dbg( p_demux, "stream %d has a header marker "
  889.                             "but is of an unknown type", p_ogg->i_streams-1 );
  890.                         free( p_stream );
  891.                         p_ogg->i_streams--;
  892.                     }
  893.                 }
  894.                 else
  895.                 {
  896.                     msg_Dbg( p_demux, "stream %d is of unknown type",
  897.                              p_ogg->i_streams-1 );
  898.                     free( p_stream );
  899.                     p_ogg->i_streams--;
  900.                 }
  901.                 if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
  902.                     return VLC_EGENERIC;
  903.             }
  904.             /* This is the first data page, which means we are now finished
  905.              * with the initial pages. We just need to store it in the relevant
  906.              * bitstream. */
  907.             for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
  908.             {
  909.                 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
  910.                                        &oggpage ) == 0 )
  911.                 {
  912.                     break;
  913.                 }
  914.             }
  915.             return VLC_SUCCESS;
  916.         }
  917.     }
  918. #undef p_stream
  919.     return VLC_EGENERIC;
  920. }
  921. /****************************************************************************
  922.  * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
  923.  *                        Elementary streams.
  924.  ****************************************************************************/
  925. static int Ogg_BeginningOfStream( demux_t *p_demux )
  926. {
  927.     demux_sys_t *p_ogg = p_demux->p_sys  ;
  928.     int i_stream;
  929.     /* Find the logical streams embedded in the physical stream and
  930.      * initialize our p_ogg structure. */
  931.     if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
  932.     {
  933.         msg_Warn( p_demux, "couldn't find any ogg logical stream" );
  934.         return VLC_EGENERIC;
  935.     }
  936.     p_ogg->i_bitrate = 0;
  937.     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
  938.     {
  939. #define p_stream p_ogg->pp_stream[i_stream]
  940.         p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
  941.         if( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
  942.         {
  943.             /* Set the CMML stream active */
  944.             es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
  945.         }
  946.         p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
  947.         p_stream->i_pcr = p_stream->i_previous_pcr =
  948.             p_stream->i_interpolated_pcr = -1;
  949.         p_stream->b_reinit = 0;
  950. #undef p_stream
  951.     }
  952.     return VLC_SUCCESS;
  953. }
  954. /****************************************************************************
  955.  * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
  956.  ****************************************************************************/
  957. static void Ogg_EndOfStream( demux_t *p_demux )
  958. {
  959.     demux_sys_t *p_ogg = p_demux->p_sys  ;
  960.     int i_stream;
  961. #define p_stream p_ogg->pp_stream[i_stream]
  962.     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
  963.     {
  964.         if( p_stream->p_es )
  965.             es_out_Del( p_demux->out, p_stream->p_es );
  966.         p_ogg->i_bitrate -= p_stream->fmt.i_bitrate;
  967.         ogg_stream_clear( &p_ogg->pp_stream[i_stream]->os );
  968.         if( p_ogg->pp_stream[i_stream]->p_headers)
  969.             free( p_ogg->pp_stream[i_stream]->p_headers );
  970.         es_format_Clean( &p_stream->fmt );
  971.         free( p_ogg->pp_stream[i_stream] );
  972.     }
  973. #undef p_stream
  974.     /* Reinit p_ogg */
  975.     if( p_ogg->pp_stream ) free( p_ogg->pp_stream );
  976.     p_ogg->pp_stream = NULL;
  977.     p_ogg->i_streams = 0;
  978. }
  979. static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
  980.                                   ogg_packet *p_oggpacket )
  981. {
  982.     bs_t bitstream;
  983.     int i_fps_numerator;
  984.     int i_fps_denominator;
  985.     int i_keyframe_frequency_force;
  986.     p_stream->fmt.i_cat = VIDEO_ES;
  987.     p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
  988.     /* Signal that we want to keep a backup of the theora
  989.      * stream headers. They will be used when switching between
  990.      * audio streams. */
  991.     p_stream->b_force_backup = 1;
  992.     /* Cheat and get additionnal info ;) */
  993.     bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
  994.     bs_skip( &bitstream, 56 );
  995.     bs_read( &bitstream, 8 ); /* major version num */
  996.     bs_read( &bitstream, 8 ); /* minor version num */
  997.     bs_read( &bitstream, 8 ); /* subminor version num */
  998.     bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
  999.     bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
  1000.     bs_read( &bitstream, 24 ); /* frame width */
  1001.     bs_read( &bitstream, 24 ); /* frame height */
  1002.     bs_read( &bitstream, 8 ); /* x offset */
  1003.     bs_read( &bitstream, 8 ); /* y offset */
  1004.     i_fps_numerator = bs_read( &bitstream, 32 );
  1005.     i_fps_denominator = bs_read( &bitstream, 32 );
  1006.     bs_read( &bitstream, 24 ); /* aspect_numerator */
  1007.     bs_read( &bitstream, 24 ); /* aspect_denominator */
  1008.     bs_read( &bitstream, 8 ); /* colorspace */
  1009.     p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
  1010.     bs_read( &bitstream, 6 ); /* quality */
  1011.     i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
  1012.     /* granule_shift = i_log( frequency_force -1 ) */
  1013.     p_stream->i_theora_keyframe_granule_shift = 0;
  1014.     i_keyframe_frequency_force--;
  1015.     while( i_keyframe_frequency_force )
  1016.     {
  1017.         p_stream->i_theora_keyframe_granule_shift++;
  1018.         i_keyframe_frequency_force >>= 1;
  1019.     }
  1020.     p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
  1021. }
  1022. static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
  1023.                                   ogg_packet *p_oggpacket )
  1024. {
  1025.     oggpack_buffer opb;
  1026.     p_stream->fmt.i_cat = AUDIO_ES;
  1027.     p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
  1028.     /* Signal that we want to keep a backup of the vorbis
  1029.      * stream headers. They will be used when switching between
  1030.      * audio streams. */
  1031.     p_stream->b_force_backup = 1;
  1032.     /* Cheat and get additionnal info ;) */
  1033.     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
  1034.     oggpack_adv( &opb, 88 );
  1035.     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
  1036.     p_stream->f_rate = p_stream->fmt.audio.i_rate =
  1037.         oggpack_read( &opb, 32 );
  1038.     oggpack_adv( &opb, 32 );
  1039.     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
  1040. }
  1041. static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
  1042.                                  ogg_packet *p_oggpacket )
  1043. {
  1044.     oggpack_buffer opb;
  1045.     p_stream->fmt.i_cat = AUDIO_ES;
  1046.     p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
  1047.     /* Signal that we want to keep a backup of the speex
  1048.      * stream headers. They will be used when switching between
  1049.      * audio streams. */
  1050.     p_stream->b_force_backup = 1;
  1051.     /* Cheat and get additionnal info ;) */
  1052.     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
  1053.     oggpack_adv( &opb, 224 );
  1054.     oggpack_adv( &opb, 32 ); /* speex_version_id */
  1055.     oggpack_adv( &opb, 32 ); /* header_size */
  1056.     p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
  1057.     oggpack_adv( &opb, 32 ); /* mode */
  1058.     oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
  1059.     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
  1060.     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
  1061. }
  1062. static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
  1063.                                 ogg_packet *p_oggpacket )
  1064. {
  1065.     /* Parse the STREAMINFO metadata */
  1066.     bs_t s;
  1067.     bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
  1068.     bs_read( &s, 1 );
  1069.     if( bs_read( &s, 7 ) == 0 )
  1070.     {
  1071.         if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
  1072.         {
  1073.             bs_skip( &s, 80 );
  1074.             p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
  1075.             p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
  1076.             msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
  1077.                      p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
  1078.         }
  1079.         else msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
  1080.         /* Fake this as the last metadata block */
  1081.         *((uint8_t*)p_oggpacket->packet) |= 0x80;
  1082.     }
  1083.     else
  1084.     {
  1085.         /* This ain't a STREAMINFO metadata */
  1086.         msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
  1087.     }
  1088. }
  1089. static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
  1090.                                    logical_stream_t *p_stream,
  1091.                                    ogg_packet *p_oggpacket )
  1092. {
  1093.     if( ! strncmp( &p_oggpacket->packet[0], "Annodex", 7 ) )
  1094.     {
  1095.         oggpack_buffer opb;
  1096.         uint16_t major_version;
  1097.         uint16_t minor_version;
  1098.         uint64_t timebase_numerator;
  1099.         uint64_t timebase_denominator;
  1100.         Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
  1101.         oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
  1102.         oggpack_adv( &opb, 8*8 ); /* "Annodex" header */
  1103.         major_version = oggpack_read( &opb, 2*8 ); /* major version */
  1104.         minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
  1105.         timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
  1106.         timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
  1107.     }
  1108.     else if( ! strncmp( &p_oggpacket->packet[0], "AnxData", 7 ) )
  1109.     {
  1110.         uint64_t granule_rate_numerator;
  1111.         uint64_t granule_rate_denominator;
  1112.         char content_type_string[1024];
  1113.         /* Read in Annodex header fields */
  1114.         granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
  1115.         granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
  1116.         p_stream->secondary_header_packets =
  1117.             GetDWLE( &p_oggpacket->packet[24] );
  1118.         msg_Dbg( p_this, "anxdata packet info: %qd/%qd, %d",
  1119.                  granule_rate_numerator, granule_rate_denominator,
  1120.                  p_stream->secondary_header_packets);
  1121.         /* we are guaranteed that the first header field will be
  1122.          * the content-type (by the Annodex standard) */
  1123.         sscanf( &p_oggpacket->packet[28], "Content-Type: %1024srn",
  1124.                 content_type_string );
  1125.         p_stream->f_rate = (float) granule_rate_numerator /
  1126.             (float) granule_rate_denominator;
  1127.         /* What type of file do we have?
  1128.          * strcmp is safe to use here because we've extracted
  1129.          * content_type_string from the stream manually */
  1130.         if( !strncmp(content_type_string, "audio/x-wav", 11) )
  1131.         {
  1132.             /* n.b. WAVs are unsupported right now */
  1133.             p_stream->fmt.i_cat = UNKNOWN_ES;
  1134.         }
  1135.         else if( !strncmp(content_type_string, "audio/x-vorbis", 14) )
  1136.         {
  1137.             p_stream->fmt.i_cat = AUDIO_ES;
  1138.             p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
  1139.             p_stream->b_force_backup = 1;
  1140.         }
  1141.         else if( !strncmp(content_type_string, "video/x-theora", 14) )
  1142.         {
  1143.             p_stream->fmt.i_cat = VIDEO_ES;
  1144.             p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
  1145.             p_stream->b_force_backup = 1;
  1146.         }
  1147.         else if( !strncmp(content_type_string, "video/x-xvid", 14) )
  1148.         {
  1149.             p_stream->fmt.i_cat = VIDEO_ES;
  1150.             p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
  1151.             p_stream->b_force_backup = 1;
  1152.         }
  1153.         else if( !strncmp(content_type_string, "video/mpeg", 14) )
  1154.         {
  1155.             /* n.b. MPEG streams are unsupported right now */
  1156.             p_stream->fmt.i_cat = VIDEO_ES;
  1157.             p_stream->fmt.i_codec = VLC_FOURCC( 'm','p','g','v' );
  1158.         }
  1159.         else if( !strncmp(content_type_string, "text/x-cmml", 11) )
  1160.         {
  1161.             ogg_stream_packetout( &p_stream->os, p_oggpacket );
  1162.             p_stream->fmt.i_cat = SPU_ES;
  1163.             p_stream->fmt.i_codec = VLC_FOURCC( 'c','m','m','l' );
  1164.         }
  1165.     }
  1166. }