]> git.sesse.net Git - vlc/blob - modules/demux/ogg.c
demux: ogg: remove discontinuity flag
[vlc] / modules / demux / ogg.c
1 /*****************************************************************************
2  * ogg.c : ogg stream demux module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2007 VLC authors and VideoLAN
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 it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * 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 "xiph.h"
43 #include "xiph_metadata.h"
44 #include "ogg.h"
45 #include "oggseek.h"
46
47 /*****************************************************************************
48  * Module descriptor
49  *****************************************************************************/
50 static int  Open ( vlc_object_t * );
51 static void Close( vlc_object_t * );
52
53 vlc_module_begin ()
54     set_shortname ( "OGG" )
55     set_description( N_("OGG demuxer" ) )
56     set_category( CAT_INPUT )
57     set_subcategory( SUBCAT_INPUT_DEMUX )
58     set_capability( "demux", 50 )
59     set_callbacks( Open, Close )
60     add_shortcut( "ogg" )
61 vlc_module_end ()
62
63
64 /*****************************************************************************
65  * Definitions of structures and functions used by this plugins
66  *****************************************************************************/
67
68 /* OggDS headers for the new header format (used in ogm files) */
69 typedef struct
70 {
71     ogg_int32_t width;
72     ogg_int32_t height;
73 } stream_header_video_t;
74
75 typedef struct
76 {
77     ogg_int16_t channels;
78     ogg_int16_t padding;
79     ogg_int16_t blockalign;
80     ogg_int32_t avgbytespersec;
81 } stream_header_audio_t;
82
83 typedef struct
84 {
85     char        streamtype[8];
86     char        subtype[4];
87
88     ogg_int32_t size;                               /* size of the structure */
89
90     ogg_int64_t time_unit;                              /* in reference time */
91     ogg_int64_t samples_per_unit;
92     ogg_int32_t default_len;                                /* in media time */
93
94     ogg_int32_t buffersize;
95     ogg_int16_t bits_per_sample;
96     ogg_int16_t padding;
97
98     union
99     {
100         /* Video specific */
101         stream_header_video_t video;
102         /* Audio specific */
103         stream_header_audio_t audio;
104     } sh;
105 } stream_header_t;
106
107 /*****************************************************************************
108  * Local prototypes
109  *****************************************************************************/
110 static int  Demux  ( demux_t * );
111 static int  Control( demux_t *, int, va_list );
112
113 /* Bitstream manipulation */
114 static int  Ogg_ReadPage     ( demux_t *, ogg_page * );
115 static void Ogg_UpdatePCR    ( demux_t *, logical_stream_t *, ogg_packet * );
116 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
117 static int  Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * );
118
119 static void Ogg_CreateES( demux_t *p_demux );
120 static int Ogg_BeginningOfStream( demux_t *p_demux );
121 static int Ogg_FindLogicalStreams( demux_t *p_demux );
122 static void Ogg_EndOfStream( demux_t *p_demux );
123
124 /* */
125 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
126 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
127
128 /* */
129 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
130
131 /* Logical bitstream headers */
132 static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
133 static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
134 static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
135 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
136 static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
137 static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
138 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
139 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
140 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
141
142 /* Skeleton */
143 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
144 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
145 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
146 static void Ogg_ApplySkeleton( logical_stream_t * );
147
148 static void fill_channels_info(audio_format_t *audio)
149 {
150     static const int pi_channels_map[9] =
151     {
152         0,
153         AOUT_CHAN_CENTER,
154         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
155         AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
156         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
157             | AOUT_CHAN_REARRIGHT,
158         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
159             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
160         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
161             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
162         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
163             | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
164             | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
165         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
166             | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
167             | AOUT_CHAN_LFE,
168     };
169
170     unsigned chans = audio->i_channels;
171     if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
172         audio->i_physical_channels =
173         audio->i_original_channels = pi_channels_map[chans];
174 }
175
176 /*****************************************************************************
177  * Open: initializes ogg demux structures
178  *****************************************************************************/
179 static int Open( vlc_object_t * p_this )
180 {
181     demux_t *p_demux = (demux_t *)p_this;
182     demux_sys_t    *p_sys;
183     const uint8_t  *p_peek;
184
185     /* Check if we are dealing with an ogg stream */
186     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
187     if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
188     {
189         return VLC_EGENERIC;
190     }
191
192     /* */
193     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
194     if( !p_sys )
195         return VLC_ENOMEM;
196
197     p_sys->i_length = -1;
198     p_sys->b_preparsing_done = false;
199
200     /* Set exported functions */
201     p_demux->pf_demux = Demux;
202     p_demux->pf_control = Control;
203
204     /* Initialize the Ogg physical bitstream parser */
205     ogg_sync_init( &p_sys->oy );
206
207     /* */
208     TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
209
210
211     while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
212     {}
213
214     return VLC_SUCCESS;
215 }
216
217 /*****************************************************************************
218  * Close: frees unused data
219  *****************************************************************************/
220 static void Close( vlc_object_t *p_this )
221 {
222     demux_t *p_demux = (demux_t *)p_this;
223     demux_sys_t *p_sys = p_demux->p_sys  ;
224
225     /* Cleanup the bitstream parser */
226     ogg_sync_clear( &p_sys->oy );
227
228     Ogg_EndOfStream( p_demux );
229
230     if( p_sys->p_old_stream )
231         Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
232
233     free( p_sys );
234 }
235
236 /*****************************************************************************
237  * Demux: reads and demuxes data packets
238  *****************************************************************************
239  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
240  *****************************************************************************/
241 static int Demux( demux_t * p_demux )
242 {
243     demux_sys_t *p_sys = p_demux->p_sys;
244     ogg_packet  oggpacket;
245     int         i_stream;
246     bool b_skipping = false;
247     bool b_canseek;
248
249     int i_active_streams = p_sys->i_streams;
250     for ( int i=0; i < p_sys->i_streams; i++ )
251     {
252         if ( p_sys->pp_stream[i]->b_finished )
253             i_active_streams--;
254     }
255
256     if ( i_active_streams == 0 )
257     {
258         if ( p_sys->i_streams ) /* All finished */
259         {
260             msg_Dbg( p_demux, "end of a group of logical streams" );
261             /* We keep the ES to try reusing it in Ogg_BeginningOfStream
262              * only 1 ES is supported (common case for ogg web radio) */
263             if( p_sys->i_streams == 1 )
264             {
265                 p_sys->p_old_stream = p_sys->pp_stream[0];
266                 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
267             }
268             Ogg_EndOfStream( p_demux );
269             p_sys->b_chained_boundary = true;
270         }
271
272         if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
273             return 0;
274
275         msg_Dbg( p_demux, "beginning of a group of logical streams" );
276
277         if ( !p_sys->b_chained_boundary )
278         {
279             /* Find the real duration */
280             stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
281             if ( b_canseek )
282                 Oggseek_ProbeEnd( p_demux );
283             es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 );
284         }
285         else
286         {
287             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
288             p_sys->b_chained_boundary = false;
289         }
290     }
291
292     if ( p_sys->b_preparsing_done )
293     {
294         for ( int i=0; i < p_sys->i_streams; i++ )
295         {
296             if ( !p_sys->pp_stream[i]->p_es )
297             {
298                 Ogg_CreateES( p_demux );
299                 break;
300             }
301         }
302     }
303
304     /*
305      * The first data page of a physical stream is stored in the relevant logical stream
306      * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
307      * stream it belongs to if we haven't processed this first page yet. If we do, we
308      * will only process that first page whenever we find the second page for this stream.
309      * While this is fine for Vorbis and Theora, which are continuous codecs, which means
310      * the second page will arrive real quick, this is not fine for Kate, whose second
311      * data page will typically arrive much later.
312      * This means it is now possible to seek right at the start of a stream where the last
313      * logical stream is Kate, without having to wait for the second data page to unblock
314      * the first one, which is the one that triggers the 'no more headers to backup' code.
315      * And, as we all know, seeking without having backed up all headers is bad, since the
316      * codec will fail to initialize if it's missing its headers.
317      */
318     if( !p_sys->b_page_waiting)
319     {
320         /*
321          * Demux an ogg page from the stream
322          */
323         if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
324             return 0; /* EOF */
325         /* Test for End of Stream */
326         if( ogg_page_eos( &p_sys->current_page ) )
327         {
328             /* If we delayed restarting encoders/SET_ES_FMT for more
329              * skeleton provided configuration */
330             if ( p_sys->p_skelstream )
331             {
332                 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
333                 {
334                     msg_Dbg( p_demux, "End of Skeleton" );
335                     p_sys->b_preparsing_done = true;
336                     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
337                     {
338                         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
339                         Ogg_ApplySkeleton( p_stream );
340                     }
341                 }
342             }
343
344             for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
345             {
346                 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
347                 {
348                     p_sys->pp_stream[i_stream]->b_finished = true;
349                     break;
350                 }
351             }
352         }
353     }
354
355     b_skipping = false;
356     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
357     {
358         b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
359     }
360
361     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
362     {
363         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
364
365         /* if we've just pulled page, look for the right logical stream */
366         if( !p_sys->b_page_waiting )
367         {
368             if( p_sys->i_streams == 1 &&
369                 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
370             {
371                 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
372                 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
373
374                 p_stream->b_reinit = true;
375                 p_stream->i_pcr = VLC_TS_0;
376                 p_stream->i_interpolated_pcr = VLC_TS_0;
377                 p_stream->i_previous_granulepos = -1;
378                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0);
379             }
380
381             /* Does fail if serialno differs */
382             if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
383             {
384                 continue;
385             }
386
387         }
388
389         /* clear the finished flag if pages after eos (ex: after a seek) */
390         if ( ! ogg_page_eos( &p_sys->current_page ) ) p_stream->b_finished = false;
391
392         DemuxDebug(
393             if ( p_stream->fmt.i_cat == VIDEO_ES )
394                 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
395                     ogg_page_pageno( &p_sys->current_page ),
396                     ogg_page_granulepos( &p_sys->current_page ),
397                     ogg_page_packets( &p_sys->current_page ),
398                     ogg_page_continued(&p_sys->current_page),
399                     p_sys->current_page.body_len )
400         );
401
402         while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
403         {
404             /* Read info from any secondary header packets, if there are any */
405             if( p_stream->i_secondary_header_packets > 0 )
406             {
407                 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
408                         oggpacket.bytes >= 7 &&
409                         ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
410                 {
411                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
412                     p_stream->i_secondary_header_packets = 0;
413                 }
414                 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
415                         oggpacket.bytes >= 7 &&
416                         ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
417                 {
418                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
419                     p_stream->i_secondary_header_packets = 0;
420                 }
421                 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
422                 {
423                     p_stream->i_secondary_header_packets = 0;
424                 }
425
426                 /* update start of data pointer */
427                 p_stream->i_data_start = stream_Tell( p_demux->s );
428             }
429
430             /* If any streams have i_skip_frames, only decode (pre-roll)
431              *  for those streams, but don't skip headers */
432             if ( b_skipping && p_stream->i_skip_frames == 0
433                  && p_stream->i_secondary_header_packets ) continue;
434
435             if( p_stream->b_reinit )
436             {
437                 if ( Oggseek_PacketPCRFixup( p_stream, &p_sys->current_page,
438                                          &oggpacket ) )
439                 {
440                     DemuxDebug( msg_Dbg( p_demux, "PCR fixup for %"PRId64,
441                              ogg_page_granulepos( &p_sys->current_page ) ) );
442                 }
443                 else
444                 {
445                     /* If synchro is re-initialized we need to drop all the packets
446                          * until we find a new dated one. */
447                     Ogg_UpdatePCR( p_demux, p_stream, &oggpacket );
448                 }
449
450                 if( p_stream->i_pcr >= 0 )
451                 {
452                     p_stream->b_reinit = false;
453                     /* For Opus, trash the first 80 ms of decoded output as
454                        well, to avoid blowing out speakers if we get unlucky.
455                        Opus predicts content from prior frames, which can go
456                        badly if we seek right where the stream goes from very
457                        quiet to very loud. It will converge after a bit. */
458                     if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
459                     {
460                         ogg_int64_t start_time;
461                         int duration;
462                         p_stream->i_skip_frames = 80*48;
463                         /* Make sure we never play audio from within the
464                            pre-skip at the beginning of the stream. */
465                         duration =
466                             Ogg_OpusPacketDuration( p_stream, &oggpacket );
467                         start_time = p_stream->i_previous_granulepos;
468                         if( duration > 0 )
469                         {
470                             start_time = start_time > duration ?
471                                 start_time - duration : 0;
472                         }
473                         if( p_stream->i_pre_skip > start_time )
474                         {
475                             p_stream->i_skip_frames +=
476                                 p_stream->i_pre_skip - start_time;
477                         }
478                     }
479                 }
480                 else
481                 {
482                     DemuxDebug(
483                         msg_Dbg(p_demux, "DEMUX DROPS PACKET (? / %d) pageno %ld granule %"PRId64,
484                             ogg_page_packets( &p_sys->current_page ),
485                             ogg_page_pageno( &p_sys->current_page ), oggpacket.granulepos );
486                     );
487
488                     p_stream->i_interpolated_pcr = -1;
489                     p_stream->i_previous_granulepos = -1;
490                     continue;
491                 }
492
493                 /* An Ogg/vorbis packet contains an end date granulepos */
494                 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
495                     p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
496                     p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
497                     p_stream->fmt.i_codec == VLC_CODEC_FLAC )
498                 {
499                     if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
500                     {
501                         Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
502                     }
503                     else
504                     {
505                         es_out_Control( p_demux->out, ES_OUT_SET_PCR,
506                                         VLC_TS_0 + p_stream->i_pcr );
507                     }
508                     continue;
509                 }
510             }
511
512             DemuxDebug( if ( p_sys->b_seeked )
513             {
514                 if ( Ogg_IsKeyFrame( p_stream, &oggpacket ) )
515                      msg_Dbg(p_demux, "** DEMUX ON KEYFRAME **" );
516
517                 ogg_int64_t iframe = ogg_page_granulepos( &p_sys->current_page ) >> p_stream->i_granule_shift;
518                 ogg_int64_t pframe = ogg_page_granulepos( &p_sys->current_page ) - ( iframe << p_stream->i_granule_shift );
519
520                 msg_Dbg(p_demux, "DEMUX PACKET (size %d) IS at iframe %"PRId64" pageno %ld pframe %"PRId64" OFFSET %"PRId64" PACKET NO %"PRId64" skipleft=%d",
521                         ogg_page_packets( &p_sys->current_page ),
522                         iframe, ogg_page_pageno( &p_sys->current_page ), pframe, p_sys->i_input_position, oggpacket.packetno, p_stream->i_skip_frames );
523             })
524
525             Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
526         }
527
528         DemuxDebug( p_sys->b_seeked = false; )
529
530         if( !p_sys->b_page_waiting )
531             break;
532     }
533
534     /* if a page was waiting, it's now processed */
535     p_sys->b_page_waiting = false;
536
537     if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
538         p_sys->b_preparsing_done = false;
539     else
540         p_sys->b_preparsing_done = true;
541
542     p_sys->i_pcr = -1;
543     for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
544     {
545         logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
546
547         if ( p_sys->b_preparsing_done && p_stream->b_initializing )
548         {
549             /* We have 1 or more streams needing more than 1 page for preparsing */
550             p_sys->b_preparsing_done = false;
551         }
552
553         if( p_stream->fmt.i_cat == SPU_ES )
554             continue;
555         if( p_stream->i_interpolated_pcr < 0 )
556             continue;
557
558         if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )
559             p_sys->i_pcr = p_stream->i_interpolated_pcr;
560     }
561
562     if( p_sys->i_pcr >= 0 && ! b_skipping )
563         es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_pcr );
564
565     return 1;
566 }
567
568 static void Ogg_ResetStreamHelper( demux_sys_t *p_sys )
569 {
570     for( int i = 0; i < p_sys->i_streams; i++ )
571     {
572         logical_stream_t *p_stream = p_sys->pp_stream[i];
573
574         /* we'll trash all the data until we find the next pcr */
575         p_stream->b_reinit = true;
576         p_stream->i_pcr = -1;
577         p_stream->i_interpolated_pcr = -1;
578         p_stream->i_previous_granulepos = -1;
579         ogg_stream_reset( &p_stream->os );
580     }
581     ogg_sync_reset( &p_sys->oy );
582 }
583
584 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
585 {
586     demux_sys_t *p_sys = p_demux->p_sys;
587     logical_stream_t *p_stream = NULL;
588     for( int i=0; i<p_sys->i_streams; i++ )
589     {
590         logical_stream_t *p_candidate = p_sys->pp_stream[i];
591
592         bool b_selected = false;
593         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
594                         p_candidate->p_es, &b_selected );
595         if ( !b_selected ) continue;
596
597         if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
598         {
599             p_stream = p_candidate;
600             continue; /* Try to find video anyway */
601         }
602
603         if ( p_candidate->fmt.i_cat == VIDEO_ES )
604         {
605             p_stream = p_candidate;
606             break;
607         }
608     }
609     return p_stream;
610 }
611
612 /*****************************************************************************
613  * Control:
614  *****************************************************************************/
615 static int Control( demux_t *p_demux, int i_query, va_list args )
616 {
617     demux_sys_t *p_sys  = p_demux->p_sys;
618     vlc_meta_t *p_meta;
619     int64_t *pi64, i64;
620     double *pf, f;
621     bool *pb_bool, b;
622
623     switch( i_query )
624     {
625         case DEMUX_GET_META:
626             p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
627             if( p_sys->p_meta )
628                 vlc_meta_Merge( p_meta, p_sys->p_meta );
629             return VLC_SUCCESS;
630
631         case DEMUX_HAS_UNSUPPORTED_META:
632             pb_bool = (bool*)va_arg( args, bool* );
633             *pb_bool = true;
634             return VLC_SUCCESS;
635
636         case DEMUX_GET_TIME:
637             pi64 = (int64_t*)va_arg( args, int64_t * );
638             *pi64 = p_sys->i_pcr;
639             return VLC_SUCCESS;
640
641         case DEMUX_SET_TIME:
642             i64 = (int64_t)va_arg( args, int64_t );
643             logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
644             if ( !p_stream )
645             {
646                 msg_Err( p_demux, "No selected seekable stream found" );
647                 return VLC_EGENERIC;
648             }
649             stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
650             if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
651             {
652                 Ogg_ResetStreamHelper( p_sys );
653                 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
654                                 VLC_TS_0 + i64 );
655                 return VLC_SUCCESS;
656             }
657             else
658                 return VLC_EGENERIC;
659
660         case DEMUX_GET_ATTACHMENTS:
661         {
662             input_attachment_t ***ppp_attach =
663                 (input_attachment_t***)va_arg( args, input_attachment_t*** );
664             int *pi_int = (int*)va_arg( args, int * );
665
666             if( p_sys->i_attachments <= 0 )
667                 return VLC_EGENERIC;
668
669             *pi_int = p_sys->i_attachments;
670             *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
671             for( int i = 0; i < p_sys->i_attachments; i++ )
672                 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
673             return VLC_SUCCESS;
674         }
675
676         case DEMUX_GET_POSITION:
677             pf = (double*)va_arg( args, double * );
678             if( p_sys->i_length > 0 )
679             {
680                 *pf =  (double) p_sys->i_pcr /
681                        (double) ( p_sys->i_length * (mtime_t)1000000 );
682             }
683             else if( stream_Size( p_demux->s ) > 0 )
684             {
685                 i64 = stream_Tell( p_demux->s );
686                 *pf = (double) i64 / stream_Size( p_demux->s );
687             }
688             else *pf = 0.0;
689             return VLC_SUCCESS;
690
691         case DEMUX_SET_POSITION:
692             /* forbid seeking if we haven't initialized all logical bitstreams yet;
693                if we allowed, some headers would not get backed up and decoder init
694                would fail, making that logical stream unusable */
695             for ( int i=0; i< p_sys->i_streams; i++ )
696             {
697                 if ( p_sys->pp_stream[i]->b_initializing )
698                     return VLC_EGENERIC;
699             }
700
701             p_stream = Ogg_GetSelectedStream( p_demux );
702             if ( !p_stream )
703             {
704                 msg_Err( p_demux, "No selected seekable stream found" );
705                 return VLC_EGENERIC;
706             }
707
708             stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
709
710             f = (double)va_arg( args, double );
711             if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
712             {
713                 Ogg_ResetStreamHelper( p_sys );
714                 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
715                 return VLC_SUCCESS;
716             }
717
718             assert( p_sys->i_length > 0 );
719             i64 = CLOCK_FREQ * p_sys->i_length * f;
720             Ogg_ResetStreamHelper( p_sys );
721             if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
722             {
723                 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
724                                 VLC_TS_0 + i64 );
725                 return VLC_SUCCESS;
726             }
727
728             return VLC_EGENERIC;
729
730         case DEMUX_GET_LENGTH:
731             if ( p_sys->i_length < 0 )
732                 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
733                                               1, i_query, args );
734             pi64 = (int64_t*)va_arg( args, int64_t * );
735             *pi64 = p_sys->i_length * 1000000;
736             return VLC_SUCCESS;
737
738         case DEMUX_GET_TITLE_INFO:
739         {
740             input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
741             int *pi_int    = (int*)va_arg( args, int* );
742             int *pi_title_offset = (int*)va_arg( args, int* );
743             int *pi_seekpoint_offset = (int*)va_arg( args, int* );
744
745             if( p_sys->i_seekpoints > 0 )
746             {
747                 *pi_int = 1;
748                 *ppp_title = malloc( sizeof( input_title_t* ) );
749                 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
750                 for( int i = 0; i < p_sys->i_seekpoints; i++ )
751                 {
752                     seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
753                     if ( likely( p_seekpoint_copy ) )
754                         TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
755                 }
756                 *pi_title_offset = 0;
757                 *pi_seekpoint_offset = 0;
758             }
759             return VLC_SUCCESS;
760         }
761         case DEMUX_SET_TITLE:
762         {
763             const int i_title = (int)va_arg( args, int );
764             if( i_title > 1 )
765                 return VLC_EGENERIC;
766             return VLC_SUCCESS;
767         }
768         case DEMUX_SET_SEEKPOINT:
769         {
770             const int i_seekpoint = (int)va_arg( args, int );
771             if( i_seekpoint > p_sys->i_seekpoints )
772                 return VLC_EGENERIC;
773
774             for ( int i=0; i< p_sys->i_streams; i++ )
775             {
776                 if ( p_sys->pp_stream[i]->b_initializing )
777                     return VLC_EGENERIC;
778             }
779
780             i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
781
782             p_stream = Ogg_GetSelectedStream( p_demux );
783             if ( !p_stream )
784             {
785                 msg_Err( p_demux, "No selected seekable stream found" );
786                 return VLC_EGENERIC;
787             }
788
789             stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
790             if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
791             {
792                 Ogg_ResetStreamHelper( p_sys );
793                 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
794                                 VLC_TS_0 + i64 );
795                 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
796                 p_demux->info.i_seekpoint = i_seekpoint;
797                 return VLC_SUCCESS;
798             }
799             else
800                 return VLC_EGENERIC;
801         }
802
803         default:
804             return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
805                                            1, i_query, args );
806     }
807 }
808
809 /****************************************************************************
810  * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
811  ****************************************************************************
812  * Returns VLC_SUCCESS if a page has been read. An error might happen if we
813  * are at the end of stream.
814  ****************************************************************************/
815 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
816 {
817     demux_sys_t *p_ogg = p_demux->p_sys  ;
818     int i_read = 0;
819     char *p_buffer;
820
821     while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
822     {
823         p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
824
825         i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
826         if( i_read <= 0 )
827             return VLC_EGENERIC;
828
829         ogg_sync_wrote( &p_ogg->oy, i_read );
830     }
831
832     return VLC_SUCCESS;
833 }
834
835 /****************************************************************************
836  * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
837  *                current stream.
838  ****************************************************************************/
839 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
840                            ogg_packet *p_oggpacket )
841 {
842     demux_sys_t *p_ogg = p_demux->p_sys;
843     p_stream->i_end_trim = 0;
844
845     /* Convert the granulepos into a pcr */
846     if( p_oggpacket->granulepos >= 0 )
847     {
848         if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
849             p_stream->fmt.i_codec == VLC_CODEC_KATE ||
850             p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
851         {
852             p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream,
853                                                 p_oggpacket->granulepos, true );
854         }
855         else
856         {
857             ogg_int64_t sample;
858             sample = p_oggpacket->granulepos;
859             if( p_oggpacket->e_o_s &&
860                 p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
861                 p_stream->i_previous_granulepos >= 0 )
862             {
863                 int duration;
864                 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
865                 if( duration > 0 )
866                 {
867                     ogg_int64_t end_sample;
868                     end_sample = p_stream->i_previous_granulepos + duration;
869                     if( end_sample > sample )
870                         p_stream->i_end_trim = (int)(end_sample - sample);
871                 }
872             }
873             if (sample >= p_stream->i_pre_skip)
874                 sample -= p_stream->i_pre_skip;
875             else
876                 sample = 0;
877             p_stream->i_pcr = sample * CLOCK_FREQ / p_stream->f_rate;
878         }
879
880         if ( !p_ogg->i_pcr_offset )
881             p_stream->i_pcr += VLC_TS_0;
882         else
883             p_stream->i_pcr += p_ogg->i_pcr_offset;
884         p_stream->i_interpolated_pcr = p_stream->i_pcr;
885     }
886     else
887     {
888         int duration;
889         p_stream->i_pcr = -1;
890
891         /* no granulepos available, try to interpolate the pcr.
892          * If we can't then don't touch the old value. */
893         if( p_stream->fmt.i_cat == VIDEO_ES )
894             /* 1 frame per packet */
895             p_stream->i_interpolated_pcr += (CLOCK_FREQ / p_stream->f_rate);
896         else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
897                  p_stream->i_previous_granulepos >= 0 &&
898                  ( duration =
899                      Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
900         {
901             ogg_int64_t sample;
902             p_oggpacket->granulepos =
903                 p_stream->i_previous_granulepos + duration;
904             sample = p_oggpacket->granulepos;
905             if (sample >= p_stream->i_pre_skip)
906                 sample -= p_stream->i_pre_skip;
907             else
908                 sample = 0;
909             p_stream->i_interpolated_pcr =
910                 VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
911             p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
912         }
913         else if( p_stream->fmt.i_bitrate )
914         {
915             p_stream->i_interpolated_pcr +=
916                 ( p_oggpacket->bytes * CLOCK_FREQ /
917                   p_stream->fmt.i_bitrate / 8 );
918             p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
919         }
920     }
921     p_stream->i_previous_granulepos = p_oggpacket->granulepos;
922 }
923
924 /****************************************************************************
925  * Ogg_DecodePacket: Decode an Ogg packet.
926  ****************************************************************************/
927 static void Ogg_DecodePacket( demux_t *p_demux,
928                               logical_stream_t *p_stream,
929                               ogg_packet *p_oggpacket )
930 {
931     block_t *p_block;
932     bool b_selected;
933     int i_header_len = 0;
934     mtime_t i_pts = -1, i_interpolated_pts;
935     demux_sys_t *p_ogg = p_demux->p_sys;
936
937     if( p_oggpacket->bytes >= 7 &&
938         ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
939     {
940         /* it's an Annodex packet -- skip it (do nothing) */
941         return;
942     }
943     else if( p_oggpacket->bytes >= 7 &&
944         ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
945     {
946         /* it's an AnxData packet -- skip it (do nothing) */
947         return;
948     }
949     else if( p_oggpacket->bytes >= 8 &&
950         ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
951     {
952         Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
953         return;
954     }
955     else if( p_oggpacket->bytes >= 6 &&
956         ! memcmp ( p_oggpacket->packet, "index", 6 ) )
957     {
958         Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
959         return;
960     }
961
962     if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
963         p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
964
965     /* Check the ES is selected */
966     if ( !p_stream->p_es )
967         b_selected = true;
968     else
969         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
970                         p_stream->p_es, &b_selected );
971
972     if( p_stream->b_force_backup )
973     {
974         bool b_xiph;
975         p_stream->i_packets_backup++;
976         switch( p_stream->fmt.i_codec )
977         {
978         case VLC_CODEC_VORBIS:
979         case VLC_CODEC_THEORA:
980             if( p_stream->i_packets_backup == 3 )
981                 p_stream->b_force_backup = false;
982             b_xiph = true;
983             break;
984
985         case VLC_CODEC_SPEEX:
986             if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
987                 p_stream->b_force_backup = false;
988             b_xiph = true;
989             break;
990
991         case VLC_CODEC_OPUS:
992             if( p_stream->i_packets_backup == 2 )
993                 p_stream->b_force_backup = false;
994             b_xiph = true;
995             break;
996
997         case VLC_CODEC_FLAC:
998             if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
999             {
1000                 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1001                 p_stream->b_force_backup = false;
1002             }
1003             else if( p_stream->fmt.audio.i_rate )
1004             {
1005                 p_stream->b_force_backup = false;
1006                 if( p_oggpacket->bytes >= 9 )
1007                 {
1008                     p_oggpacket->packet += 9;
1009                     p_oggpacket->bytes -= 9;
1010                 }
1011             }
1012             b_xiph = false;
1013             break;
1014
1015         case VLC_CODEC_KATE:
1016             if( p_stream->i_packets_backup == p_stream->i_kate_num_headers )
1017                 p_stream->b_force_backup = false;
1018             b_xiph = true;
1019             break;
1020
1021         default:
1022             p_stream->b_force_backup = false;
1023             b_xiph = false;
1024             break;
1025         }
1026
1027         /* Backup the ogg packet (likely an header packet) */
1028         if( !b_xiph )
1029         {
1030             void *p_org = p_stream->p_headers;
1031             p_stream->i_headers += p_oggpacket->bytes;
1032             p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1033             if( p_stream->p_headers )
1034             {
1035                 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1036                         p_oggpacket->packet, p_oggpacket->bytes );
1037             }
1038             else
1039             {
1040 #warning Memory leak
1041                 p_stream->i_headers = 0;
1042                 p_stream->p_headers = NULL;
1043                 free( p_org );
1044             }
1045         }
1046         else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1047                                      p_oggpacket->bytes, p_oggpacket->packet ) )
1048         {
1049             p_stream->i_headers = 0;
1050             p_stream->p_headers = NULL;
1051         }
1052         if( p_stream->i_headers > 0 )
1053         {
1054             if( !p_stream->b_force_backup )
1055             {
1056                 /* Last header received, commit changes */
1057                 free( p_stream->fmt.p_extra );
1058
1059                 p_stream->fmt.i_extra = p_stream->i_headers;
1060                 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1061                 if( p_stream->fmt.p_extra )
1062                     memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1063                             p_stream->i_headers );
1064                 else
1065                     p_stream->fmt.i_extra = 0;
1066
1067                 if( p_stream->i_headers > 0 )
1068                     Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1069                                      p_stream->p_headers, p_stream->i_headers );
1070
1071                 /* we're not at BOS anymore for this logical stream */
1072                 p_stream->b_initializing = false;
1073             }
1074         }
1075
1076         b_selected = false; /* Discard the header packet */
1077     }
1078     else
1079         p_stream->b_initializing = false;
1080
1081     /* Convert the pcr into a pts */
1082     if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
1083         p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1084         p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
1085         p_stream->fmt.i_codec == VLC_CODEC_FLAC )
1086     {
1087         if( p_stream->i_pcr >= 0 )
1088         {
1089             p_stream->i_previous_pcr = p_stream->i_pcr;
1090             /* The granulepos is the end date of the sample */
1091             i_pts = p_stream->i_pcr;
1092         }
1093     }
1094
1095     /* Convert the granulepos into the next pcr */
1096     i_interpolated_pts = p_stream->i_interpolated_pcr;
1097     Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1098
1099     if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1100         p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1101         p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1102         p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1103         p_stream->i_pcr >= 0 )
1104     {
1105         p_stream->i_previous_pcr = p_stream->i_pcr;
1106
1107         /* The granulepos is the start date of the sample */
1108         i_pts = p_stream->i_pcr;
1109     }
1110
1111     if( !b_selected )
1112     {
1113         /* This stream isn't currently selected so we don't need to decode it,
1114          * but we did need to store its pcr as it might be selected later on */
1115         return;
1116     }
1117
1118     if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1119
1120
1121     /* may need to preroll after a seek */
1122     if ( p_stream->i_skip_frames > 0 )
1123     {
1124         if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1125         {
1126             int duration;
1127             duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1128             if( p_stream->i_skip_frames > duration )
1129             {
1130                 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1131                 p_block->i_nb_samples = 0;
1132                 p_stream->i_skip_frames -= duration;
1133             }
1134             else
1135             {
1136                 p_block->i_nb_samples = duration - p_stream->i_skip_frames;
1137                 if( p_stream->i_previous_granulepos >=
1138                     p_block->i_nb_samples + p_stream->i_pre_skip )
1139                 {
1140                     i_pts = VLC_TS_0 + (p_stream->i_previous_granulepos
1141                         - p_block->i_nb_samples - p_stream->i_pre_skip) *
1142                         CLOCK_FREQ / p_stream->f_rate;
1143                 }
1144                 p_stream->i_skip_frames = 0;
1145             }
1146         }
1147         else
1148         {
1149             p_block->i_flags |= BLOCK_FLAG_PREROLL;
1150             p_stream->i_skip_frames--;
1151         }
1152     }
1153     else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1154         p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1155
1156
1157     /* Normalize PTS */
1158     if( i_pts == VLC_TS_INVALID ) i_pts = VLC_TS_0;
1159     else if( i_pts == -1 && i_interpolated_pts == VLC_TS_INVALID )
1160         i_pts = VLC_TS_0;
1161     else if( i_pts == -1 && (p_stream->fmt.i_cat == VIDEO_ES || p_stream->fmt.i_codec == VLC_CODEC_OPUS) )
1162         i_pts = i_interpolated_pts; /* FIXME : why is this incorrect for vorbis? */
1163     else if( i_pts == -1 ) i_pts = VLC_TS_INVALID;
1164
1165     if( p_stream->fmt.i_cat == AUDIO_ES )
1166     {
1167         p_block->i_dts = p_block->i_pts = i_pts;
1168         /* Blatant abuse of the i_length field. */
1169         p_block->i_length = p_stream->i_end_trim;
1170     }
1171     else if( p_stream->fmt.i_cat == SPU_ES )
1172     {
1173         p_block->i_dts = p_block->i_pts = i_pts;
1174         p_block->i_length = 0;
1175     }
1176     else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1177     {
1178         p_block->i_dts = p_block->i_pts = i_pts;
1179         if( (p_oggpacket->granulepos & ((1<<p_stream->i_granule_shift)-1)) == 0 )
1180         {
1181             p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1182         }
1183     }
1184     else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1185     {
1186         ogg_int64_t dts = p_oggpacket->granulepos >> 31;
1187         ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
1188
1189         uint64_t u_pnum = dts + delay;
1190
1191         p_block->i_dts = p_stream->i_pcr;
1192         p_block->i_pts = VLC_TS_INVALID;
1193         /* NB, OggDirac granulepos values are in units of 2*picturerate */
1194
1195         /* granulepos for dirac is possibly broken, this value should be ignored */
1196         if( -1 != p_oggpacket->granulepos )
1197             p_block->i_pts = u_pnum * CLOCK_FREQ / p_stream->f_rate / 2;
1198     }
1199     else
1200     {
1201         p_block->i_dts = i_pts;
1202         p_block->i_pts = VLC_TS_INVALID;
1203     }
1204
1205     if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1206         p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1207         p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1208         p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1209         p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1210         p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1211         p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1212         p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1213         p_stream->fmt.i_codec != VLC_CODEC_KATE )
1214     {
1215         if( p_oggpacket->bytes <= 0 )
1216         {
1217             msg_Dbg( p_demux, "discarding 0 sized packet" );
1218             block_Release( p_block );
1219             return;
1220         }
1221         /* We remove the header from the packet */
1222         i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1223         i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1224
1225         if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1226         {
1227             /* But with subtitles we need to retrieve the duration first */
1228             int i, lenbytes = 0;
1229
1230             if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1231             {
1232                 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1233                 {
1234                     lenbytes = lenbytes << 8;
1235                     lenbytes += *(p_oggpacket->packet + i_header_len - i);
1236                 }
1237             }
1238             if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1239                 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1240                   p_oggpacket->packet[i_header_len + 1] != 0 &&
1241                   p_oggpacket->packet[i_header_len + 1] != '\n' &&
1242                   p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1243             {
1244                 p_block->i_length = (mtime_t)lenbytes * 1000;
1245             }
1246         }
1247
1248         i_header_len++;
1249         if( p_block->i_buffer >= (unsigned int)i_header_len )
1250             p_block->i_buffer -= i_header_len;
1251         else
1252             p_block->i_buffer = 0;
1253     }
1254
1255
1256     if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1257     {
1258         /* FIXME: the biggest hack I've ever done */
1259         msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1260                   p_block->i_pts, p_block->i_dts );
1261         msleep(10000);
1262     }
1263
1264     memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1265             p_oggpacket->bytes - i_header_len );
1266
1267     if ( p_stream->p_es )
1268     {
1269         /* Because ES creation is delayed for preparsing */
1270         if ( p_stream->p_preparse_block )
1271         {
1272             es_out_Send( p_demux->out, p_stream->p_es, p_stream->p_preparse_block );
1273             p_stream->p_preparse_block = NULL;
1274         }
1275         es_out_Send( p_demux->out, p_stream->p_es, p_block );
1276     }
1277     else
1278         block_ChainAppend( & p_stream->p_preparse_block, p_block );
1279 }
1280
1281 /* Re-implemented to avoid linking against libopus from the demuxer. */
1282 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1283                                    ogg_packet *p_oggpacket )
1284 {
1285     static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1286     int toc;
1287     int nframes;
1288     int frame_size;
1289     int nsamples;
1290     int i_rate;
1291     if( p_oggpacket->bytes < 1 )
1292         return VLC_EGENERIC;
1293     toc = p_oggpacket->packet[0];
1294     switch( toc&3 )
1295     {
1296         case 0:
1297             nframes = 1;
1298             break;
1299         case 1:
1300         case 2:
1301             nframes = 2;
1302             break;
1303         default:
1304             if( p_oggpacket->bytes < 2 )
1305                 return VLC_EGENERIC;
1306             nframes = p_oggpacket->packet[1]&0x3F;
1307             break;
1308     }
1309     i_rate = (int)p_stream->fmt.audio.i_rate;
1310     if( toc&0x80 )
1311         frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1312     else if( ( toc&0x60 ) == 0x60 )
1313         frame_size = i_rate/(100 >> (toc >> 3 & 1));
1314     else
1315         frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1316     nsamples = nframes*frame_size;
1317     if( nsamples*25 > i_rate*3 )
1318         return VLC_EGENERIC;
1319     return nsamples;
1320 }
1321
1322 /****************************************************************************
1323  * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1324  *                         stream and fill p_ogg.
1325  *****************************************************************************
1326  * The initial page of a logical stream is marked as a 'bos' page.
1327  * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1328  * together and all of the initial pages must appear before any data pages.
1329  *
1330  * On success this function returns VLC_SUCCESS.
1331  ****************************************************************************/
1332 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1333 {
1334     demux_sys_t *p_ogg = p_demux->p_sys  ;
1335     ogg_packet oggpacket;
1336     int i_stream = 0;
1337
1338     p_ogg->i_total_length = stream_Size ( p_demux->s );
1339     msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1340
1341
1342     while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1343     {
1344
1345         if( ogg_page_bos( &p_ogg->current_page ) )
1346         {
1347
1348             /* All is wonderful in our fine fine little world.
1349              * We found the beginning of our first logical stream. */
1350             while( ogg_page_bos( &p_ogg->current_page ) )
1351             {
1352                 logical_stream_t *p_stream;
1353
1354                 p_stream = malloc( sizeof(logical_stream_t) );
1355                 if( unlikely( !p_stream ) )
1356                     return VLC_ENOMEM;
1357
1358                 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1359
1360                 memset( p_stream, 0, sizeof(logical_stream_t) );
1361
1362                 es_format_Init( &p_stream->fmt, 0, 0 );
1363                 es_format_Init( &p_stream->fmt_old, 0, 0 );
1364                 p_stream->b_initializing = true;
1365
1366                 /* Setup the logical stream */
1367                 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1368                 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1369
1370                 /* Extract the initial header from the first page and verify
1371                  * the codec type of this Ogg bitstream */
1372                 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1373                 {
1374                     /* error. stream version mismatch perhaps */
1375                     msg_Err( p_demux, "error reading first page of "
1376                              "Ogg bitstream data" );
1377                     return VLC_EGENERIC;
1378                 }
1379
1380                 /* FIXME: check return value */
1381                 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1382
1383                 /* Check for Vorbis header */
1384                 if( oggpacket.bytes >= 7 &&
1385                     ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1386                 {
1387                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
1388                     msg_Dbg( p_demux, "found vorbis header" );
1389                 }
1390                 /* Check for Speex header */
1391                 else if( oggpacket.bytes >= 5 &&
1392                     ! memcmp( oggpacket.packet, "Speex", 5 ) )
1393                 {
1394                     Ogg_ReadSpeexHeader( p_stream, &oggpacket );
1395                     msg_Dbg( p_demux, "found speex header, channels: %i, "
1396                              "rate: %i,  bitrate: %i",
1397                              p_stream->fmt.audio.i_channels,
1398                              (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
1399                 }
1400                 /* Check for Opus header */
1401                 else if( oggpacket.bytes >= 8 &&
1402                     ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1403                 {
1404                     Ogg_ReadOpusHeader( p_stream, &oggpacket );
1405                     msg_Dbg( p_demux, "found opus header, channels: %i, "
1406                              "pre-skip: %i",
1407                              p_stream->fmt.audio.i_channels,
1408                              (int)p_stream->i_pre_skip);
1409                     p_stream->i_skip_frames = p_stream->i_pre_skip;
1410                 }
1411                 /* Check for Flac header (< version 1.1.1) */
1412                 else if( oggpacket.bytes >= 4 &&
1413                     ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1414                 {
1415                     msg_Dbg( p_demux, "found FLAC header" );
1416
1417                     /* Grrrr!!!! Did they really have to put all the
1418                      * important info in the second header packet!!!
1419                      * (STREAMINFO metadata is in the following packet) */
1420                     p_stream->b_force_backup = true;
1421
1422                     p_stream->fmt.i_cat = AUDIO_ES;
1423                     p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1424                 }
1425                 /* Check for Flac header (>= version 1.1.1) */
1426                 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1427                     ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1428                     ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1429                 {
1430                     int i_packets = ((int)oggpacket.packet[7]) << 8 |
1431                         oggpacket.packet[8];
1432                     msg_Dbg( p_demux, "found FLAC header version %i.%i "
1433                              "(%i header packets)",
1434                              oggpacket.packet[5], oggpacket.packet[6],
1435                              i_packets );
1436
1437                     p_stream->b_force_backup = true;
1438
1439                     p_stream->fmt.i_cat = AUDIO_ES;
1440                     p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1441                     oggpacket.packet += 13; oggpacket.bytes -= 13;
1442                     Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
1443                 }
1444                 /* Check for Theora header */
1445                 else if( oggpacket.bytes >= 7 &&
1446                          ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1447                 {
1448                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
1449
1450                     msg_Dbg( p_demux,
1451                              "found theora header, bitrate: %i, rate: %f",
1452                              p_stream->fmt.i_bitrate, p_stream->f_rate );
1453                 }
1454                 /* Check for Dirac header */
1455                 else if( ( oggpacket.bytes >= 5 &&
1456                            ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1457                          ( oggpacket.bytes >= 9 &&
1458                            ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1459                 {
1460                     if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1461                         msg_Dbg( p_demux, "found dirac header" );
1462                     else
1463                     {
1464                         msg_Warn( p_demux, "found dirac header isn't decodable" );
1465                         free( p_stream );
1466                         p_ogg->i_streams--;
1467                     }
1468                 }
1469                 /* Check for Tarkin header */
1470                 else if( oggpacket.bytes >= 7 &&
1471                          ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1472                 {
1473                     oggpack_buffer opb;
1474
1475                     msg_Dbg( p_demux, "found tarkin header" );
1476                     p_stream->fmt.i_cat = VIDEO_ES;
1477                     p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1478
1479                     /* Cheat and get additionnal info ;) */
1480                     oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1481                     oggpack_adv( &opb, 88 );
1482                     oggpack_adv( &opb, 104 );
1483                     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1484                     p_stream->f_rate = 2; /* FIXME */
1485                     msg_Dbg( p_demux,
1486                              "found tarkin header, bitrate: %i, rate: %f",
1487                              p_stream->fmt.i_bitrate, p_stream->f_rate );
1488                 }
1489                 /* Check for Annodex header */
1490                 else if( oggpacket.bytes >= 7 &&
1491                          ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1492                 {
1493                     Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1494                     /* kill annodex track */
1495                     free( p_stream );
1496                     p_ogg->i_streams--;
1497                 }
1498                 /* Check for Annodex header */
1499                 else if( oggpacket.bytes >= 7 &&
1500                          ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1501                 {
1502                     Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1503                 }
1504                 /* Check for Kate header */
1505                 else if( oggpacket.bytes >= 8 &&
1506                     ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1507                 {
1508                     Ogg_ReadKateHeader( p_stream, &oggpacket );
1509                     msg_Dbg( p_demux, "found kate header" );
1510                 }
1511                 /* Check for OggDS */
1512                 else if( oggpacket.bytes >= 142 &&
1513                          !memcmp( &oggpacket.packet[1],
1514                                    "Direct Show Samples embedded in Ogg", 35 ))
1515                 {
1516                     /* Old header type */
1517                     p_stream->b_oggds = true;
1518                     /* Check for video header (old format) */
1519                     if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1520                         oggpacket.bytes >= 184 )
1521                     {
1522                         p_stream->fmt.i_cat = VIDEO_ES;
1523                         p_stream->fmt.i_codec =
1524                             VLC_FOURCC( oggpacket.packet[68],
1525                                         oggpacket.packet[69],
1526                                         oggpacket.packet[70],
1527                                         oggpacket.packet[71] );
1528                         msg_Dbg( p_demux, "found video header of type: %.4s",
1529                                  (char *)&p_stream->fmt.i_codec );
1530
1531                         p_stream->fmt.video.i_frame_rate = 10000000;
1532                         p_stream->fmt.video.i_frame_rate_base =
1533                             GetQWLE((oggpacket.packet+164));
1534                         p_stream->f_rate = 10000000.0 /
1535                             GetQWLE((oggpacket.packet+164));
1536                         p_stream->fmt.video.i_bits_per_pixel =
1537                             GetWLE((oggpacket.packet+182));
1538                         if( !p_stream->fmt.video.i_bits_per_pixel )
1539                             /* hack, FIXME */
1540                             p_stream->fmt.video.i_bits_per_pixel = 24;
1541                         p_stream->fmt.video.i_width =
1542                             GetDWLE((oggpacket.packet+176));
1543                         p_stream->fmt.video.i_height =
1544                             GetDWLE((oggpacket.packet+180));
1545
1546                         msg_Dbg( p_demux,
1547                                  "fps: %f, width:%i; height:%i, bitcount:%i",
1548                                  p_stream->f_rate,
1549                                  p_stream->fmt.video.i_width,
1550                                  p_stream->fmt.video.i_height,
1551                                  p_stream->fmt.video.i_bits_per_pixel);
1552
1553                     }
1554                     /* Check for audio header (old format) */
1555                     else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1556                     {
1557                         int i_extra_size;
1558                         unsigned int i_format_tag;
1559
1560                         p_stream->fmt.i_cat = AUDIO_ES;
1561
1562                         i_extra_size = GetWLE((oggpacket.packet+140));
1563                         if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1564                         {
1565                             p_stream->fmt.i_extra = i_extra_size;
1566                             p_stream->fmt.p_extra = malloc( i_extra_size );
1567                             if( p_stream->fmt.p_extra )
1568                                 memcpy( p_stream->fmt.p_extra,
1569                                         oggpacket.packet + 142, i_extra_size );
1570                             else
1571                                 p_stream->fmt.i_extra = 0;
1572                         }
1573
1574                         i_format_tag = GetWLE((oggpacket.packet+124));
1575                         p_stream->fmt.audio.i_channels =
1576                             GetWLE((oggpacket.packet+126));
1577                         fill_channels_info(&p_stream->fmt.audio);
1578                         p_stream->f_rate = p_stream->fmt.audio.i_rate =
1579                             GetDWLE((oggpacket.packet+128));
1580                         p_stream->fmt.i_bitrate =
1581                             GetDWLE((oggpacket.packet+132)) * 8;
1582                         p_stream->fmt.audio.i_blockalign =
1583                             GetWLE((oggpacket.packet+136));
1584                         p_stream->fmt.audio.i_bitspersample =
1585                             GetWLE((oggpacket.packet+138));
1586
1587                         wf_tag_to_fourcc( i_format_tag,
1588                                           &p_stream->fmt.i_codec, 0 );
1589
1590                         if( p_stream->fmt.i_codec ==
1591                             VLC_FOURCC('u','n','d','f') )
1592                         {
1593                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1594                                 ( i_format_tag >> 8 ) & 0xff,
1595                                 i_format_tag & 0xff );
1596                         }
1597
1598                         msg_Dbg( p_demux, "found audio header of type: %.4s",
1599                                  (char *)&p_stream->fmt.i_codec );
1600                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1601                                  "%dbits/sample %dkb/s",
1602                                  i_format_tag,
1603                                  p_stream->fmt.audio.i_channels,
1604                                  p_stream->fmt.audio.i_rate,
1605                                  p_stream->fmt.audio.i_bitspersample,
1606                                  p_stream->fmt.i_bitrate / 1024 );
1607
1608                     }
1609                     else
1610                     {
1611                         msg_Dbg( p_demux, "stream %d has an old header "
1612                             "but is of an unknown type", p_ogg->i_streams-1 );
1613                         free( p_stream );
1614                         p_ogg->i_streams--;
1615                     }
1616                 }
1617                 /* Check for OggDS */
1618                 else if( oggpacket.bytes >= 44+1 &&
1619                          (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1620                 {
1621                     stream_header_t tmp;
1622                     stream_header_t *st = &tmp;
1623
1624                     p_stream->b_oggds = true;
1625
1626                     memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1627                     memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1628                     st->size = GetDWLE( &oggpacket.packet[1+12] );
1629                     st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1630                     st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1631                     st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1632                     st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1633                     st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1634
1635                     /* Check for video header (new format) */
1636                     if( !strncmp( st->streamtype, "video", 5 ) &&
1637                         oggpacket.bytes >= 52+1 )
1638                     {
1639                         st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1640                         st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1641
1642                         p_stream->fmt.i_cat = VIDEO_ES;
1643
1644                         /* We need to get rid of the header packet */
1645                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1646
1647                         p_stream->fmt.i_codec =
1648                             VLC_FOURCC( st->subtype[0], st->subtype[1],
1649                                         st->subtype[2], st->subtype[3] );
1650                         msg_Dbg( p_demux, "found video header of type: %.4s",
1651                                  (char *)&p_stream->fmt.i_codec );
1652
1653                         p_stream->fmt.video.i_frame_rate = 10000000;
1654                         p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1655                         if( st->time_unit <= 0 )
1656                             st->time_unit = 400000;
1657                         p_stream->f_rate = 10000000.0 / st->time_unit;
1658                         p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1659                         p_stream->fmt.video.i_width = st->sh.video.width;
1660                         p_stream->fmt.video.i_height = st->sh.video.height;
1661
1662                         msg_Dbg( p_demux,
1663                                  "fps: %f, width:%i; height:%i, bitcount:%i",
1664                                  p_stream->f_rate,
1665                                  p_stream->fmt.video.i_width,
1666                                  p_stream->fmt.video.i_height,
1667                                  p_stream->fmt.video.i_bits_per_pixel );
1668                     }
1669                     /* Check for audio header (new format) */
1670                     else if( !strncmp( st->streamtype, "audio", 5 ) &&
1671                              oggpacket.bytes >= 56+1 )
1672                     {
1673                         char p_buffer[5];
1674                         int i_extra_size;
1675                         int i_format_tag;
1676
1677                         st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1678                         st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1679                         st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1680
1681                         p_stream->fmt.i_cat = AUDIO_ES;
1682
1683                         /* We need to get rid of the header packet */
1684                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1685
1686                         i_extra_size = st->size - 56;
1687
1688                         if( i_extra_size > 0 &&
1689                             i_extra_size < oggpacket.bytes - 1 - 56 )
1690                         {
1691                             p_stream->fmt.i_extra = i_extra_size;
1692                             p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1693                             if( p_stream->fmt.p_extra )
1694                                 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1695                                         p_stream->fmt.i_extra );
1696                             else
1697                                 p_stream->fmt.i_extra = 0;
1698                         }
1699
1700                         memcpy( p_buffer, st->subtype, 4 );
1701                         p_buffer[4] = '\0';
1702                         i_format_tag = strtol(p_buffer,NULL,16);
1703                         p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1704                         fill_channels_info(&p_stream->fmt.audio);
1705                         if( st->time_unit <= 0 )
1706                             st->time_unit = 10000000;
1707                         p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1708                         p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1709                         p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1710                         p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1711
1712                         wf_tag_to_fourcc( i_format_tag,
1713                                           &p_stream->fmt.i_codec, 0 );
1714
1715                         if( p_stream->fmt.i_codec ==
1716                             VLC_FOURCC('u','n','d','f') )
1717                         {
1718                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1719                                 ( i_format_tag >> 8 ) & 0xff,
1720                                 i_format_tag & 0xff );
1721                         }
1722
1723                         msg_Dbg( p_demux, "found audio header of type: %.4s",
1724                                  (char *)&p_stream->fmt.i_codec );
1725                         msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1726                                  "%dbits/sample %dkb/s",
1727                                  i_format_tag,
1728                                  p_stream->fmt.audio.i_channels,
1729                                  p_stream->fmt.audio.i_rate,
1730                                  p_stream->fmt.audio.i_bitspersample,
1731                                  p_stream->fmt.i_bitrate / 1024 );
1732                     }
1733                     /* Check for text (subtitles) header */
1734                     else if( !strncmp(st->streamtype, "text", 4) )
1735                     {
1736                         /* We need to get rid of the header packet */
1737                         ogg_stream_packetout( &p_stream->os, &oggpacket );
1738
1739                         msg_Dbg( p_demux, "found text subtitle header" );
1740                         p_stream->fmt.i_cat = SPU_ES;
1741                         p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1742                         p_stream->f_rate = 1000; /* granulepos is in millisec */
1743                     }
1744                     else
1745                     {
1746                         msg_Dbg( p_demux, "stream %d has a header marker "
1747                             "but is of an unknown type", p_ogg->i_streams-1 );
1748                         free( p_stream );
1749                         p_ogg->i_streams--;
1750                     }
1751                 }
1752                 else if( oggpacket.bytes >= 8 &&
1753                              ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1754
1755                 {
1756                     /* Skeleton */
1757                     msg_Dbg( p_demux, "stream %d is a skeleton",
1758                                 p_ogg->i_streams-1 );
1759                     Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1760                 }
1761                 else
1762                 {
1763                     msg_Dbg( p_demux, "stream %d is of unknown type",
1764                              p_ogg->i_streams-1 );
1765                     free( p_stream );
1766                     p_ogg->i_streams--;
1767                 }
1768
1769                 /* we'll need to get all headers */
1770                 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1771
1772                 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1773                     return VLC_EGENERIC;
1774             }
1775
1776             /* This is the first data page, which means we are now finished
1777              * with the initial pages. We just need to store it in the relevant
1778              * bitstream. */
1779             for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1780             {
1781                 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1782                                        &p_ogg->current_page ) == 0 )
1783                 {
1784                     p_ogg->b_page_waiting = true;
1785                     break;
1786                 }
1787             }
1788
1789             return VLC_SUCCESS;
1790         }
1791     }
1792
1793     return VLC_EGENERIC;
1794 }
1795
1796 /****************************************************************************
1797  * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1798  ****************************************************************************/
1799 static void Ogg_CreateES( demux_t *p_demux )
1800 {
1801     demux_sys_t *p_ogg = p_demux->p_sys;
1802     logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1803     int i_stream;
1804
1805     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1806     {
1807         logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1808
1809         if ( p_stream->p_es == NULL )
1810         {
1811             /* Better be safe than sorry when possible with ogm */
1812             if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1813                 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1814                 p_stream->fmt.b_packetized = false;
1815
1816             /* Try first to reuse an old ES */
1817             if( p_old_stream &&
1818                 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1819                 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1820             {
1821                 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1822
1823                 p_stream->p_es = p_old_stream->p_es;
1824                 p_stream->b_finished = false;
1825                 p_stream->b_reinit = false;
1826                 p_stream->b_initializing = false;
1827                 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1828
1829                 p_old_stream->p_es = NULL;
1830                 p_old_stream = NULL;
1831                 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
1832                                 p_stream->p_es, &p_stream->fmt );
1833             }
1834             else
1835             {
1836                 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1837             }
1838
1839             // TODO: something to do here ?
1840             if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
1841             {
1842                 /* Set the CMML stream active */
1843                 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
1844             }
1845         }
1846     }
1847
1848     if( p_ogg->p_old_stream )
1849     {
1850         if( p_ogg->p_old_stream->p_es )
1851             msg_Dbg( p_demux, "old stream not reused" );
1852         Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
1853         p_ogg->p_old_stream = NULL;
1854     }
1855 }
1856
1857 /****************************************************************************
1858  * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1859  *                        Elementary streams.
1860  ****************************************************************************/
1861 static int Ogg_BeginningOfStream( demux_t *p_demux )
1862 {
1863     demux_sys_t *p_ogg = p_demux->p_sys  ;
1864     int i_stream;
1865
1866     /* Find the logical streams embedded in the physical stream and
1867      * initialize our p_ogg structure. */
1868     if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
1869     {
1870         msg_Warn( p_demux, "couldn't find any ogg logical stream" );
1871         return VLC_EGENERIC;
1872     }
1873
1874     p_ogg->i_bitrate = 0;
1875
1876     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1877     {
1878         logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1879
1880         p_stream->p_es = NULL;
1881
1882         /* initialise kframe index */
1883         p_stream->idx=NULL;
1884
1885         if ( p_stream->fmt.i_bitrate == 0  &&
1886              ( p_stream->fmt.i_cat == VIDEO_ES ||
1887                p_stream->fmt.i_cat == AUDIO_ES ) )
1888             p_ogg->b_partial_bitrate = true;
1889         else
1890             p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
1891
1892         p_stream->i_pcr = p_stream->i_previous_pcr =
1893             p_stream->i_interpolated_pcr = -1;
1894         p_stream->b_reinit = false;
1895     }
1896
1897     /* get total frame count for video stream; we will need this for seeking */
1898     p_ogg->i_total_frames = 0;
1899
1900     return VLC_SUCCESS;
1901 }
1902
1903 /****************************************************************************
1904  * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1905  ****************************************************************************/
1906 static void Ogg_EndOfStream( demux_t *p_demux )
1907 {
1908     demux_sys_t *p_ogg = p_demux->p_sys  ;
1909     int i_stream;
1910
1911     for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1912         Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
1913     free( p_ogg->pp_stream );
1914
1915     /* Reinit p_ogg */
1916     p_ogg->i_bitrate = 0;
1917     p_ogg->i_streams = 0;
1918     p_ogg->pp_stream = NULL;
1919     p_ogg->skeleton.major = 0;
1920     p_ogg->skeleton.minor = 0;
1921     p_ogg->b_preparsing_done = false;
1922     p_ogg->i_pcr_offset = p_ogg->i_pcr;
1923
1924     /* */
1925     if( p_ogg->p_meta )
1926         vlc_meta_Delete( p_ogg->p_meta );
1927     p_ogg->p_meta = NULL;
1928
1929     for ( int i=0; i < p_ogg->i_seekpoints; i++ )
1930     {
1931         if ( p_ogg->pp_seekpoints[i] )
1932             vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
1933     }
1934     TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
1935     p_ogg->i_seekpoints = 0;
1936 }
1937
1938 /**
1939  * This function delete and release all data associated to a logical_stream_t
1940  */
1941 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
1942 {
1943     if( p_stream->p_es )
1944         es_out_Del( p_demux->out, p_stream->p_es );
1945
1946     ogg_stream_clear( &p_stream->os );
1947     free( p_stream->p_headers );
1948
1949     es_format_Clean( &p_stream->fmt_old );
1950     es_format_Clean( &p_stream->fmt );
1951
1952     if ( p_stream->idx != NULL)
1953     {
1954         oggseek_index_entries_free( p_stream->idx );
1955     }
1956
1957     Ogg_FreeSkeleton( p_stream->p_skel );
1958     p_stream->p_skel = NULL;
1959     if ( p_demux->p_sys->p_skelstream == p_stream )
1960         p_demux->p_sys->p_skelstream = NULL;
1961
1962     /* Shouldn't happen */
1963     if ( unlikely( p_stream->p_preparse_block ) )
1964     {
1965         block_ChainRelease( p_stream->p_preparse_block );
1966         p_stream->p_preparse_block = NULL;
1967     }
1968
1969     free( p_stream );
1970 }
1971 /**
1972  * This function check if a we need to reset a decoder in case we are
1973  * reusing an old ES
1974  */
1975 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
1976 {
1977     unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
1978     void     *pp_new_data[XIPH_MAX_HEADER_COUNT];
1979     unsigned i_new_count;
1980     if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
1981         i_new_count = 0;
1982
1983     unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
1984     void     *pp_old_data[XIPH_MAX_HEADER_COUNT];
1985     unsigned i_old_count;
1986     if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
1987         i_old_count = 0;
1988
1989     bool b_match = i_new_count == i_old_count;
1990     for( unsigned i = 0; i < i_new_count && b_match; i++ )
1991     {
1992         /* Ignore vorbis comment */
1993         if( i == 1 )
1994             continue;
1995         if( pi_new_size[i] != pi_old_size[i] ||
1996             memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
1997             b_match = false;
1998     }
1999
2000     return b_match;
2001 }
2002
2003 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2004                                         const es_format_t *p_old )
2005 {
2006     unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2007     void     *pp_new_data[XIPH_MAX_HEADER_COUNT];
2008     unsigned i_new_count;
2009     if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2010         i_new_count = 0;
2011     unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2012     void     *pp_old_data[XIPH_MAX_HEADER_COUNT];
2013     unsigned i_old_count;
2014     if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2015         i_old_count = 0;
2016     bool b_match = false;
2017     if( i_new_count == i_old_count && i_new_count > 0 )
2018     {
2019         static const unsigned char default_map[2] = { 0, 1 };
2020         unsigned char *p_old_head;
2021         unsigned char *p_new_head;
2022         const unsigned char *p_old_map;
2023         const unsigned char *p_new_map;
2024         int i_old_channel_count;
2025         int i_new_channel_count;
2026         int i_old_stream_count;
2027         int i_new_stream_count;
2028         int i_old_coupled_count;
2029         int i_new_coupled_count;
2030         p_old_head = (unsigned char *)pp_old_data[0];
2031         i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2032         p_old_map = default_map;
2033         if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2034         {
2035             i_old_channel_count = p_old_head[9];
2036             switch( p_old_head[18] )
2037             {
2038                 case 0:
2039                     i_old_stream_count = 1;
2040                     i_old_coupled_count = i_old_channel_count - 1;
2041                     break;
2042                 case 1:
2043                     if( pi_old_size[0] >= 21U + i_old_channel_count )
2044                     {
2045                         i_old_stream_count = p_old_head[19];
2046                         i_old_coupled_count = p_old_head[20];
2047                         p_old_map = p_old_head + 21;
2048                     }
2049                     break;
2050             }
2051         }
2052         p_new_head = (unsigned char *)pp_new_data[0];
2053         i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2054         p_new_map = default_map;
2055         if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2056         {
2057             i_new_channel_count = p_new_head[9];
2058             switch( p_new_head[18] )
2059             {
2060                 case 0:
2061                     i_new_stream_count = 1;
2062                     i_new_coupled_count = i_new_channel_count - 1;
2063                     break;
2064                 case 1:
2065                     if( pi_new_size[0] >= 21U + i_new_channel_count )
2066                     {
2067                         i_new_stream_count = p_new_head[19];
2068                         i_new_coupled_count = p_new_head[20];
2069                         p_new_map = p_new_head+21;
2070                     }
2071                     break;
2072             }
2073         }
2074         b_match = i_old_channel_count == i_new_channel_count &&
2075                   i_old_stream_count == i_new_stream_count &&
2076                   i_old_coupled_count == i_new_coupled_count &&
2077                   memcmp(p_old_map, p_new_map,
2078                       i_new_channel_count*sizeof(*p_new_map)) == 0;
2079     }
2080
2081     return b_match;
2082 }
2083
2084 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2085 {
2086     bool b_compatible = false;
2087     if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2088         return true;
2089
2090     /* Only Vorbis and Opus are supported. */
2091     if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2092         b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2093     else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2094         b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2095
2096     if( !b_compatible )
2097         msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2098
2099     return !b_compatible;
2100 }
2101 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2102                                  const void *p_headers, unsigned i_headers, unsigned i_skip )
2103 {
2104     demux_sys_t *p_ogg = p_demux->p_sys;
2105
2106     unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2107     void     *pp_data[XIPH_MAX_HEADER_COUNT];
2108     unsigned i_count;
2109     if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2110         return;
2111
2112     /* TODO how to handle multiple comments properly ? */
2113     if( i_count >= 2 && pi_size[1] > i_skip )
2114     {
2115         int i_cover_score = 0;
2116         int i_cover_idx = 0;
2117         float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2118         float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2119         for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2120         {
2121             pf_replay_gain[i] = 0;
2122             pf_replay_peak[i] = 0;
2123         }
2124         vorbis_ParseComment( &p_ogg->p_meta, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip,
2125                              &p_ogg->i_attachments, &p_ogg->attachments,
2126                              &i_cover_score, &i_cover_idx,
2127                              &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2128                              &pf_replay_gain, &pf_replay_peak );
2129         if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2130         {
2131             char psz_url[128];
2132             snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2133                 p_ogg->attachments[i_cover_idx]->psz_name );
2134             vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2135         }
2136
2137         for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2138         {
2139             if ( pf_replay_gain[i] != 0 )
2140             {
2141                 p_fmt->audio_replay_gain.pb_gain[i] = true;
2142                 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2143                 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2144             }
2145             if ( pf_replay_peak[i] != 0 )
2146             {
2147                 p_fmt->audio_replay_gain.pb_peak[i] = true;
2148                 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2149                 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2150             }
2151         }
2152     }
2153
2154     if( p_ogg->i_seekpoints > 1 )
2155     {
2156         p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2157     }
2158 }
2159 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2160 {
2161     demux_sys_t *p_ogg = p_demux->p_sys;
2162
2163     switch( p_fmt->i_codec )
2164     {
2165     /* 3 headers with the 2° one being the comments */
2166     case VLC_CODEC_VORBIS:
2167     case VLC_CODEC_THEORA:
2168         Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2169         break;
2170     case VLC_CODEC_OPUS:
2171         Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2172         break;
2173     case VLC_CODEC_SPEEX:
2174         Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2175         break;
2176
2177     /* N headers with the 2° one being the comments */
2178     case VLC_CODEC_KATE:
2179         /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2180         Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2181         break;
2182
2183     /* TODO */
2184     case VLC_CODEC_FLAC:
2185         msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2186         break;
2187
2188     /* No meta data */
2189     case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2190     case VLC_CODEC_DIRAC:
2191     default:
2192         break;
2193     }
2194     if( p_ogg->p_meta )
2195         p_demux->info.i_update |= INPUT_UPDATE_META;
2196 }
2197
2198 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2199                                   ogg_packet *p_oggpacket )
2200 {
2201     bs_t bitstream;
2202     int i_fps_numerator;
2203     int i_fps_denominator;
2204     int i_keyframe_frequency_force;
2205     int i_major;
2206     int i_minor;
2207     int i_subminor;
2208     int i_version;
2209
2210     p_stream->fmt.i_cat = VIDEO_ES;
2211     p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2212
2213     /* Signal that we want to keep a backup of the theora
2214      * stream headers. They will be used when switching between
2215      * audio streams. */
2216     p_stream->b_force_backup = true;
2217
2218     /* Cheat and get additionnal info ;) */
2219     bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2220     bs_skip( &bitstream, 56 );
2221
2222     i_major = bs_read( &bitstream, 8 ); /* major version num */
2223     i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2224     i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2225
2226     bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2227     bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2228     bs_read( &bitstream, 24 ); /* frame width */
2229     bs_read( &bitstream, 24 ); /* frame height */
2230     bs_read( &bitstream, 8 ); /* x offset */
2231     bs_read( &bitstream, 8 ); /* y offset */
2232
2233     i_fps_numerator = bs_read( &bitstream, 32 );
2234     i_fps_denominator = bs_read( &bitstream, 32 );
2235     i_fps_denominator = __MAX( i_fps_denominator, 1 );
2236     bs_read( &bitstream, 24 ); /* aspect_numerator */
2237     bs_read( &bitstream, 24 ); /* aspect_denominator */
2238
2239     p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2240     p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2241
2242     bs_read( &bitstream, 8 ); /* colorspace */
2243     p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2244     bs_read( &bitstream, 6 ); /* quality */
2245
2246     i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2247
2248     /* granule_shift = i_log( frequency_force -1 ) */
2249     p_stream->i_granule_shift = 0;
2250     i_keyframe_frequency_force--;
2251     while( i_keyframe_frequency_force )
2252     {
2253         p_stream->i_granule_shift++;
2254         i_keyframe_frequency_force >>= 1;
2255     }
2256
2257     i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2258     p_stream->i_keyframe_offset = 0;
2259     p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
2260
2261     if ( i_version >= 3002001 )
2262     {
2263         p_stream->i_keyframe_offset = 1;
2264     }
2265 }
2266
2267 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2268                                   ogg_packet *p_oggpacket )
2269 {
2270     oggpack_buffer opb;
2271
2272     p_stream->fmt.i_cat = AUDIO_ES;
2273     p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2274
2275     /* Signal that we want to keep a backup of the vorbis
2276      * stream headers. They will be used when switching between
2277      * audio streams. */
2278     p_stream->b_force_backup = true;
2279
2280     /* Cheat and get additionnal info ;) */
2281     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2282     oggpack_adv( &opb, 88 );
2283     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2284     fill_channels_info(&p_stream->fmt.audio);
2285     p_stream->f_rate = p_stream->fmt.audio.i_rate =
2286         oggpack_read( &opb, 32 );
2287     oggpack_adv( &opb, 32 );
2288     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2289 }
2290
2291 static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2292                                  ogg_packet *p_oggpacket )
2293 {
2294     oggpack_buffer opb;
2295
2296     p_stream->fmt.i_cat = AUDIO_ES;
2297     p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2298
2299     /* Signal that we want to keep a backup of the speex
2300      * stream headers. They will be used when switching between
2301      * audio streams. */
2302     p_stream->b_force_backup = true;
2303
2304     /* Cheat and get additionnal info ;) */
2305     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2306     oggpack_adv( &opb, 224 );
2307     oggpack_adv( &opb, 32 ); /* speex_version_id */
2308     oggpack_adv( &opb, 32 ); /* header_size */
2309     p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2310     oggpack_adv( &opb, 32 ); /* mode */
2311     oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2312     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2313     fill_channels_info(&p_stream->fmt.audio);
2314     p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2315     oggpack_adv( &opb, 32 ); /* frame_size */
2316     oggpack_adv( &opb, 32 ); /* vbr */
2317     oggpack_adv( &opb, 32 ); /* frames_per_packet */
2318     p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2319 }
2320
2321 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2322                                 ogg_packet *p_oggpacket )
2323 {
2324     oggpack_buffer opb;
2325
2326     p_stream->fmt.i_cat = AUDIO_ES;
2327     p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2328
2329     /* Signal that we want to keep a backup of the opus
2330      * stream headers. They will be used when switching between
2331      * audio streams. */
2332     p_stream->b_force_backup = true;
2333
2334     /* All OggOpus streams are timestamped at 48kHz and
2335      * can be played at 48kHz. */
2336     p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2337     p_stream->fmt.i_bitrate = 0;
2338
2339     /* Cheat and get additional info ;) */
2340     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2341     oggpack_adv( &opb, 64 );
2342     oggpack_adv( &opb, 8 ); /* version_id */
2343     p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2344     fill_channels_info(&p_stream->fmt.audio);
2345     p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2346 }
2347
2348 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2349                                 ogg_packet *p_oggpacket )
2350 {
2351     /* Parse the STREAMINFO metadata */
2352     bs_t s;
2353
2354     bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2355
2356     bs_read( &s, 1 );
2357     if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2358     {
2359         msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2360         return;
2361     }
2362
2363     if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2364     {
2365         bs_skip( &s, 80 );
2366         p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2367         p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2368         fill_channels_info(&p_stream->fmt.audio);
2369
2370         msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2371                  p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2372     }
2373     else
2374     {
2375         msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2376     }
2377
2378     /* Fake this as the last metadata block */
2379     *((uint8_t*)p_oggpacket->packet) |= 0x80;
2380 }
2381
2382 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
2383                                 ogg_packet *p_oggpacket )
2384 {
2385     oggpack_buffer opb;
2386     int32_t gnum;
2387     int32_t gden;
2388     int n;
2389     char *psz_desc;
2390
2391     p_stream->fmt.i_cat = SPU_ES;
2392     p_stream->fmt.i_codec = VLC_CODEC_KATE;
2393
2394     /* Signal that we want to keep a backup of the kate
2395      * stream headers. They will be used when switching between
2396      * kate streams. */
2397     p_stream->b_force_backup = true;
2398
2399     /* Cheat and get additionnal info ;) */
2400     oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2401     oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2402     p_stream->i_kate_num_headers = oggpack_read( &opb, 8 );
2403     oggpack_adv( &opb, 3*8 );
2404     p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2405     oggpack_adv( &opb, 8*8 ); /* reserved */
2406     gnum = oggpack_read( &opb, 32 );
2407     gden = oggpack_read( &opb, 32 );
2408     p_stream->f_rate = (double)gnum/gden;
2409
2410     p_stream->fmt.psz_language = malloc(16);
2411     if( p_stream->fmt.psz_language )
2412     {
2413         for( n = 0; n < 16; n++ )
2414             p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2415         p_stream->fmt.psz_language[15] = 0; /* just in case */
2416     }
2417     else
2418     {
2419         for( n = 0; n < 16; n++ )
2420             oggpack_read(&opb,8);
2421     }
2422     p_stream->fmt.psz_description = malloc(16);
2423     if( p_stream->fmt.psz_description )
2424     {
2425         for( n = 0; n < 16; n++ )
2426             p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2427         p_stream->fmt.psz_description[15] = 0; /* just in case */
2428
2429         /* Now find a localized user readable description for this category */
2430         psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2431         if( psz_desc )
2432         {
2433             free( p_stream->fmt.psz_description );
2434             p_stream->fmt.psz_description = psz_desc;
2435         }
2436     }
2437     else
2438     {
2439         for( n = 0; n < 16; n++ )
2440             oggpack_read(&opb,8);
2441     }
2442 }
2443
2444 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2445                                   bool *b_force_backup, bool *b_packet_out )
2446 {
2447     if( !strncmp(psz_value, "audio/x-wav", 11) )
2448     {
2449         /* n.b. WAVs are unsupported right now */
2450         p_stream->fmt.i_cat = UNKNOWN_ES;
2451         free( p_stream->fmt.psz_description );
2452         p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2453     }
2454     else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2455              !strncmp(psz_value, "audio/vorbis", 12) )
2456     {
2457         p_stream->fmt.i_cat = AUDIO_ES;
2458         p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2459
2460         *b_force_backup = true;
2461     }
2462     else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2463              !strncmp(psz_value, "audio/speex", 11) )
2464     {
2465         p_stream->fmt.i_cat = AUDIO_ES;
2466         p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2467
2468         *b_force_backup = true;
2469     }
2470     else if( !strncmp(psz_value, "audio/flac", 10) )
2471     {
2472         p_stream->fmt.i_cat = AUDIO_ES;
2473         p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2474
2475         *b_force_backup = true;
2476     }
2477     else if( !strncmp(psz_value, "video/x-theora", 14) ||
2478              !strncmp(psz_value, "video/theora", 12) )
2479     {
2480         p_stream->fmt.i_cat = VIDEO_ES;
2481         p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2482
2483         *b_force_backup = true;
2484     }
2485     else if( !strncmp(psz_value, "video/x-xvid", 12) )
2486     {
2487         p_stream->fmt.i_cat = VIDEO_ES;
2488         p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2489
2490         *b_force_backup = true;
2491     }
2492     else if( !strncmp(psz_value, "video/mpeg", 10) )
2493     {
2494         /* n.b. MPEG streams are unsupported right now */
2495         p_stream->fmt.i_cat = VIDEO_ES;
2496         p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2497     }
2498     else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2499              !strncmp(psz_value, "text/cmml", 9) )
2500     {
2501         p_stream->fmt.i_cat = SPU_ES;
2502         p_stream->fmt.i_codec = VLC_CODEC_CMML;
2503         *b_packet_out = true;
2504     }
2505     else if( !strncmp(psz_value, "application/kate", 16) )
2506     {
2507         /* ??? */
2508         p_stream->fmt.i_cat = UNKNOWN_ES;
2509         free( p_stream->fmt.psz_description );
2510         p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2511     }
2512 }
2513
2514 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2515                                    logical_stream_t *p_stream,
2516                                    ogg_packet *p_oggpacket )
2517 {
2518     if( p_oggpacket->bytes >= 28 &&
2519         !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2520     {
2521         oggpack_buffer opb;
2522
2523         uint16_t major_version;
2524         uint16_t minor_version;
2525         uint64_t timebase_numerator;
2526         uint64_t timebase_denominator;
2527
2528         Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2529
2530         oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2531         oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2532         major_version = oggpack_read( &opb, 2*8 ); /* major version */
2533         minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2534         timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2535         timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2536
2537         msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2538                           "Timebase  %"PRId64" / %"PRId64,
2539                           major_version, minor_version,
2540                           timebase_numerator, timebase_denominator );
2541     }
2542     else if( p_oggpacket->bytes >= 42 &&
2543              !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2544     {
2545         uint64_t granule_rate_numerator;
2546         uint64_t granule_rate_denominator;
2547         char content_type_string[1024];
2548
2549         /* Read in Annodex header fields */
2550
2551         granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2552         granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2553         p_stream->i_secondary_header_packets =
2554             GetDWLE( &p_oggpacket->packet[24] );
2555
2556         /* we are guaranteed that the first header field will be
2557          * the content-type (by the Annodex standard) */
2558         content_type_string[0] = '\0';
2559         if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2560         {
2561             uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2562                                  p_oggpacket->bytes - 1 );
2563             if( p && p[0] == '\r' && p[1] == '\n' )
2564                 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2565                         content_type_string );
2566         }
2567
2568         msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2569                  granule_rate_numerator, granule_rate_denominator,
2570                  p_stream->i_secondary_header_packets, content_type_string );
2571
2572         p_stream->f_rate = (float) granule_rate_numerator /
2573             (float) granule_rate_denominator;
2574
2575         /* What type of file do we have?
2576          * strcmp is safe to use here because we've extracted
2577          * content_type_string from the stream manually */
2578         bool b_dopacketout = false;
2579         Ogg_ApplyContentType( p_stream, content_type_string,
2580                               &p_stream->b_force_backup, &b_dopacketout );
2581         if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2582     }
2583 }
2584
2585 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2586                                     ogg_packet *p_oggpacket )
2587 {
2588     p_demux->p_sys->p_skelstream = p_stream;
2589     /* There can be only 1 skeleton for streams */
2590     p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2591     p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2592     if ( asprintf( & p_stream->fmt.psz_description,
2593                         "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2594                         p_demux->p_sys->skeleton.major,
2595                         p_demux->p_sys->skeleton.minor ) < 0 )
2596         p_stream->fmt.psz_description = NULL;
2597 }
2598
2599 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2600 {
2601     if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2602
2603     /* Find the matching stream for this skeleton data */
2604     ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2605     logical_stream_t *p_target_stream = NULL;
2606     for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2607     {
2608         if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2609         {
2610             p_target_stream = p_demux->p_sys->pp_stream[i];
2611             break;
2612         }
2613     }
2614     if ( !p_target_stream ) return;
2615
2616     ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2617     if ( !p_skel )
2618     {
2619         p_skel = malloc( sizeof( ogg_skeleton_t ) );
2620         if ( !p_skel ) return;
2621         TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2622         p_skel->p_index = NULL;
2623         p_target_stream->p_skel = p_skel;
2624     }
2625
2626     const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2627     const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2628     const unsigned char *p = p_messages;
2629     while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2630     {
2631         if ( *p == 0x0D && *(p+1) == 0x0A )
2632         {
2633             char *psz_message = strndup( (const char *) p_messages,
2634                                          p - p_messages );
2635             if ( psz_message )
2636             {
2637                 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2638                 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2639             }
2640             if ( p < p_boundary - 1 ) p_messages = p + 2;
2641         }
2642         p++;
2643     }
2644
2645 }
2646
2647 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2648 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2649                                            unsigned const char *p_end,
2650                                            uint64_t *pi_value )
2651 {
2652     int i_shift = 0;
2653     int64_t i_read = 0;
2654     *pi_value = 0;
2655
2656     while ( p_begin < p_end )
2657     {
2658         i_read = *p_begin & 0x7F; /* High bit is start of integer */
2659         *pi_value = *pi_value | ( i_read << i_shift );
2660         i_shift += 7;
2661         if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2662     }
2663
2664     *pi_value = GetQWLE( pi_value );
2665     return p_begin;
2666 }
2667
2668 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2669 {
2670     if ( p_demux->p_sys->skeleton.major < 4
2671          || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2672     ) return;
2673
2674     /* Find the matching stream for this skeleton data */
2675     int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2676     logical_stream_t *p_stream = NULL;
2677     for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2678     {
2679         if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2680         {
2681             p_stream = p_demux->p_sys->pp_stream[i];
2682             break;
2683         }
2684     }
2685     if ( !p_stream ) return;
2686     uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2687     msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2688     if ( !i_keypoints ) return;
2689
2690     p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
2691     p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
2692     p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
2693     unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
2694     unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2695     uint64_t i_offset = 0;
2696     uint64_t i_time = 0;
2697     uint64_t i_keypoints_found = 0;
2698
2699     while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
2700     {
2701         uint64_t i_val;
2702         p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2703         i_offset += i_val;
2704         p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2705         i_time += i_val * p_stream->p_skel->i_indexstampden;
2706         i_keypoints_found++;
2707     }
2708
2709     if ( i_keypoints_found != i_keypoints )
2710     {
2711         msg_Warn( p_demux, "Invalid Index: missing entries" );
2712         return;
2713     }
2714
2715     p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
2716     if ( !p_stream->p_skel->p_index ) return;
2717     memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
2718             p_oggpacket->bytes - 42 );
2719     p_stream->p_skel->i_index = i_keypoints_found;
2720     p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
2721 }
2722
2723 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
2724 {
2725     if ( !p_skel ) return;
2726     for ( int i=0; i< p_skel->i_messages; i++ )
2727         free( p_skel->ppsz_messages[i] );
2728     TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
2729     free( p_skel->p_index );
2730     free( p_skel );
2731 }
2732
2733 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
2734 {
2735     if ( !p_stream->p_skel ) return;
2736     for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
2737     {
2738         const char *psz_message = p_stream->p_skel->ppsz_messages[i];
2739         if ( ! strncmp( "Name: ", psz_message, 6 ) )
2740         {
2741             free( p_stream->fmt.psz_description );
2742             p_stream->fmt.psz_description = strdup( psz_message + 6 );
2743         }
2744         else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
2745         {
2746             bool b_foo;
2747             Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
2748         }
2749     }
2750 }
2751
2752 /* Return true if there's a skeleton exact match */
2753 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
2754                                       int64_t *pi_lower, int64_t *pi_upper )
2755 {
2756     if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
2757         return false;
2758
2759     /* Validate range */
2760     if ( i_time < p_stream->p_skel->i_indexfirstnum
2761                 * p_stream->p_skel->i_indexstampden ||
2762          i_time > p_stream->p_skel->i_indexlastnum
2763                 * p_stream->p_skel->i_indexstampden ) return false;
2764
2765     /* Then Lookup its index */
2766     unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
2767     struct
2768     {
2769         int64_t i_pos;
2770         int64_t i_time;
2771     } current = { 0, 0 }, prev = { -1, -1 };
2772
2773     uint64_t i_keypoints_found = 0;
2774
2775     while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
2776            && i_keypoints_found < p_stream->p_skel->i_index )
2777     {
2778         uint64_t i_val;
2779         p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2780                         p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2781         current.i_pos += i_val;
2782         p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2783                         p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2784         current.i_time += i_val * p_stream->p_skel->i_indexstampden;
2785         if ( current.i_pos < 0 || current.i_time < 0 ) break;
2786
2787         i_keypoints_found++;
2788
2789         if ( i_time <= current.i_time )
2790         {
2791             *pi_lower = prev.i_pos;
2792             *pi_upper = current.i_pos;
2793             return ( i_time == current.i_time );
2794         }
2795         prev = current;
2796     }
2797     return false;
2798 }
2799
2800 static uint32_t dirac_uint( bs_t *p_bs )
2801 {
2802     uint32_t u_count = 0, u_value = 0;
2803
2804     while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
2805     {
2806         u_count++;
2807         u_value <<= 1;
2808         u_value |= bs_read( p_bs, 1 );
2809     }
2810
2811     return (1<<u_count) - 1 + u_value;
2812 }
2813
2814 static int dirac_bool( bs_t *p_bs )
2815 {
2816     return bs_read( p_bs, 1 );
2817 }
2818
2819 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
2820                                  ogg_packet *p_oggpacket )
2821 {
2822     static const struct {
2823         uint32_t u_n /* numerator */, u_d /* denominator */;
2824     } p_dirac_frate_tbl[] = { /* table 10.3 */
2825         {1,1}, /* this first value is never used */
2826         {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
2827         {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
2828     };
2829     static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
2830
2831     static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
2832         1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
2833     };
2834     static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
2835
2836     bs_t bs;
2837
2838     p_stream->i_granule_shift = 22; /* not 32 */
2839
2840     /* Backing up stream headers is not required -- seqhdrs are repeated
2841      * thoughout the stream at suitable decoding start points */
2842     p_stream->b_force_backup = false;
2843
2844     /* read in useful bits from sequence header */
2845     bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
2846     bs_skip( &bs, 13*8); /* parse_info_header */
2847     dirac_uint( &bs ); /* major_version */
2848     dirac_uint( &bs ); /* minor_version */
2849     dirac_uint( &bs ); /* profile */
2850     dirac_uint( &bs ); /* level */
2851
2852     uint32_t u_video_format = dirac_uint( &bs ); /* index */
2853     if( u_video_format >= u_dirac_vidfmt_frate )
2854     {
2855         /* don't know how to parse this ogg dirac stream */
2856         return false;
2857     }
2858
2859     if( dirac_bool( &bs ) )
2860     {
2861         dirac_uint( &bs ); /* frame_width */
2862         dirac_uint( &bs ); /* frame_height */
2863     }
2864
2865     if( dirac_bool( &bs ) )
2866     {
2867         dirac_uint( &bs ); /* chroma_format */
2868     }
2869
2870     if( dirac_bool( &bs ) )
2871     {
2872         dirac_uint( &bs ); /* scan_format */
2873     }
2874
2875     uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
2876     uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
2877     if( dirac_bool( &bs ) )
2878     {
2879         uint32_t u_frame_rate_index = dirac_uint( &bs );
2880         if( u_frame_rate_index >= u_dirac_frate_tbl )
2881         {
2882             /* something is wrong with this stream */
2883             return false;
2884         }
2885         u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
2886         u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
2887         if( u_frame_rate_index == 0 )
2888         {
2889             u_n = dirac_uint( &bs ); /* frame_rate_numerator */
2890             u_d = dirac_uint( &bs ); /* frame_rate_denominator */
2891         }
2892     }
2893     p_stream->f_rate = (float) u_n / u_d;
2894
2895     /* probably is an ogg dirac es */
2896     p_stream->fmt.i_cat = VIDEO_ES;
2897     p_stream->fmt.i_codec = VLC_CODEC_DIRAC;
2898
2899     return true;
2900 }