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