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