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