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