]> git.sesse.net Git - vlc/blob - modules/demux/ogg.c
Parse meta data at ogg level.
[vlc] / modules / demux / ogg.c
1 /*****************************************************************************
2  * ogg.c : ogg stream demux module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2007 the VideoLAN team
5  * $Id$
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_demux.h>
35 #include <vlc_meta.h>
36 #include <vlc_input.h>
37
38 #include <ogg/ogg.h>
39
40 #include <vlc_codecs.h>
41 #include <vlc_bits.h>
42 #include <vlc_charset.h>
43 #include "vorbis.h"
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 static int  Open ( vlc_object_t * );
49 static void Close( vlc_object_t * );
50
51 vlc_module_begin ()
52     set_shortname ( "OGG" )
53     set_description( N_("OGG demuxer" ) )
54     set_category( CAT_INPUT )
55     set_subcategory( SUBCAT_INPUT_DEMUX )
56     set_capability( "demux", 50 )
57     set_callbacks( Open, Close )
58     add_shortcut( "ogg" )
59 vlc_module_end ()
60
61
62 /*****************************************************************************
63  * Definitions of structures and functions used by this plugins
64  *****************************************************************************/
65 typedef struct logical_stream_s
66 {
67     ogg_stream_state os;                        /* logical stream of packets */
68
69     es_format_t      fmt;
70     es_format_t      fmt_old;                  /* format of old ES is reused */
71     es_out_id_t      *p_es;
72     double           f_rate;
73
74     int              i_serial_no;
75
76     /* the header of some logical streams (eg vorbis) contain essential
77      * data for the decoder. We back them up here in case we need to re-feed
78      * them to the decoder. */
79     int              b_force_backup;
80     int              i_packets_backup;
81     uint8_t          *p_headers;
82     int              i_headers;
83
84     /* program clock reference (in units of 90kHz) derived from the previous
85      * granulepos */
86     mtime_t          i_pcr;
87     mtime_t          i_interpolated_pcr;
88     mtime_t          i_previous_pcr;
89
90     /* Misc */
91     bool b_reinit;
92     int i_granule_shift;
93
94     /* kate streams have the number of headers in the ID header */
95     int i_kate_num_headers;
96
97     /* for Annodex logical bitstreams */
98     int i_secondary_header_packets;
99
100 } logical_stream_t;
101
102 struct demux_sys_t
103 {
104     ogg_sync_state oy;        /* sync and verify incoming physical bitstream */
105
106     int i_streams;                           /* number of logical bitstreams */
107     logical_stream_t **pp_stream;  /* pointer to an array of logical streams */
108
109     logical_stream_t *p_old_stream; /* pointer to a old logical stream to avoid recreating it */
110
111     /* program clock reference (in units of 90kHz) derived from the pcr of
112      * the sub-streams */
113     mtime_t i_pcr;
114
115     /* stream state */
116     int     i_bos;
117     int     i_eos;
118
119     /* bitrate */
120     int     i_bitrate;
121
122     /* after reading all headers, the first data page is stuffed into the relevant stream, ready to use */
123     bool    b_page_waiting;
124
125     /* */
126     vlc_meta_t *p_meta;
127 };
128
129 /* OggDS headers for the new header format (used in ogm files) */
130 typedef struct
131 {
132     ogg_int32_t width;
133     ogg_int32_t height;
134 } stream_header_video_t;
135
136 typedef struct
137 {
138     ogg_int16_t channels;
139     ogg_int16_t padding;
140     ogg_int16_t blockalign;
141     ogg_int32_t avgbytespersec;
142 } stream_header_audio_t;
143
144 typedef struct
145 {
146     char        streamtype[8];
147     char        subtype[4];
148
149     ogg_int32_t size;                               /* size of the structure */
150
151     ogg_int64_t time_unit;                              /* in reference time */
152     ogg_int64_t samples_per_unit;
153     ogg_int32_t default_len;                                /* in media time */
154
155     ogg_int32_t buffersize;
156     ogg_int16_t bits_per_sample;
157     ogg_int16_t padding;
158
159     union
160     {
161         /* Video specific */
162         stream_header_video_t video;
163         /* Audio specific */
164         stream_header_audio_t audio;
165     } sh;
166 } stream_header_t;
167
168 #define OGG_BLOCK_SIZE 4096
169
170 /* Some defines from OggDS */
171 #define PACKET_TYPE_HEADER   0x01
172 #define PACKET_TYPE_BITS     0x07
173 #define PACKET_LEN_BITS01    0xc0
174 #define PACKET_LEN_BITS2     0x02
175 #define PACKET_IS_SYNCPOINT  0x08
176
177 /*****************************************************************************
178  * Local prototypes
179  *****************************************************************************/
180 static int  Demux  ( demux_t * );
181 static int  Control( demux_t *, int, va_list );
182
183 /* Bitstream manipulation */
184 static int  Ogg_ReadPage     ( demux_t *, ogg_page * );
185 static void Ogg_UpdatePCR    ( logical_stream_t *, ogg_packet * );
186 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
187
188 static int Ogg_BeginningOfStream( demux_t *p_demux );
189 static int Ogg_FindLogicalStreams( demux_t *p_demux );
190 static void Ogg_EndOfStream( demux_t *p_demux );
191
192 /* */
193 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
194 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
195
196 /* */
197 static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers );
198
199 /* Logical bitstream headers */
200 static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
201 static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
202 static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
203 static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
204 static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
205 static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
206 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
207
208 /*****************************************************************************
209  * Open: initializes ogg demux structures
210  *****************************************************************************/
211 static int Open( vlc_object_t * p_this )
212 {
213     demux_t *p_demux = (demux_t *)p_this;
214     demux_sys_t    *p_sys;
215     const uint8_t  *p_peek;
216
217
218     /* Check if we are dealing with an ogg stream */
219     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
220     if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
221     {
222         return VLC_EGENERIC;
223     }
224
225     /* Set exported functions */
226     p_demux->pf_demux = Demux;
227     p_demux->pf_control = Control;
228     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
229     if( !p_sys )
230         return VLC_ENOMEM;
231
232     memset( p_sys, 0, sizeof( demux_sys_t ) );
233     p_sys->i_bitrate = 0;
234     p_sys->pp_stream = NULL;
235     p_sys->p_old_stream = NULL;
236
237     /* Begnning of stream, tell the demux to look for elementary streams. */
238     p_sys->i_bos = 0;
239     p_sys->i_eos = 0;
240
241     /* Initialize the Ogg physical bitstream parser */
242     ogg_sync_init( &p_sys->oy );
243     p_sys->b_page_waiting = false;
244
245     /* */
246     p_sys->p_meta = NULL;
247
248     return VLC_SUCCESS;
249 }
250
251 /*****************************************************************************
252  * Close: frees unused data
253  *****************************************************************************/
254 static void Close( vlc_object_t *p_this )
255 {
256     demux_t *p_demux = (demux_t *)p_this;
257     demux_sys_t *p_sys = p_demux->p_sys  ;
258
259     /* Cleanup the bitstream parser */
260     ogg_sync_clear( &p_sys->oy );
261
262     Ogg_EndOfStream( p_demux );
263
264     if( p_sys->p_old_stream )
265         Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
266
267     free( p_sys );
268 }
269
270 /*****************************************************************************
271  * Demux: reads and demuxes data packets
272  *****************************************************************************
273  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
274  *****************************************************************************/
275 static int Demux( demux_t * p_demux )
276 {
277     demux_sys_t *p_sys = p_demux->p_sys;
278     ogg_page    oggpage;
279     ogg_packet  oggpacket;
280     int         i_stream;
281
282
283     if( p_sys->i_eos == p_sys->i_streams )
284     {
285         if( p_sys->i_eos )
286         {
287             msg_Dbg( p_demux, "end of a group of logical streams" );
288             /* We keep the ES to try reusing it in Ogg_BeginningOfStream
289              * only 1 ES is supported (common case for ogg web radio) */
290             if( p_sys->i_streams == 1 )
291             {
292                 p_sys->p_old_stream = p_sys->pp_stream[0];
293                 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
294             }
295             Ogg_EndOfStream( p_demux );
296         }
297
298         p_sys->i_eos = 0;
299         if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
300             return 0;
301
302         msg_Dbg( p_demux, "beginning of a group of logical streams" );
303         es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
304     }
305
306     /*
307      * The first data page of a physical stream is stored in the relevant logical stream
308      * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
309      * stream it belongs to if we haven't processed this first page yet. If we do, we
310      * will only process that first page whenever we find the second page for this stream.
311      * While this is fine for Vorbis and Theora, which are continuous codecs, which means
312      * the second page will arrive real quick, this is not fine for Kate, whose second
313      * data page will typically arrive much later.
314      * This means it is now possible to seek right at the start of a stream where the last
315      * logical stream is Kate, without having to wait for the second data page to unblock
316      * the first one, which is the one that triggers the 'no more headers to backup' code.
317      * And, as we all know, seeking without having backed up all headers is bad, since the
318      * codec will fail to initialize if it's missing its headers.
319      */
320     if( !p_sys->b_page_waiting)
321     {
322         /*
323          * Demux an ogg page from the stream
324          */
325         if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
326             return 0; /* EOF */
327
328         /* Test for End of Stream */
329         if( ogg_page_eos( &oggpage ) )
330             p_sys->i_eos++;
331     }
332
333
334     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
335     {
336         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
337
338         /* if we've just pulled page, look for the right logical stream */
339         if( !p_sys->b_page_waiting )
340         {
341             if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 )
342                 continue;
343         }
344
345         while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
346         {
347             /* Read info from any secondary header packets, if there are any */
348             if( p_stream->i_secondary_header_packets > 0 )
349             {
350                 if( p_stream->fmt.i_codec == VLC_FOURCC('t','h','e','o') &&
351                         oggpacket.bytes >= 7 &&
352                         ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
353                 {
354                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
355                     p_stream->i_secondary_header_packets = 0;
356                 }
357                 else if( p_stream->fmt.i_codec == VLC_FOURCC('v','o','r','b') &&
358                         oggpacket.bytes >= 7 &&
359                         ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
360                 {
361                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
362                     p_stream->i_secondary_header_packets = 0;
363                 }
364                 else if( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
365                 {
366                     p_stream->i_secondary_header_packets = 0;
367                 }
368             }
369
370             if( p_stream->b_reinit )
371             {
372                 /* If synchro is re-initialized we need to drop all the packets
373                  * until we find a new dated one. */
374                 Ogg_UpdatePCR( p_stream, &oggpacket );
375
376                 if( p_stream->i_pcr >= 0 )
377                 {
378                     p_stream->b_reinit = false;
379                 }
380                 else
381                 {
382                     p_stream->i_interpolated_pcr = -1;
383                     continue;
384                 }
385
386                 /* An Ogg/vorbis packet contains an end date granulepos */
387                 if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
388                     p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
389                     p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
390                 {
391                     if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
392                     {
393                         Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
394                     }
395                     else
396                     {
397                         es_out_Control( p_demux->out, ES_OUT_SET_PCR,
398                                         p_stream->i_pcr );
399                     }
400                     continue;
401                 }
402             }
403
404             Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
405         }
406
407         if( !p_sys->b_page_waiting )
408             break;
409     }
410
411     /* if a page was waiting, it's now processed */
412     p_sys->b_page_waiting = false;
413
414     p_sys->i_pcr = -1;
415     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
416     {
417         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
418
419         if( p_stream->fmt.i_cat == SPU_ES )
420             continue;
421         if( p_stream->i_interpolated_pcr < 0 )
422             continue;
423
424         if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )
425             p_sys->i_pcr = p_stream->i_interpolated_pcr;
426     }
427
428     if( p_sys->i_pcr >= 0 )
429         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
430
431     return 1;
432 }
433
434 /*****************************************************************************
435  * Control:
436  *****************************************************************************/
437 static int Control( demux_t *p_demux, int i_query, va_list args )
438 {
439     demux_sys_t *p_sys  = p_demux->p_sys;
440     vlc_meta_t *p_meta;
441     int64_t *pi64;
442     bool *pb_bool;
443     int i;
444
445     switch( i_query )
446     {
447         case DEMUX_GET_META:
448             p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
449             if( p_sys->p_meta )
450                 vlc_meta_Merge( p_meta, p_sys->p_meta );
451             return VLC_SUCCESS;
452
453         case DEMUX_HAS_UNSUPPORTED_META:
454             pb_bool = (bool*)va_arg( args, bool* );
455             *pb_bool = true;
456             return VLC_SUCCESS;
457
458         case DEMUX_GET_TIME:
459             pi64 = (int64_t*)va_arg( args, int64_t * );
460             *pi64 = p_sys->i_pcr;
461             return VLC_SUCCESS;
462
463         case DEMUX_SET_TIME:
464             return VLC_EGENERIC;
465
466         case DEMUX_SET_POSITION:
467             /* forbid seeking if we haven't initialized all logical bitstreams yet;
468                if we allowed, some headers would not get backed up and decoder init
469                would fail, making that logical stream unusable */
470             if( p_sys->i_bos > 0 )
471             {
472                 return VLC_EGENERIC;
473             }
474
475             for( i = 0; i < p_sys->i_streams; i++ )
476             {
477                 logical_stream_t *p_stream = p_sys->pp_stream[i];
478
479                 /* we'll trash all the data until we find the next pcr */
480                 p_stream->b_reinit = true;
481                 p_stream->i_pcr = -1;
482                 p_stream->i_interpolated_pcr = -1;
483                 ogg_stream_reset( &p_stream->os );
484             }
485             ogg_sync_reset( &p_sys->oy );
486             /* XXX The break/return is missing on purpose as
487              * demux_vaControlHelper will do the last part of the job */
488
489         default:
490             return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
491                                            1, i_query, args );
492     }
493 }
494
495 /****************************************************************************
496  * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
497  ****************************************************************************
498  * Returns VLC_SUCCESS if a page has been read. An error might happen if we
499  * are at the end of stream.
500  ****************************************************************************/
501 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
502 {
503     demux_sys_t *p_ogg = p_demux->p_sys  ;
504     int i_read = 0;
505     char *p_buffer;
506
507     while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
508     {
509         p_buffer = ogg_sync_buffer( &p_ogg->oy, OGG_BLOCK_SIZE );
510
511         i_read = stream_Read( p_demux->s, p_buffer, OGG_BLOCK_SIZE );
512         if( i_read <= 0 )
513             return VLC_EGENERIC;
514
515         ogg_sync_wrote( &p_ogg->oy, i_read );
516     }
517
518     return VLC_SUCCESS;
519 }
520
521 /****************************************************************************
522  * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
523  *                current stream.
524  ****************************************************************************/
525 static void Ogg_UpdatePCR( logical_stream_t *p_stream,
526                            ogg_packet *p_oggpacket )
527 {
528     /* Convert the granulepos into a pcr */
529     if( p_oggpacket->granulepos >= 0 )
530     {
531         if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) ||
532             p_stream->fmt.i_codec == VLC_FOURCC( 'k','a','t','e' ) )
533         {
534             ogg_int64_t iframe = p_oggpacket->granulepos >>
535               p_stream->i_granule_shift;
536             ogg_int64_t pframe = p_oggpacket->granulepos -
537               ( iframe << p_stream->i_granule_shift );
538
539             p_stream->i_pcr = ( iframe + pframe ) * INT64_C(1000000)
540                               / p_stream->f_rate;
541         }
542         else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
543         {
544             ogg_int64_t i_dts = p_oggpacket->granulepos >> 31;
545             /* NB, OggDirac granulepos values are in units of 2*picturerate */
546             p_stream->i_pcr = (i_dts/2) * INT64_C(1000000) / p_stream->f_rate;
547         }
548         else
549         {
550             p_stream->i_pcr = p_oggpacket->granulepos * INT64_C(1000000)
551                               / p_stream->f_rate;
552         }
553
554         p_stream->i_interpolated_pcr = p_stream->i_pcr;
555     }
556     else
557     {
558         p_stream->i_pcr = -1;
559
560         /* no granulepos available, try to interpolate the pcr.
561          * If we can't then don't touch the old value. */
562         if( p_stream->fmt.i_cat == VIDEO_ES )
563             /* 1 frame per packet */
564             p_stream->i_interpolated_pcr += (INT64_C(1000000) / p_stream->f_rate);
565         else if( p_stream->fmt.i_bitrate )
566             p_stream->i_interpolated_pcr +=
567                 ( p_oggpacket->bytes * INT64_C(1000000) /
568                   p_stream->fmt.i_bitrate / 8 );
569     }
570 }
571
572 /****************************************************************************
573  * Ogg_DecodePacket: Decode an Ogg packet.
574  ****************************************************************************/
575 static void Ogg_DecodePacket( demux_t *p_demux,
576                               logical_stream_t *p_stream,
577                               ogg_packet *p_oggpacket )
578 {
579     block_t *p_block;
580     bool b_selected;
581     int i_header_len = 0;
582     mtime_t i_pts = -1, i_interpolated_pts;
583     demux_sys_t *p_ogg = p_demux->p_sys;
584
585     /* Sanity check */
586     if( !p_oggpacket->bytes )
587     {
588         msg_Dbg( p_demux, "discarding 0 sized packet" );
589         return;
590     }
591
592     if( p_oggpacket->bytes >= 7 &&
593         ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
594     {
595         /* it's an Annodex packet -- skip it (do nothing) */
596         return;
597     }
598     else if( p_oggpacket->bytes >= 7 &&
599         ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
600     {
601         /* it's an AnxData packet -- skip it (do nothing) */
602         return;
603     }
604
605     if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ) &&
606         p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
607
608     /* Check the ES is selected */
609     es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
610                     p_stream->p_es, &b_selected );
611
612     if( p_stream->b_force_backup )
613     {
614         uint8_t *p_sav;
615         bool b_store_size = true;
616         bool b_store_num_headers = false;
617
618         p_stream->i_packets_backup++;
619         switch( p_stream->fmt.i_codec )
620         {
621         case VLC_FOURCC( 'v','o','r','b' ):
622         case VLC_FOURCC( 's','p','x',' ' ):
623         case VLC_FOURCC( 't','h','e','o' ):
624             if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
625             break;
626
627         case VLC_FOURCC( 'f','l','a','c' ):
628             if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
629             {
630                 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
631                 p_stream->b_force_backup = 0;
632             }
633             else if( p_stream->fmt.audio.i_rate )
634             {
635                 p_stream->b_force_backup = 0;
636                 if( p_oggpacket->bytes >= 9 )
637                 {
638                     p_oggpacket->packet += 9;
639                     p_oggpacket->bytes -= 9;
640                 }
641             }
642             b_store_size = false;
643             break;
644
645         case VLC_FOURCC( 'k','a','t','e' ):
646             if( p_stream->i_packets_backup == 1)
647                 b_store_num_headers = true;
648             if( p_stream->i_packets_backup == p_stream->i_kate_num_headers ) p_stream->b_force_backup = 0;
649             break;
650
651         default:
652             p_stream->b_force_backup = 0;
653             break;
654         }
655
656         /* Backup the ogg packet (likely an header packet) */
657         p_stream->p_headers =
658             realloc( p_sav = p_stream->p_headers, p_stream->i_headers +
659                      p_oggpacket->bytes + (b_store_size ? 2 : 0) + (b_store_num_headers ? 1 : 0) );
660         if( p_stream->p_headers )
661         {
662             uint8_t *p_extra = p_stream->p_headers + p_stream->i_headers;
663
664             if( b_store_num_headers )
665             {
666                 /* Kate streams store the number of headers in the first header,
667                    so we can't just test for 3 as Vorbis/Theora */
668                 *(p_extra++) = p_stream->i_kate_num_headers;
669             }
670             if( b_store_size )
671             {
672                 *(p_extra++) = p_oggpacket->bytes >> 8;
673                 *(p_extra++) = p_oggpacket->bytes & 0xFF;
674             }
675             memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes );
676             p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0) + (b_store_num_headers ? 1 : 0);
677
678             if( !p_stream->b_force_backup )
679             {
680                 /* Last header received, commit changes */
681                 free( p_stream->fmt.p_extra );
682
683                 p_stream->fmt.i_extra = p_stream->i_headers;
684                 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
685                 if( p_stream->fmt.p_extra )
686                     memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
687                             p_stream->i_headers );
688                 else
689                     p_stream->fmt.i_extra = 0;
690
691                 if( Ogg_LogicalStreamResetEsFormat( p_demux, p_stream ) )
692                     es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
693                                     p_stream->p_es, &p_stream->fmt );
694
695                 if( p_stream->i_headers > 0 )
696                     Ogg_ExtractMeta( p_demux, p_stream->fmt.i_codec,
697                                      p_stream->p_headers, p_stream->i_headers );
698
699                 /* we're not at BOS anymore for this logical stream */
700                 p_ogg->i_bos--;
701             }
702         }
703         else
704         {
705                 p_stream->p_headers = p_sav;
706         }
707
708         b_selected = false; /* Discard the header packet */
709     }
710
711     /* Convert the pcr into a pts */
712     if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
713         p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
714         p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
715     {
716         if( p_stream->i_pcr >= 0 )
717         {
718             /* This is for streams where the granulepos of the header packets
719              * doesn't match these of the data packets (eg. ogg web radios). */
720             if( p_stream->i_previous_pcr == 0 &&
721                 p_stream->i_pcr  > 3 * DEFAULT_PTS_DELAY )
722             {
723                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
724
725                 /* Call the pace control */
726                 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
727                                 p_stream->i_pcr );
728             }
729
730             p_stream->i_previous_pcr = p_stream->i_pcr;
731
732             /* The granulepos is the end date of the sample */
733             i_pts =  p_stream->i_pcr;
734         }
735     }
736
737     /* Convert the granulepos into the next pcr */
738     i_interpolated_pts = p_stream->i_interpolated_pcr;
739     Ogg_UpdatePCR( p_stream, p_oggpacket );
740
741     /* SPU streams are typically discontinuous, do not mind large gaps */
742     if( p_stream->fmt.i_cat != SPU_ES )
743     {
744         if( p_stream->i_pcr >= 0 )
745         {
746             /* This is for streams where the granulepos of the header packets
747              * doesn't match these of the data packets (eg. ogg web radios). */
748             if( p_stream->i_previous_pcr == 0 &&
749                 p_stream->i_pcr  > 3 * DEFAULT_PTS_DELAY )
750             {
751                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
752
753                 /* Call the pace control */
754                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_stream->i_pcr );
755             }
756         }
757     }
758
759     if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
760         p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
761         p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
762         p_stream->i_pcr >= 0 )
763     {
764         p_stream->i_previous_pcr = p_stream->i_pcr;
765
766         /* The granulepos is the start date of the sample */
767         i_pts = p_stream->i_pcr;
768     }
769
770     if( !b_selected )
771     {
772         /* This stream isn't currently selected so we don't need to decode it,
773          * but we did need to store its pcr as it might be selected later on */
774         return;
775     }
776
777     if( p_oggpacket->bytes <= 0 )
778         return;
779
780     if( !( p_block = block_New( p_demux, p_oggpacket->bytes ) ) ) return;
781
782     /* Normalize PTS */
783     if( i_pts == 0 ) i_pts = 1;
784     else if( i_pts == -1 && i_interpolated_pts == 0 ) i_pts = 1;
785     else if( i_pts == -1 ) i_pts = 0;
786
787     if( p_stream->fmt.i_cat == AUDIO_ES )
788         p_block->i_dts = p_block->i_pts = i_pts;
789     else if( p_stream->fmt.i_cat == SPU_ES )
790     {
791         p_block->i_dts = p_block->i_pts = i_pts;
792         p_block->i_length = 0;
793     }
794     else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )
795         p_block->i_dts = p_block->i_pts = i_pts;
796     else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
797     {
798         ogg_int64_t dts = p_oggpacket->granulepos >> 31;
799         ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
800
801         uint64_t u_pnum = dts + delay;
802
803         p_block->i_dts = p_stream->i_pcr;
804         p_block->i_pts = 0;
805         /* NB, OggDirac granulepos values are in units of 2*picturerate */
806         if( -1 != p_oggpacket->granulepos )
807             p_block->i_pts = u_pnum * INT64_C(1000000) / p_stream->f_rate / 2;
808     }
809     else
810     {
811         p_block->i_dts = i_pts;
812         p_block->i_pts = 0;
813     }
814
815     if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
816         p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
817         p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
818         p_stream->fmt.i_codec != VLC_FOURCC( 't','a','r','k' ) &&
819         p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) &&
820         p_stream->fmt.i_codec != VLC_FOURCC( 'c','m','m','l' ) &&
821         p_stream->fmt.i_codec != VLC_FOURCC( 'd','r','a','c' ) &&
822         p_stream->fmt.i_codec != VLC_FOURCC( 'k','a','t','e' ) )
823     {
824         /* We remove the header from the packet */
825         i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
826         i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
827
828         if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ))
829         {
830             /* But with subtitles we need to retrieve the duration first */
831             int i, lenbytes = 0;
832
833             if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
834             {
835                 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
836                 {
837                     lenbytes = lenbytes << 8;
838                     lenbytes += *(p_oggpacket->packet + i_header_len - i);
839                 }
840             }
841             if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
842                 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
843                   p_oggpacket->packet[i_header_len + 1] != 0 &&
844                   p_oggpacket->packet[i_header_len + 1] != '\n' &&
845                   p_oggpacket->packet[i_header_len + 1] != '\r' ) )
846             {
847                 p_block->i_length = (mtime_t)lenbytes * 1000;
848             }
849         }
850
851         i_header_len++;
852         if( p_block->i_buffer >= (unsigned int)i_header_len )
853             p_block->i_buffer -= i_header_len;
854         else
855             p_block->i_buffer = 0;
856     }
857
858     if( p_stream->fmt.i_codec == VLC_FOURCC( 't','a','r','k' ) )
859     {
860         /* FIXME: the biggest hack I've ever done */
861         msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
862                   p_block->i_pts, p_block->i_dts );
863         msleep(10000);
864     }
865
866     memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
867             p_oggpacket->bytes - i_header_len );
868
869     es_out_Send( p_demux->out, p_stream->p_es, p_block );
870 }
871
872 /****************************************************************************
873  * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
874  *                         stream and fill p_ogg.
875  *****************************************************************************
876  * The initial page of a logical stream is marked as a 'bos' page.
877  * Furthermore, the Ogg specification mandates that grouped bitstreams begin
878  * together and all of the initial pages must appear before any data pages.
879  *
880  * On success this function returns VLC_SUCCESS.
881  ****************************************************************************/
882 static int Ogg_FindLogicalStreams( demux_t *p_demux )
883 {
884     demux_sys_t *p_ogg = p_demux->p_sys  ;
885     ogg_packet oggpacket;
886     ogg_page oggpage;
887     int i_stream;
888
889     while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS )
890     {
891         if( ogg_page_bos( &oggpage ) )
892         {
893
894             /* All is wonderful in our fine fine little world.
895              * We found the beginning of our first logical stream. */
896             while( ogg_page_bos( &oggpage ) )
897             {
898                 logical_stream_t *p_stream;
899
900                 p_stream = malloc( sizeof(logical_stream_t) );
901                 if( !p_stream )
902                     return VLC_ENOMEM;
903
904                 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
905
906                 memset( p_stream, 0, sizeof(logical_stream_t) );
907                 p_stream->p_headers = 0;
908                 p_stream->i_secondary_header_packets = 0;
909
910                 es_format_Init( &p_stream->fmt, 0, 0 );
911                 es_format_Init( &p_stream->fmt_old, 0, 0 );
912
913                 /* Setup the logical stream */
914                 p_stream->i_serial_no = ogg_page_serialno( &oggpage );
915                 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
916
917                 /* Extract the initial header from the first page and verify
918                  * the codec type of this Ogg bitstream */
919                 if( ogg_stream_pagein( &p_stream->os, &oggpage ) < 0 )
920                 {
921                     /* error. stream version mismatch perhaps */
922                     msg_Err( p_demux, "error reading first page of "
923                              "Ogg bitstream data" );
924                     return VLC_EGENERIC;
925                 }
926
927                 /* FIXME: check return value */
928                 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
929
930                 /* Check for Vorbis header */
931                 if( oggpacket.bytes >= 7 &&
932                     ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
933                 {
934                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
935                     msg_Dbg( p_demux, "found vorbis header" );
936                 }
937                 /* Check for Speex header */
938                 else if( oggpacket.bytes >= 5 &&
939                     ! memcmp( oggpacket.packet, "Speex", 5 ) )
940                 {
941                     Ogg_ReadSpeexHeader( p_stream, &oggpacket );
942                     msg_Dbg( p_demux, "found speex header, channels: %i, "
943                              "rate: %i,  bitrate: %i",
944                              p_stream->fmt.audio.i_channels,
945                              (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
946                 }
947                 /* Check for Flac header (< version 1.1.1) */
948                 else if( oggpacket.bytes >= 4 &&
949                     ! memcmp( oggpacket.packet, "fLaC", 4 ) )
950                 {
951                     msg_Dbg( p_demux, "found FLAC header" );
952
953                     /* Grrrr!!!! Did they really have to put all the
954                      * important info in the second header packet!!!
955                      * (STREAMINFO metadata is in the following packet) */
956                     p_stream->b_force_backup = 1;
957
958                     p_stream->fmt.i_cat = AUDIO_ES;
959                     p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );
960                 }
961                 /* Check for Flac header (>= version 1.1.1) */
962                 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
963                     ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
964                     ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
965                 {
966                     int i_packets = ((int)oggpacket.packet[7]) << 8 |
967                         oggpacket.packet[8];
968                     msg_Dbg( p_demux, "found FLAC header version %i.%i "
969                              "(%i header packets)",
970                              oggpacket.packet[5], oggpacket.packet[6],
971                              i_packets );
972
973                     p_stream->b_force_backup = 1;
974
975                     p_stream->fmt.i_cat = AUDIO_ES;
976                     p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );
977                     oggpacket.packet += 13; oggpacket.bytes -= 13;
978                     Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
979                 }
980                 /* Check for Theora header */
981                 else if( oggpacket.bytes >= 7 &&
982                          ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
983                 {
984                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
985
986                     msg_Dbg( p_demux,
987                              "found theora header, bitrate: %i, rate: %f",
988                              p_stream->fmt.i_bitrate, p_stream->f_rate );
989                 }
990                 /* Check for Dirac header */
991                 else if( oggpacket.bytes >= 5 &&
992                          ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) )
993                 {
994                     if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
995                         msg_Dbg( p_demux, "found dirac header" );
996                     else
997                     {
998                         msg_Warn( p_demux, "found dirac header isn't decodable" );
999                         free( p_stream );
1000                         p_ogg->i_streams--;
1001                     }
1002                 }
1003                 /* Check for Tarkin header */
1004                 else if( oggpacket.bytes >= 7 &&
1005                          ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1006                 {
1007                     oggpack_buffer opb;
1008
1009                     msg_Dbg( p_demux, "found tarkin header" );
1010                     p_stream->fmt.i_cat = VIDEO_ES;
1011                     p_stream->fmt.i_codec = VLC_FOURCC( 't','a','r','k' );
1012
1013                     /* Cheat and get additionnal info ;) */
1014                     oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1015                     oggpack_adv( &opb, 88 );
1016                     oggpack_adv( &opb, 104 );
1017                     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1018                     p_stream->f_rate = 2; /* FIXME */
1019                     msg_Dbg( p_demux,
1020                              "found tarkin header, bitrate: %i, rate: %f",
1021                              p_stream->fmt.i_bitrate, p_stream->f_rate );
1022                 }
1023                 /* Check for Annodex header */
1024                 else if( oggpacket.bytes >= 7 &&
1025                          ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1026                 {
1027                     Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
1028                                            &oggpacket );
1029                     /* kill annodex track */
1030                     free( p_stream );
1031                     p_ogg->i_streams--;
1032                 }
1033                 /* Check for Annodex header */
1034                 else if( oggpacket.bytes >= 7 &&
1035                          ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1036                 {
1037                     Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
1038                                            &oggpacket );
1039                 }
1040                 /* Check for Kate header */
1041                 else if( oggpacket.bytes >= 8 &&
1042                     ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1043                 {
1044                     Ogg_ReadKateHeader( p_stream, &oggpacket );
1045                     msg_Dbg( p_demux, "found kate header" );
1046                 }
1047                 else if( oggpacket.bytes >= 142 &&
1048                          !memcmp( &oggpacket.packet[1],
1049                                    "Direct Show Samples embedded in Ogg", 35 ))
1050                 {
1051                     /* Old header type */
1052
1053                     /* Check for video header (old format) */
1054                     if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1055                         oggpacket.bytes >= 184 )
1056                     {
1057                         p_stream->fmt.i_cat = VIDEO_ES;
1058                         p_stream->fmt.i_codec =
1059                             VLC_FOURCC( oggpacket.packet[68],
1060                                         oggpacket.packet[69],
1061                                         oggpacket.packet[70],
1062                                         oggpacket.packet[71] );
1063                         msg_Dbg( p_demux, "found video header of type: %.4s",
1064                                  (char *)&p_stream->fmt.i_codec );
1065
1066                         p_stream->fmt.video.i_frame_rate = 10000000;
1067                         p_stream->fmt.video.i_frame_rate_base =
1068                             GetQWLE((oggpacket.packet+164));
1069                         p_stream->f_rate = 10000000.0 /
1070                             GetQWLE((oggpacket.packet+164));
1071                         p_stream->fmt.video.i_bits_per_pixel =
1072                             GetWLE((oggpacket.packet+182));
1073                         if( !p_stream->fmt.video.i_bits_per_pixel )
1074                             /* hack, FIXME */
1075                             p_stream->fmt.video.i_bits_per_pixel = 24;
1076                         p_stream->fmt.video.i_width =
1077                             GetDWLE((oggpacket.packet+176));
1078                         p_stream->fmt.video.i_height =
1079                             GetDWLE((oggpacket.packet+180));
1080
1081                         msg_Dbg( p_demux,
1082                                  "fps: %f, width:%i; height:%i, bitcount:%i",
1083                                  p_stream->f_rate,
1084                                  p_stream->fmt.video.i_width,
1085                                  p_stream->fmt.video.i_height,
1086                                  p_stream->fmt.video.i_bits_per_pixel);
1087
1088                     }
1089                     /* Check for audio header (old format) */
1090                     else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1091                     {
1092                         unsigned int i_extra_size;
1093                         unsigned int i_format_tag;
1094
1095                         p_stream->fmt.i_cat = AUDIO_ES;
1096
1097                         i_extra_size = GetWLE((oggpacket.packet+140));
1098                         if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1099                         {
1100                             p_stream->fmt.i_extra = i_extra_size;
1101                             p_stream->fmt.p_extra = malloc( i_extra_size );
1102                             if( p_stream->fmt.p_extra )
1103                                 memcpy( p_stream->fmt.p_extra,
1104                                         oggpacket.packet + 142, i_extra_size );
1105                             else
1106                                 p_stream->fmt.i_extra = 0;
1107                         }
1108
1109                         i_format_tag = GetWLE((oggpacket.packet+124));
1110                         p_stream->fmt.audio.i_channels =
1111                             GetWLE((oggpacket.packet+126));
1112                         p_stream->f_rate = p_stream->fmt.audio.i_rate =
1113                             GetDWLE((oggpacket.packet+128));
1114                         p_stream->fmt.i_bitrate =
1115                             GetDWLE((oggpacket.packet+132)) * 8;
1116                         p_stream->fmt.audio.i_blockalign =
1117                             GetWLE((oggpacket.packet+136));
1118                         p_stream->fmt.audio.i_bitspersample =
1119                             GetWLE((oggpacket.packet+138));
1120
1121                         wf_tag_to_fourcc( i_format_tag,
1122                                           &p_stream->fmt.i_codec, 0 );
1123
1124                         if( p_stream->fmt.i_codec ==
1125                             VLC_FOURCC('u','n','d','f') )
1126                         {
1127                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1128                                 ( i_format_tag >> 8 ) & 0xff,
1129                                 i_format_tag & 0xff );
1130                         }
1131
1132                         msg_Dbg( p_demux, "found audio header of type: %.4s",
1133                                  (char *)&p_stream->fmt.i_codec );
1134                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1135                                  "%dbits/sample %dkb/s",
1136                                  i_format_tag,
1137                                  p_stream->fmt.audio.i_channels,
1138                                  p_stream->fmt.audio.i_rate,
1139                                  p_stream->fmt.audio.i_bitspersample,
1140                                  p_stream->fmt.i_bitrate / 1024 );
1141
1142                     }
1143                     else
1144                     {
1145                         msg_Dbg( p_demux, "stream %d has an old header "
1146                             "but is of an unknown type", p_ogg->i_streams-1 );
1147                         free( p_stream );
1148                         p_ogg->i_streams--;
1149                     }
1150                 }
1151                 else if( (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
1152                          oggpacket.bytes >= 56+1 )
1153                 {
1154                     stream_header_t tmp;
1155                     stream_header_t *st = &tmp;
1156
1157                     memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1158                     memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1159                     st->size = GetDWLE( &oggpacket.packet[1+12] );
1160                     st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1161                     st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1162                     st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1163                     st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1164                     st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1165
1166                     /* Check for video header (new format) */
1167                     if( !strncmp( st->streamtype, "video", 5 ) )
1168                     {
1169                         st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1170                         st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1171
1172                         p_stream->fmt.i_cat = VIDEO_ES;
1173
1174                         /* We need to get rid of the header packet */
1175                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1176
1177                         p_stream->fmt.i_codec =
1178                             VLC_FOURCC( st->subtype[0], st->subtype[1],
1179                                         st->subtype[2], st->subtype[3] );
1180                         msg_Dbg( p_demux, "found video header of type: %.4s",
1181                                  (char *)&p_stream->fmt.i_codec );
1182
1183                         p_stream->fmt.video.i_frame_rate = 10000000;
1184                         p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1185                         if( st->time_unit <= 0 )
1186                             st->time_unit = 400000;
1187                         p_stream->f_rate = 10000000.0 / st->time_unit;
1188                         p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1189                         p_stream->fmt.video.i_width = st->sh.video.width;
1190                         p_stream->fmt.video.i_height = st->sh.video.height;
1191
1192                         msg_Dbg( p_demux,
1193                                  "fps: %f, width:%i; height:%i, bitcount:%i",
1194                                  p_stream->f_rate,
1195                                  p_stream->fmt.video.i_width,
1196                                  p_stream->fmt.video.i_height,
1197                                  p_stream->fmt.video.i_bits_per_pixel );
1198                     }
1199                     /* Check for audio header (new format) */
1200                     else if( !strncmp( st->streamtype, "audio", 5 ) )
1201                     {
1202                         char p_buffer[5];
1203                         unsigned int i_extra_size;
1204                         int i_format_tag;
1205
1206                         st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1207                         st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1208                         st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1209
1210                         p_stream->fmt.i_cat = AUDIO_ES;
1211
1212                         /* We need to get rid of the header packet */
1213                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1214
1215                         i_extra_size = st->size - 56;
1216
1217                         if( i_extra_size > 0 &&
1218                             i_extra_size < oggpacket.bytes - 1 - 56 )
1219                         {
1220                             p_stream->fmt.i_extra = i_extra_size;
1221                             p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1222                             if( p_stream->fmt.p_extra )
1223                                 memcpy( p_stream->fmt.p_extra, st + 1,
1224                                         p_stream->fmt.i_extra );
1225                             else
1226                                 p_stream->fmt.i_extra = 0;
1227                         }
1228
1229                         memcpy( p_buffer, st->subtype, 4 );
1230                         p_buffer[4] = '\0';
1231                         i_format_tag = strtol(p_buffer,NULL,16);
1232                         p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1233                         if( st->time_unit <= 0 )
1234                             st->time_unit = 10000000;
1235                         p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1236                         p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1237                         p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1238                         p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1239
1240                         wf_tag_to_fourcc( i_format_tag,
1241                                           &p_stream->fmt.i_codec, 0 );
1242
1243                         if( p_stream->fmt.i_codec ==
1244                             VLC_FOURCC('u','n','d','f') )
1245                         {
1246                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1247                                 ( i_format_tag >> 8 ) & 0xff,
1248                                 i_format_tag & 0xff );
1249                         }
1250
1251                         msg_Dbg( p_demux, "found audio header of type: %.4s",
1252                                  (char *)&p_stream->fmt.i_codec );
1253                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1254                                  "%dbits/sample %dkb/s",
1255                                  i_format_tag,
1256                                  p_stream->fmt.audio.i_channels,
1257                                  p_stream->fmt.audio.i_rate,
1258                                  p_stream->fmt.audio.i_bitspersample,
1259                                  p_stream->fmt.i_bitrate / 1024 );
1260                     }
1261                     /* Check for text (subtitles) header */
1262                     else if( !strncmp(st->streamtype, "text", 4) )
1263                     {
1264                         /* We need to get rid of the header packet */
1265                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1266
1267                         msg_Dbg( p_demux, "found text subtitles header" );
1268                         p_stream->fmt.i_cat = SPU_ES;
1269                         p_stream->fmt.i_codec = VLC_FOURCC('s','u','b','t');
1270                         p_stream->f_rate = 1000; /* granulepos is in millisec */
1271                     }
1272                     else
1273                     {
1274                         msg_Dbg( p_demux, "stream %d has a header marker "
1275                             "but is of an unknown type", p_ogg->i_streams-1 );
1276                         free( p_stream );
1277                         p_ogg->i_streams--;
1278                     }
1279                 }
1280                 else if( oggpacket.bytes >= 7 &&
1281                              ! memcmp( oggpacket.packet, "fishead", 7 ) )
1282
1283                 {
1284                     /* Skeleton */
1285                     msg_Dbg( p_demux, "stream %d is a skeleton",
1286                                 p_ogg->i_streams-1 );
1287                     /* FIXME: https://trac.videolan.org/vlc/ticket/1412 */
1288                 }
1289                 else
1290                 {
1291                     msg_Dbg( p_demux, "stream %d is of unknown type",
1292                              p_ogg->i_streams-1 );
1293                     free( p_stream );
1294                     p_ogg->i_streams--;
1295                 }
1296
1297                 if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
1298                     return VLC_EGENERIC;
1299             }
1300
1301             /* we'll need to get all headers for all of those streams
1302                that we have to backup headers for */
1303             p_ogg->i_bos = 0;
1304             for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1305             {
1306                 if( p_ogg->pp_stream[i_stream]->b_force_backup )
1307                     p_ogg->i_bos++;
1308             }
1309
1310
1311             /* This is the first data page, which means we are now finished
1312              * with the initial pages. We just need to store it in the relevant
1313              * bitstream. */
1314             for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1315             {
1316                 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1317                                        &oggpage ) == 0 )
1318                 {
1319                     p_ogg->b_page_waiting = true;
1320                     break;
1321                 }
1322             }
1323
1324             return VLC_SUCCESS;
1325         }
1326     }
1327
1328     return VLC_EGENERIC;
1329 }
1330
1331 /****************************************************************************
1332  * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1333  *                        Elementary streams.
1334  ****************************************************************************/
1335 static int Ogg_BeginningOfStream( demux_t *p_demux )
1336 {
1337     demux_sys_t *p_ogg = p_demux->p_sys  ;
1338     logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1339     int i_stream;
1340
1341     /* Find the logical streams embedded in the physical stream and
1342      * initialize our p_ogg structure. */
1343     if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
1344     {
1345         msg_Warn( p_demux, "couldn't find any ogg logical stream" );
1346         return VLC_EGENERIC;
1347     }
1348
1349     p_ogg->i_bitrate = 0;
1350
1351     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1352     {
1353         logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1354
1355         p_stream->p_es = NULL;
1356
1357         /* Try first to reuse an old ES */
1358         if( p_old_stream &&
1359             p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1360             p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1361         {
1362             msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1363
1364             p_stream->p_es = p_old_stream->p_es;
1365             es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1366
1367             p_old_stream->p_es = NULL;
1368             p_old_stream = NULL;
1369         }
1370
1371         if( !p_stream->p_es )
1372         {
1373             /* Better be safe than sorry when possible with ogm */
1374             if( p_stream->fmt.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'a' ) ||
1375                 p_stream->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', ' ' ) )
1376                 p_stream->fmt.b_packetized = false;
1377
1378             p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1379         }
1380
1381         // TODO: something to do here ?
1382         if( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
1383         {
1384             /* Set the CMML stream active */
1385             es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
1386         }
1387
1388         p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
1389
1390         p_stream->i_pcr = p_stream->i_previous_pcr =
1391             p_stream->i_interpolated_pcr = -1;
1392         p_stream->b_reinit = false;
1393     }
1394
1395     if( p_ogg->p_old_stream )
1396     {
1397         if( p_ogg->p_old_stream->p_es )
1398             msg_Dbg( p_demux, "old stream not reused" );
1399         Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
1400         p_ogg->p_old_stream = NULL;
1401     }
1402     return VLC_SUCCESS;
1403 }
1404
1405 /****************************************************************************
1406  * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1407  ****************************************************************************/
1408 static void Ogg_EndOfStream( demux_t *p_demux )
1409 {
1410     demux_sys_t *p_ogg = p_demux->p_sys  ;
1411     int i_stream;
1412
1413     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1414         Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
1415     free( p_ogg->pp_stream );
1416
1417     /* Reinit p_ogg */
1418     p_ogg->i_bitrate = 0;
1419     p_ogg->i_streams = 0;
1420     p_ogg->pp_stream = NULL;
1421
1422     /* */
1423     if( p_ogg->p_meta )
1424         vlc_meta_Delete( p_ogg->p_meta );
1425     p_ogg->p_meta = NULL;
1426 }
1427
1428 /**
1429  * This function delete and release all data associated to a logical_stream_t
1430  */
1431 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
1432 {
1433     if( p_stream->p_es )
1434         es_out_Del( p_demux->out, p_stream->p_es );
1435
1436     ogg_stream_clear( &p_stream->os );
1437     free( p_stream->p_headers );
1438
1439     es_format_Clean( &p_stream->fmt_old );
1440     es_format_Clean( &p_stream->fmt );
1441
1442     free( p_stream );
1443 }
1444 /**
1445  * This function check if a we need to reset a decoder in case we are
1446  * reusing an old ES
1447  */
1448 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
1449 {
1450     int i_new = 0;
1451     int i_old = 0;
1452     int i;
1453
1454     for( i = 0; i < 3; i++ )
1455     {
1456         const uint8_t *p_new_extra = ( const uint8_t*)p_new->p_extra + i_new;
1457         const uint8_t *p_old_extra = ( const uint8_t*)p_old->p_extra + i_old;
1458
1459         if( p_new->i_extra < i_new+2 || p_old->i_extra < i_old+2 )
1460             return false;
1461
1462         const int i_new_size = GetWBE( &p_new_extra[0] );
1463         const int i_old_size = GetWBE( &p_old_extra[0] );
1464
1465         if( i != 1 ) /* Ignore vorbis comment */
1466         {
1467             if( i_new_size != i_old_size )
1468                 return false;
1469             if( memcmp( &p_new_extra[2], &p_old_extra[2], i_new_size ) )
1470                 return false;
1471         }
1472
1473         i_new += 2 + i_new_size;
1474         i_old += 2 + i_old_size;
1475     }
1476     return true;
1477 }
1478 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
1479 {
1480     bool b_compatible = false;
1481     if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
1482         return true;
1483
1484     /* Only vorbis is supported */
1485     if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) )
1486         b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
1487
1488     if( !b_compatible )
1489         msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
1490
1491     return !b_compatible;
1492 }
1493 static void Ogg_ExtractXiphMeta( demux_t *p_demux, const uint8_t *p_headers, int i_headers, int i_skip )
1494 {
1495     demux_sys_t *p_ogg = p_demux->p_sys;
1496
1497     if( i_headers <= 2 )
1498         return;
1499
1500     /* Skip first packet */
1501     const int i_tmp = GetWBE( &p_headers[0] );
1502     if( i_tmp > i_headers-2 )
1503         return;
1504     p_headers += 2 + i_tmp;
1505     i_headers -= 2 + i_tmp;
1506
1507     if( i_headers <= 2 )
1508         return;
1509
1510     /* */
1511     int i_comment = GetWBE( &p_headers[0] );
1512     const uint8_t *p_comment = &p_headers[2];
1513     if( i_comment > i_headers - 2 )
1514         return;
1515
1516     if( i_comment <= i_skip )
1517         return;
1518
1519     /* TODO how to handle multiple comments properly ? */
1520     vorbis_ParseComment( &p_ogg->p_meta, &p_comment[i_skip], i_comment - i_skip );
1521 }
1522 static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers )
1523 {
1524     demux_sys_t *p_ogg = p_demux->p_sys;
1525
1526     switch( i_codec )
1527     {
1528     /* 3 headers with the 2° one being the comments */
1529     case VLC_FOURCC( 'v','o','r','b' ):
1530         Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 1+6 );
1531         break;
1532     case VLC_FOURCC( 't','h','e','o' ):
1533         Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 1+6 );
1534         break;
1535     case VLC_FOURCC( 's','p','x',' ' ):
1536         Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 0 );
1537         break;
1538
1539     /* TODO */
1540     case VLC_FOURCC( 'k','a','t','e' ):
1541     case VLC_FOURCC( 'f','l','a','c' ):
1542     case VLC_FOURCC( 'c','m','m','l' ):
1543         msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&i_codec );
1544         break;
1545     /* No meta data */
1546     case VLC_FOURCC( 'd','r','a','c' ):
1547     default:
1548         break;
1549     }
1550     if( p_ogg->p_meta )
1551         p_demux->info.i_update |= INPUT_UPDATE_META;
1552 }
1553
1554 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
1555                                   ogg_packet *p_oggpacket )
1556 {
1557     bs_t bitstream;
1558     int i_fps_numerator;
1559     int i_fps_denominator;
1560     int i_keyframe_frequency_force;
1561
1562     p_stream->fmt.i_cat = VIDEO_ES;
1563     p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
1564
1565     /* Signal that we want to keep a backup of the theora
1566      * stream headers. They will be used when switching between
1567      * audio streams. */
1568     p_stream->b_force_backup = 1;
1569
1570     /* Cheat and get additionnal info ;) */
1571     bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
1572     bs_skip( &bitstream, 56 );
1573     bs_read( &bitstream, 8 ); /* major version num */
1574     bs_read( &bitstream, 8 ); /* minor version num */
1575     bs_read( &bitstream, 8 ); /* subminor version num */
1576     bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
1577     bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
1578     bs_read( &bitstream, 24 ); /* frame width */
1579     bs_read( &bitstream, 24 ); /* frame height */
1580     bs_read( &bitstream, 8 ); /* x offset */
1581     bs_read( &bitstream, 8 ); /* y offset */
1582
1583     i_fps_numerator = bs_read( &bitstream, 32 );
1584     i_fps_denominator = bs_read( &bitstream, 32 );
1585     bs_read( &bitstream, 24 ); /* aspect_numerator */
1586     bs_read( &bitstream, 24 ); /* aspect_denominator */
1587
1588     p_stream->fmt.video.i_frame_rate = i_fps_numerator;
1589     p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
1590
1591     bs_read( &bitstream, 8 ); /* colorspace */
1592     p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
1593     bs_read( &bitstream, 6 ); /* quality */
1594
1595     i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
1596
1597     /* granule_shift = i_log( frequency_force -1 ) */
1598     p_stream->i_granule_shift = 0;
1599     i_keyframe_frequency_force--;
1600     while( i_keyframe_frequency_force )
1601     {
1602         p_stream->i_granule_shift++;
1603         i_keyframe_frequency_force >>= 1;
1604     }
1605
1606     p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
1607 }
1608
1609 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
1610                                   ogg_packet *p_oggpacket )
1611 {
1612     oggpack_buffer opb;
1613
1614     p_stream->fmt.i_cat = AUDIO_ES;
1615     p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
1616
1617     /* Signal that we want to keep a backup of the vorbis
1618      * stream headers. They will be used when switching between
1619      * audio streams. */
1620     p_stream->b_force_backup = 1;
1621
1622     /* Cheat and get additionnal info ;) */
1623     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
1624     oggpack_adv( &opb, 88 );
1625     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
1626     p_stream->f_rate = p_stream->fmt.audio.i_rate =
1627         oggpack_read( &opb, 32 );
1628     oggpack_adv( &opb, 32 );
1629     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1630 }
1631
1632 static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
1633                                  ogg_packet *p_oggpacket )
1634 {
1635     oggpack_buffer opb;
1636
1637     p_stream->fmt.i_cat = AUDIO_ES;
1638     p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
1639
1640     /* Signal that we want to keep a backup of the speex
1641      * stream headers. They will be used when switching between
1642      * audio streams. */
1643     p_stream->b_force_backup = 1;
1644
1645     /* Cheat and get additionnal info ;) */
1646     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
1647     oggpack_adv( &opb, 224 );
1648     oggpack_adv( &opb, 32 ); /* speex_version_id */
1649     oggpack_adv( &opb, 32 ); /* header_size */
1650     p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
1651     oggpack_adv( &opb, 32 ); /* mode */
1652     oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
1653     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
1654     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1655 }
1656
1657 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
1658                                 ogg_packet *p_oggpacket )
1659 {
1660     /* Parse the STREAMINFO metadata */
1661     bs_t s;
1662
1663     bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
1664
1665     bs_read( &s, 1 );
1666     if( bs_read( &s, 7 ) == 0 )
1667     {
1668         if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
1669         {
1670             bs_skip( &s, 80 );
1671             p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
1672             p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
1673
1674             msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
1675                      p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
1676         }
1677         else
1678         {
1679             msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
1680         }
1681
1682         /* Fake this as the last metadata block */
1683         *((uint8_t*)p_oggpacket->packet) |= 0x80;
1684     }
1685     else
1686     {
1687         /* This ain't a STREAMINFO metadata */
1688         msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
1689     }
1690 }
1691
1692 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
1693                                 ogg_packet *p_oggpacket )
1694 {
1695     oggpack_buffer opb;
1696     int32_t gnum;
1697     int32_t gden;
1698     int n;
1699
1700     p_stream->fmt.i_cat = SPU_ES;
1701     p_stream->fmt.i_codec = VLC_FOURCC( 'k','a','t','e' );
1702
1703     /* Signal that we want to keep a backup of the kate
1704      * stream headers. They will be used when switching between
1705      * kate streams. */
1706     p_stream->b_force_backup = 1;
1707
1708     /* Cheat and get additionnal info ;) */
1709     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
1710     oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
1711     p_stream->i_kate_num_headers = oggpack_read( &opb, 8 );
1712     oggpack_adv( &opb, 3*8 );
1713     p_stream->i_granule_shift = oggpack_read( &opb, 8 );
1714     oggpack_adv( &opb, 8*8 ); /* reserved */
1715     gnum = oggpack_read( &opb, 32 );
1716     gden = oggpack_read( &opb, 32 );
1717     p_stream->f_rate = (double)gnum/gden;
1718
1719     p_stream->fmt.psz_language = malloc(16);
1720     if( p_stream->fmt.psz_language )
1721     {
1722         for( n = 0; n < 16; ++n )
1723             p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
1724         p_stream->fmt.psz_language[15] = 0; /* just in case */
1725     }
1726     else
1727     {
1728         for( n = 0; n < 16; ++n )
1729             oggpack_read(&opb,8);
1730     }
1731     p_stream->fmt.psz_description = malloc(16);
1732     if( p_stream->fmt.psz_description )
1733     {
1734         for( n = 0; n < 16; ++n )
1735             p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
1736         p_stream->fmt.psz_description[15] = 0; /* just in case */
1737     }
1738     else
1739     {
1740         for( n = 0; n < 16; ++n )
1741             oggpack_read(&opb,8);
1742     }
1743 }
1744
1745 static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
1746                                    logical_stream_t *p_stream,
1747                                    ogg_packet *p_oggpacket )
1748 {
1749     if( p_oggpacket->bytes >= 28 &&
1750         !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
1751     {
1752         oggpack_buffer opb;
1753
1754         uint16_t major_version;
1755         uint16_t minor_version;
1756         uint64_t timebase_numerator;
1757         uint64_t timebase_denominator;
1758
1759         Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
1760
1761         oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
1762         oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
1763         major_version = oggpack_read( &opb, 2*8 ); /* major version */
1764         minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
1765         timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
1766         timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
1767     }
1768     else if( p_oggpacket->bytes >= 42 &&
1769              !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
1770     {
1771         uint64_t granule_rate_numerator;
1772         uint64_t granule_rate_denominator;
1773         char content_type_string[1024];
1774
1775         /* Read in Annodex header fields */
1776
1777         granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
1778         granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
1779         p_stream->i_secondary_header_packets =
1780             GetDWLE( &p_oggpacket->packet[24] );
1781
1782         /* we are guaranteed that the first header field will be
1783          * the content-type (by the Annodex standard) */
1784         content_type_string[0] = '\0';
1785         if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
1786         {
1787             uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
1788                                  p_oggpacket->bytes - 1 );
1789             if( p && p[0] == '\r' && p[1] == '\n' )
1790                 sscanf( (char*)(&p_oggpacket->packet[42]), "%1024s\r\n",
1791                         content_type_string );
1792         }
1793
1794         msg_Dbg( p_this, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
1795                  granule_rate_numerator, granule_rate_denominator,
1796                  p_stream->i_secondary_header_packets, content_type_string );
1797
1798         p_stream->f_rate = (float) granule_rate_numerator /
1799             (float) granule_rate_denominator;
1800
1801         /* What type of file do we have?
1802          * strcmp is safe to use here because we've extracted
1803          * content_type_string from the stream manually */
1804         if( !strncmp(content_type_string, "audio/x-wav", 11) )
1805         {
1806             /* n.b. WAVs are unsupported right now */
1807             p_stream->fmt.i_cat = UNKNOWN_ES;
1808         }
1809         else if( !strncmp(content_type_string, "audio/x-vorbis", 14) )
1810         {
1811             p_stream->fmt.i_cat = AUDIO_ES;
1812             p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
1813
1814             p_stream->b_force_backup = 1;
1815         }
1816         else if( !strncmp(content_type_string, "audio/x-speex", 14) )
1817         {
1818             p_stream->fmt.i_cat = AUDIO_ES;
1819             p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
1820
1821             p_stream->b_force_backup = 1;
1822         }
1823         else if( !strncmp(content_type_string, "video/x-theora", 14) )
1824         {
1825             p_stream->fmt.i_cat = VIDEO_ES;
1826             p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
1827
1828             p_stream->b_force_backup = 1;
1829         }
1830         else if( !strncmp(content_type_string, "video/x-xvid", 14) )
1831         {
1832             p_stream->fmt.i_cat = VIDEO_ES;
1833             p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
1834
1835             p_stream->b_force_backup = 1;
1836         }
1837         else if( !strncmp(content_type_string, "video/mpeg", 14) )
1838         {
1839             /* n.b. MPEG streams are unsupported right now */
1840             p_stream->fmt.i_cat = VIDEO_ES;
1841             p_stream->fmt.i_codec = VLC_FOURCC( 'm','p','g','v' );
1842         }
1843         else if( !strncmp(content_type_string, "text/x-cmml", 11) )
1844         {
1845             ogg_stream_packetout( &p_stream->os, p_oggpacket );
1846             p_stream->fmt.i_cat = SPU_ES;
1847             p_stream->fmt.i_codec = VLC_FOURCC( 'c','m','m','l' );
1848         }
1849     }
1850 }
1851
1852 static uint32_t dirac_uint( bs_t *p_bs )
1853 {
1854     uint32_t u_count = 0, u_value = 0;
1855
1856     while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
1857     {
1858         u_count++;
1859         u_value <<= 1;
1860         u_value |= bs_read( p_bs, 1 );
1861     }
1862
1863     return (1<<u_count) - 1 + u_value;
1864 }
1865
1866 static int dirac_bool( bs_t *p_bs )
1867 {
1868     return bs_read( p_bs, 1 );
1869 }
1870
1871 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
1872                                  ogg_packet *p_oggpacket )
1873 {
1874     static const struct {
1875         uint32_t u_n /* numerator */, u_d /* denominator */;
1876     } p_dirac_frate_tbl[] = { /* table 10.3 */
1877         {1,1}, /* this first value is never used */
1878         {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
1879         {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
1880     };
1881     static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
1882
1883     static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
1884         1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
1885     };
1886     static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
1887
1888     bs_t bs;
1889
1890     p_stream->i_granule_shift = 22; /* not 32 */
1891
1892     /* Backing up stream headers is not required -- seqhdrs are repeated
1893      * thoughout the stream at suitable decoding start points */
1894     p_stream->b_force_backup = 0;
1895
1896     /* read in useful bits from sequence header */
1897     bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
1898     bs_skip( &bs, 13*8); /* parse_info_header */
1899     dirac_uint( &bs ); /* major_version */
1900     dirac_uint( &bs ); /* minor_version */
1901     dirac_uint( &bs ); /* profile */
1902     dirac_uint( &bs ); /* level */
1903
1904     uint32_t u_video_format = dirac_uint( &bs ); /* index */
1905     if( u_video_format >= u_dirac_vidfmt_frate )
1906     {
1907         /* don't know how to parse this ogg dirac stream */
1908         return false;
1909     }
1910
1911     if( dirac_bool( &bs ) )
1912     {
1913         dirac_uint( &bs ); /* frame_width */
1914         dirac_uint( &bs ); /* frame_height */
1915     }
1916
1917     if( dirac_bool( &bs ) )
1918     {
1919         dirac_uint( &bs ); /* chroma_format */
1920     }
1921
1922     if( dirac_bool( &bs ) )
1923     {
1924         dirac_uint( &bs ); /* scan_format */
1925     }
1926
1927     uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
1928     uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
1929     if( dirac_bool( &bs ) )
1930     {
1931         uint32_t u_frame_rate_index = dirac_uint( &bs );
1932         if( u_frame_rate_index >= u_dirac_frate_tbl )
1933         {
1934             /* something is wrong with this stream */
1935             return false;
1936         }
1937         u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
1938         u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
1939         if( u_frame_rate_index == 0 )
1940         {
1941             u_n = dirac_uint( &bs ); /* frame_rate_numerator */
1942             u_d = dirac_uint( &bs ); /* frame_rate_denominator */
1943         }
1944     }
1945     p_stream->f_rate = (float) u_n / u_d;
1946
1947     /* probably is an ogg dirac es */
1948     p_stream->fmt.i_cat = VIDEO_ES;
1949     p_stream->fmt.i_codec = VLC_FOURCC( 'd','r','a','c' );
1950
1951     return true;
1952 }