chromecast: refactor, make place for SPUs
[vlc.git] / modules / demux / ogg.c
blob496354d65432d2029f2f88055570ff5b576eaed6
1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
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>
39 #include <ogg/ogg.h>
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"
49 /*****************************************************************************
50 * Module descriptor
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close( vlc_object_t * );
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 ()
66 /*****************************************************************************
67 * Definitions of structures and functions used by this plugins
68 *****************************************************************************/
70 /* OggDS headers for the new header format (used in ogm files) */
71 typedef struct
73 ogg_int32_t width;
74 ogg_int32_t height;
75 } stream_header_video_t;
77 typedef struct
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;
85 typedef struct
87 char streamtype[8];
88 char subtype[4];
90 ogg_int32_t size; /* size of the structure */
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 */
96 ogg_int32_t buffersize;
97 ogg_int16_t bits_per_sample;
98 ogg_int16_t padding;
100 union
102 /* Video specific */
103 stream_header_video_t video;
104 /* Audio specific */
105 stream_header_audio_t audio;
106 } sh;
107 } stream_header_t;
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
116 /*****************************************************************************
117 * Local prototypes
118 *****************************************************************************/
119 static int Demux ( demux_t * );
120 static int Control( demux_t *, int, va_list );
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 * );
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 );
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 );
139 /* */
140 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
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 * );
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 * );
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
168 static void fill_channels_info(audio_format_t *audio)
170 static const int pi_channels_map[9] =
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,
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];
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)
199 /*****************************************************************************
200 * Open: initializes ogg demux structures
201 *****************************************************************************/
202 static int Open( vlc_object_t * p_this )
204 demux_t *p_demux = (demux_t *)p_this;
205 demux_sys_t *p_sys;
206 const uint8_t *p_peek;
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 ) )
212 char *psz_mime = stream_ContentType( p_demux->s );
213 if( !psz_mime )
215 return VLC_EGENERIC;
217 else if ( strcmp( psz_mime, "application/ogg" ) &&
218 strcmp( psz_mime, "video/ogg" ) &&
219 strcmp( psz_mime, "audio/ogg" ) )
221 free( psz_mime );
222 return VLC_EGENERIC;
224 free( psz_mime );
227 /* */
228 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
229 if( !p_sys )
230 return VLC_ENOMEM;
232 p_sys->i_length = -1;
233 p_sys->b_preparsing_done = false;
235 vlc_stream_Control( p_demux->s, STREAM_GET_PTS_DELAY,
236 &p_sys->i_access_delay );
238 /* Set exported functions */
239 p_demux->pf_demux = Demux;
240 p_demux->pf_control = Control;
242 /* Initialize the Ogg physical bitstream parser */
243 ogg_sync_init( &p_sys->oy );
245 /* */
246 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
249 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
251 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
252 Ogg_CreateES( p_demux );
254 return VLC_SUCCESS;
257 /*****************************************************************************
258 * Close: frees unused data
259 *****************************************************************************/
260 static void Close( vlc_object_t *p_this )
262 demux_t *p_demux = (demux_t *)p_this;
263 demux_sys_t *p_sys = p_demux->p_sys ;
265 /* Cleanup the bitstream parser */
266 ogg_sync_clear( &p_sys->oy );
268 Ogg_EndOfStream( p_demux );
270 if( p_sys->p_old_stream )
271 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
273 free( p_sys );
276 /*****************************************************************************
277 * Demux: reads and demuxes data packets
278 *****************************************************************************
279 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
280 *****************************************************************************/
281 static int Demux( demux_t * p_demux )
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;
289 int i_active_streams = p_sys->i_streams;
290 for ( int i=0; i < p_sys->i_streams; i++ )
292 if ( p_sys->pp_stream[i]->b_finished )
293 i_active_streams--;
296 if ( i_active_streams == 0 )
298 if ( p_sys->i_streams ) /* All finished */
300 msg_Dbg( p_demux, "end of a group of logical streams" );
302 mtime_t i_lastpcr = VLC_TS_INVALID;
303 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
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;
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 )
314 p_sys->p_old_stream = p_sys->pp_stream[0];
315 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
318 Ogg_EndOfStream( p_demux );
319 p_sys->b_chained_boundary = true;
321 if( i_lastpcr > VLC_TS_INVALID )
323 p_sys->i_nzpcr_offset = i_lastpcr - VLC_TS_0;
324 if( likely( !p_sys->b_slave ) )
325 es_out_SetPCR( p_demux->out, i_lastpcr );
327 p_sys->i_pcr = VLC_TS_INVALID;
330 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
331 return VLC_DEMUXER_EOF;
333 msg_Dbg( p_demux, "beginning of a group of logical streams" );
335 if ( !p_sys->b_chained_boundary )
337 /* Find the real duration */
338 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
339 if ( b_canseek )
340 Oggseek_ProbeEnd( p_demux );
342 else
344 p_sys->b_chained_boundary = false;
348 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
349 Ogg_CreateES( p_demux );
352 * The first data page of a physical stream is stored in the relevant logical stream
353 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
354 * stream it belongs to if we haven't processed this first page yet. If we do, we
355 * will only process that first page whenever we find the second page for this stream.
356 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
357 * the second page will arrive real quick, this is not fine for Kate, whose second
358 * data page will typically arrive much later.
359 * This means it is now possible to seek right at the start of a stream where the last
360 * logical stream is Kate, without having to wait for the second data page to unblock
361 * the first one, which is the one that triggers the 'no more headers to backup' code.
362 * And, as we all know, seeking without having backed up all headers is bad, since the
363 * codec will fail to initialize if it's missing its headers.
365 if( !p_sys->b_page_waiting)
368 * Demux an ogg page from the stream
370 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
371 return VLC_DEMUXER_EOF; /* EOF */
372 /* Test for End of Stream */
373 if( ogg_page_eos( &p_sys->current_page ) )
375 /* If we delayed restarting encoders/SET_ES_FMT for more
376 * skeleton provided configuration */
377 if ( p_sys->p_skelstream )
379 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
381 msg_Dbg( p_demux, "End of Skeleton" );
382 p_sys->b_preparsing_done = true;
383 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
385 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
386 Ogg_ApplySkeleton( p_stream );
391 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
393 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
395 p_sys->pp_stream[i_stream]->b_finished = true;
396 break;
402 b_skipping = false;
403 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
405 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
408 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
410 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
412 /* if we've just pulled page, look for the right logical stream */
413 if( !p_sys->b_page_waiting )
415 if( p_sys->i_streams == 1 &&
416 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
418 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
419 Ogg_ResetStream( p_stream );
420 if( p_stream->i_pcr > VLC_TS_INVALID )
421 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TS_0;
422 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
425 /* Does fail if serialno differs */
426 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
428 continue;
432 /* clear the finished flag if pages after eos (ex: after a seek) */
433 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
434 p_stream->b_finished = false;
436 DemuxDebug(
437 if ( p_stream->fmt.i_cat == VIDEO_ES )
438 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
439 ogg_page_pageno( &p_sys->current_page ),
440 ogg_page_granulepos( &p_sys->current_page ),
441 ogg_page_packets( &p_sys->current_page ),
442 ogg_page_continued(&p_sys->current_page),
443 p_sys->current_page.body_len )
446 const int i_page_packets = ogg_page_packets( &p_sys->current_page );
447 bool b_doprepcr = false;
449 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
451 // PASS 0
452 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
453 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
454 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
455 p_stream->fmt.i_cat == VIDEO_ES )
457 assert( p_stream->prepcr.pp_blocks == NULL );
458 b_doprepcr = true;
462 int i_real_page_packets = 0;
463 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
465 i_real_page_packets++;
466 int i_max_packets = __MAX(i_page_packets, i_real_page_packets);
467 if ( b_doprepcr && p_stream->prepcr.i_size < i_max_packets )
469 /* always double alloc for performance */
470 i_max_packets = __MAX( i_max_packets << 1, 255 );
471 /* alloc or realloc */
472 block_t **pp_realloc = realloc( p_stream->prepcr.pp_blocks,
473 sizeof(block_t *) * i_max_packets );
474 if ( !pp_realloc )
476 /* drop it then */
477 continue;
479 p_stream->prepcr.i_size = i_max_packets;
480 p_stream->prepcr.pp_blocks = pp_realloc;
483 /* Read info from any secondary header packets, if there are any */
484 if( p_stream->i_secondary_header_packets > 0 )
486 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
487 oggpacket.bytes >= 7 &&
488 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
490 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
491 p_stream->i_secondary_header_packets = 0;
493 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
494 oggpacket.bytes >= 6 &&
495 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
497 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
498 p_stream->i_secondary_header_packets = 0;
500 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
501 oggpacket.bytes >= 7 &&
502 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
504 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
505 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
506 p_stream->i_secondary_header_packets = 0;
508 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
510 p_stream->i_secondary_header_packets = 0;
513 /* update start of data pointer */
514 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
517 /* If any streams have i_skip_frames, only decode (pre-roll)
518 * for those streams, but don't skip headers */
519 if ( b_skipping && p_stream->i_skip_frames == 0
520 && p_stream->i_secondary_header_packets ) continue;
522 if( p_stream->b_reinit )
524 p_stream->b_reinit = false;
525 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
527 p_stream->i_skip_frames = p_stream->i_pre_skip;
531 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
534 if ( p_stream->prepcr.pp_blocks )
536 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
537 p_stream->i_previous_pcr = pagestamp;
538 #ifdef HAVE_LIBVORBIS
539 int i_prev_blocksize = 0;
540 #endif
541 // PASS 1
542 for( int i=0; i<p_stream->prepcr.i_used; i++ )
544 block_t *p_block = p_stream->prepcr.pp_blocks[i];
545 ogg_packet dumb_packet;
546 dumb_packet.bytes = p_block->i_buffer;
547 dumb_packet.packet = p_block->p_buffer;
549 switch( p_stream->fmt.i_codec )
551 case VLC_CODEC_SPEEX:
552 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
553 p_stream->special.speex.i_framesperpacket;
554 break;
555 case VLC_CODEC_OPUS:
556 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
557 break;
558 #ifdef HAVE_LIBVORBIS
559 case VLC_CODEC_VORBIS:
561 if( !VORBIS_HEADERS_VALID(p_stream) )
563 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
564 break;
566 long i_blocksize = vorbis_packet_blocksize(
567 p_stream->special.vorbis.p_info, &dumb_packet );
568 if ( i_prev_blocksize )
569 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
570 else
571 p_block->i_nb_samples = i_blocksize / 2;
572 i_prev_blocksize = i_blocksize;
574 #endif
578 // PASS 2
579 bool b_fixed = false;
580 for( int i=p_stream->prepcr.i_used - 1; i>=0; i-- )
582 block_t *p_block = p_stream->prepcr.pp_blocks[i];
583 switch( p_stream->fmt.i_codec )
585 case VLC_CODEC_SPEEX:
586 case VLC_CODEC_OPUS:
587 case VLC_CODEC_VORBIS:
588 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
589 if ( pagestamp < 0 )
591 p_block->i_pts = VLC_TS_INVALID;
592 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
593 p_block->i_flags |= BLOCK_FLAG_PREROLL;
595 else
596 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
597 b_fixed = true;
598 break;
599 default:
600 if ( p_stream->fmt.i_cat == VIDEO_ES )
602 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
603 if( pagestamp < 0 )
604 pagestamp = 0;
605 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
606 b_fixed = true;
611 if ( b_fixed )
613 pagestamp = p_stream->i_previous_pcr; /* as set above */
614 if ( pagestamp < 0 ) pagestamp = 0;
615 p_stream->i_pcr = VLC_TS_0 + pagestamp;
616 p_stream->i_pcr += p_sys->i_nzpcr_offset;
617 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
620 FREENULL(p_stream->prepcr.pp_blocks);
621 p_stream->prepcr.i_used = 0;
623 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
627 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
628 ogg_page_granulepos( &p_sys->current_page ), false );
629 if ( i_pagestamp > -1 )
631 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
632 p_stream->i_pcr += p_sys->i_nzpcr_offset;
635 if( !p_sys->b_page_waiting )
636 break;
639 /* if a page was waiting, it's now processed */
640 p_sys->b_page_waiting = false;
642 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
643 p_sys->b_preparsing_done = false;
644 else
645 p_sys->b_preparsing_done = true;
647 /* We will consider the lowest PCR among tracks, because the audio core badly
648 * handles PCR rewind (mute)
650 mtime_t i_pcr_candidate = VLC_TS_INVALID;
651 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
653 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
655 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
657 /* We have 1 or more streams needing more than 1 page for preparsing */
658 p_sys->b_preparsing_done = false;
661 if( p_stream->fmt.i_cat == SPU_ES )
662 continue;
663 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
664 continue;
665 if( p_stream->i_pcr < VLC_TS_0 )
666 continue;
667 if ( p_stream->b_finished || p_stream->b_initializing )
668 continue;
669 if ( p_stream->p_preparse_block )
670 continue;
671 if( i_pcr_candidate < VLC_TS_0
672 || p_stream->i_pcr <= i_pcr_candidate )
674 i_pcr_candidate = p_stream->i_pcr;
678 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
680 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
682 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
683 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
685 p_sys->i_pcr_jitter = i_pcr_jitter;
686 if ( p_sys->i_access_delay < i_pcr_jitter )
687 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
688 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
692 if( ! b_skipping && p_sys->b_preparsing_done )
694 p_sys->i_pcr = i_pcr_candidate;
695 if( likely( !p_sys->b_slave ) )
696 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
700 return VLC_DEMUXER_SUCCESS;
703 static void Ogg_ResetStream( logical_stream_t *p_stream )
705 #ifdef HAVE_LIBVORBIS
706 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
708 p_stream->special.vorbis.i_prev_blocksize = 0;
710 #endif
711 /* we'll trash all the data until we find the next pcr */
712 p_stream->b_reinit = true;
713 p_stream->i_pcr = VLC_TS_UNKNOWN;
714 p_stream->i_previous_granulepos = -1;
715 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
716 ogg_stream_reset( &p_stream->os );
717 FREENULL( p_stream->prepcr.pp_blocks );
718 p_stream->prepcr.i_size = 0;
719 p_stream->prepcr.i_used = 0;
722 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
724 for( int i = 0; i < p_sys->i_streams; i++ )
725 Ogg_ResetStream( p_sys->pp_stream[i] );
727 ogg_sync_reset( &p_sys->oy );
728 p_sys->i_pcr = VLC_TS_UNKNOWN;
731 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
733 demux_sys_t *p_sys = p_demux->p_sys;
734 logical_stream_t *p_stream = NULL;
735 for( int i=0; i<p_sys->i_streams; i++ )
737 logical_stream_t *p_candidate = p_sys->pp_stream[i];
738 if ( !p_candidate->p_es ) continue;
740 bool b_selected = false;
741 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
742 p_candidate->p_es, &b_selected );
743 if ( !b_selected ) continue;
745 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
747 p_stream = p_candidate;
748 continue; /* Try to find video anyway */
751 if ( p_candidate->fmt.i_cat == VIDEO_ES )
753 p_stream = p_candidate;
754 break;
757 return p_stream;
760 /*****************************************************************************
761 * Control:
762 *****************************************************************************/
763 static int Control( demux_t *p_demux, int i_query, va_list args )
765 demux_sys_t *p_sys = p_demux->p_sys;
766 vlc_meta_t *p_meta;
767 int64_t *pi64, i64;
768 double *pf, f;
769 bool *pb_bool, b, acc;
771 switch( i_query )
773 case DEMUX_CAN_SEEK:
774 return vlc_stream_vaControl( p_demux->s, i_query, args );
776 case DEMUX_GET_META:
777 p_meta = va_arg( args, vlc_meta_t * );
778 if( p_sys->p_meta )
779 vlc_meta_Merge( p_meta, p_sys->p_meta );
780 return VLC_SUCCESS;
782 case DEMUX_HAS_UNSUPPORTED_META:
783 pb_bool = va_arg( args, bool* );
784 *pb_bool = true;
785 return VLC_SUCCESS;
787 case DEMUX_SET_NEXT_DEMUX_TIME:
788 p_sys->b_slave = true;
789 return VLC_EGENERIC;
791 case DEMUX_GET_TIME:
792 if( p_sys->i_pcr > VLC_TS_INVALID || p_sys->b_slave )
794 pi64 = va_arg( args, int64_t * );
795 *pi64 = p_sys->i_pcr;
796 return VLC_SUCCESS;
798 return VLC_EGENERIC;
800 case DEMUX_SET_TIME:
801 i64 = va_arg( args, int64_t );
802 acc = va_arg( args, int );
803 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
804 if ( !p_stream )
806 msg_Err( p_demux, "No selected seekable stream found" );
807 return VLC_EGENERIC;
809 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
810 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
812 Ogg_ResetStreamsHelper( p_sys );
813 if( acc )
814 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
815 VLC_TS_0 + i64 );
816 return VLC_SUCCESS;
818 else
819 return VLC_EGENERIC;
821 case DEMUX_GET_ATTACHMENTS:
823 input_attachment_t ***ppp_attach =
824 va_arg( args, input_attachment_t *** );
825 int *pi_int = va_arg( args, int * );
827 if( p_sys->i_attachments <= 0 )
828 return VLC_EGENERIC;
830 *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
831 if (!**ppp_attach)
832 return VLC_ENOMEM;
833 *pi_int = p_sys->i_attachments;
834 for( int i = 0; i < p_sys->i_attachments; i++ )
835 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
836 return VLC_SUCCESS;
839 case DEMUX_GET_POSITION:
840 pf = va_arg( args, double * );
841 if( p_sys->i_length > 0 && p_sys->i_pcr > VLC_TS_INVALID )
843 *pf = (double) p_sys->i_pcr /
844 (double) ( p_sys->i_length * (mtime_t)1000000 );
846 else if( stream_Size( p_demux->s ) > 0 )
848 i64 = vlc_stream_Tell( p_demux->s );
849 *pf = (double) i64 / stream_Size( p_demux->s );
851 else *pf = 0.0;
852 return VLC_SUCCESS;
854 case DEMUX_SET_POSITION:
855 /* forbid seeking if we haven't initialized all logical bitstreams yet;
856 if we allowed, some headers would not get backed up and decoder init
857 would fail, making that logical stream unusable */
858 for ( int i=0; i< p_sys->i_streams; i++ )
860 if ( p_sys->pp_stream[i]->b_initializing )
861 return VLC_EGENERIC;
864 p_stream = Ogg_GetSelectedStream( p_demux );
865 if ( !p_stream )
867 msg_Err( p_demux, "No selected seekable stream found" );
868 return VLC_EGENERIC;
871 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
873 f = va_arg( args, double );
874 acc = va_arg( args, int );
875 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
877 Ogg_ResetStreamsHelper( p_sys );
878 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
879 return VLC_SUCCESS;
882 assert( p_sys->i_length > 0 );
883 i64 = CLOCK_FREQ * p_sys->i_length * f;
884 Ogg_ResetStreamsHelper( p_sys );
885 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
887 if( acc )
888 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
889 VLC_TS_0 + i64 );
890 return VLC_SUCCESS;
893 return VLC_EGENERIC;
895 case DEMUX_GET_LENGTH:
896 if ( p_sys->i_length < 0 )
897 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
898 1, i_query, args );
899 pi64 = va_arg( args, int64_t * );
900 *pi64 = p_sys->i_length * 1000000;
901 return VLC_SUCCESS;
903 case DEMUX_GET_TITLE_INFO:
905 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
906 int *pi_int = va_arg( args, int* );
907 int *pi_title_offset = va_arg( args, int* );
908 int *pi_seekpoint_offset = va_arg( args, int* );
910 if( p_sys->i_seekpoints > 0 )
912 *pi_int = 1;
913 *ppp_title = malloc( sizeof( input_title_t* ) );
914 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
915 for( int i = 0; i < p_sys->i_seekpoints; i++ )
917 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
918 if ( likely( p_seekpoint_copy ) )
919 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
921 *pi_title_offset = 0;
922 *pi_seekpoint_offset = 0;
924 return VLC_SUCCESS;
926 case DEMUX_SET_TITLE:
928 const int i_title = va_arg( args, int );
929 if( i_title > 1 )
930 return VLC_EGENERIC;
931 return VLC_SUCCESS;
933 case DEMUX_SET_SEEKPOINT:
935 const int i_seekpoint = va_arg( args, int );
936 if( i_seekpoint > p_sys->i_seekpoints )
937 return VLC_EGENERIC;
939 for ( int i=0; i< p_sys->i_streams; i++ )
941 if ( p_sys->pp_stream[i]->b_initializing )
942 return VLC_EGENERIC;
945 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
947 p_stream = Ogg_GetSelectedStream( p_demux );
948 if ( !p_stream )
950 msg_Err( p_demux, "No selected seekable stream found" );
951 return VLC_EGENERIC;
954 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
955 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
957 Ogg_ResetStreamsHelper( p_sys );
958 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
959 VLC_TS_0 + i64 );
960 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
961 p_sys->cur_seekpoint = i_seekpoint;
962 return VLC_SUCCESS;
964 else
965 return VLC_EGENERIC;
967 case DEMUX_GET_TITLE:
968 *va_arg( args, int * ) = 0;
969 return VLC_SUCCESS;
970 case DEMUX_GET_SEEKPOINT:
971 *va_arg( args, int * ) = p_sys->cur_seekpoint;
972 return VLC_SUCCESS;
974 default:
975 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
976 1, i_query, args );
980 /****************************************************************************
981 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
982 ****************************************************************************
983 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
984 * are at the end of stream.
985 ****************************************************************************/
986 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
988 demux_sys_t *p_ogg = p_demux->p_sys ;
989 int i_read = 0;
990 char *p_buffer;
992 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
994 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
996 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
997 if( i_read <= 0 )
998 return VLC_EGENERIC;
1000 ogg_sync_wrote( &p_ogg->oy, i_read );
1003 return VLC_SUCCESS;
1006 /****************************************************************************
1007 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
1008 * current stream.
1009 ****************************************************************************/
1010 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
1011 ogg_packet *p_oggpacket )
1013 demux_sys_t *p_ogg = p_demux->p_sys;
1014 p_stream->i_end_trim = 0;
1016 /* Convert the granulepos into a pcr */
1017 if ( p_oggpacket->granulepos == 0 )
1019 /* We're in headers, and we haven't parsed 1st data packet yet */
1020 // p_stream->i_pcr = VLC_TS_UNKNOWN;
1022 else if( p_oggpacket->granulepos > 0 )
1024 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
1025 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
1026 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
1027 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1028 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
1029 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1030 p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
1031 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
1033 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1034 p_oggpacket->granulepos, true );
1035 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1037 else if ( p_stream->i_previous_granulepos > 0 )
1039 ogg_int64_t sample = p_stream->i_previous_granulepos;
1041 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
1043 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
1044 if( duration > 0 )
1046 ogg_int64_t end_sample = p_oggpacket->granulepos;
1047 if( end_sample < ( sample + duration ) )
1048 p_stream->i_end_trim = sample + duration - end_sample;
1052 if (sample >= p_stream->i_pre_skip)
1053 sample -= p_stream->i_pre_skip;
1054 else
1055 sample = 0;
1057 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1058 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1062 else if ( p_oggpacket->granulepos == -1 )
1064 unsigned i_duration;
1065 /* no granulepos available, try to interpolate the pcr.
1066 * If we can't then don't touch the old value. */
1067 if( p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES )
1069 if( p_stream->i_previous_granulepos > 0 )
1071 p_stream->i_pcr = VLC_TS_0 + p_stream->i_previous_granulepos * CLOCK_FREQ / p_stream->f_rate;
1072 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1074 /* First frame in ogm can be -1 (0 0 -1 2 3 -1 5 ...) */
1075 else if( p_stream->i_previous_granulepos == 0 )
1077 p_stream->i_pcr = VLC_TS_0 + p_ogg->i_nzpcr_offset;
1079 else
1081 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1084 #ifdef HAVE_LIBVORBIS
1085 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1086 p_stream->special.vorbis.p_info &&
1087 VORBIS_HEADERS_VALID(p_stream) &&
1088 p_stream->i_previous_granulepos > 0 )
1090 long i_blocksize = vorbis_packet_blocksize(
1091 p_stream->special.vorbis.p_info, p_oggpacket );
1092 if ( p_stream->special.vorbis.i_prev_blocksize )
1093 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1094 else
1095 i_duration = i_blocksize / 2;
1096 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1097 /* duration in samples per channel */
1098 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1099 p_stream->i_pcr = p_stream->i_previous_granulepos *
1100 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1101 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1103 #endif
1104 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1105 p_stream->i_previous_granulepos > 0 )
1107 i_duration = p_stream->special.speex.i_framesize *
1108 p_stream->special.speex.i_framesperpacket;
1109 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1110 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1111 p_stream->i_previous_granulepos, false );
1112 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1114 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1115 p_stream->i_previous_granulepos > 0 &&
1116 ( i_duration =
1117 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1119 ogg_int64_t sample;
1120 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1121 sample = p_stream->i_previous_granulepos;
1122 if (sample >= p_stream->i_pre_skip)
1123 sample -= p_stream->i_pre_skip;
1124 else
1125 sample = 0;
1127 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1128 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1130 else if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_UNKNOWN )
1132 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1134 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1136 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1137 p_stream->fmt.i_bitrate / 8 );
1141 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1144 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1145 block_t *p_block )
1147 demux_sys_t *p_ogg = p_demux->p_sys;
1148 if ( (!p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN) &&
1149 p_ogg->i_nzpcr_offset == 0 /* Not on chained streams */ )
1151 if ( !p_block ) return;
1152 if ( p_stream->prepcr.pp_blocks )
1154 assert( p_stream->prepcr.i_size );
1155 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1157 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1158 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1159 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1161 else
1163 /* Because ES creation is delayed for preparsing */
1164 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1165 if ( p_stream->p_preparse_block )
1167 block_t *temp = p_stream->p_preparse_block;
1168 while ( temp )
1170 if ( temp && i_firstpts < VLC_TS_0 )
1171 i_firstpts = temp->i_pts;
1173 block_t *tosend = temp;
1174 temp = temp->p_next;
1175 tosend->p_next = NULL;
1177 if( tosend->i_pts < VLC_TS_0 )
1179 /* Don't send metadata from chained streams */
1180 block_Release( tosend );
1181 continue;
1183 else if( tosend->i_dts < VLC_TS_0 )
1185 tosend->i_dts = tosend->i_pts;
1188 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1189 tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1190 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1192 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1194 p_ogg->i_pcr = i_firstpts;
1195 if( likely( !p_ogg->b_slave ) )
1196 es_out_SetPCR( p_demux->out, p_ogg->i_pcr );
1199 p_stream->p_preparse_block = NULL;
1202 if ( p_block )
1204 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1205 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1206 if ( p_stream->p_es )
1207 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1208 else
1209 block_Release( p_block );
1214 /****************************************************************************
1215 * Ogg_DecodePacket: Decode an Ogg packet.
1216 ****************************************************************************/
1217 static void Ogg_DecodePacket( demux_t *p_demux,
1218 logical_stream_t *p_stream,
1219 ogg_packet *p_oggpacket )
1221 demux_sys_t *p_sys = p_demux->p_sys;
1222 block_t *p_block;
1223 bool b_selected;
1224 int i_header_len = 0;
1226 if( p_oggpacket->bytes >= 7 &&
1227 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1229 /* it's an Annodex packet -- skip it (do nothing) */
1230 return;
1232 else if( p_oggpacket->bytes >= 7 &&
1233 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1235 /* it's an AnxData packet -- skip it (do nothing) */
1236 return;
1238 else if( p_oggpacket->bytes >= 8 &&
1239 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1241 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1242 return;
1244 else if( p_oggpacket->bytes >= 6 &&
1245 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1247 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1248 return;
1250 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1251 p_oggpacket->bytes >= 7 &&
1252 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1254 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1255 return;
1258 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1259 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1261 /* Check the ES is selected */
1262 if ( !p_stream->p_es )
1263 b_selected = true;
1264 else
1265 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1266 p_stream->p_es, &b_selected );
1268 if( p_stream->b_force_backup )
1270 bool b_xiph;
1271 p_stream->i_packets_backup++;
1272 switch( p_stream->fmt.i_codec )
1274 case VLC_CODEC_VORBIS:
1275 #ifdef HAVE_LIBVORBIS
1276 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1277 #endif
1278 /* fallthrough */
1279 case VLC_CODEC_THEORA:
1280 if( p_stream->i_packets_backup == 3 )
1281 p_stream->b_force_backup = false;
1282 b_xiph = true;
1283 break;
1285 case VLC_CODEC_DAALA:
1286 if( p_stream->i_packets_backup == 3 )
1287 p_stream->b_force_backup = false;
1288 b_xiph = true;
1289 break;
1291 case VLC_CODEC_SPEEX:
1292 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1293 p_stream->b_force_backup = false;
1294 b_xiph = true;
1295 break;
1297 case VLC_CODEC_OPUS:
1298 if( p_stream->i_packets_backup == 2 )
1299 p_stream->b_force_backup = false;
1300 b_xiph = true;
1301 break;
1303 case VLC_CODEC_FLAC:
1304 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1306 p_stream->b_force_backup = false;
1308 if( p_stream->special.flac.b_old )
1310 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1312 else if( p_stream->i_packets_backup == 1 )
1314 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1316 p_oggpacket->packet += 9;
1317 p_oggpacket->bytes -= 9;
1320 b_xiph = false;
1321 break;
1323 case VLC_CODEC_KATE:
1324 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1325 p_stream->b_force_backup = false;
1326 b_xiph = true;
1327 break;
1329 default:
1330 p_stream->b_force_backup = false;
1331 b_xiph = false;
1332 break;
1335 /* Backup the ogg packet (likely an header packet) */
1336 if( !b_xiph )
1338 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1339 if( p_realloc )
1341 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1342 p_stream->i_headers += p_oggpacket->bytes;
1343 p_stream->p_headers = p_realloc;
1345 else
1347 free( p_stream->p_headers );
1348 p_stream->i_headers = 0;
1349 p_stream->p_headers = NULL;
1352 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1353 p_oggpacket->bytes, p_oggpacket->packet ) )
1355 p_stream->i_headers = 0;
1356 p_stream->p_headers = NULL;
1358 if( p_stream->i_headers > 0 )
1360 if( !p_stream->b_force_backup )
1362 /* Last header received, commit changes */
1363 free( p_stream->fmt.p_extra );
1365 p_stream->fmt.i_extra = p_stream->i_headers;
1366 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1367 if( p_stream->fmt.p_extra )
1368 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1369 p_stream->i_headers );
1370 else
1371 p_stream->fmt.i_extra = 0;
1373 if( p_stream->i_headers > 0 )
1374 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1375 p_stream->p_headers, p_stream->i_headers );
1377 /* we're not at BOS anymore for this logical stream */
1378 p_stream->b_initializing = false;
1382 b_selected = false; /* Discard the header packet */
1384 else
1386 p_stream->b_initializing = false;
1389 /* Convert the granulepos into the next pcr */
1390 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1392 if( !b_selected )
1394 /* This stream isn't currently selected so we don't need to decode it,
1395 * but we did need to store its pcr as it might be selected later on */
1396 return;
1399 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1401 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1402 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1404 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1405 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1407 /* may need to preroll after a seek or in case of preskip */
1408 if ( p_stream->i_skip_frames > 0 )
1410 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1412 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1414 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1415 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1416 p_stream->i_skip_frames -= p_block->i_nb_samples;
1417 p_block->i_nb_samples = 0;
1419 else
1421 p_block->i_nb_samples -= p_stream->i_skip_frames;
1422 p_stream->i_skip_frames = 0;
1425 else
1427 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1428 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1429 p_stream->i_skip_frames--;
1433 /* Conditional block fixes */
1434 if ( p_stream->fmt.i_cat == VIDEO_ES )
1436 if( Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1437 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1439 if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1441 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1442 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1443 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1444 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1445 /* granulepos for dirac is possibly broken, this value should be ignored */
1446 if( 0 >= p_oggpacket->granulepos )
1448 p_block->i_pts = VLC_TS_INVALID;
1449 p_block->i_dts = p_stream->i_pcr;
1452 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1454 p_block->i_pts =
1455 p_block->i_dts = p_stream->i_pcr;
1457 else
1459 p_block->i_pts = VLC_TS_INVALID;
1460 p_block->i_dts = p_stream->i_pcr;
1463 else if( p_stream->fmt.i_cat == AUDIO_ES )
1465 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1466 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1467 p_stream->fmt.b_packetized )
1469 /* Handle OggFlac spec violation (multiple frame/packet
1470 * by turning on packetizer */
1471 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1472 p_stream->fmt.b_packetized = false;
1473 es_out_Del( p_demux->out, p_stream->p_es );
1474 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1476 else if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1478 /* FIXME: the biggest hack I've ever done */
1479 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1480 p_block->i_pts, p_block->i_dts );
1481 msleep(10000);
1484 /* Blatant abuse of the i_length field. */
1485 p_block->i_length = p_stream->i_end_trim;
1486 p_block->i_pts = p_block->i_dts = p_stream->i_pcr;
1488 else if( p_stream->fmt.i_cat == SPU_ES )
1490 p_block->i_length = 0;
1491 p_block->i_pts = p_block->i_dts = p_stream->i_pcr;
1494 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1495 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1496 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1497 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1498 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1499 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1500 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1501 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1502 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1503 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1504 p_stream->fmt.i_codec != VLC_CODEC_KATE &&
1505 p_stream->fmt.i_codec != VLC_CODEC_OGGSPOTS )
1507 if( p_oggpacket->bytes <= 0 )
1509 msg_Dbg( p_demux, "discarding 0 sized packet" );
1510 block_Release( p_block );
1511 return;
1513 /* We remove the header from the packet */
1514 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1515 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1517 if( i_header_len >= p_oggpacket->bytes )
1519 msg_Dbg( p_demux, "discarding invalid packet" );
1520 block_Release( p_block );
1521 return;
1524 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1526 /* But with subtitles we need to retrieve the duration first */
1527 int i, lenbytes = 0;
1529 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1531 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1533 lenbytes = lenbytes << 8;
1534 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1537 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1538 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1539 p_oggpacket->packet[i_header_len + 1] != 0 &&
1540 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1541 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1543 p_block->i_length = (mtime_t)lenbytes * 1000;
1547 i_header_len++;
1548 if( p_block->i_buffer >= (unsigned int)i_header_len )
1549 p_block->i_buffer -= i_header_len;
1550 else
1551 p_block->i_buffer = 0;
1554 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1555 p_oggpacket->bytes - i_header_len );
1557 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1560 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1562 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1565 /****************************************************************************
1566 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1567 * stream and fill p_ogg.
1568 *****************************************************************************
1569 * The initial page of a logical stream is marked as a 'bos' page.
1570 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1571 * together and all of the initial pages must appear before any data pages.
1573 * On success this function returns VLC_SUCCESS.
1574 ****************************************************************************/
1575 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1577 demux_sys_t *p_ogg = p_demux->p_sys ;
1578 ogg_packet oggpacket;
1580 p_ogg->i_total_length = stream_Size ( p_demux->s );
1581 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1584 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1587 if( ogg_page_bos( &p_ogg->current_page ) )
1590 /* All is wonderful in our fine fine little world.
1591 * We found the beginning of our first logical stream. */
1592 while( ogg_page_bos( &p_ogg->current_page ) )
1594 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1595 if( unlikely( !p_stream ) )
1596 return VLC_ENOMEM;
1598 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1600 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
1601 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
1602 p_stream->b_initializing = true;
1604 /* Setup the logical stream */
1605 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1606 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1608 /* Extract the initial header from the first page and verify
1609 * the codec type of this Ogg bitstream */
1610 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1612 /* error. stream version mismatch perhaps */
1613 msg_Err( p_demux, "error reading first page of "
1614 "Ogg bitstream data" );
1615 return VLC_EGENERIC;
1618 /* FIXME: check return value */
1619 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1621 /* Check for Vorbis header */
1622 if( oggpacket.bytes >= 7 &&
1623 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1625 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1626 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1627 msg_Dbg( p_demux, "found vorbis header" );
1628 else
1630 msg_Dbg( p_demux, "found invalid vorbis header" );
1631 Ogg_LogicalStreamDelete( p_demux, p_stream );
1632 p_stream = NULL;
1633 p_ogg->i_streams--;
1636 /* Check for Speex header */
1637 else if( oggpacket.bytes >= 5 &&
1638 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1640 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1641 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1642 msg_Dbg( p_demux, "found speex header, channels: %i, "
1643 "rate: %i, bitrate: %i, frames: %i group %i",
1644 p_stream->fmt.audio.i_channels,
1645 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1646 p_stream->special.speex.i_framesize,
1647 p_stream->special.speex.i_framesperpacket );
1648 else
1650 msg_Dbg( p_demux, "found invalid Speex header" );
1651 Ogg_LogicalStreamDelete( p_demux, p_stream );
1652 p_stream = NULL;
1653 p_ogg->i_streams--;
1656 /* Check for Opus header */
1657 else if( oggpacket.bytes >= 8 &&
1658 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1660 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1661 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1662 msg_Dbg( p_demux, "found opus header, channels: %i, "
1663 "pre-skip: %i",
1664 p_stream->fmt.audio.i_channels,
1665 (int)p_stream->i_pre_skip);
1666 p_stream->i_skip_frames = p_stream->i_pre_skip;
1668 /* Check for OLD Flac header */
1669 else if( oggpacket.bytes >= 4 &&
1670 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1672 msg_Dbg( p_demux, "found FLAC header" );
1674 /* Grrrr!!!! Did they really have to put all the
1675 * important info in the second header packet!!!
1676 * (STREAMINFO metadata is in the following packet) */
1677 p_stream->b_force_backup = true;
1678 p_stream->i_extra_headers_packets = 1;
1679 p_stream->special.flac.b_old = true;
1680 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1682 /* Check for Flac header (>= version 1.0.0) */
1683 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1684 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1685 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1687 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1688 oggpacket.packet[8];
1689 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1690 "(%i header packets)",
1691 oggpacket.packet[5], oggpacket.packet[6],
1692 i_packets );
1693 /* STREAMINFO is in current packet, and then
1694 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1695 p_stream->b_force_backup = true;
1696 p_stream->i_extra_headers_packets = i_packets;
1697 p_stream->special.flac.b_old = false;
1699 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1700 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1701 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1703 msg_Dbg( p_demux, "found invalid Flac header" );
1704 Ogg_LogicalStreamDelete( p_demux, p_stream );
1705 p_stream = NULL;
1706 p_ogg->i_streams--;
1709 /* Check for Theora header */
1710 else if( oggpacket.bytes >= 7 &&
1711 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1713 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1714 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1715 msg_Dbg( p_demux,
1716 "found theora header, bitrate: %i, rate: %f",
1717 p_stream->fmt.i_bitrate, p_stream->f_rate );
1718 else
1720 msg_Dbg( p_demux, "found invalid Theora header" );
1721 Ogg_LogicalStreamDelete( p_demux, p_stream );
1722 p_stream = NULL;
1723 p_ogg->i_streams--;
1726 /* Check for Daala header */
1727 else if( oggpacket.bytes >= 6 &&
1728 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1730 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1731 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1732 msg_Dbg( p_demux,
1733 "found daala header, bitrate: %i, rate: %f",
1734 p_stream->fmt.i_bitrate, p_stream->f_rate );
1735 else
1737 msg_Dbg( p_demux, "found invalid Daala header" );
1738 Ogg_LogicalStreamDelete( p_demux, p_stream );
1739 p_stream = NULL;
1740 p_ogg->i_streams--;
1743 /* Check for Dirac header */
1744 else if( ( oggpacket.bytes >= 5 &&
1745 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1746 ( oggpacket.bytes >= 9 &&
1747 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1749 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1750 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1751 msg_Dbg( p_demux, "found dirac header" );
1752 else
1754 msg_Warn( p_demux, "found dirac header isn't decodable" );
1755 Ogg_LogicalStreamDelete( p_demux, p_stream );
1756 p_stream = NULL;
1757 p_ogg->i_streams--;
1760 /* Check for Tarkin header */
1761 else if( oggpacket.bytes >= 7 &&
1762 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1764 oggpack_buffer opb;
1766 msg_Dbg( p_demux, "found tarkin header" );
1767 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_TARKIN );
1769 /* Cheat and get additionnal info ;) */
1770 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1771 oggpack_adv( &opb, 88 );
1772 oggpack_adv( &opb, 104 );
1773 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1774 p_stream->f_rate = 2; /* FIXME */
1775 msg_Dbg( p_demux,
1776 "found tarkin header, bitrate: %i, rate: %f",
1777 p_stream->fmt.i_bitrate, p_stream->f_rate );
1779 /* Check for VP8 header */
1780 else if( oggpacket.bytes >= 26 &&
1781 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1783 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1784 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1785 msg_Dbg( p_demux, "found VP8 header "
1786 "fps: %f, width:%i; height:%i",
1787 p_stream->f_rate,
1788 p_stream->fmt.video.i_width,
1789 p_stream->fmt.video.i_height );
1790 else
1792 msg_Dbg( p_demux, "invalid VP8 header found");
1793 Ogg_LogicalStreamDelete( p_demux, p_stream );
1794 p_stream = NULL;
1795 p_ogg->i_streams--;
1798 /* Check for Annodex header */
1799 else if( oggpacket.bytes >= 7 &&
1800 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1802 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1803 /* kill annodex track */
1804 FREENULL( p_stream );
1805 p_ogg->i_streams--;
1807 /* Check for Annodex header */
1808 else if( oggpacket.bytes >= 7 &&
1809 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1811 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1813 /* Check for Kate header */
1814 else if( oggpacket.bytes >= 8 &&
1815 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1817 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1818 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1819 msg_Dbg( p_demux, "found kate header" );
1820 else
1822 msg_Dbg( p_demux, "invalid kate header found");
1823 Ogg_LogicalStreamDelete( p_demux, p_stream );
1824 p_stream = NULL;
1825 p_ogg->i_streams--;
1828 /* Check for OggDS */
1829 else if( oggpacket.bytes >= 142 &&
1830 !memcmp( &oggpacket.packet[1],
1831 "Direct Show Samples embedded in Ogg", 35 ))
1833 /* Old header type */
1834 p_stream->b_oggds = true;
1835 /* Check for video header (old format) */
1836 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1837 oggpacket.bytes >= 184 )
1839 es_format_Change( &p_stream->fmt, VIDEO_ES,
1840 VLC_FOURCC( oggpacket.packet[68],
1841 oggpacket.packet[69],
1842 oggpacket.packet[70],
1843 oggpacket.packet[71] ) );
1844 msg_Dbg( p_demux, "found video header of type: %.4s",
1845 (char *)&p_stream->fmt.i_codec );
1847 p_stream->fmt.video.i_frame_rate = 10000000;
1848 p_stream->fmt.video.i_frame_rate_base =
1849 GetQWLE((oggpacket.packet+164));
1850 p_stream->fmt.video.i_frame_rate_base =
1851 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1852 p_stream->f_rate = 10000000.0 /
1853 p_stream->fmt.video.i_frame_rate_base;
1854 p_stream->fmt.video.i_bits_per_pixel =
1855 GetWLE((oggpacket.packet+182));
1856 if( !p_stream->fmt.video.i_bits_per_pixel )
1857 /* hack, FIXME */
1858 p_stream->fmt.video.i_bits_per_pixel = 24;
1859 p_stream->fmt.video.i_width =
1860 GetDWLE((oggpacket.packet+176));
1861 p_stream->fmt.video.i_height =
1862 GetDWLE((oggpacket.packet+180));
1863 p_stream->fmt.video.i_visible_width =
1864 p_stream->fmt.video.i_width;
1865 p_stream->fmt.video.i_visible_height =
1866 p_stream->fmt.video.i_height;
1868 msg_Dbg( p_demux,
1869 "fps: %f, width:%i; height:%i, bitcount:%i",
1870 p_stream->f_rate,
1871 p_stream->fmt.video.i_width,
1872 p_stream->fmt.video.i_height,
1873 p_stream->fmt.video.i_bits_per_pixel);
1876 /* Check for audio header (old format) */
1877 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1879 int i_extra_size;
1880 unsigned int i_format_tag;
1882 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1884 i_extra_size = GetWLE((oggpacket.packet+140));
1885 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1887 p_stream->fmt.i_extra = i_extra_size;
1888 p_stream->fmt.p_extra = malloc( i_extra_size );
1889 if( p_stream->fmt.p_extra )
1890 memcpy( p_stream->fmt.p_extra,
1891 oggpacket.packet + 142, i_extra_size );
1892 else
1893 p_stream->fmt.i_extra = 0;
1896 i_format_tag = GetWLE((oggpacket.packet+124));
1897 p_stream->fmt.audio.i_channels =
1898 GetWLE((oggpacket.packet+126));
1899 fill_channels_info(&p_stream->fmt.audio);
1900 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1901 GetDWLE((oggpacket.packet+128));
1902 p_stream->fmt.i_bitrate =
1903 GetDWLE((oggpacket.packet+132)) * 8;
1904 p_stream->fmt.audio.i_blockalign =
1905 GetWLE((oggpacket.packet+136));
1906 p_stream->fmt.audio.i_bitspersample =
1907 GetWLE((oggpacket.packet+138));
1909 wf_tag_to_fourcc( i_format_tag,
1910 &p_stream->fmt.i_codec, 0 );
1912 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1914 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1915 ( i_format_tag >> 8 ) & 0xff,
1916 i_format_tag & 0xff );
1919 msg_Dbg( p_demux, "found audio header of type: %.4s",
1920 (char *)&p_stream->fmt.i_codec );
1921 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1922 "%dbits/sample %dkb/s",
1923 i_format_tag,
1924 p_stream->fmt.audio.i_channels,
1925 p_stream->fmt.audio.i_rate,
1926 p_stream->fmt.audio.i_bitspersample,
1927 p_stream->fmt.i_bitrate / 1024 );
1928 if ( p_stream->f_rate == 0 )
1930 msg_Dbg( p_demux, "invalid oggds audio header" );
1931 Ogg_LogicalStreamDelete( p_demux, p_stream );
1932 p_stream = NULL;
1933 p_ogg->i_streams--;
1936 else
1938 msg_Dbg( p_demux, "stream %d has an old header "
1939 "but is of an unknown type", p_ogg->i_streams-1 );
1940 FREENULL( p_stream );
1941 p_ogg->i_streams--;
1944 /* Check for OggDS */
1945 else if( oggpacket.bytes >= 44+1 &&
1946 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1948 stream_header_t tmp;
1949 stream_header_t *st = &tmp;
1951 p_stream->b_oggds = true;
1953 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1954 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1955 st->size = GetDWLE( &oggpacket.packet[1+12] );
1956 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1957 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1958 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1959 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1960 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1962 /* Check for video header (new format) */
1963 if( !strncmp( st->streamtype, "video", 5 ) &&
1964 oggpacket.bytes >= 52+1 )
1966 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1967 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1969 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1971 /* We need to get rid of the header packet */
1972 ogg_stream_packetout( &p_stream->os, &oggpacket );
1974 p_stream->fmt.i_codec =
1975 VLC_FOURCC( st->subtype[0], st->subtype[1],
1976 st->subtype[2], st->subtype[3] );
1977 msg_Dbg( p_demux, "found video header of type: %.4s",
1978 (char *)&p_stream->fmt.i_codec );
1980 p_stream->fmt.video.i_frame_rate = 10000000;
1981 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1982 if( st->time_unit <= 0 )
1983 st->time_unit = 400000;
1984 p_stream->f_rate = 10000000.0 / st->time_unit;
1985 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1986 p_stream->fmt.video.i_width = st->sh.video.width;
1987 p_stream->fmt.video.i_height = st->sh.video.height;
1988 p_stream->fmt.video.i_visible_width =
1989 p_stream->fmt.video.i_width;
1990 p_stream->fmt.video.i_visible_height =
1991 p_stream->fmt.video.i_height;
1993 msg_Dbg( p_demux,
1994 "fps: %f, width:%i; height:%i, bitcount:%i",
1995 p_stream->f_rate,
1996 p_stream->fmt.video.i_width,
1997 p_stream->fmt.video.i_height,
1998 p_stream->fmt.video.i_bits_per_pixel );
2000 /* Check for audio header (new format) */
2001 else if( !strncmp( st->streamtype, "audio", 5 ) &&
2002 oggpacket.bytes >= 56+1 )
2004 char p_buffer[5];
2005 int i_extra_size;
2006 int i_format_tag;
2008 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
2009 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
2010 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
2012 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
2014 /* We need to get rid of the header packet */
2015 ogg_stream_packetout( &p_stream->os, &oggpacket );
2017 i_extra_size = st->size - 56;
2019 if( i_extra_size > 0 &&
2020 i_extra_size < oggpacket.bytes - 1 - 56 )
2022 p_stream->fmt.i_extra = i_extra_size;
2023 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
2024 if( p_stream->fmt.p_extra )
2025 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
2026 p_stream->fmt.i_extra );
2027 else
2028 p_stream->fmt.i_extra = 0;
2031 memcpy( p_buffer, st->subtype, 4 );
2032 p_buffer[4] = '\0';
2033 i_format_tag = strtol(p_buffer,NULL,16);
2034 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
2035 fill_channels_info(&p_stream->fmt.audio);
2036 if( st->time_unit <= 0 )
2037 st->time_unit = 10000000;
2038 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
2039 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
2040 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
2041 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
2043 wf_tag_to_fourcc( i_format_tag,
2044 &p_stream->fmt.i_codec, 0 );
2046 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
2048 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
2049 ( i_format_tag >> 8 ) & 0xff,
2050 i_format_tag & 0xff );
2053 msg_Dbg( p_demux, "found audio header of type: %.4s",
2054 (char *)&p_stream->fmt.i_codec );
2055 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2056 "%dbits/sample %dkb/s",
2057 i_format_tag,
2058 p_stream->fmt.audio.i_channels,
2059 p_stream->fmt.audio.i_rate,
2060 p_stream->fmt.audio.i_bitspersample,
2061 p_stream->fmt.i_bitrate / 1024 );
2062 if ( p_stream->f_rate == 0 )
2064 msg_Dbg( p_demux, "invalid oggds audio header" );
2065 Ogg_LogicalStreamDelete( p_demux, p_stream );
2066 p_stream = NULL;
2067 p_ogg->i_streams--;
2070 /* Check for text (subtitles) header */
2071 else if( !strncmp(st->streamtype, "text", 4) )
2073 /* We need to get rid of the header packet */
2074 ogg_stream_packetout( &p_stream->os, &oggpacket );
2076 msg_Dbg( p_demux, "found text subtitle header" );
2077 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2078 p_stream->f_rate = 1000; /* granulepos is in millisec */
2080 else
2082 msg_Dbg( p_demux, "stream %d has a header marker "
2083 "but is of an unknown type", p_ogg->i_streams-1 );
2084 FREENULL( p_stream );
2085 p_ogg->i_streams--;
2088 else if( oggpacket.bytes >= 8 &&
2089 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2092 /* Skeleton */
2093 msg_Dbg( p_demux, "stream %d is a skeleton",
2094 p_ogg->i_streams-1 );
2095 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2097 /* Check for OggSpots header */
2098 else if( oggpacket.bytes >= 8 &&
2099 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2101 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2102 msg_Dbg( p_demux,
2103 "found OggSpots header, time resolution: %f",
2104 p_stream->f_rate );
2105 else
2107 msg_Err( p_demux, "found invalid OggSpots header" );
2108 Ogg_LogicalStreamDelete( p_demux, p_stream );
2109 p_stream = NULL;
2110 p_ogg->i_streams--;
2113 else
2115 msg_Dbg( p_demux, "stream %d is of unknown type",
2116 p_ogg->i_streams-1 );
2119 /* we'll need to get all headers */
2120 if ( p_stream )
2121 p_stream->b_initializing &= p_stream->b_force_backup;
2123 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2124 return VLC_EGENERIC;
2127 /* This is the first data page, which means we are now finished
2128 * with the initial pages. We just need to store it in the relevant
2129 * bitstream. */
2130 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2132 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2133 &p_ogg->current_page ) == 0 )
2135 p_ogg->b_page_waiting = true;
2136 break;
2140 return VLC_SUCCESS;
2144 return VLC_EGENERIC;
2147 /****************************************************************************
2148 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2149 ****************************************************************************/
2150 static void Ogg_CreateES( demux_t *p_demux )
2152 demux_sys_t *p_ogg = p_demux->p_sys;
2153 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2154 int i_stream;
2156 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2158 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2160 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2162 /* Better be safe than sorry when possible with ogm */
2163 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2164 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2165 p_stream->fmt.b_packetized = false;
2167 /* Try first to reuse an old ES */
2168 if( p_old_stream &&
2169 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2170 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2172 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2174 p_stream->p_es = p_old_stream->p_es;
2175 p_stream->b_finished = false;
2176 p_stream->b_reinit = false;
2177 p_stream->b_initializing = false;
2178 p_stream->i_pre_skip = 0;
2179 es_format_Clean( &p_stream->fmt_old );
2180 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2181 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2183 p_old_stream->p_es = NULL;
2184 p_old_stream = NULL;
2185 if ( b_resetdecoder )
2187 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2188 p_stream->p_es, &p_stream->fmt );
2191 else
2193 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2196 // TODO: something to do here ?
2197 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2199 /* Set the CMML stream active */
2200 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2205 if( p_ogg->p_old_stream )
2207 if( p_ogg->p_old_stream->p_es )
2208 msg_Dbg( p_demux, "old stream not reused" );
2209 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2210 p_ogg->p_old_stream = NULL;
2212 p_ogg->b_es_created = true;
2215 /****************************************************************************
2216 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2217 * Elementary streams.
2218 ****************************************************************************/
2219 static int Ogg_BeginningOfStream( demux_t *p_demux )
2221 demux_sys_t *p_ogg = p_demux->p_sys ;
2222 int i_stream;
2224 /* Find the logical streams embedded in the physical stream and
2225 * initialize our p_ogg structure. */
2226 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2228 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2229 return VLC_EGENERIC;
2232 p_ogg->i_bitrate = 0;
2234 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2236 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2238 p_stream->p_es = NULL;
2240 /* initialise kframe index */
2241 p_stream->idx=NULL;
2243 if ( p_stream->fmt.i_bitrate == 0 &&
2244 ( p_stream->fmt.i_cat == VIDEO_ES ||
2245 p_stream->fmt.i_cat == AUDIO_ES ) )
2246 p_ogg->b_partial_bitrate = true;
2247 else
2248 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2250 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2251 p_stream->i_previous_granulepos = -1;
2252 p_stream->b_reinit = false;
2255 /* get total frame count for video stream; we will need this for seeking */
2256 p_ogg->i_total_frames = 0;
2258 return VLC_SUCCESS;
2261 /****************************************************************************
2262 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2263 ****************************************************************************/
2264 static void Ogg_EndOfStream( demux_t *p_demux )
2266 demux_sys_t *p_ogg = p_demux->p_sys ;
2267 int i_stream;
2269 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2270 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2271 free( p_ogg->pp_stream );
2273 /* Reinit p_ogg */
2274 p_ogg->i_bitrate = 0;
2275 p_ogg->i_streams = 0;
2276 p_ogg->pp_stream = NULL;
2277 p_ogg->skeleton.major = 0;
2278 p_ogg->skeleton.minor = 0;
2279 p_ogg->b_preparsing_done = false;
2280 p_ogg->b_es_created = false;
2282 /* */
2283 if( p_ogg->p_meta )
2284 vlc_meta_Delete( p_ogg->p_meta );
2285 p_ogg->p_meta = NULL;
2287 for(int i=0; i<p_ogg->i_attachments; i++)
2288 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2289 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2291 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2293 if ( p_ogg->pp_seekpoints[i] )
2294 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2296 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2299 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2301 #ifdef HAVE_LIBVORBIS
2302 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2304 if( p_stream->special.vorbis.p_info )
2305 vorbis_info_clear( p_stream->special.vorbis.p_info );
2306 FREENULL( p_stream->special.vorbis.p_info );
2307 if( p_stream->special.vorbis.p_comment )
2308 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2309 FREENULL( p_stream->special.vorbis.p_comment );
2310 p_stream->special.vorbis.i_headers_flags = 0;
2312 #else
2313 VLC_UNUSED( p_stream );
2314 #endif
2318 * This function delete and release all data associated to a logical_stream_t
2320 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2322 demux_sys_t *p_sys = p_demux->p_sys;
2324 if( p_stream->p_es )
2325 es_out_Del( p_demux->out, p_stream->p_es );
2327 ogg_stream_clear( &p_stream->os );
2328 free( p_stream->p_headers );
2330 Ogg_CleanSpecificData( p_stream );
2332 es_format_Clean( &p_stream->fmt_old );
2333 es_format_Clean( &p_stream->fmt );
2335 if ( p_stream->idx != NULL)
2337 oggseek_index_entries_free( p_stream->idx );
2340 Ogg_FreeSkeleton( p_stream->p_skel );
2341 p_stream->p_skel = NULL;
2342 if( p_sys->p_skelstream == p_stream )
2343 p_sys->p_skelstream = NULL;
2345 /* Shouldn't happen */
2346 if ( unlikely( p_stream->p_preparse_block ) )
2348 block_ChainRelease( p_stream->p_preparse_block );
2349 p_stream->p_preparse_block = NULL;
2351 free( p_stream->prepcr.pp_blocks );
2353 free( p_stream );
2356 * This function check if a we need to reset a decoder in case we are
2357 * reusing an old ES
2359 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2361 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2362 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2363 unsigned i_new_count;
2364 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2365 i_new_count = 0;
2367 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2368 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2369 unsigned i_old_count;
2370 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2371 i_old_count = 0;
2373 bool b_match = i_new_count == i_old_count;
2374 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2376 /* Ignore vorbis comment */
2377 if( i == 1 )
2378 continue;
2379 if( pi_new_size[i] != pi_old_size[i] ||
2380 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2381 b_match = false;
2384 return b_match;
2387 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2388 const es_format_t *p_old )
2390 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2391 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2392 unsigned i_new_count;
2393 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2394 i_new_count = 0;
2395 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2396 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2397 unsigned i_old_count;
2398 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2399 i_old_count = 0;
2400 bool b_match = false;
2401 if( i_new_count == i_old_count && i_new_count > 0 )
2403 static const unsigned char default_map[2] = { 0, 1 };
2404 unsigned char *p_old_head;
2405 unsigned char *p_new_head;
2406 const unsigned char *p_old_map;
2407 const unsigned char *p_new_map;
2408 int i_old_channel_count;
2409 int i_new_channel_count;
2410 int i_old_stream_count;
2411 int i_new_stream_count;
2412 int i_old_coupled_count;
2413 int i_new_coupled_count;
2414 p_old_head = (unsigned char *)pp_old_data[0];
2415 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2416 p_old_map = default_map;
2417 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2419 i_old_channel_count = p_old_head[9];
2420 switch( p_old_head[18] )
2422 case 0:
2423 i_old_stream_count = 1;
2424 i_old_coupled_count = i_old_channel_count - 1;
2425 break;
2426 case 1:
2427 if( pi_old_size[0] >= 21U + i_old_channel_count )
2429 i_old_stream_count = p_old_head[19];
2430 i_old_coupled_count = p_old_head[20];
2431 p_old_map = p_old_head + 21;
2433 break;
2436 p_new_head = (unsigned char *)pp_new_data[0];
2437 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2438 p_new_map = default_map;
2439 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2441 i_new_channel_count = p_new_head[9];
2442 switch( p_new_head[18] )
2444 case 0:
2445 i_new_stream_count = 1;
2446 i_new_coupled_count = i_new_channel_count - 1;
2447 break;
2448 case 1:
2449 if( pi_new_size[0] >= 21U + i_new_channel_count )
2451 i_new_stream_count = p_new_head[19];
2452 i_new_coupled_count = p_new_head[20];
2453 p_new_map = p_new_head+21;
2455 break;
2458 b_match = i_old_channel_count == i_new_channel_count &&
2459 i_old_stream_count == i_new_stream_count &&
2460 i_old_coupled_count == i_new_coupled_count &&
2461 memcmp(p_old_map, p_new_map,
2462 i_new_channel_count*sizeof(*p_new_map)) == 0;
2465 return b_match;
2468 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2470 bool b_compatible = false;
2471 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2472 return true;
2474 /* Only Vorbis and Opus are supported. */
2475 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2476 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2477 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2478 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2480 if( !b_compatible )
2481 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2483 return !b_compatible;
2486 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2487 const void *p_headers, unsigned i_headers )
2489 demux_sys_t *p_ogg = p_demux->p_sys;
2490 int i_cover_score = 0;
2491 int i_cover_idx = 0;
2492 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2493 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2494 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2496 pf_replay_gain[i] = 0;
2497 pf_replay_peak[i] = 0;
2499 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2500 &p_ogg->i_attachments, &p_ogg->attachments,
2501 &i_cover_score, &i_cover_idx,
2502 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2503 &pf_replay_gain, &pf_replay_peak );
2504 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2506 char psz_url[128];
2507 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2508 p_ogg->attachments[i_cover_idx]->psz_name );
2509 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2512 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2514 if ( pf_replay_gain[i] != 0 )
2516 p_fmt->audio_replay_gain.pb_gain[i] = true;
2517 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2518 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2520 if ( pf_replay_peak[i] != 0 )
2522 p_fmt->audio_replay_gain.pb_peak[i] = true;
2523 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2524 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2528 if( p_ogg->i_seekpoints > 1 )
2530 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2534 static inline uint32_t GetDW24BE( const uint8_t *p )
2536 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2537 #ifdef WORDS_BIGENDIAN
2538 i = bswap32(i);
2539 #endif
2540 return i;
2543 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2544 const uint8_t *p_headers, unsigned i_headers )
2546 /* Skip Streaminfo 42 bytes / 1st page */
2547 if(i_headers <= 46)
2548 return;
2549 p_headers += 42; i_headers -= 42;
2550 /* Block Header 1 + 3 bytes */
2551 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2552 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2554 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2558 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2559 const void *p_headers, unsigned i_headers, unsigned i_skip )
2561 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2562 void *pp_data[XIPH_MAX_HEADER_COUNT];
2563 unsigned i_count;
2565 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2566 return;
2567 /* TODO how to handle multiple comments properly ? */
2568 if( i_count >= 2 && pi_size[1] > i_skip )
2570 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2574 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2576 demux_sys_t *p_ogg = p_demux->p_sys;
2578 switch( p_fmt->i_codec )
2580 /* 3 headers with the 2° one being the comments */
2581 case VLC_CODEC_VORBIS:
2582 case VLC_CODEC_THEORA:
2583 case VLC_CODEC_DAALA:
2584 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2585 break;
2586 case VLC_CODEC_OPUS:
2587 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2588 break;
2589 case VLC_CODEC_SPEEX:
2590 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2591 break;
2592 case VLC_CODEC_VP8:
2593 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2594 break;
2595 /* N headers with the 2° one being the comments */
2596 case VLC_CODEC_KATE:
2597 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2598 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2599 break;
2601 /* TODO */
2602 case VLC_CODEC_FLAC:
2603 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2604 break;
2606 /* No meta data */
2607 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2608 case VLC_CODEC_DIRAC:
2609 default:
2610 break;
2612 if( p_ogg->p_meta )
2613 p_demux->info.i_update |= INPUT_UPDATE_META;
2616 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2617 ogg_packet *p_oggpacket )
2619 bs_t bitstream;
2620 unsigned int i_fps_numerator;
2621 unsigned int i_fps_denominator;
2622 int i_keyframe_frequency_force;
2623 int i_major;
2624 int i_minor;
2625 int i_subminor;
2626 int i_version;
2628 /* Signal that we want to keep a backup of the theora
2629 * stream headers. They will be used when switching between
2630 * audio streams. */
2631 p_stream->b_force_backup = true;
2633 /* Cheat and get additionnal info ;) */
2634 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2635 bs_skip( &bitstream, 56 );
2637 i_major = bs_read( &bitstream, 8 ); /* major version num */
2638 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2639 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2641 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2642 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2643 bs_read( &bitstream, 24 ); /* frame width */
2644 bs_read( &bitstream, 24 ); /* frame height */
2645 bs_read( &bitstream, 8 ); /* x offset */
2646 bs_read( &bitstream, 8 ); /* y offset */
2648 i_fps_numerator = bs_read( &bitstream, 32 );
2649 i_fps_denominator = bs_read( &bitstream, 32 );
2650 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2651 bs_read( &bitstream, 24 ); /* aspect_numerator */
2652 bs_read( &bitstream, 24 ); /* aspect_denominator */
2654 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2655 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2657 bs_read( &bitstream, 8 ); /* colorspace */
2658 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2659 bs_read( &bitstream, 6 ); /* quality */
2661 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2663 /* granule_shift = i_log( frequency_force -1 ) */
2664 p_stream->i_granule_shift = 0;
2665 i_keyframe_frequency_force--;
2666 while( i_keyframe_frequency_force )
2668 p_stream->i_granule_shift++;
2669 i_keyframe_frequency_force >>= 1;
2672 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2673 p_stream->i_keyframe_offset = 0;
2674 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2675 if ( p_stream->f_rate == 0 ) return false;
2677 if ( i_version >= 3002001 )
2679 p_stream->i_keyframe_offset = 1;
2681 return true;
2684 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2685 ogg_packet *p_oggpacket )
2687 oggpack_buffer opb;
2688 uint32_t i_timebase_numerator;
2689 uint32_t i_timebase_denominator;
2690 int i_keyframe_frequency_force;
2691 uint8_t i_major;
2692 uint8_t i_minor;
2693 uint8_t i_subminor;
2694 int i_version;
2696 /* Signal that we want to keep a backup of the daala
2697 * stream headers. They will be used when switching between
2698 * audio streams. */
2699 p_stream->b_force_backup = true;
2701 /* Cheat and get additionnal info ;) */
2702 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2703 oggpack_adv( &opb, 48 );
2705 i_major = oggpack_read( &opb, 8 ); /* major version num */
2706 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2707 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2709 oggpack_adv( &opb, 32 ); /* width */
2710 oggpack_adv( &opb, 32 ); /* height */
2712 oggpack_adv( &opb, 32 ); /* aspect numerator */
2713 oggpack_adv( &opb, 32 ); /* aspect denominator */
2714 i_timebase_numerator = oggpack_read( &opb, 32 );
2716 i_timebase_denominator = oggpack_read( &opb, 32 );
2717 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2719 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2720 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2722 oggpack_adv( &opb, 32 ); /* frame duration */
2724 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2726 /* granule_shift = i_log( frequency_force -1 ) */
2727 p_stream->i_granule_shift = 0;
2728 i_keyframe_frequency_force--;
2729 while( i_keyframe_frequency_force )
2731 p_stream->i_granule_shift++;
2732 i_keyframe_frequency_force >>= 1;
2735 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2736 VLC_UNUSED(i_version);
2737 p_stream->i_keyframe_offset = 0;
2738 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2739 if ( p_stream->f_rate == 0 ) return false;
2741 return true;
2744 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2745 ogg_packet *p_oggpacket )
2747 oggpack_buffer opb;
2749 /* Signal that we want to keep a backup of the vorbis
2750 * stream headers. They will be used when switching between
2751 * audio streams. */
2752 p_stream->b_force_backup = true;
2754 /* Cheat and get additionnal info ;) */
2755 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2756 oggpack_adv( &opb, 88 );
2757 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2758 fill_channels_info(&p_stream->fmt.audio);
2759 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2760 oggpack_read( &opb, 32 );
2761 oggpack_adv( &opb, 32 );
2762 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2763 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2764 if ( p_stream->f_rate == 0 ) return false;
2765 return true;
2767 #ifdef HAVE_LIBVORBIS
2768 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2769 ogg_packet *p_oggpacket, int i_number )
2771 switch( i_number )
2773 case VORBIS_HEADER_IDENTIFICATION:
2774 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2775 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2776 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2778 FREENULL( p_stream->special.vorbis.p_info );
2779 FREENULL( p_stream->special.vorbis.p_comment );
2780 break;
2782 vorbis_info_init( p_stream->special.vorbis.p_info );
2783 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2784 /* fallthrough */
2786 case VORBIS_HEADER_COMMENT:
2787 case VORBIS_HEADER_SETUP:
2788 if ( !p_stream->special.vorbis.p_info ||
2789 vorbis_synthesis_headerin(
2790 p_stream->special.vorbis.p_info,
2791 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2792 break;
2794 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2795 /* fallthrough */
2797 default:
2798 break;
2801 #endif
2803 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2804 ogg_packet *p_oggpacket )
2806 oggpack_buffer opb;
2808 /* Signal that we want to keep a backup of the speex
2809 * stream headers. They will be used when switching between
2810 * audio streams. */
2811 p_stream->b_force_backup = true;
2813 /* Cheat and get additionnal info ;) */
2814 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2815 oggpack_adv( &opb, 224 );
2816 oggpack_adv( &opb, 32 ); /* speex_version_id */
2817 oggpack_adv( &opb, 32 ); /* header_size */
2818 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2819 if ( p_stream->f_rate == 0 ) return false;
2820 oggpack_adv( &opb, 32 ); /* mode */
2821 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2822 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2823 fill_channels_info(&p_stream->fmt.audio);
2824 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2825 p_stream->special.speex.i_framesize =
2826 oggpack_read( &opb, 32 ); /* frame_size */
2827 oggpack_adv( &opb, 32 ); /* vbr */
2828 p_stream->special.speex.i_framesperpacket =
2829 oggpack_read( &opb, 32 ); /* frames_per_packet */
2830 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2831 return true;
2834 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2835 ogg_packet *p_oggpacket )
2837 oggpack_buffer opb;
2839 /* Signal that we want to keep a backup of the opus
2840 * stream headers. They will be used when switching between
2841 * audio streams. */
2842 p_stream->b_force_backup = true;
2844 /* All OggOpus streams are timestamped at 48kHz and
2845 * can be played at 48kHz. */
2846 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2847 p_stream->fmt.i_bitrate = 0;
2849 /* Cheat and get additional info ;) */
2850 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2851 oggpack_adv( &opb, 64 );
2852 oggpack_adv( &opb, 8 ); /* version_id */
2853 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2854 fill_channels_info(&p_stream->fmt.audio);
2855 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2856 /* For Opus, trash the first 80 ms of decoded output as
2857 well, to avoid blowing out speakers if we get unlucky.
2858 Opus predicts content from prior frames, which can go
2859 badly if we seek right where the stream goes from very
2860 quiet to very loud. It will converge after a bit. */
2861 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2864 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2865 ogg_packet *p_oggpacket )
2867 /* Parse the STREAMINFO metadata */
2868 bs_t s;
2870 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2872 bs_read( &s, 1 );
2873 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2875 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2876 return false;
2879 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2881 bs_skip( &s, 80 );
2882 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2883 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2884 fill_channels_info(&p_stream->fmt.audio);
2886 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2887 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2888 if ( p_stream->f_rate == 0 ) return false;
2890 else
2892 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2895 /* Fake this as the last metadata block */
2896 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2897 return true;
2900 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2901 ogg_packet *p_oggpacket )
2903 oggpack_buffer opb;
2904 uint32_t gnum;
2905 uint32_t gden;
2906 int n;
2907 char *psz_desc;
2909 /* Signal that we want to keep a backup of the kate
2910 * stream headers. They will be used when switching between
2911 * kate streams. */
2912 p_stream->b_force_backup = true;
2914 /* Cheat and get additionnal info ;) */
2915 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2916 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2917 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2918 oggpack_adv( &opb, 3*8 );
2919 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2920 oggpack_adv( &opb, 8*8 ); /* reserved */
2921 gnum = oggpack_read( &opb, 32 );
2922 gden = oggpack_read( &opb, 32 );
2923 gden = __MAX( gden, 1 );
2924 p_stream->f_rate = (double)gnum/gden;
2925 if ( p_stream->f_rate == 0 ) return false;
2927 p_stream->fmt.psz_language = malloc(16);
2928 if( p_stream->fmt.psz_language )
2930 for( n = 0; n < 16; n++ )
2931 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2932 p_stream->fmt.psz_language[15] = 0; /* just in case */
2934 else
2936 for( n = 0; n < 16; n++ )
2937 oggpack_read(&opb,8);
2939 p_stream->fmt.psz_description = malloc(16);
2940 if( p_stream->fmt.psz_description )
2942 for( n = 0; n < 16; n++ )
2943 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2944 p_stream->fmt.psz_description[15] = 0; /* just in case */
2946 /* Now find a localized user readable description for this category */
2947 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2948 if( psz_desc )
2950 free( p_stream->fmt.psz_description );
2951 p_stream->fmt.psz_description = psz_desc;
2954 else
2956 for( n = 0; n < 16; n++ )
2957 oggpack_read(&opb,8);
2960 return true;
2963 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2964 ogg_packet *p_oggpacket )
2966 switch( p_oggpacket->packet[5] )
2968 /* STREAMINFO */
2969 case 0x01:
2970 /* Mapping version */
2971 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2972 return false;
2973 p_stream->i_granule_shift = 32;
2974 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2975 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2976 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2977 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2978 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2979 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2980 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2981 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2982 p_stream->fmt.video.i_frame_rate_base =
2983 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2984 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2985 if ( p_stream->f_rate == 0 ) return false;
2986 return true;
2987 /* METADATA */
2988 case 0x02:
2989 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2990 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2991 return true;
2992 default:
2993 return false;
2997 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2998 bool *b_force_backup, bool *b_packet_out )
3000 if( p_stream->fmt.i_cat != UNKNOWN_ES )
3001 return;
3003 if( !strncmp(psz_value, "audio/x-wav", 11) )
3005 /* n.b. WAVs are unsupported right now */
3006 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3007 free( p_stream->fmt.psz_description );
3008 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
3010 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
3011 !strncmp(psz_value, "audio/vorbis", 12) )
3013 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
3015 *b_force_backup = true;
3017 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
3018 !strncmp(psz_value, "audio/speex", 11) )
3020 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
3022 *b_force_backup = true;
3024 else if( !strncmp(psz_value, "audio/flac", 10) )
3026 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
3028 *b_force_backup = true;
3030 else if( !strncmp(psz_value, "video/x-theora", 14) ||
3031 !strncmp(psz_value, "video/theora", 12) )
3033 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
3035 *b_force_backup = true;
3037 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3038 !strncmp(psz_value, "video/daala", 11) )
3040 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
3042 *b_force_backup = true;
3044 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3046 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
3048 *b_force_backup = true;
3050 else if( !strncmp(psz_value, "video/mpeg", 10) )
3052 /* n.b. MPEG streams are unsupported right now */
3053 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3055 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
3056 !strncmp(psz_value, "text/cmml", 9) )
3058 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_CMML );
3059 *b_packet_out = true;
3061 else if( !strncmp(psz_value, "application/kate", 16) )
3063 /* ??? */
3064 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3065 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3067 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3069 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3073 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3074 logical_stream_t *p_stream,
3075 ogg_packet *p_oggpacket )
3077 if( p_oggpacket->bytes >= 28 &&
3078 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3080 oggpack_buffer opb;
3082 uint16_t major_version;
3083 uint16_t minor_version;
3084 uint64_t timebase_numerator;
3085 uint64_t timebase_denominator;
3087 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3089 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3090 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3091 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3092 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3093 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3094 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3096 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3097 "Timebase %"PRId64" / %"PRId64,
3098 major_version, minor_version,
3099 timebase_numerator, timebase_denominator );
3101 else if( p_oggpacket->bytes >= 42 &&
3102 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3104 uint64_t granule_rate_numerator;
3105 uint64_t granule_rate_denominator;
3106 char content_type_string[1024];
3108 /* Read in Annodex header fields */
3110 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3111 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3112 p_stream->i_secondary_header_packets =
3113 GetDWLE( &p_oggpacket->packet[24] );
3115 /* we are guaranteed that the first header field will be
3116 * the content-type (by the Annodex standard) */
3117 content_type_string[0] = '\0';
3118 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3120 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3121 p_oggpacket->bytes - 1 );
3122 if( p && p[0] == '\r' && p[1] == '\n' )
3123 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3124 content_type_string );
3127 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3128 granule_rate_numerator, granule_rate_denominator,
3129 p_stream->i_secondary_header_packets, content_type_string );
3131 p_stream->f_rate = (float) granule_rate_numerator /
3132 (float) granule_rate_denominator;
3134 /* What type of file do we have?
3135 * strcmp is safe to use here because we've extracted
3136 * content_type_string from the stream manually */
3137 bool b_dopacketout = false;
3138 Ogg_ApplyContentType( p_stream, content_type_string,
3139 &p_stream->b_force_backup, &b_dopacketout );
3140 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3144 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3145 ogg_packet *p_oggpacket )
3147 demux_sys_t *p_sys = p_demux->p_sys;
3149 p_sys->p_skelstream = p_stream;
3150 /* There can be only 1 skeleton for streams */
3151 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3152 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3153 if ( asprintf( & p_stream->fmt.psz_description,
3154 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3155 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3156 p_stream->fmt.psz_description = NULL;
3159 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3161 demux_sys_t *p_sys = p_demux->p_sys;
3163 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3165 /* Find the matching stream for this skeleton data */
3166 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3167 logical_stream_t *p_target_stream = NULL;
3168 for ( int i=0; i< p_sys->i_streams; i++ )
3170 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3172 p_target_stream = p_sys->pp_stream[i];
3173 break;
3176 if ( !p_target_stream ) return;
3178 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3179 if ( !p_skel )
3181 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3182 if ( !p_skel ) return;
3183 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3184 p_skel->p_index = NULL;
3185 p_target_stream->p_skel = p_skel;
3188 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3189 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3190 const unsigned char *p = p_messages;
3191 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3193 if ( *p == 0x0D && *(p+1) == 0x0A )
3195 char *psz_message = strndup( (const char *) p_messages,
3196 p - p_messages );
3197 if ( psz_message )
3199 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3200 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3202 if ( p < p_boundary - 1 ) p_messages = p + 2;
3204 p++;
3209 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3210 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3211 unsigned const char *p_end,
3212 uint64_t *pi_value )
3214 int i_shift = 0;
3215 int64_t i_read = 0;
3216 *pi_value = 0;
3218 while ( p_begin < p_end )
3220 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3221 *pi_value = *pi_value | ( i_read << i_shift );
3222 i_shift += 7;
3223 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3226 *pi_value = GetQWLE( pi_value );
3227 return p_begin;
3230 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3232 demux_sys_t *p_sys = p_demux->p_sys;
3234 if( p_sys->skeleton.major < 4
3235 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3236 ) return;
3238 /* Find the matching stream for this skeleton data */
3239 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3240 logical_stream_t *p_stream = NULL;
3241 for ( int i=0; i< p_sys->i_streams; i++ )
3243 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3245 p_stream = p_sys->pp_stream[i];
3246 break;
3249 if ( !p_stream || !p_stream->p_skel ) return;
3250 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3251 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3252 if ( !i_keypoints ) return;
3254 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3255 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3256 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3257 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3258 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3259 uint64_t i_offset = 0;
3260 uint64_t i_time = 0;
3261 uint64_t i_keypoints_found = 0;
3263 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3265 uint64_t i_val;
3266 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3267 i_offset += i_val;
3268 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3269 i_time += i_val * p_stream->p_skel->i_indexstampden;
3270 i_keypoints_found++;
3273 if ( i_keypoints_found != i_keypoints )
3275 msg_Warn( p_demux, "Invalid Index: missing entries" );
3276 return;
3279 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3280 if ( !p_stream->p_skel->p_index ) return;
3281 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3282 p_oggpacket->bytes - 42 );
3283 p_stream->p_skel->i_index = i_keypoints_found;
3284 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3287 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3289 if ( !p_skel ) return;
3290 for ( int i=0; i< p_skel->i_messages; i++ )
3291 free( p_skel->ppsz_messages[i] );
3292 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3293 free( p_skel->p_index );
3294 free( p_skel );
3297 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3299 if ( !p_stream->p_skel ) return;
3300 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3302 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3303 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3305 free( p_stream->fmt.psz_description );
3306 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3308 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3310 bool b_foo;
3311 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3316 /* Return true if there's a skeleton exact match */
3317 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3318 int64_t *pi_lower, int64_t *pi_upper )
3320 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3321 return false;
3323 /* Validate range */
3324 if ( i_time < p_stream->p_skel->i_indexfirstnum
3325 * p_stream->p_skel->i_indexstampden ||
3326 i_time > p_stream->p_skel->i_indexlastnum
3327 * p_stream->p_skel->i_indexstampden ) return false;
3329 /* Then Lookup its index */
3330 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3331 struct
3333 int64_t i_pos;
3334 int64_t i_time;
3335 } current = { 0, 0 }, prev = { -1, -1 };
3337 uint64_t i_keypoints_found = 0;
3339 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3340 && i_keypoints_found < p_stream->p_skel->i_index )
3342 uint64_t i_val;
3343 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3344 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3345 current.i_pos += i_val;
3346 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3347 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3348 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3349 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3351 i_keypoints_found++;
3353 if ( i_time <= current.i_time )
3355 *pi_lower = prev.i_pos;
3356 *pi_upper = current.i_pos;
3357 return ( i_time == current.i_time );
3359 prev = current;
3361 return false;
3364 static uint32_t dirac_uint( bs_t *p_bs )
3366 uint32_t u_count = 0, u_value = 0;
3368 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3370 u_count++;
3371 u_value <<= 1;
3372 u_value |= bs_read( p_bs, 1 );
3375 return (1<<u_count) - 1 + u_value;
3378 static int dirac_bool( bs_t *p_bs )
3380 return bs_read( p_bs, 1 );
3383 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3384 ogg_packet *p_oggpacket )
3386 static const struct {
3387 uint32_t u_n /* numerator */, u_d /* denominator */;
3388 } p_dirac_frate_tbl[] = { /* table 10.3 */
3389 {1,1}, /* this first value is never used */
3390 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3391 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3393 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3395 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3396 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3398 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3400 bs_t bs;
3402 p_stream->i_granule_shift = 22; /* not 32 */
3404 /* Backing up stream headers is not required -- seqhdrs are repeated
3405 * thoughout the stream at suitable decoding start points */
3406 p_stream->b_force_backup = false;
3408 /* read in useful bits from sequence header */
3409 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3410 bs_skip( &bs, 13*8); /* parse_info_header */
3411 dirac_uint( &bs ); /* major_version */
3412 dirac_uint( &bs ); /* minor_version */
3413 dirac_uint( &bs ); /* profile */
3414 dirac_uint( &bs ); /* level */
3416 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3417 if( u_video_format >= u_dirac_vidfmt_frate )
3419 /* don't know how to parse this ogg dirac stream */
3420 return false;
3423 if( dirac_bool( &bs ) )
3425 dirac_uint( &bs ); /* frame_width */
3426 dirac_uint( &bs ); /* frame_height */
3429 if( dirac_bool( &bs ) )
3431 dirac_uint( &bs ); /* chroma_format */
3434 if( dirac_bool( &bs ) )
3436 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3438 else
3439 p_stream->special.dirac.b_interlaced = false;
3441 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3442 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3443 u_d = __MAX( u_d, 1 );
3444 if( dirac_bool( &bs ) )
3446 uint32_t u_frame_rate_index = dirac_uint( &bs );
3447 if( u_frame_rate_index >= u_dirac_frate_tbl )
3449 /* something is wrong with this stream */
3450 return false;
3452 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3453 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3454 if( u_frame_rate_index == 0 )
3456 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3457 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3460 p_stream->f_rate = (float) u_n / u_d;
3461 if ( p_stream->f_rate == 0 ) return false;
3463 return true;
3466 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3467 ogg_packet *p_oggpacket )
3469 uint64_t i_granulerate_numerator;
3470 uint64_t i_granulerate_denominator;
3471 int i_major;
3472 int i_minor;
3474 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3476 /* Signal that we want to keep a backup of the OggSpots
3477 * stream headers. They will be used when switching between
3478 * audio streams. */
3479 p_stream->b_force_backup = true;
3481 /* Cheat and get additionnal info ;) */
3482 if ( p_oggpacket->bytes != 52 )
3484 /* The OggSpots header is always 52 bytes */
3485 return false;
3488 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3489 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3490 if ( i_major != 0 || i_minor != 1 )
3492 return false;
3495 /* Granule rate */
3496 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3497 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3498 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3500 return false;
3503 /* The OggSpots spec contained an error and there are implementations out
3504 * there that used the wrong value. So we detect that case and switch
3505 * numerator and denominator in that case */
3506 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3508 i_granulerate_numerator = 30;
3509 i_granulerate_denominator = 1;
3512 p_stream->f_rate = ((double)i_granulerate_numerator) / i_granulerate_denominator;
3513 if ( p_stream->f_rate == 0 )
3515 return false;
3518 /* Normalize granulerate */
3519 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3520 &p_stream->fmt.video.i_frame_rate_base,
3521 i_granulerate_numerator, i_granulerate_denominator, 0);
3523 p_stream->i_granule_shift = p_oggpacket->packet[28];
3525 return true;