1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
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 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_demux.h>
37 #include <vlc_input.h>
41 #include <vlc_codecs.h>
44 #include "xiph_metadata.h"
49 /*****************************************************************************
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close( vlc_object_t * );
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 )
66 /*****************************************************************************
67 * Definitions of structures and functions used by this plugins
68 *****************************************************************************/
70 /* OggDS headers for the new header format (used in ogm files) */
75 } stream_header_video_t;
81 ogg_int16_t blockalign;
82 ogg_int32_t avgbytespersec;
83 } stream_header_audio_t;
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;
103 stream_header_video_t video;
105 stream_header_audio_t audio;
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 & 0b111) == 0b111)
116 /*****************************************************************************
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 int 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 );
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 );
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_ReadFlacHeader( 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 * );
156 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
157 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
158 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
159 static void Ogg_ApplySkeleton( logical_stream_t * );
161 /* Special decoding */
162 static void Ogg_CleanSpecificData( logical_stream_t * );
163 #ifdef HAVE_LIBVORBIS
164 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
167 static void fill_channels_info(audio_format_t *audio)
169 static const int pi_channels_map[9] =
173 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
174 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
175 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
176 | AOUT_CHAN_REARRIGHT,
177 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
178 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
179 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
180 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
181 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
182 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
183 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
184 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
185 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
189 unsigned chans = audio->i_channels;
190 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
191 audio->i_physical_channels =
192 audio->i_original_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;
206 const uint8_t *p_peek;
208 /* Check if we are dealing with an ogg stream */
209 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
210 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
212 char *psz_mime = stream_ContentType( p_demux->s );
217 else if ( strcmp( psz_mime, "application/ogg" ) &&
218 strcmp( psz_mime, "video/ogg" ) &&
219 strcmp( psz_mime, "audio/ogg" ) )
228 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
232 p_sys->i_length = -1;
233 p_sys->b_preparsing_done = false;
235 stream_Control( p_demux->s, ACCESS_GET_PTS_DELAY, & p_sys->i_access_delay );
237 /* Set exported functions */
238 p_demux->pf_demux = Demux;
239 p_demux->pf_control = Control;
241 /* Initialize the Ogg physical bitstream parser */
242 ogg_sync_init( &p_sys->oy );
245 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
248 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
254 /*****************************************************************************
255 * Close: frees unused data
256 *****************************************************************************/
257 static void Close( vlc_object_t *p_this )
259 demux_t *p_demux = (demux_t *)p_this;
260 demux_sys_t *p_sys = p_demux->p_sys ;
262 /* Cleanup the bitstream parser */
263 ogg_sync_clear( &p_sys->oy );
265 Ogg_EndOfStream( p_demux );
267 if( p_sys->p_old_stream )
268 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
273 /*****************************************************************************
274 * Demux: reads and demuxes data packets
275 *****************************************************************************
276 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
277 *****************************************************************************/
278 static int Demux( demux_t * p_demux )
280 demux_sys_t *p_sys = p_demux->p_sys;
281 ogg_packet oggpacket;
283 bool b_skipping = false;
286 int i_active_streams = p_sys->i_streams;
287 for ( int i=0; i < p_sys->i_streams; i++ )
289 if ( p_sys->pp_stream[i]->b_finished )
293 if ( i_active_streams == 0 )
295 if ( p_sys->i_streams ) /* All finished */
297 msg_Dbg( p_demux, "end of a group of logical streams" );
298 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
299 * only 1 ES is supported (common case for ogg web radio) */
300 if( p_sys->i_streams == 1 )
302 p_sys->p_old_stream = p_sys->pp_stream[0];
303 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
305 Ogg_EndOfStream( p_demux );
306 p_sys->b_chained_boundary = true;
309 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
312 msg_Dbg( p_demux, "beginning of a group of logical streams" );
314 if ( !p_sys->b_chained_boundary )
316 /* Find the real duration */
317 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
319 Oggseek_ProbeEnd( p_demux );
323 p_sys->b_chained_boundary = false;
327 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
329 Ogg_CreateES( p_demux );
330 p_sys->b_es_created = true;
334 * The first data page of a physical stream is stored in the relevant logical stream
335 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
336 * stream it belongs to if we haven't processed this first page yet. If we do, we
337 * will only process that first page whenever we find the second page for this stream.
338 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
339 * the second page will arrive real quick, this is not fine for Kate, whose second
340 * data page will typically arrive much later.
341 * This means it is now possible to seek right at the start of a stream where the last
342 * logical stream is Kate, without having to wait for the second data page to unblock
343 * the first one, which is the one that triggers the 'no more headers to backup' code.
344 * And, as we all know, seeking without having backed up all headers is bad, since the
345 * codec will fail to initialize if it's missing its headers.
347 if( !p_sys->b_page_waiting)
350 * Demux an ogg page from the stream
352 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
354 /* Test for End of Stream */
355 if( ogg_page_eos( &p_sys->current_page ) )
357 /* If we delayed restarting encoders/SET_ES_FMT for more
358 * skeleton provided configuration */
359 if ( p_sys->p_skelstream )
361 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
363 msg_Dbg( p_demux, "End of Skeleton" );
364 p_sys->b_preparsing_done = true;
365 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
367 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
368 Ogg_ApplySkeleton( p_stream );
373 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
375 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
377 p_sys->pp_stream[i_stream]->b_finished = true;
385 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
387 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
390 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
392 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
394 /* if we've just pulled page, look for the right logical stream */
395 if( !p_sys->b_page_waiting )
397 if( p_sys->i_streams == 1 &&
398 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
400 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
401 Ogg_ResetStream( p_stream );
402 p_sys->i_nzpcr_offset = (p_sys->i_pcr >= VLC_TS_INVALID) ?
403 p_sys->i_pcr - VLC_TS_0 : 0;
404 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
407 /* Does fail if serialno differs */
408 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
414 /* clear the finished flag if pages after eos (ex: after a seek) */
415 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
416 p_stream->b_finished = false;
419 if ( p_stream->fmt.i_cat == VIDEO_ES )
420 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
421 ogg_page_pageno( &p_sys->current_page ),
422 ogg_page_granulepos( &p_sys->current_page ),
423 ogg_page_packets( &p_sys->current_page ),
424 ogg_page_continued(&p_sys->current_page),
425 p_sys->current_page.body_len )
428 const int i_page_packets = ogg_page_packets( &p_sys->current_page );
429 bool b_doprepcr = false;
431 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
434 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
435 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
436 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
437 p_stream->fmt.i_cat == VIDEO_ES )
439 assert( p_stream->prepcr.pp_blocks == NULL );
444 int i_real_page_packets = 0;
445 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
447 i_real_page_packets++;
448 int i_max_packets = __MAX(i_page_packets, i_real_page_packets);
449 if ( b_doprepcr && p_stream->prepcr.i_size < i_max_packets )
451 /* always double alloc for performance */
452 i_max_packets = __MAX( i_max_packets << 1, 255 );
453 /* alloc or realloc */
454 block_t **pp_realloc = realloc( p_stream->prepcr.pp_blocks,
455 sizeof(block_t *) * i_max_packets );
461 p_stream->prepcr.i_size = i_max_packets;
462 p_stream->prepcr.pp_blocks = pp_realloc;
465 /* Read info from any secondary header packets, if there are any */
466 if( p_stream->i_secondary_header_packets > 0 )
468 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
469 oggpacket.bytes >= 7 &&
470 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
472 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
473 p_stream->i_secondary_header_packets = 0;
475 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
476 oggpacket.bytes >= 6 &&
477 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
479 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
480 p_stream->i_secondary_header_packets = 0;
482 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
483 oggpacket.bytes >= 7 &&
484 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
486 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
487 p_stream->i_secondary_header_packets = 0;
489 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
491 p_stream->i_secondary_header_packets = 0;
494 /* update start of data pointer */
495 p_stream->i_data_start = stream_Tell( p_demux->s );
498 /* If any streams have i_skip_frames, only decode (pre-roll)
499 * for those streams, but don't skip headers */
500 if ( b_skipping && p_stream->i_skip_frames == 0
501 && p_stream->i_secondary_header_packets ) continue;
503 if( p_stream->b_reinit )
505 p_stream->b_reinit = false;
506 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
508 p_stream->i_skip_frames = p_stream->i_pre_skip;
512 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
515 if ( p_stream->prepcr.pp_blocks )
517 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
518 p_stream->i_previous_pcr = pagestamp;
519 #ifdef HAVE_LIBVORBIS
520 int i_prev_blocksize = 0;
523 for( int i=0; i<p_stream->prepcr.i_used; i++ )
525 block_t *p_block = p_stream->prepcr.pp_blocks[i];
526 ogg_packet dumb_packet;
527 dumb_packet.bytes = p_block->i_buffer;
528 dumb_packet.packet = p_block->p_buffer;
530 switch( p_stream->fmt.i_codec )
532 case VLC_CODEC_SPEEX:
533 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
534 p_stream->special.speex.i_framesperpacket;
537 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
539 #ifdef HAVE_LIBVORBIS
540 case VLC_CODEC_VORBIS:
542 if( !VORBIS_HEADERS_VALID(p_stream) )
544 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
547 long i_blocksize = vorbis_packet_blocksize(
548 p_stream->special.vorbis.p_info, &dumb_packet );
549 if ( i_prev_blocksize )
550 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
552 p_block->i_nb_samples = i_blocksize / 2;
553 i_prev_blocksize = i_blocksize;
560 bool b_fixed = false;
561 for( int i=p_stream->prepcr.i_used - 1; i>=0; i-- )
563 block_t *p_block = p_stream->prepcr.pp_blocks[i];
564 switch( p_stream->fmt.i_codec )
566 case VLC_CODEC_SPEEX:
568 case VLC_CODEC_VORBIS:
569 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
572 p_block->i_pts = VLC_TS_INVALID;
573 p_block->i_flags |= BLOCK_FLAG_PREROLL;
576 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
580 if ( p_stream->fmt.i_cat == VIDEO_ES )
582 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
583 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
591 if ( pagestamp < 0 ) pagestamp = 0;
592 p_stream->i_pcr = VLC_TS_0 + pagestamp;
593 p_stream->i_pcr += p_sys->i_nzpcr_offset;
594 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
597 FREENULL(p_stream->prepcr.pp_blocks);
598 p_stream->prepcr.i_used = 0;
600 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
604 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
605 ogg_page_granulepos( &p_sys->current_page ), false );
606 if ( i_pagestamp > -1 )
608 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
609 p_stream->i_pcr += p_sys->i_nzpcr_offset;
612 if( !p_sys->b_page_waiting )
616 /* if a page was waiting, it's now processed */
617 p_sys->b_page_waiting = false;
619 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
620 p_sys->b_preparsing_done = false;
622 p_sys->b_preparsing_done = true;
624 /* We will consider the lowest PCR among tracks, because the audio core badly
625 * handles PCR rewind (mute)
627 mtime_t i_pcr_candidate = VLC_TS_INVALID;
628 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
630 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
632 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
634 /* We have 1 or more streams needing more than 1 page for preparsing */
635 p_sys->b_preparsing_done = false;
638 if( p_stream->fmt.i_cat == SPU_ES )
640 if( p_stream->i_pcr < VLC_TS_0 )
642 if ( p_stream->b_finished || p_stream->b_initializing )
644 if ( p_stream->p_preparse_block )
646 if( i_pcr_candidate < VLC_TS_0
647 || p_stream->i_pcr <= i_pcr_candidate )
649 i_pcr_candidate = p_stream->i_pcr;
653 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
655 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
657 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
658 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
660 p_sys->i_pcr_jitter = i_pcr_jitter;
661 if ( p_sys->i_access_delay < i_pcr_jitter )
662 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
663 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
667 if( ! b_skipping && p_sys->b_preparsing_done )
669 p_sys->i_pcr = i_pcr_candidate;
670 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
677 static void Ogg_ResetStream( logical_stream_t *p_stream )
679 #ifdef HAVE_LIBVORBIS
680 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
682 p_stream->special.vorbis.i_prev_blocksize = 0;
685 /* we'll trash all the data until we find the next pcr */
686 p_stream->b_reinit = true;
687 p_stream->i_pcr = VLC_TS_UNKNOWN;
688 p_stream->i_previous_granulepos = -1;
689 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
690 ogg_stream_reset( &p_stream->os );
691 FREENULL( p_stream->prepcr.pp_blocks );
692 p_stream->prepcr.i_size = 0;
693 p_stream->prepcr.i_used = 0;
696 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
698 for( int i = 0; i < p_sys->i_streams; i++ )
699 Ogg_ResetStream( p_sys->pp_stream[i] );
701 ogg_sync_reset( &p_sys->oy );
702 p_sys->i_pcr = VLC_TS_UNKNOWN;
705 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
707 demux_sys_t *p_sys = p_demux->p_sys;
708 logical_stream_t *p_stream = NULL;
709 for( int i=0; i<p_sys->i_streams; i++ )
711 logical_stream_t *p_candidate = p_sys->pp_stream[i];
712 if ( !p_candidate->p_es ) continue;
714 bool b_selected = false;
715 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
716 p_candidate->p_es, &b_selected );
717 if ( !b_selected ) continue;
719 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
721 p_stream = p_candidate;
722 continue; /* Try to find video anyway */
725 if ( p_candidate->fmt.i_cat == VIDEO_ES )
727 p_stream = p_candidate;
734 /*****************************************************************************
736 *****************************************************************************/
737 static int Control( demux_t *p_demux, int i_query, va_list args )
739 demux_sys_t *p_sys = p_demux->p_sys;
748 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
750 vlc_meta_Merge( p_meta, p_sys->p_meta );
753 case DEMUX_HAS_UNSUPPORTED_META:
754 pb_bool = (bool*)va_arg( args, bool* );
759 pi64 = (int64_t*)va_arg( args, int64_t * );
760 *pi64 = p_sys->i_pcr;
764 i64 = (int64_t)va_arg( args, int64_t );
765 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
768 msg_Err( p_demux, "No selected seekable stream found" );
771 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
772 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
774 Ogg_ResetStreamsHelper( p_sys );
775 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
782 case DEMUX_GET_ATTACHMENTS:
784 input_attachment_t ***ppp_attach =
785 (input_attachment_t***)va_arg( args, input_attachment_t*** );
786 int *pi_int = (int*)va_arg( args, int * );
788 if( p_sys->i_attachments <= 0 )
791 *pi_int = p_sys->i_attachments;
792 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
793 for( int i = 0; i < p_sys->i_attachments; i++ )
794 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
798 case DEMUX_GET_POSITION:
799 pf = (double*)va_arg( args, double * );
800 if( p_sys->i_length > 0 )
802 *pf = (double) p_sys->i_pcr /
803 (double) ( p_sys->i_length * (mtime_t)1000000 );
805 else if( stream_Size( p_demux->s ) > 0 )
807 i64 = stream_Tell( p_demux->s );
808 *pf = (double) i64 / stream_Size( p_demux->s );
813 case DEMUX_SET_POSITION:
814 /* forbid seeking if we haven't initialized all logical bitstreams yet;
815 if we allowed, some headers would not get backed up and decoder init
816 would fail, making that logical stream unusable */
817 for ( int i=0; i< p_sys->i_streams; i++ )
819 if ( p_sys->pp_stream[i]->b_initializing )
823 p_stream = Ogg_GetSelectedStream( p_demux );
826 msg_Err( p_demux, "No selected seekable stream found" );
830 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
832 f = (double)va_arg( args, double );
833 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
835 Ogg_ResetStreamsHelper( p_sys );
836 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
840 assert( p_sys->i_length > 0 );
841 i64 = CLOCK_FREQ * p_sys->i_length * f;
842 Ogg_ResetStreamsHelper( p_sys );
843 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
845 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
852 case DEMUX_GET_LENGTH:
853 if ( p_sys->i_length < 0 )
854 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
856 pi64 = (int64_t*)va_arg( args, int64_t * );
857 *pi64 = p_sys->i_length * 1000000;
860 case DEMUX_GET_TITLE_INFO:
862 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
863 int *pi_int = (int*)va_arg( args, int* );
864 int *pi_title_offset = (int*)va_arg( args, int* );
865 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
867 if( p_sys->i_seekpoints > 0 )
870 *ppp_title = malloc( sizeof( input_title_t* ) );
871 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
872 for( int i = 0; i < p_sys->i_seekpoints; i++ )
874 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
875 if ( likely( p_seekpoint_copy ) )
876 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
878 *pi_title_offset = 0;
879 *pi_seekpoint_offset = 0;
883 case DEMUX_SET_TITLE:
885 const int i_title = (int)va_arg( args, int );
890 case DEMUX_SET_SEEKPOINT:
892 const int i_seekpoint = (int)va_arg( args, int );
893 if( i_seekpoint > p_sys->i_seekpoints )
896 for ( int i=0; i< p_sys->i_streams; i++ )
898 if ( p_sys->pp_stream[i]->b_initializing )
902 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
904 p_stream = Ogg_GetSelectedStream( p_demux );
907 msg_Err( p_demux, "No selected seekable stream found" );
911 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
912 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
914 Ogg_ResetStreamsHelper( p_sys );
915 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
917 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
918 p_demux->info.i_seekpoint = i_seekpoint;
926 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
931 /****************************************************************************
932 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
933 ****************************************************************************
934 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
935 * are at the end of stream.
936 ****************************************************************************/
937 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
939 demux_sys_t *p_ogg = p_demux->p_sys ;
943 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
945 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
947 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
951 ogg_sync_wrote( &p_ogg->oy, i_read );
957 /****************************************************************************
958 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
960 ****************************************************************************/
961 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
962 ogg_packet *p_oggpacket )
964 demux_sys_t *p_ogg = p_demux->p_sys;
965 p_stream->i_end_trim = 0;
967 /* Convert the granulepos into a pcr */
968 if ( p_oggpacket->granulepos == 0 )
970 /* We're in headers, and we haven't parsed 1st data packet yet */
971 // p_stream->i_pcr = VLC_TS_UNKNOWN;
973 else if( p_oggpacket->granulepos > 0 )
975 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
976 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
977 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
978 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
979 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
980 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
981 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
983 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
984 p_oggpacket->granulepos, true );
985 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
987 else if ( p_stream->i_previous_granulepos > 0 )
989 ogg_int64_t sample = p_stream->i_previous_granulepos;
991 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
993 int duration = Ogg_OpusPacketDuration( p_oggpacket );
996 ogg_int64_t end_sample = p_oggpacket->granulepos;
997 if( end_sample < ( sample + duration ) )
998 p_stream->i_end_trim = sample + duration - end_sample;
1002 if (sample >= p_stream->i_pre_skip)
1003 sample -= p_stream->i_pre_skip;
1007 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1008 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1012 else if ( p_oggpacket->granulepos == -1 )
1015 /* no granulepos available, try to interpolate the pcr.
1016 * If we can't then don't touch the old value. */
1017 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
1019 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1021 #ifdef HAVE_LIBVORBIS
1022 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1023 p_stream->special.vorbis.p_info &&
1024 VORBIS_HEADERS_VALID(p_stream) &&
1025 p_stream->i_previous_granulepos > 0 )
1027 long i_blocksize = vorbis_packet_blocksize(
1028 p_stream->special.vorbis.p_info, p_oggpacket );
1029 if ( p_stream->special.vorbis.i_prev_blocksize )
1030 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1032 i_duration = i_blocksize / 2;
1033 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1034 /* duration in samples per channel */
1035 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1036 p_stream->i_pcr = p_stream->i_previous_granulepos *
1037 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1038 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1041 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1042 p_stream->i_previous_granulepos > 0 )
1044 i_duration = p_stream->special.speex.i_framesize *
1045 p_stream->special.speex.i_framesperpacket;
1046 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1047 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1048 p_stream->i_previous_granulepos, false );
1049 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1051 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1052 p_stream->i_previous_granulepos > 0 &&
1054 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1057 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1058 sample = p_stream->i_previous_granulepos;
1059 if (sample >= p_stream->i_pre_skip)
1060 sample -= p_stream->i_pre_skip;
1064 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1065 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1067 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1069 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1070 p_stream->fmt.i_bitrate / 8 );
1074 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1077 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1080 demux_sys_t *p_ogg = p_demux->p_sys;
1081 if ( !p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1083 if ( !p_block ) return;
1084 if ( p_stream->prepcr.pp_blocks )
1086 assert( p_stream->prepcr.i_size );
1087 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1089 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1090 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1091 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1095 /* Because ES creation is delayed for preparsing */
1096 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1097 if ( p_stream->p_preparse_block )
1099 block_t *temp = p_stream->p_preparse_block;
1102 if ( temp && i_firstpts < VLC_TS_0 )
1103 i_firstpts = temp->i_pts;
1105 block_t *tosend = temp;
1106 temp = temp->p_next;
1107 tosend->p_next = NULL;
1109 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1110 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1111 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1113 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1115 p_ogg->i_pcr = i_firstpts;
1116 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1119 p_stream->p_preparse_block = NULL;
1124 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1125 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1126 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1131 /****************************************************************************
1132 * Ogg_DecodePacket: Decode an Ogg packet.
1133 ****************************************************************************/
1134 static void Ogg_DecodePacket( demux_t *p_demux,
1135 logical_stream_t *p_stream,
1136 ogg_packet *p_oggpacket )
1140 int i_header_len = 0;
1142 if( p_oggpacket->bytes >= 7 &&
1143 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1145 /* it's an Annodex packet -- skip it (do nothing) */
1148 else if( p_oggpacket->bytes >= 7 &&
1149 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1151 /* it's an AnxData packet -- skip it (do nothing) */
1154 else if( p_oggpacket->bytes >= 8 &&
1155 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1157 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1160 else if( p_oggpacket->bytes >= 6 &&
1161 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1163 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1166 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1167 p_oggpacket->bytes >= 7 &&
1168 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1170 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1174 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1175 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1177 /* Check the ES is selected */
1178 if ( !p_stream->p_es )
1181 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1182 p_stream->p_es, &b_selected );
1184 if( p_stream->b_force_backup )
1187 p_stream->i_packets_backup++;
1188 switch( p_stream->fmt.i_codec )
1190 case VLC_CODEC_VORBIS:
1191 #ifdef HAVE_LIBVORBIS
1192 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1195 case VLC_CODEC_THEORA:
1196 if( p_stream->i_packets_backup == 3 )
1197 p_stream->b_force_backup = false;
1201 case VLC_CODEC_DAALA:
1202 if( p_stream->i_packets_backup == 3 )
1203 p_stream->b_force_backup = false;
1207 case VLC_CODEC_SPEEX:
1208 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1209 p_stream->b_force_backup = false;
1213 case VLC_CODEC_OPUS:
1214 if( p_stream->i_packets_backup == 2 )
1215 p_stream->b_force_backup = false;
1219 case VLC_CODEC_FLAC:
1220 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1222 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1223 p_stream->b_force_backup = false;
1225 else if( p_stream->fmt.audio.i_rate )
1227 p_stream->b_force_backup = false;
1228 if( p_oggpacket->bytes >= 9 )
1230 p_oggpacket->packet += 9;
1231 p_oggpacket->bytes -= 9;
1237 case VLC_CODEC_KATE:
1238 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1239 p_stream->b_force_backup = false;
1244 p_stream->b_force_backup = false;
1249 /* Backup the ogg packet (likely an header packet) */
1252 void *p_org = p_stream->p_headers;
1253 p_stream->i_headers += p_oggpacket->bytes;
1254 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1255 if( p_stream->p_headers )
1257 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1258 p_oggpacket->packet, p_oggpacket->bytes );
1262 #warning Memory leak
1263 p_stream->i_headers = 0;
1264 p_stream->p_headers = NULL;
1268 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1269 p_oggpacket->bytes, p_oggpacket->packet ) )
1271 p_stream->i_headers = 0;
1272 p_stream->p_headers = NULL;
1274 if( p_stream->i_headers > 0 )
1276 if( !p_stream->b_force_backup )
1278 /* Last header received, commit changes */
1279 free( p_stream->fmt.p_extra );
1281 p_stream->fmt.i_extra = p_stream->i_headers;
1282 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1283 if( p_stream->fmt.p_extra )
1284 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1285 p_stream->i_headers );
1287 p_stream->fmt.i_extra = 0;
1289 if( p_stream->i_headers > 0 )
1290 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1291 p_stream->p_headers, p_stream->i_headers );
1293 /* we're not at BOS anymore for this logical stream */
1294 p_stream->b_initializing = false;
1298 b_selected = false; /* Discard the header packet */
1302 p_stream->b_initializing = false;
1305 /* Convert the granulepos into the next pcr */
1306 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1310 /* This stream isn't currently selected so we don't need to decode it,
1311 * but we did need to store its pcr as it might be selected later on */
1315 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1316 p_block->i_pts = p_stream->i_pcr;
1318 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1319 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1321 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1322 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1324 /* may need to preroll after a seek or in case of preskip */
1325 if ( p_stream->i_skip_frames > 0 )
1327 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1329 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1331 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1332 p_stream->i_skip_frames -= p_block->i_nb_samples;
1333 p_block->i_nb_samples = 0;
1337 p_block->i_nb_samples -= p_stream->i_skip_frames;
1338 p_stream->i_skip_frames = 0;
1343 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1344 p_stream->i_skip_frames--;
1348 /* Conditional block fixes */
1349 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1350 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1352 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1354 else if( p_stream->fmt.i_cat == AUDIO_ES )
1356 /* Blatant abuse of the i_length field. */
1357 p_block->i_length = p_stream->i_end_trim;
1359 else if( p_stream->fmt.i_cat == SPU_ES )
1361 p_block->i_length = 0;
1363 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1365 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1366 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1367 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1368 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1369 /* granulepos for dirac is possibly broken, this value should be ignored */
1370 if( 0 >= p_oggpacket->granulepos )
1372 p_block->i_pts = VLC_TS_INVALID;
1373 p_block->i_dts = p_stream->i_pcr;
1377 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1378 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1379 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1380 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1381 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1382 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1383 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1384 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1385 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1386 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1387 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1389 if( p_oggpacket->bytes <= 0 )
1391 msg_Dbg( p_demux, "discarding 0 sized packet" );
1392 block_Release( p_block );
1395 /* We remove the header from the packet */
1396 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1397 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1399 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1401 /* But with subtitles we need to retrieve the duration first */
1402 int i, lenbytes = 0;
1404 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1406 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1408 lenbytes = lenbytes << 8;
1409 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1412 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1413 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1414 p_oggpacket->packet[i_header_len + 1] != 0 &&
1415 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1416 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1418 p_block->i_length = (mtime_t)lenbytes * 1000;
1423 if( p_block->i_buffer >= (unsigned int)i_header_len )
1424 p_block->i_buffer -= i_header_len;
1426 p_block->i_buffer = 0;
1430 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1432 /* FIXME: the biggest hack I've ever done */
1433 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1434 p_block->i_pts, p_block->i_dts );
1438 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1439 p_oggpacket->bytes - i_header_len );
1441 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1444 static int Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1446 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1449 /****************************************************************************
1450 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1451 * stream and fill p_ogg.
1452 *****************************************************************************
1453 * The initial page of a logical stream is marked as a 'bos' page.
1454 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1455 * together and all of the initial pages must appear before any data pages.
1457 * On success this function returns VLC_SUCCESS.
1458 ****************************************************************************/
1459 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1461 demux_sys_t *p_ogg = p_demux->p_sys ;
1462 ogg_packet oggpacket;
1465 p_ogg->i_total_length = stream_Size ( p_demux->s );
1466 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1469 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1472 if( ogg_page_bos( &p_ogg->current_page ) )
1475 /* All is wonderful in our fine fine little world.
1476 * We found the beginning of our first logical stream. */
1477 while( ogg_page_bos( &p_ogg->current_page ) )
1479 logical_stream_t *p_stream;
1481 p_stream = malloc( sizeof(logical_stream_t) );
1482 if( unlikely( !p_stream ) )
1485 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1487 memset( p_stream, 0, sizeof(logical_stream_t) );
1489 es_format_Init( &p_stream->fmt, 0, 0 );
1490 es_format_Init( &p_stream->fmt_old, 0, 0 );
1491 p_stream->b_initializing = true;
1493 /* Setup the logical stream */
1494 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1495 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1497 /* Extract the initial header from the first page and verify
1498 * the codec type of this Ogg bitstream */
1499 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1501 /* error. stream version mismatch perhaps */
1502 msg_Err( p_demux, "error reading first page of "
1503 "Ogg bitstream data" );
1504 return VLC_EGENERIC;
1507 /* FIXME: check return value */
1508 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1510 /* Check for Vorbis header */
1511 if( oggpacket.bytes >= 7 &&
1512 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1514 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1515 msg_Dbg( p_demux, "found vorbis header" );
1518 msg_Dbg( p_demux, "found invalid vorbis header" );
1519 Ogg_LogicalStreamDelete( p_demux, p_stream );
1523 /* Check for Speex header */
1524 else if( oggpacket.bytes >= 5 &&
1525 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1527 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1528 msg_Dbg( p_demux, "found speex header, channels: %i, "
1529 "rate: %i, bitrate: %i, frames: %i group %i",
1530 p_stream->fmt.audio.i_channels,
1531 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1532 p_stream->special.speex.i_framesize,
1533 p_stream->special.speex.i_framesperpacket );
1536 msg_Dbg( p_demux, "found invalid Speex header" );
1537 Ogg_LogicalStreamDelete( p_demux, p_stream );
1541 /* Check for Opus header */
1542 else if( oggpacket.bytes >= 8 &&
1543 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1545 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1546 msg_Dbg( p_demux, "found opus header, channels: %i, "
1548 p_stream->fmt.audio.i_channels,
1549 (int)p_stream->i_pre_skip);
1550 p_stream->i_skip_frames = p_stream->i_pre_skip;
1552 /* Check for Flac header (< version 1.1.1) */
1553 else if( oggpacket.bytes >= 4 &&
1554 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1556 msg_Dbg( p_demux, "found FLAC header" );
1558 /* Grrrr!!!! Did they really have to put all the
1559 * important info in the second header packet!!!
1560 * (STREAMINFO metadata is in the following packet) */
1561 p_stream->b_force_backup = true;
1562 p_stream->fmt.i_cat = AUDIO_ES;
1563 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1565 /* Check for Flac header (>= version 1.1.1) */
1566 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1567 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1568 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1570 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1571 oggpacket.packet[8];
1572 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1573 "(%i header packets)",
1574 oggpacket.packet[5], oggpacket.packet[6],
1577 p_stream->b_force_backup = true;
1579 p_stream->fmt.i_cat = AUDIO_ES;
1580 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1581 oggpacket.packet += 13; oggpacket.bytes -= 13;
1582 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1584 msg_Dbg( p_demux, "found invalid Flac header" );
1585 Ogg_LogicalStreamDelete( p_demux, p_stream );
1589 /* Check for Theora header */
1590 else if( oggpacket.bytes >= 7 &&
1591 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1593 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1595 "found theora header, bitrate: %i, rate: %f",
1596 p_stream->fmt.i_bitrate, p_stream->f_rate );
1599 msg_Dbg( p_demux, "found invalid Theora header" );
1600 Ogg_LogicalStreamDelete( p_demux, p_stream );
1604 /* Check for Daala header */
1605 else if( oggpacket.bytes >= 6 &&
1606 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1608 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1610 "found daala header, bitrate: %i, rate: %f",
1611 p_stream->fmt.i_bitrate, p_stream->f_rate );
1614 msg_Dbg( p_demux, "found invalid Daala header" );
1615 Ogg_LogicalStreamDelete( p_demux, p_stream );
1619 /* Check for Dirac header */
1620 else if( ( oggpacket.bytes >= 5 &&
1621 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1622 ( oggpacket.bytes >= 9 &&
1623 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1625 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1626 msg_Dbg( p_demux, "found dirac header" );
1629 msg_Warn( p_demux, "found dirac header isn't decodable" );
1630 Ogg_LogicalStreamDelete( p_demux, p_stream );
1634 /* Check for Tarkin header */
1635 else if( oggpacket.bytes >= 7 &&
1636 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1640 msg_Dbg( p_demux, "found tarkin header" );
1641 p_stream->fmt.i_cat = VIDEO_ES;
1642 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1644 /* Cheat and get additionnal info ;) */
1645 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1646 oggpack_adv( &opb, 88 );
1647 oggpack_adv( &opb, 104 );
1648 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1649 p_stream->f_rate = 2; /* FIXME */
1651 "found tarkin header, bitrate: %i, rate: %f",
1652 p_stream->fmt.i_bitrate, p_stream->f_rate );
1654 /* Check for VP8 header */
1655 else if( oggpacket.bytes >= 26 &&
1656 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1658 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1659 msg_Dbg( p_demux, "found VP8 header "
1660 "fps: %f, width:%i; height:%i",
1662 p_stream->fmt.video.i_width,
1663 p_stream->fmt.video.i_height );
1666 msg_Dbg( p_demux, "invalid VP8 header found");
1667 Ogg_LogicalStreamDelete( p_demux, p_stream );
1671 /* Check for Annodex header */
1672 else if( oggpacket.bytes >= 7 &&
1673 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1675 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1676 /* kill annodex track */
1680 /* Check for Annodex header */
1681 else if( oggpacket.bytes >= 7 &&
1682 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1684 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1686 /* Check for Kate header */
1687 else if( oggpacket.bytes >= 8 &&
1688 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1690 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1691 msg_Dbg( p_demux, "found kate header" );
1694 msg_Dbg( p_demux, "invalid kate header found");
1695 Ogg_LogicalStreamDelete( p_demux, p_stream );
1699 /* Check for OggDS */
1700 else if( oggpacket.bytes >= 142 &&
1701 !memcmp( &oggpacket.packet[1],
1702 "Direct Show Samples embedded in Ogg", 35 ))
1704 /* Old header type */
1705 p_stream->b_oggds = true;
1706 /* Check for video header (old format) */
1707 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1708 oggpacket.bytes >= 184 )
1710 p_stream->fmt.i_cat = VIDEO_ES;
1711 p_stream->fmt.i_codec =
1712 VLC_FOURCC( oggpacket.packet[68],
1713 oggpacket.packet[69],
1714 oggpacket.packet[70],
1715 oggpacket.packet[71] );
1716 msg_Dbg( p_demux, "found video header of type: %.4s",
1717 (char *)&p_stream->fmt.i_codec );
1719 p_stream->fmt.video.i_frame_rate = 10000000;
1720 p_stream->fmt.video.i_frame_rate_base =
1721 GetQWLE((oggpacket.packet+164));
1722 p_stream->fmt.video.i_frame_rate_base =
1723 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1724 p_stream->f_rate = 10000000.0 /
1725 p_stream->fmt.video.i_frame_rate_base;
1726 p_stream->fmt.video.i_bits_per_pixel =
1727 GetWLE((oggpacket.packet+182));
1728 if( !p_stream->fmt.video.i_bits_per_pixel )
1730 p_stream->fmt.video.i_bits_per_pixel = 24;
1731 p_stream->fmt.video.i_width =
1732 GetDWLE((oggpacket.packet+176));
1733 p_stream->fmt.video.i_height =
1734 GetDWLE((oggpacket.packet+180));
1737 "fps: %f, width:%i; height:%i, bitcount:%i",
1739 p_stream->fmt.video.i_width,
1740 p_stream->fmt.video.i_height,
1741 p_stream->fmt.video.i_bits_per_pixel);
1744 /* Check for audio header (old format) */
1745 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1748 unsigned int i_format_tag;
1750 p_stream->fmt.i_cat = AUDIO_ES;
1752 i_extra_size = GetWLE((oggpacket.packet+140));
1753 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1755 p_stream->fmt.i_extra = i_extra_size;
1756 p_stream->fmt.p_extra = malloc( i_extra_size );
1757 if( p_stream->fmt.p_extra )
1758 memcpy( p_stream->fmt.p_extra,
1759 oggpacket.packet + 142, i_extra_size );
1761 p_stream->fmt.i_extra = 0;
1764 i_format_tag = GetWLE((oggpacket.packet+124));
1765 p_stream->fmt.audio.i_channels =
1766 GetWLE((oggpacket.packet+126));
1767 fill_channels_info(&p_stream->fmt.audio);
1768 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1769 GetDWLE((oggpacket.packet+128));
1770 p_stream->fmt.i_bitrate =
1771 GetDWLE((oggpacket.packet+132)) * 8;
1772 p_stream->fmt.audio.i_blockalign =
1773 GetWLE((oggpacket.packet+136));
1774 p_stream->fmt.audio.i_bitspersample =
1775 GetWLE((oggpacket.packet+138));
1777 wf_tag_to_fourcc( i_format_tag,
1778 &p_stream->fmt.i_codec, 0 );
1780 if( p_stream->fmt.i_codec ==
1781 VLC_FOURCC('u','n','d','f') )
1783 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1784 ( i_format_tag >> 8 ) & 0xff,
1785 i_format_tag & 0xff );
1788 msg_Dbg( p_demux, "found audio header of type: %.4s",
1789 (char *)&p_stream->fmt.i_codec );
1790 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1791 "%dbits/sample %dkb/s",
1793 p_stream->fmt.audio.i_channels,
1794 p_stream->fmt.audio.i_rate,
1795 p_stream->fmt.audio.i_bitspersample,
1796 p_stream->fmt.i_bitrate / 1024 );
1797 if ( p_stream->f_rate == 0 )
1799 msg_Dbg( p_demux, "invalid oggds audio header" );
1800 Ogg_LogicalStreamDelete( p_demux, p_stream );
1806 msg_Dbg( p_demux, "stream %d has an old header "
1807 "but is of an unknown type", p_ogg->i_streams-1 );
1812 /* Check for OggDS */
1813 else if( oggpacket.bytes >= 44+1 &&
1814 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1816 stream_header_t tmp;
1817 stream_header_t *st = &tmp;
1819 p_stream->b_oggds = true;
1821 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1822 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1823 st->size = GetDWLE( &oggpacket.packet[1+12] );
1824 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1825 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1826 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1827 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1828 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1830 /* Check for video header (new format) */
1831 if( !strncmp( st->streamtype, "video", 5 ) &&
1832 oggpacket.bytes >= 52+1 )
1834 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1835 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1837 p_stream->fmt.i_cat = VIDEO_ES;
1839 /* We need to get rid of the header packet */
1840 ogg_stream_packetout( &p_stream->os, &oggpacket );
1842 p_stream->fmt.i_codec =
1843 VLC_FOURCC( st->subtype[0], st->subtype[1],
1844 st->subtype[2], st->subtype[3] );
1845 msg_Dbg( p_demux, "found video header of type: %.4s",
1846 (char *)&p_stream->fmt.i_codec );
1848 p_stream->fmt.video.i_frame_rate = 10000000;
1849 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1850 if( st->time_unit <= 0 )
1851 st->time_unit = 400000;
1852 p_stream->f_rate = 10000000.0 / st->time_unit;
1853 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1854 p_stream->fmt.video.i_width = st->sh.video.width;
1855 p_stream->fmt.video.i_height = st->sh.video.height;
1858 "fps: %f, width:%i; height:%i, bitcount:%i",
1860 p_stream->fmt.video.i_width,
1861 p_stream->fmt.video.i_height,
1862 p_stream->fmt.video.i_bits_per_pixel );
1864 /* Check for audio header (new format) */
1865 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1866 oggpacket.bytes >= 56+1 )
1872 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1873 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1874 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1876 p_stream->fmt.i_cat = AUDIO_ES;
1878 /* We need to get rid of the header packet */
1879 ogg_stream_packetout( &p_stream->os, &oggpacket );
1881 i_extra_size = st->size - 56;
1883 if( i_extra_size > 0 &&
1884 i_extra_size < oggpacket.bytes - 1 - 56 )
1886 p_stream->fmt.i_extra = i_extra_size;
1887 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1888 if( p_stream->fmt.p_extra )
1889 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1890 p_stream->fmt.i_extra );
1892 p_stream->fmt.i_extra = 0;
1895 memcpy( p_buffer, st->subtype, 4 );
1897 i_format_tag = strtol(p_buffer,NULL,16);
1898 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1899 fill_channels_info(&p_stream->fmt.audio);
1900 if( st->time_unit <= 0 )
1901 st->time_unit = 10000000;
1902 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1903 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1904 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1905 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1907 wf_tag_to_fourcc( i_format_tag,
1908 &p_stream->fmt.i_codec, 0 );
1910 if( p_stream->fmt.i_codec ==
1911 VLC_FOURCC('u','n','d','f') )
1913 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1914 ( i_format_tag >> 8 ) & 0xff,
1915 i_format_tag & 0xff );
1918 msg_Dbg( p_demux, "found audio header of type: %.4s",
1919 (char *)&p_stream->fmt.i_codec );
1920 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1921 "%dbits/sample %dkb/s",
1923 p_stream->fmt.audio.i_channels,
1924 p_stream->fmt.audio.i_rate,
1925 p_stream->fmt.audio.i_bitspersample,
1926 p_stream->fmt.i_bitrate / 1024 );
1927 if ( p_stream->f_rate == 0 )
1929 msg_Dbg( p_demux, "invalid oggds audio header" );
1930 Ogg_LogicalStreamDelete( p_demux, p_stream );
1934 /* Check for text (subtitles) header */
1935 else if( !strncmp(st->streamtype, "text", 4) )
1937 /* We need to get rid of the header packet */
1938 ogg_stream_packetout( &p_stream->os, &oggpacket );
1940 msg_Dbg( p_demux, "found text subtitle header" );
1941 p_stream->fmt.i_cat = SPU_ES;
1942 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1943 p_stream->f_rate = 1000; /* granulepos is in millisec */
1947 msg_Dbg( p_demux, "stream %d has a header marker "
1948 "but is of an unknown type", p_ogg->i_streams-1 );
1953 else if( oggpacket.bytes >= 8 &&
1954 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1958 msg_Dbg( p_demux, "stream %d is a skeleton",
1959 p_ogg->i_streams-1 );
1960 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1964 msg_Dbg( p_demux, "stream %d is of unknown type",
1965 p_ogg->i_streams-1 );
1970 /* we'll need to get all headers */
1971 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1973 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1974 return VLC_EGENERIC;
1977 /* This is the first data page, which means we are now finished
1978 * with the initial pages. We just need to store it in the relevant
1980 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1982 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1983 &p_ogg->current_page ) == 0 )
1985 p_ogg->b_page_waiting = true;
1994 return VLC_EGENERIC;
1997 /****************************************************************************
1998 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1999 ****************************************************************************/
2000 static void Ogg_CreateES( demux_t *p_demux )
2002 demux_sys_t *p_ogg = p_demux->p_sys;
2003 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2006 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2008 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2010 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2012 /* Better be safe than sorry when possible with ogm */
2013 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2014 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2015 p_stream->fmt.b_packetized = false;
2017 /* Try first to reuse an old ES */
2019 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2020 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2022 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2024 p_stream->p_es = p_old_stream->p_es;
2025 p_stream->b_finished = false;
2026 p_stream->b_reinit = false;
2027 p_stream->b_initializing = false;
2028 p_stream->i_pre_skip = 0;
2029 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2030 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2032 p_old_stream->p_es = NULL;
2033 p_old_stream = NULL;
2034 if ( b_resetdecoder )
2036 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2037 p_stream->p_es, &p_stream->fmt );
2042 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2045 // TODO: something to do here ?
2046 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2048 /* Set the CMML stream active */
2049 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2054 if( p_ogg->p_old_stream )
2056 if( p_ogg->p_old_stream->p_es )
2057 msg_Dbg( p_demux, "old stream not reused" );
2058 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2059 p_ogg->p_old_stream = NULL;
2063 /****************************************************************************
2064 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2065 * Elementary streams.
2066 ****************************************************************************/
2067 static int Ogg_BeginningOfStream( demux_t *p_demux )
2069 demux_sys_t *p_ogg = p_demux->p_sys ;
2072 /* Find the logical streams embedded in the physical stream and
2073 * initialize our p_ogg structure. */
2074 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2076 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2077 return VLC_EGENERIC;
2080 p_ogg->i_bitrate = 0;
2082 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2084 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2086 p_stream->p_es = NULL;
2088 /* initialise kframe index */
2091 if ( p_stream->fmt.i_bitrate == 0 &&
2092 ( p_stream->fmt.i_cat == VIDEO_ES ||
2093 p_stream->fmt.i_cat == AUDIO_ES ) )
2094 p_ogg->b_partial_bitrate = true;
2096 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2098 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2099 p_stream->i_previous_granulepos = -1;
2100 p_stream->b_reinit = false;
2103 /* get total frame count for video stream; we will need this for seeking */
2104 p_ogg->i_total_frames = 0;
2109 /****************************************************************************
2110 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2111 ****************************************************************************/
2112 static void Ogg_EndOfStream( demux_t *p_demux )
2114 demux_sys_t *p_ogg = p_demux->p_sys ;
2117 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2118 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2119 free( p_ogg->pp_stream );
2122 p_ogg->i_bitrate = 0;
2123 p_ogg->i_streams = 0;
2124 p_ogg->pp_stream = NULL;
2125 p_ogg->skeleton.major = 0;
2126 p_ogg->skeleton.minor = 0;
2127 p_ogg->b_preparsing_done = false;
2128 p_ogg->b_es_created = false;
2129 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2130 p_ogg->i_pcr - VLC_TS_0 : 0;
2134 vlc_meta_Delete( p_ogg->p_meta );
2135 p_ogg->p_meta = NULL;
2137 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2139 if ( p_ogg->pp_seekpoints[i] )
2140 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2142 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2143 p_ogg->i_seekpoints = 0;
2146 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2148 #ifdef HAVE_LIBVORBIS
2149 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2151 FREENULL( p_stream->special.vorbis.p_info );
2152 FREENULL( p_stream->special.vorbis.p_comment );
2153 p_stream->special.vorbis.i_headers_flags = 0;
2156 VLC_UNUSED( p_stream );
2161 * This function delete and release all data associated to a logical_stream_t
2163 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2165 if( p_stream->p_es )
2166 es_out_Del( p_demux->out, p_stream->p_es );
2168 ogg_stream_clear( &p_stream->os );
2169 free( p_stream->p_headers );
2171 Ogg_CleanSpecificData( p_stream );
2173 es_format_Clean( &p_stream->fmt_old );
2174 es_format_Clean( &p_stream->fmt );
2176 if ( p_stream->idx != NULL)
2178 oggseek_index_entries_free( p_stream->idx );
2181 Ogg_FreeSkeleton( p_stream->p_skel );
2182 p_stream->p_skel = NULL;
2183 if ( p_demux->p_sys->p_skelstream == p_stream )
2184 p_demux->p_sys->p_skelstream = NULL;
2186 /* Shouldn't happen */
2187 if ( unlikely( p_stream->p_preparse_block ) )
2189 block_ChainRelease( p_stream->p_preparse_block );
2190 p_stream->p_preparse_block = NULL;
2192 free( p_stream->prepcr.pp_blocks );
2197 * This function check if a we need to reset a decoder in case we are
2200 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2202 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2203 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2204 unsigned i_new_count;
2205 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2208 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2209 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2210 unsigned i_old_count;
2211 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2214 bool b_match = i_new_count == i_old_count;
2215 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2217 /* Ignore vorbis comment */
2220 if( pi_new_size[i] != pi_old_size[i] ||
2221 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2228 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2229 const es_format_t *p_old )
2231 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2232 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2233 unsigned i_new_count;
2234 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2236 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2237 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2238 unsigned i_old_count;
2239 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2241 bool b_match = false;
2242 if( i_new_count == i_old_count && i_new_count > 0 )
2244 static const unsigned char default_map[2] = { 0, 1 };
2245 unsigned char *p_old_head;
2246 unsigned char *p_new_head;
2247 const unsigned char *p_old_map;
2248 const unsigned char *p_new_map;
2249 int i_old_channel_count;
2250 int i_new_channel_count;
2251 int i_old_stream_count;
2252 int i_new_stream_count;
2253 int i_old_coupled_count;
2254 int i_new_coupled_count;
2255 p_old_head = (unsigned char *)pp_old_data[0];
2256 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2257 p_old_map = default_map;
2258 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2260 i_old_channel_count = p_old_head[9];
2261 switch( p_old_head[18] )
2264 i_old_stream_count = 1;
2265 i_old_coupled_count = i_old_channel_count - 1;
2268 if( pi_old_size[0] >= 21U + i_old_channel_count )
2270 i_old_stream_count = p_old_head[19];
2271 i_old_coupled_count = p_old_head[20];
2272 p_old_map = p_old_head + 21;
2277 p_new_head = (unsigned char *)pp_new_data[0];
2278 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2279 p_new_map = default_map;
2280 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2282 i_new_channel_count = p_new_head[9];
2283 switch( p_new_head[18] )
2286 i_new_stream_count = 1;
2287 i_new_coupled_count = i_new_channel_count - 1;
2290 if( pi_new_size[0] >= 21U + i_new_channel_count )
2292 i_new_stream_count = p_new_head[19];
2293 i_new_coupled_count = p_new_head[20];
2294 p_new_map = p_new_head+21;
2299 b_match = i_old_channel_count == i_new_channel_count &&
2300 i_old_stream_count == i_new_stream_count &&
2301 i_old_coupled_count == i_new_coupled_count &&
2302 memcmp(p_old_map, p_new_map,
2303 i_new_channel_count*sizeof(*p_new_map)) == 0;
2309 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2311 bool b_compatible = false;
2312 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2315 /* Only Vorbis and Opus are supported. */
2316 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2317 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2318 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2319 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2322 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2324 return !b_compatible;
2327 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2328 const void *p_headers, unsigned i_headers )
2330 demux_sys_t *p_ogg = p_demux->p_sys;
2331 int i_cover_score = 0;
2332 int i_cover_idx = 0;
2333 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2334 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2335 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2337 pf_replay_gain[i] = 0;
2338 pf_replay_peak[i] = 0;
2340 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2341 &p_ogg->i_attachments, &p_ogg->attachments,
2342 &i_cover_score, &i_cover_idx,
2343 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2344 &pf_replay_gain, &pf_replay_peak );
2345 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2348 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2349 p_ogg->attachments[i_cover_idx]->psz_name );
2350 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2353 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2355 if ( pf_replay_gain[i] != 0 )
2357 p_fmt->audio_replay_gain.pb_gain[i] = true;
2358 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2359 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2361 if ( pf_replay_peak[i] != 0 )
2363 p_fmt->audio_replay_gain.pb_peak[i] = true;
2364 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2365 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2369 if( p_ogg->i_seekpoints > 1 )
2371 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2375 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2376 const void *p_headers, unsigned i_headers, unsigned i_skip )
2378 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2379 void *pp_data[XIPH_MAX_HEADER_COUNT];
2382 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2384 /* TODO how to handle multiple comments properly ? */
2385 if( i_count >= 2 && pi_size[1] > i_skip )
2387 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2391 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2393 demux_sys_t *p_ogg = p_demux->p_sys;
2395 switch( p_fmt->i_codec )
2397 /* 3 headers with the 2° one being the comments */
2398 case VLC_CODEC_VORBIS:
2399 case VLC_CODEC_THEORA:
2400 case VLC_CODEC_DAALA:
2401 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2403 case VLC_CODEC_OPUS:
2404 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2406 case VLC_CODEC_SPEEX:
2407 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2410 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2412 /* N headers with the 2° one being the comments */
2413 case VLC_CODEC_KATE:
2414 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2415 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2419 case VLC_CODEC_FLAC:
2420 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2424 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2425 case VLC_CODEC_DIRAC:
2430 p_demux->info.i_update |= INPUT_UPDATE_META;
2433 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2434 ogg_packet *p_oggpacket )
2437 unsigned int i_fps_numerator;
2438 unsigned int i_fps_denominator;
2439 int i_keyframe_frequency_force;
2445 p_stream->fmt.i_cat = VIDEO_ES;
2446 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2448 /* Signal that we want to keep a backup of the theora
2449 * stream headers. They will be used when switching between
2451 p_stream->b_force_backup = true;
2453 /* Cheat and get additionnal info ;) */
2454 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2455 bs_skip( &bitstream, 56 );
2457 i_major = bs_read( &bitstream, 8 ); /* major version num */
2458 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2459 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2461 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2462 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2463 bs_read( &bitstream, 24 ); /* frame width */
2464 bs_read( &bitstream, 24 ); /* frame height */
2465 bs_read( &bitstream, 8 ); /* x offset */
2466 bs_read( &bitstream, 8 ); /* y offset */
2468 i_fps_numerator = bs_read( &bitstream, 32 );
2469 i_fps_denominator = bs_read( &bitstream, 32 );
2470 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2471 bs_read( &bitstream, 24 ); /* aspect_numerator */
2472 bs_read( &bitstream, 24 ); /* aspect_denominator */
2474 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2475 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2477 bs_read( &bitstream, 8 ); /* colorspace */
2478 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2479 bs_read( &bitstream, 6 ); /* quality */
2481 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2483 /* granule_shift = i_log( frequency_force -1 ) */
2484 p_stream->i_granule_shift = 0;
2485 i_keyframe_frequency_force--;
2486 while( i_keyframe_frequency_force )
2488 p_stream->i_granule_shift++;
2489 i_keyframe_frequency_force >>= 1;
2492 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2493 p_stream->i_keyframe_offset = 0;
2494 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2495 if ( p_stream->f_rate == 0 ) return false;
2497 if ( i_version >= 3002001 )
2499 p_stream->i_keyframe_offset = 1;
2504 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2505 ogg_packet *p_oggpacket )
2508 uint32_t i_timebase_numerator;
2509 uint32_t i_timebase_denominator;
2510 int i_keyframe_frequency_force;
2516 p_stream->fmt.i_cat = VIDEO_ES;
2517 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2519 /* Signal that we want to keep a backup of the daala
2520 * stream headers. They will be used when switching between
2522 p_stream->b_force_backup = true;
2524 /* Cheat and get additionnal info ;) */
2525 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2526 oggpack_adv( &opb, 48 );
2528 i_major = oggpack_read( &opb, 8 ); /* major version num */
2529 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2530 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2532 oggpack_adv( &opb, 32 ); /* width */
2533 oggpack_adv( &opb, 32 ); /* height */
2535 oggpack_adv( &opb, 32 ); /* aspect numerator */
2536 oggpack_adv( &opb, 32 ); /* aspect denominator */
2537 i_timebase_numerator = oggpack_read( &opb, 32 );
2539 i_timebase_denominator = oggpack_read( &opb, 32 );
2540 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2542 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2543 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2545 oggpack_adv( &opb, 32 ); /* frame duration */
2547 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2549 /* granule_shift = i_log( frequency_force -1 ) */
2550 p_stream->i_granule_shift = 0;
2551 i_keyframe_frequency_force--;
2552 while( i_keyframe_frequency_force )
2554 p_stream->i_granule_shift++;
2555 i_keyframe_frequency_force >>= 1;
2558 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2559 p_stream->i_keyframe_offset = 0;
2560 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2561 if ( p_stream->f_rate == 0 ) return false;
2566 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2567 ogg_packet *p_oggpacket )
2571 p_stream->fmt.i_cat = AUDIO_ES;
2572 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2574 /* Signal that we want to keep a backup of the vorbis
2575 * stream headers. They will be used when switching between
2577 p_stream->b_force_backup = true;
2579 /* Cheat and get additionnal info ;) */
2580 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2581 oggpack_adv( &opb, 88 );
2582 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2583 fill_channels_info(&p_stream->fmt.audio);
2584 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2585 oggpack_read( &opb, 32 );
2586 oggpack_adv( &opb, 32 );
2587 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2588 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2589 if ( p_stream->f_rate == 0 ) return false;
2592 #ifdef HAVE_LIBVORBIS
2593 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2594 ogg_packet *p_oggpacket, int i_number )
2598 case VORBIS_HEADER_IDENTIFICATION:
2599 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2600 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2601 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2603 FREENULL( p_stream->special.vorbis.p_info );
2604 FREENULL( p_stream->special.vorbis.p_comment );
2607 vorbis_info_init( p_stream->special.vorbis.p_info );
2608 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2611 case VORBIS_HEADER_COMMENT:
2612 case VORBIS_HEADER_SETUP:
2613 if ( !p_stream->special.vorbis.p_info ||
2614 vorbis_synthesis_headerin(
2615 p_stream->special.vorbis.p_info,
2616 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2619 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2628 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2629 ogg_packet *p_oggpacket )
2633 p_stream->fmt.i_cat = AUDIO_ES;
2634 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2636 /* Signal that we want to keep a backup of the speex
2637 * stream headers. They will be used when switching between
2639 p_stream->b_force_backup = true;
2641 /* Cheat and get additionnal info ;) */
2642 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2643 oggpack_adv( &opb, 224 );
2644 oggpack_adv( &opb, 32 ); /* speex_version_id */
2645 oggpack_adv( &opb, 32 ); /* header_size */
2646 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2647 if ( p_stream->f_rate == 0 ) return false;
2648 oggpack_adv( &opb, 32 ); /* mode */
2649 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2650 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2651 fill_channels_info(&p_stream->fmt.audio);
2652 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2653 p_stream->special.speex.i_framesize =
2654 oggpack_read( &opb, 32 ); /* frame_size */
2655 oggpack_adv( &opb, 32 ); /* vbr */
2656 p_stream->special.speex.i_framesperpacket =
2657 oggpack_read( &opb, 32 ); /* frames_per_packet */
2658 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2662 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2663 ogg_packet *p_oggpacket )
2667 p_stream->fmt.i_cat = AUDIO_ES;
2668 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2670 /* Signal that we want to keep a backup of the opus
2671 * stream headers. They will be used when switching between
2673 p_stream->b_force_backup = true;
2675 /* All OggOpus streams are timestamped at 48kHz and
2676 * can be played at 48kHz. */
2677 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2678 p_stream->fmt.i_bitrate = 0;
2680 /* Cheat and get additional info ;) */
2681 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2682 oggpack_adv( &opb, 64 );
2683 oggpack_adv( &opb, 8 ); /* version_id */
2684 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2685 fill_channels_info(&p_stream->fmt.audio);
2686 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2687 /* For Opus, trash the first 80 ms of decoded output as
2688 well, to avoid blowing out speakers if we get unlucky.
2689 Opus predicts content from prior frames, which can go
2690 badly if we seek right where the stream goes from very
2691 quiet to very loud. It will converge after a bit. */
2692 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2695 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2696 ogg_packet *p_oggpacket )
2698 /* Parse the STREAMINFO metadata */
2701 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2704 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2706 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2710 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2713 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2714 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2715 fill_channels_info(&p_stream->fmt.audio);
2717 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2718 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2719 if ( p_stream->f_rate == 0 ) return false;
2723 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2726 /* Fake this as the last metadata block */
2727 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2731 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2732 ogg_packet *p_oggpacket )
2740 p_stream->fmt.i_cat = SPU_ES;
2741 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2743 /* Signal that we want to keep a backup of the kate
2744 * stream headers. They will be used when switching between
2746 p_stream->b_force_backup = true;
2748 /* Cheat and get additionnal info ;) */
2749 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2750 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2751 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2752 oggpack_adv( &opb, 3*8 );
2753 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2754 oggpack_adv( &opb, 8*8 ); /* reserved */
2755 gnum = oggpack_read( &opb, 32 );
2756 gden = oggpack_read( &opb, 32 );
2757 gden = __MAX( gden, 1 );
2758 p_stream->f_rate = (double)gnum/gden;
2759 if ( p_stream->f_rate == 0 ) return false;
2761 p_stream->fmt.psz_language = malloc(16);
2762 if( p_stream->fmt.psz_language )
2764 for( n = 0; n < 16; n++ )
2765 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2766 p_stream->fmt.psz_language[15] = 0; /* just in case */
2770 for( n = 0; n < 16; n++ )
2771 oggpack_read(&opb,8);
2773 p_stream->fmt.psz_description = malloc(16);
2774 if( p_stream->fmt.psz_description )
2776 for( n = 0; n < 16; n++ )
2777 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2778 p_stream->fmt.psz_description[15] = 0; /* just in case */
2780 /* Now find a localized user readable description for this category */
2781 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2784 free( p_stream->fmt.psz_description );
2785 p_stream->fmt.psz_description = psz_desc;
2790 for( n = 0; n < 16; n++ )
2791 oggpack_read(&opb,8);
2797 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2798 ogg_packet *p_oggpacket )
2800 switch( p_oggpacket->packet[5] )
2804 /* Mapping version */
2805 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2807 p_stream->fmt.i_cat = VIDEO_ES;
2808 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2809 p_stream->i_granule_shift = 32;
2810 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2811 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2812 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2813 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2814 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2815 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2816 p_stream->fmt.video.i_frame_rate_base =
2817 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2818 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2819 if ( p_stream->f_rate == 0 ) return false;
2823 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2824 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2831 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2832 bool *b_force_backup, bool *b_packet_out )
2834 if( !strncmp(psz_value, "audio/x-wav", 11) )
2836 /* n.b. WAVs are unsupported right now */
2837 p_stream->fmt.i_cat = UNKNOWN_ES;
2838 free( p_stream->fmt.psz_description );
2839 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2841 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2842 !strncmp(psz_value, "audio/vorbis", 12) )
2844 p_stream->fmt.i_cat = AUDIO_ES;
2845 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2847 *b_force_backup = true;
2849 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2850 !strncmp(psz_value, "audio/speex", 11) )
2852 p_stream->fmt.i_cat = AUDIO_ES;
2853 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2855 *b_force_backup = true;
2857 else if( !strncmp(psz_value, "audio/flac", 10) )
2859 p_stream->fmt.i_cat = AUDIO_ES;
2860 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2862 *b_force_backup = true;
2864 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2865 !strncmp(psz_value, "video/theora", 12) )
2867 p_stream->fmt.i_cat = VIDEO_ES;
2868 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2870 *b_force_backup = true;
2872 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2873 !strncmp(psz_value, "video/daala", 11) )
2875 p_stream->fmt.i_cat = VIDEO_ES;
2876 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2878 *b_force_backup = true;
2880 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2882 p_stream->fmt.i_cat = VIDEO_ES;
2883 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2885 *b_force_backup = true;
2887 else if( !strncmp(psz_value, "video/mpeg", 10) )
2889 /* n.b. MPEG streams are unsupported right now */
2890 p_stream->fmt.i_cat = VIDEO_ES;
2891 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2893 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2894 !strncmp(psz_value, "text/cmml", 9) )
2896 p_stream->fmt.i_cat = SPU_ES;
2897 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2898 *b_packet_out = true;
2900 else if( !strncmp(psz_value, "application/kate", 16) )
2903 p_stream->fmt.i_cat = UNKNOWN_ES;
2904 free( p_stream->fmt.psz_description );
2905 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2907 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2909 p_stream->fmt.i_cat = VIDEO_ES;
2910 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2914 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2915 logical_stream_t *p_stream,
2916 ogg_packet *p_oggpacket )
2918 if( p_oggpacket->bytes >= 28 &&
2919 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2923 uint16_t major_version;
2924 uint16_t minor_version;
2925 uint64_t timebase_numerator;
2926 uint64_t timebase_denominator;
2928 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2930 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2931 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2932 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2933 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2934 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2935 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2937 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2938 "Timebase %"PRId64" / %"PRId64,
2939 major_version, minor_version,
2940 timebase_numerator, timebase_denominator );
2942 else if( p_oggpacket->bytes >= 42 &&
2943 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2945 uint64_t granule_rate_numerator;
2946 uint64_t granule_rate_denominator;
2947 char content_type_string[1024];
2949 /* Read in Annodex header fields */
2951 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2952 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2953 p_stream->i_secondary_header_packets =
2954 GetDWLE( &p_oggpacket->packet[24] );
2956 /* we are guaranteed that the first header field will be
2957 * the content-type (by the Annodex standard) */
2958 content_type_string[0] = '\0';
2959 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2961 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2962 p_oggpacket->bytes - 1 );
2963 if( p && p[0] == '\r' && p[1] == '\n' )
2964 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2965 content_type_string );
2968 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2969 granule_rate_numerator, granule_rate_denominator,
2970 p_stream->i_secondary_header_packets, content_type_string );
2972 p_stream->f_rate = (float) granule_rate_numerator /
2973 (float) granule_rate_denominator;
2975 /* What type of file do we have?
2976 * strcmp is safe to use here because we've extracted
2977 * content_type_string from the stream manually */
2978 bool b_dopacketout = false;
2979 Ogg_ApplyContentType( p_stream, content_type_string,
2980 &p_stream->b_force_backup, &b_dopacketout );
2981 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2985 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2986 ogg_packet *p_oggpacket )
2988 p_demux->p_sys->p_skelstream = p_stream;
2989 /* There can be only 1 skeleton for streams */
2990 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2991 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2992 if ( asprintf( & p_stream->fmt.psz_description,
2993 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2994 p_demux->p_sys->skeleton.major,
2995 p_demux->p_sys->skeleton.minor ) < 0 )
2996 p_stream->fmt.psz_description = NULL;
2999 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3001 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3003 /* Find the matching stream for this skeleton data */
3004 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3005 logical_stream_t *p_target_stream = NULL;
3006 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3008 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3010 p_target_stream = p_demux->p_sys->pp_stream[i];
3014 if ( !p_target_stream ) return;
3016 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3019 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3020 if ( !p_skel ) return;
3021 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3022 p_skel->p_index = NULL;
3023 p_target_stream->p_skel = p_skel;
3026 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3027 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3028 const unsigned char *p = p_messages;
3029 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3031 if ( *p == 0x0D && *(p+1) == 0x0A )
3033 char *psz_message = strndup( (const char *) p_messages,
3037 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3038 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3040 if ( p < p_boundary - 1 ) p_messages = p + 2;
3047 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3048 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3049 unsigned const char *p_end,
3050 uint64_t *pi_value )
3056 while ( p_begin < p_end )
3058 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3059 *pi_value = *pi_value | ( i_read << i_shift );
3061 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3064 *pi_value = GetQWLE( pi_value );
3068 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3070 if ( p_demux->p_sys->skeleton.major < 4
3071 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3074 /* Find the matching stream for this skeleton data */
3075 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3076 logical_stream_t *p_stream = NULL;
3077 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3079 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3081 p_stream = p_demux->p_sys->pp_stream[i];
3085 if ( !p_stream || !p_stream->p_skel ) return;
3086 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3087 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3088 if ( !i_keypoints ) return;
3090 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3091 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3092 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3093 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3094 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3095 uint64_t i_offset = 0;
3096 uint64_t i_time = 0;
3097 uint64_t i_keypoints_found = 0;
3099 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3102 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3104 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3105 i_time += i_val * p_stream->p_skel->i_indexstampden;
3106 i_keypoints_found++;
3109 if ( i_keypoints_found != i_keypoints )
3111 msg_Warn( p_demux, "Invalid Index: missing entries" );
3115 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3116 if ( !p_stream->p_skel->p_index ) return;
3117 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3118 p_oggpacket->bytes - 42 );
3119 p_stream->p_skel->i_index = i_keypoints_found;
3120 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3123 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3125 if ( !p_skel ) return;
3126 for ( int i=0; i< p_skel->i_messages; i++ )
3127 free( p_skel->ppsz_messages[i] );
3128 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3129 free( p_skel->p_index );
3133 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3135 if ( !p_stream->p_skel ) return;
3136 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3138 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3139 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3141 free( p_stream->fmt.psz_description );
3142 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3144 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3147 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3152 /* Return true if there's a skeleton exact match */
3153 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3154 int64_t *pi_lower, int64_t *pi_upper )
3156 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3159 /* Validate range */
3160 if ( i_time < p_stream->p_skel->i_indexfirstnum
3161 * p_stream->p_skel->i_indexstampden ||
3162 i_time > p_stream->p_skel->i_indexlastnum
3163 * p_stream->p_skel->i_indexstampden ) return false;
3165 /* Then Lookup its index */
3166 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3171 } current = { 0, 0 }, prev = { -1, -1 };
3173 uint64_t i_keypoints_found = 0;
3175 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3176 && i_keypoints_found < p_stream->p_skel->i_index )
3179 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3180 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3181 current.i_pos += i_val;
3182 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3183 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3184 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3185 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3187 i_keypoints_found++;
3189 if ( i_time <= current.i_time )
3191 *pi_lower = prev.i_pos;
3192 *pi_upper = current.i_pos;
3193 return ( i_time == current.i_time );
3200 static uint32_t dirac_uint( bs_t *p_bs )
3202 uint32_t u_count = 0, u_value = 0;
3204 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3208 u_value |= bs_read( p_bs, 1 );
3211 return (1<<u_count) - 1 + u_value;
3214 static int dirac_bool( bs_t *p_bs )
3216 return bs_read( p_bs, 1 );
3219 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3220 ogg_packet *p_oggpacket )
3222 static const struct {
3223 uint32_t u_n /* numerator */, u_d /* denominator */;
3224 } p_dirac_frate_tbl[] = { /* table 10.3 */
3225 {1,1}, /* this first value is never used */
3226 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3227 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3229 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3231 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3232 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3234 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3238 p_stream->i_granule_shift = 22; /* not 32 */
3240 /* Backing up stream headers is not required -- seqhdrs are repeated
3241 * thoughout the stream at suitable decoding start points */
3242 p_stream->b_force_backup = false;
3244 /* read in useful bits from sequence header */
3245 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3246 bs_skip( &bs, 13*8); /* parse_info_header */
3247 dirac_uint( &bs ); /* major_version */
3248 dirac_uint( &bs ); /* minor_version */
3249 dirac_uint( &bs ); /* profile */
3250 dirac_uint( &bs ); /* level */
3252 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3253 if( u_video_format >= u_dirac_vidfmt_frate )
3255 /* don't know how to parse this ogg dirac stream */
3259 if( dirac_bool( &bs ) )
3261 dirac_uint( &bs ); /* frame_width */
3262 dirac_uint( &bs ); /* frame_height */
3265 if( dirac_bool( &bs ) )
3267 dirac_uint( &bs ); /* chroma_format */
3270 if( dirac_bool( &bs ) )
3272 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3275 p_stream->special.dirac.b_interlaced = false;
3277 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3278 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3279 u_d = __MAX( u_d, 1 );
3280 if( dirac_bool( &bs ) )
3282 uint32_t u_frame_rate_index = dirac_uint( &bs );
3283 if( u_frame_rate_index >= u_dirac_frate_tbl )
3285 /* something is wrong with this stream */
3288 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3289 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3290 if( u_frame_rate_index == 0 )
3292 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3293 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3296 p_stream->f_rate = (float) u_n / u_d;
3297 if ( p_stream->f_rate == 0 ) return false;
3299 /* probably is an ogg dirac es */
3300 p_stream->fmt.i_cat = VIDEO_ES;
3301 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;