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