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