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