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