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