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 & 0x07) == 0x07) // 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 )
310 return VLC_DEMUXER_EOF;
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 )
353 return VLC_DEMUXER_EOF; /* EOF */
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 );
674 return VLC_DEMUXER_SUCCESS;
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 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1357 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1358 p_stream->fmt.b_packetized )
1360 /* Handle OggFlac spec violation (multiple frame/packet
1361 * by turning on packetizer */
1362 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1363 p_stream->fmt.b_packetized = false;
1364 es_out_Del( p_demux->out, p_stream->p_es );
1365 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1368 /* Blatant abuse of the i_length field. */
1369 p_block->i_length = p_stream->i_end_trim;
1371 else if( p_stream->fmt.i_cat == SPU_ES )
1373 p_block->i_length = 0;
1375 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1377 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1378 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1379 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1380 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1381 /* granulepos for dirac is possibly broken, this value should be ignored */
1382 if( 0 >= p_oggpacket->granulepos )
1384 p_block->i_pts = VLC_TS_INVALID;
1385 p_block->i_dts = p_stream->i_pcr;
1389 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1390 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1391 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1392 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1393 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1394 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1395 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1396 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1397 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1398 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1399 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1401 if( p_oggpacket->bytes <= 0 )
1403 msg_Dbg( p_demux, "discarding 0 sized packet" );
1404 block_Release( p_block );
1407 /* We remove the header from the packet */
1408 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1409 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1411 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1413 /* But with subtitles we need to retrieve the duration first */
1414 int i, lenbytes = 0;
1416 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1418 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1420 lenbytes = lenbytes << 8;
1421 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1424 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1425 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1426 p_oggpacket->packet[i_header_len + 1] != 0 &&
1427 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1428 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1430 p_block->i_length = (mtime_t)lenbytes * 1000;
1435 if( p_block->i_buffer >= (unsigned int)i_header_len )
1436 p_block->i_buffer -= i_header_len;
1438 p_block->i_buffer = 0;
1442 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1444 /* FIXME: the biggest hack I've ever done */
1445 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1446 p_block->i_pts, p_block->i_dts );
1450 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1451 p_oggpacket->bytes - i_header_len );
1453 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1456 static int Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1458 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1461 /****************************************************************************
1462 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1463 * stream and fill p_ogg.
1464 *****************************************************************************
1465 * The initial page of a logical stream is marked as a 'bos' page.
1466 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1467 * together and all of the initial pages must appear before any data pages.
1469 * On success this function returns VLC_SUCCESS.
1470 ****************************************************************************/
1471 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1473 demux_sys_t *p_ogg = p_demux->p_sys ;
1474 ogg_packet oggpacket;
1476 p_ogg->i_total_length = stream_Size ( p_demux->s );
1477 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1480 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1483 if( ogg_page_bos( &p_ogg->current_page ) )
1486 /* All is wonderful in our fine fine little world.
1487 * We found the beginning of our first logical stream. */
1488 while( ogg_page_bos( &p_ogg->current_page ) )
1490 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1491 if( unlikely( !p_stream ) )
1494 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1496 es_format_Init( &p_stream->fmt, 0, 0 );
1497 es_format_Init( &p_stream->fmt_old, 0, 0 );
1498 p_stream->b_initializing = true;
1500 /* Setup the logical stream */
1501 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1502 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1504 /* Extract the initial header from the first page and verify
1505 * the codec type of this Ogg bitstream */
1506 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1508 /* error. stream version mismatch perhaps */
1509 msg_Err( p_demux, "error reading first page of "
1510 "Ogg bitstream data" );
1511 return VLC_EGENERIC;
1514 /* FIXME: check return value */
1515 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1517 /* Check for Vorbis header */
1518 if( oggpacket.bytes >= 7 &&
1519 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1521 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1522 msg_Dbg( p_demux, "found vorbis header" );
1525 msg_Dbg( p_demux, "found invalid vorbis header" );
1526 Ogg_LogicalStreamDelete( p_demux, p_stream );
1531 /* Check for Speex header */
1532 else if( oggpacket.bytes >= 5 &&
1533 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1535 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1536 msg_Dbg( p_demux, "found speex header, channels: %i, "
1537 "rate: %i, bitrate: %i, frames: %i group %i",
1538 p_stream->fmt.audio.i_channels,
1539 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1540 p_stream->special.speex.i_framesize,
1541 p_stream->special.speex.i_framesperpacket );
1544 msg_Dbg( p_demux, "found invalid Speex header" );
1545 Ogg_LogicalStreamDelete( p_demux, p_stream );
1550 /* Check for Opus header */
1551 else if( oggpacket.bytes >= 8 &&
1552 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1554 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1555 msg_Dbg( p_demux, "found opus header, channels: %i, "
1557 p_stream->fmt.audio.i_channels,
1558 (int)p_stream->i_pre_skip);
1559 p_stream->i_skip_frames = p_stream->i_pre_skip;
1561 /* Check for Flac header (< version 1.1.1) */
1562 else if( oggpacket.bytes >= 4 &&
1563 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1565 msg_Dbg( p_demux, "found FLAC header" );
1567 /* Grrrr!!!! Did they really have to put all the
1568 * important info in the second header packet!!!
1569 * (STREAMINFO metadata is in the following packet) */
1570 p_stream->b_force_backup = true;
1571 p_stream->fmt.i_cat = AUDIO_ES;
1572 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1574 /* Check for Flac header (>= version 1.1.1) */
1575 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1576 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1577 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1579 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1580 oggpacket.packet[8];
1581 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1582 "(%i header packets)",
1583 oggpacket.packet[5], oggpacket.packet[6],
1586 p_stream->b_force_backup = true;
1588 p_stream->fmt.i_cat = AUDIO_ES;
1589 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1590 oggpacket.packet += 13; oggpacket.bytes -= 13;
1591 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1593 msg_Dbg( p_demux, "found invalid Flac header" );
1594 Ogg_LogicalStreamDelete( p_demux, p_stream );
1599 /* Check for Theora header */
1600 else if( oggpacket.bytes >= 7 &&
1601 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1603 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1605 "found theora header, bitrate: %i, rate: %f",
1606 p_stream->fmt.i_bitrate, p_stream->f_rate );
1609 msg_Dbg( p_demux, "found invalid Theora header" );
1610 Ogg_LogicalStreamDelete( p_demux, p_stream );
1615 /* Check for Daala header */
1616 else if( oggpacket.bytes >= 6 &&
1617 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1619 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1621 "found daala header, bitrate: %i, rate: %f",
1622 p_stream->fmt.i_bitrate, p_stream->f_rate );
1625 msg_Dbg( p_demux, "found invalid Daala header" );
1626 Ogg_LogicalStreamDelete( p_demux, p_stream );
1631 /* Check for Dirac header */
1632 else if( ( oggpacket.bytes >= 5 &&
1633 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1634 ( oggpacket.bytes >= 9 &&
1635 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1637 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1638 msg_Dbg( p_demux, "found dirac header" );
1641 msg_Warn( p_demux, "found dirac header isn't decodable" );
1642 Ogg_LogicalStreamDelete( p_demux, p_stream );
1647 /* Check for Tarkin header */
1648 else if( oggpacket.bytes >= 7 &&
1649 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1653 msg_Dbg( p_demux, "found tarkin header" );
1654 p_stream->fmt.i_cat = VIDEO_ES;
1655 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1657 /* Cheat and get additionnal info ;) */
1658 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1659 oggpack_adv( &opb, 88 );
1660 oggpack_adv( &opb, 104 );
1661 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1662 p_stream->f_rate = 2; /* FIXME */
1664 "found tarkin header, bitrate: %i, rate: %f",
1665 p_stream->fmt.i_bitrate, p_stream->f_rate );
1667 /* Check for VP8 header */
1668 else if( oggpacket.bytes >= 26 &&
1669 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1671 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1672 msg_Dbg( p_demux, "found VP8 header "
1673 "fps: %f, width:%i; height:%i",
1675 p_stream->fmt.video.i_width,
1676 p_stream->fmt.video.i_height );
1679 msg_Dbg( p_demux, "invalid VP8 header found");
1680 Ogg_LogicalStreamDelete( p_demux, p_stream );
1685 /* Check for Annodex header */
1686 else if( oggpacket.bytes >= 7 &&
1687 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1689 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1690 /* kill annodex track */
1691 FREENULL( p_stream );
1694 /* Check for Annodex header */
1695 else if( oggpacket.bytes >= 7 &&
1696 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1698 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1700 /* Check for Kate header */
1701 else if( oggpacket.bytes >= 8 &&
1702 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1704 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1705 msg_Dbg( p_demux, "found kate header" );
1708 msg_Dbg( p_demux, "invalid kate header found");
1709 Ogg_LogicalStreamDelete( p_demux, p_stream );
1714 /* Check for OggDS */
1715 else if( oggpacket.bytes >= 142 &&
1716 !memcmp( &oggpacket.packet[1],
1717 "Direct Show Samples embedded in Ogg", 35 ))
1719 /* Old header type */
1720 p_stream->b_oggds = true;
1721 /* Check for video header (old format) */
1722 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1723 oggpacket.bytes >= 184 )
1725 p_stream->fmt.i_cat = VIDEO_ES;
1726 p_stream->fmt.i_codec =
1727 VLC_FOURCC( oggpacket.packet[68],
1728 oggpacket.packet[69],
1729 oggpacket.packet[70],
1730 oggpacket.packet[71] );
1731 msg_Dbg( p_demux, "found video header of type: %.4s",
1732 (char *)&p_stream->fmt.i_codec );
1734 p_stream->fmt.video.i_frame_rate = 10000000;
1735 p_stream->fmt.video.i_frame_rate_base =
1736 GetQWLE((oggpacket.packet+164));
1737 p_stream->fmt.video.i_frame_rate_base =
1738 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1739 p_stream->f_rate = 10000000.0 /
1740 p_stream->fmt.video.i_frame_rate_base;
1741 p_stream->fmt.video.i_bits_per_pixel =
1742 GetWLE((oggpacket.packet+182));
1743 if( !p_stream->fmt.video.i_bits_per_pixel )
1745 p_stream->fmt.video.i_bits_per_pixel = 24;
1746 p_stream->fmt.video.i_width =
1747 GetDWLE((oggpacket.packet+176));
1748 p_stream->fmt.video.i_height =
1749 GetDWLE((oggpacket.packet+180));
1752 "fps: %f, width:%i; height:%i, bitcount:%i",
1754 p_stream->fmt.video.i_width,
1755 p_stream->fmt.video.i_height,
1756 p_stream->fmt.video.i_bits_per_pixel);
1759 /* Check for audio header (old format) */
1760 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1763 unsigned int i_format_tag;
1765 p_stream->fmt.i_cat = AUDIO_ES;
1767 i_extra_size = GetWLE((oggpacket.packet+140));
1768 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1770 p_stream->fmt.i_extra = i_extra_size;
1771 p_stream->fmt.p_extra = malloc( i_extra_size );
1772 if( p_stream->fmt.p_extra )
1773 memcpy( p_stream->fmt.p_extra,
1774 oggpacket.packet + 142, i_extra_size );
1776 p_stream->fmt.i_extra = 0;
1779 i_format_tag = GetWLE((oggpacket.packet+124));
1780 p_stream->fmt.audio.i_channels =
1781 GetWLE((oggpacket.packet+126));
1782 fill_channels_info(&p_stream->fmt.audio);
1783 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1784 GetDWLE((oggpacket.packet+128));
1785 p_stream->fmt.i_bitrate =
1786 GetDWLE((oggpacket.packet+132)) * 8;
1787 p_stream->fmt.audio.i_blockalign =
1788 GetWLE((oggpacket.packet+136));
1789 p_stream->fmt.audio.i_bitspersample =
1790 GetWLE((oggpacket.packet+138));
1792 wf_tag_to_fourcc( i_format_tag,
1793 &p_stream->fmt.i_codec, 0 );
1795 if( p_stream->fmt.i_codec ==
1796 VLC_FOURCC('u','n','d','f') )
1798 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1799 ( i_format_tag >> 8 ) & 0xff,
1800 i_format_tag & 0xff );
1803 msg_Dbg( p_demux, "found audio header of type: %.4s",
1804 (char *)&p_stream->fmt.i_codec );
1805 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1806 "%dbits/sample %dkb/s",
1808 p_stream->fmt.audio.i_channels,
1809 p_stream->fmt.audio.i_rate,
1810 p_stream->fmt.audio.i_bitspersample,
1811 p_stream->fmt.i_bitrate / 1024 );
1812 if ( p_stream->f_rate == 0 )
1814 msg_Dbg( p_demux, "invalid oggds audio header" );
1815 Ogg_LogicalStreamDelete( p_demux, p_stream );
1822 msg_Dbg( p_demux, "stream %d has an old header "
1823 "but is of an unknown type", p_ogg->i_streams-1 );
1824 FREENULL( p_stream );
1828 /* Check for OggDS */
1829 else if( oggpacket.bytes >= 44+1 &&
1830 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1832 stream_header_t tmp;
1833 stream_header_t *st = &tmp;
1835 p_stream->b_oggds = true;
1837 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1838 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1839 st->size = GetDWLE( &oggpacket.packet[1+12] );
1840 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1841 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1842 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1843 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1844 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1846 /* Check for video header (new format) */
1847 if( !strncmp( st->streamtype, "video", 5 ) &&
1848 oggpacket.bytes >= 52+1 )
1850 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1851 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1853 p_stream->fmt.i_cat = VIDEO_ES;
1855 /* We need to get rid of the header packet */
1856 ogg_stream_packetout( &p_stream->os, &oggpacket );
1858 p_stream->fmt.i_codec =
1859 VLC_FOURCC( st->subtype[0], st->subtype[1],
1860 st->subtype[2], st->subtype[3] );
1861 msg_Dbg( p_demux, "found video header of type: %.4s",
1862 (char *)&p_stream->fmt.i_codec );
1864 p_stream->fmt.video.i_frame_rate = 10000000;
1865 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1866 if( st->time_unit <= 0 )
1867 st->time_unit = 400000;
1868 p_stream->f_rate = 10000000.0 / st->time_unit;
1869 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1870 p_stream->fmt.video.i_width = st->sh.video.width;
1871 p_stream->fmt.video.i_height = st->sh.video.height;
1874 "fps: %f, width:%i; height:%i, bitcount:%i",
1876 p_stream->fmt.video.i_width,
1877 p_stream->fmt.video.i_height,
1878 p_stream->fmt.video.i_bits_per_pixel );
1880 /* Check for audio header (new format) */
1881 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1882 oggpacket.bytes >= 56+1 )
1888 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1889 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1890 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1892 p_stream->fmt.i_cat = AUDIO_ES;
1894 /* We need to get rid of the header packet */
1895 ogg_stream_packetout( &p_stream->os, &oggpacket );
1897 i_extra_size = st->size - 56;
1899 if( i_extra_size > 0 &&
1900 i_extra_size < oggpacket.bytes - 1 - 56 )
1902 p_stream->fmt.i_extra = i_extra_size;
1903 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1904 if( p_stream->fmt.p_extra )
1905 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1906 p_stream->fmt.i_extra );
1908 p_stream->fmt.i_extra = 0;
1911 memcpy( p_buffer, st->subtype, 4 );
1913 i_format_tag = strtol(p_buffer,NULL,16);
1914 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1915 fill_channels_info(&p_stream->fmt.audio);
1916 if( st->time_unit <= 0 )
1917 st->time_unit = 10000000;
1918 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1919 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1920 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1921 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1923 wf_tag_to_fourcc( i_format_tag,
1924 &p_stream->fmt.i_codec, 0 );
1926 if( p_stream->fmt.i_codec ==
1927 VLC_FOURCC('u','n','d','f') )
1929 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1930 ( i_format_tag >> 8 ) & 0xff,
1931 i_format_tag & 0xff );
1934 msg_Dbg( p_demux, "found audio header of type: %.4s",
1935 (char *)&p_stream->fmt.i_codec );
1936 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1937 "%dbits/sample %dkb/s",
1939 p_stream->fmt.audio.i_channels,
1940 p_stream->fmt.audio.i_rate,
1941 p_stream->fmt.audio.i_bitspersample,
1942 p_stream->fmt.i_bitrate / 1024 );
1943 if ( p_stream->f_rate == 0 )
1945 msg_Dbg( p_demux, "invalid oggds audio header" );
1946 Ogg_LogicalStreamDelete( p_demux, p_stream );
1951 /* Check for text (subtitles) header */
1952 else if( !strncmp(st->streamtype, "text", 4) )
1954 /* We need to get rid of the header packet */
1955 ogg_stream_packetout( &p_stream->os, &oggpacket );
1957 msg_Dbg( p_demux, "found text subtitle header" );
1958 p_stream->fmt.i_cat = SPU_ES;
1959 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1960 p_stream->f_rate = 1000; /* granulepos is in millisec */
1964 msg_Dbg( p_demux, "stream %d has a header marker "
1965 "but is of an unknown type", p_ogg->i_streams-1 );
1966 FREENULL( p_stream );
1970 else if( oggpacket.bytes >= 8 &&
1971 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1975 msg_Dbg( p_demux, "stream %d is a skeleton",
1976 p_ogg->i_streams-1 );
1977 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1981 msg_Dbg( p_demux, "stream %d is of unknown type",
1982 p_ogg->i_streams-1 );
1983 FREENULL( p_stream );
1987 /* we'll need to get all headers */
1989 p_stream->b_initializing &= p_stream->b_force_backup;
1991 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1992 return VLC_EGENERIC;
1995 /* This is the first data page, which means we are now finished
1996 * with the initial pages. We just need to store it in the relevant
1998 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2000 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2001 &p_ogg->current_page ) == 0 )
2003 p_ogg->b_page_waiting = true;
2012 return VLC_EGENERIC;
2015 /****************************************************************************
2016 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2017 ****************************************************************************/
2018 static void Ogg_CreateES( demux_t *p_demux )
2020 demux_sys_t *p_ogg = p_demux->p_sys;
2021 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2024 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2026 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2028 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2030 /* Better be safe than sorry when possible with ogm */
2031 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2032 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2033 p_stream->fmt.b_packetized = false;
2035 /* Try first to reuse an old ES */
2037 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2038 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2040 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2042 p_stream->p_es = p_old_stream->p_es;
2043 p_stream->b_finished = false;
2044 p_stream->b_reinit = false;
2045 p_stream->b_initializing = false;
2046 p_stream->i_pre_skip = 0;
2047 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2048 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2050 p_old_stream->p_es = NULL;
2051 p_old_stream = NULL;
2052 if ( b_resetdecoder )
2054 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2055 p_stream->p_es, &p_stream->fmt );
2060 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2063 // TODO: something to do here ?
2064 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2066 /* Set the CMML stream active */
2067 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2072 if( p_ogg->p_old_stream )
2074 if( p_ogg->p_old_stream->p_es )
2075 msg_Dbg( p_demux, "old stream not reused" );
2076 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2077 p_ogg->p_old_stream = NULL;
2081 /****************************************************************************
2082 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2083 * Elementary streams.
2084 ****************************************************************************/
2085 static int Ogg_BeginningOfStream( demux_t *p_demux )
2087 demux_sys_t *p_ogg = p_demux->p_sys ;
2090 /* Find the logical streams embedded in the physical stream and
2091 * initialize our p_ogg structure. */
2092 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2094 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2095 return VLC_EGENERIC;
2098 p_ogg->i_bitrate = 0;
2100 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2102 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2104 p_stream->p_es = NULL;
2106 /* initialise kframe index */
2109 if ( p_stream->fmt.i_bitrate == 0 &&
2110 ( p_stream->fmt.i_cat == VIDEO_ES ||
2111 p_stream->fmt.i_cat == AUDIO_ES ) )
2112 p_ogg->b_partial_bitrate = true;
2114 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2116 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2117 p_stream->i_previous_granulepos = -1;
2118 p_stream->b_reinit = false;
2121 /* get total frame count for video stream; we will need this for seeking */
2122 p_ogg->i_total_frames = 0;
2127 /****************************************************************************
2128 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2129 ****************************************************************************/
2130 static void Ogg_EndOfStream( demux_t *p_demux )
2132 demux_sys_t *p_ogg = p_demux->p_sys ;
2135 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2136 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2137 free( p_ogg->pp_stream );
2140 p_ogg->i_bitrate = 0;
2141 p_ogg->i_streams = 0;
2142 p_ogg->pp_stream = NULL;
2143 p_ogg->skeleton.major = 0;
2144 p_ogg->skeleton.minor = 0;
2145 p_ogg->b_preparsing_done = false;
2146 p_ogg->b_es_created = false;
2147 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2148 p_ogg->i_pcr - VLC_TS_0 : 0;
2152 vlc_meta_Delete( p_ogg->p_meta );
2153 p_ogg->p_meta = NULL;
2155 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2157 if ( p_ogg->pp_seekpoints[i] )
2158 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2160 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2161 p_ogg->i_seekpoints = 0;
2164 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2166 #ifdef HAVE_LIBVORBIS
2167 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2169 FREENULL( p_stream->special.vorbis.p_info );
2170 FREENULL( p_stream->special.vorbis.p_comment );
2171 p_stream->special.vorbis.i_headers_flags = 0;
2174 VLC_UNUSED( p_stream );
2179 * This function delete and release all data associated to a logical_stream_t
2181 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2183 if( p_stream->p_es )
2184 es_out_Del( p_demux->out, p_stream->p_es );
2186 ogg_stream_clear( &p_stream->os );
2187 free( p_stream->p_headers );
2189 Ogg_CleanSpecificData( p_stream );
2191 es_format_Clean( &p_stream->fmt_old );
2192 es_format_Clean( &p_stream->fmt );
2194 if ( p_stream->idx != NULL)
2196 oggseek_index_entries_free( p_stream->idx );
2199 Ogg_FreeSkeleton( p_stream->p_skel );
2200 p_stream->p_skel = NULL;
2201 if ( p_demux->p_sys->p_skelstream == p_stream )
2202 p_demux->p_sys->p_skelstream = NULL;
2204 /* Shouldn't happen */
2205 if ( unlikely( p_stream->p_preparse_block ) )
2207 block_ChainRelease( p_stream->p_preparse_block );
2208 p_stream->p_preparse_block = NULL;
2210 free( p_stream->prepcr.pp_blocks );
2215 * This function check if a we need to reset a decoder in case we are
2218 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2220 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2221 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2222 unsigned i_new_count;
2223 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2226 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2227 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2228 unsigned i_old_count;
2229 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2232 bool b_match = i_new_count == i_old_count;
2233 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2235 /* Ignore vorbis comment */
2238 if( pi_new_size[i] != pi_old_size[i] ||
2239 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2246 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2247 const es_format_t *p_old )
2249 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2250 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2251 unsigned i_new_count;
2252 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2254 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2255 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2256 unsigned i_old_count;
2257 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2259 bool b_match = false;
2260 if( i_new_count == i_old_count && i_new_count > 0 )
2262 static const unsigned char default_map[2] = { 0, 1 };
2263 unsigned char *p_old_head;
2264 unsigned char *p_new_head;
2265 const unsigned char *p_old_map;
2266 const unsigned char *p_new_map;
2267 int i_old_channel_count;
2268 int i_new_channel_count;
2269 int i_old_stream_count;
2270 int i_new_stream_count;
2271 int i_old_coupled_count;
2272 int i_new_coupled_count;
2273 p_old_head = (unsigned char *)pp_old_data[0];
2274 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2275 p_old_map = default_map;
2276 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2278 i_old_channel_count = p_old_head[9];
2279 switch( p_old_head[18] )
2282 i_old_stream_count = 1;
2283 i_old_coupled_count = i_old_channel_count - 1;
2286 if( pi_old_size[0] >= 21U + i_old_channel_count )
2288 i_old_stream_count = p_old_head[19];
2289 i_old_coupled_count = p_old_head[20];
2290 p_old_map = p_old_head + 21;
2295 p_new_head = (unsigned char *)pp_new_data[0];
2296 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2297 p_new_map = default_map;
2298 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2300 i_new_channel_count = p_new_head[9];
2301 switch( p_new_head[18] )
2304 i_new_stream_count = 1;
2305 i_new_coupled_count = i_new_channel_count - 1;
2308 if( pi_new_size[0] >= 21U + i_new_channel_count )
2310 i_new_stream_count = p_new_head[19];
2311 i_new_coupled_count = p_new_head[20];
2312 p_new_map = p_new_head+21;
2317 b_match = i_old_channel_count == i_new_channel_count &&
2318 i_old_stream_count == i_new_stream_count &&
2319 i_old_coupled_count == i_new_coupled_count &&
2320 memcmp(p_old_map, p_new_map,
2321 i_new_channel_count*sizeof(*p_new_map)) == 0;
2327 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2329 bool b_compatible = false;
2330 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2333 /* Only Vorbis and Opus are supported. */
2334 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2335 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2336 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2337 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2340 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2342 return !b_compatible;
2345 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2346 const void *p_headers, unsigned i_headers )
2348 demux_sys_t *p_ogg = p_demux->p_sys;
2349 int i_cover_score = 0;
2350 int i_cover_idx = 0;
2351 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2352 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2353 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2355 pf_replay_gain[i] = 0;
2356 pf_replay_peak[i] = 0;
2358 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2359 &p_ogg->i_attachments, &p_ogg->attachments,
2360 &i_cover_score, &i_cover_idx,
2361 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2362 &pf_replay_gain, &pf_replay_peak );
2363 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2366 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2367 p_ogg->attachments[i_cover_idx]->psz_name );
2368 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2371 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2373 if ( pf_replay_gain[i] != 0 )
2375 p_fmt->audio_replay_gain.pb_gain[i] = true;
2376 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2377 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2379 if ( pf_replay_peak[i] != 0 )
2381 p_fmt->audio_replay_gain.pb_peak[i] = true;
2382 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2383 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2387 if( p_ogg->i_seekpoints > 1 )
2389 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2393 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2394 const void *p_headers, unsigned i_headers, unsigned i_skip )
2396 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2397 void *pp_data[XIPH_MAX_HEADER_COUNT];
2400 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2402 /* TODO how to handle multiple comments properly ? */
2403 if( i_count >= 2 && pi_size[1] > i_skip )
2405 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2409 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2411 demux_sys_t *p_ogg = p_demux->p_sys;
2413 switch( p_fmt->i_codec )
2415 /* 3 headers with the 2° one being the comments */
2416 case VLC_CODEC_VORBIS:
2417 case VLC_CODEC_THEORA:
2418 case VLC_CODEC_DAALA:
2419 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2421 case VLC_CODEC_OPUS:
2422 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2424 case VLC_CODEC_SPEEX:
2425 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2428 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2430 /* N headers with the 2° one being the comments */
2431 case VLC_CODEC_KATE:
2432 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2433 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2437 case VLC_CODEC_FLAC:
2438 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2442 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2443 case VLC_CODEC_DIRAC:
2448 p_demux->info.i_update |= INPUT_UPDATE_META;
2451 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2452 ogg_packet *p_oggpacket )
2455 unsigned int i_fps_numerator;
2456 unsigned int i_fps_denominator;
2457 int i_keyframe_frequency_force;
2463 p_stream->fmt.i_cat = VIDEO_ES;
2464 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2466 /* Signal that we want to keep a backup of the theora
2467 * stream headers. They will be used when switching between
2469 p_stream->b_force_backup = true;
2471 /* Cheat and get additionnal info ;) */
2472 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2473 bs_skip( &bitstream, 56 );
2475 i_major = bs_read( &bitstream, 8 ); /* major version num */
2476 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2477 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2479 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2480 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2481 bs_read( &bitstream, 24 ); /* frame width */
2482 bs_read( &bitstream, 24 ); /* frame height */
2483 bs_read( &bitstream, 8 ); /* x offset */
2484 bs_read( &bitstream, 8 ); /* y offset */
2486 i_fps_numerator = bs_read( &bitstream, 32 );
2487 i_fps_denominator = bs_read( &bitstream, 32 );
2488 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2489 bs_read( &bitstream, 24 ); /* aspect_numerator */
2490 bs_read( &bitstream, 24 ); /* aspect_denominator */
2492 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2493 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2495 bs_read( &bitstream, 8 ); /* colorspace */
2496 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2497 bs_read( &bitstream, 6 ); /* quality */
2499 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2501 /* granule_shift = i_log( frequency_force -1 ) */
2502 p_stream->i_granule_shift = 0;
2503 i_keyframe_frequency_force--;
2504 while( i_keyframe_frequency_force )
2506 p_stream->i_granule_shift++;
2507 i_keyframe_frequency_force >>= 1;
2510 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2511 p_stream->i_keyframe_offset = 0;
2512 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2513 if ( p_stream->f_rate == 0 ) return false;
2515 if ( i_version >= 3002001 )
2517 p_stream->i_keyframe_offset = 1;
2522 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2523 ogg_packet *p_oggpacket )
2526 uint32_t i_timebase_numerator;
2527 uint32_t i_timebase_denominator;
2528 int i_keyframe_frequency_force;
2534 p_stream->fmt.i_cat = VIDEO_ES;
2535 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2537 /* Signal that we want to keep a backup of the daala
2538 * stream headers. They will be used when switching between
2540 p_stream->b_force_backup = true;
2542 /* Cheat and get additionnal info ;) */
2543 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2544 oggpack_adv( &opb, 48 );
2546 i_major = oggpack_read( &opb, 8 ); /* major version num */
2547 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2548 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2550 oggpack_adv( &opb, 32 ); /* width */
2551 oggpack_adv( &opb, 32 ); /* height */
2553 oggpack_adv( &opb, 32 ); /* aspect numerator */
2554 oggpack_adv( &opb, 32 ); /* aspect denominator */
2555 i_timebase_numerator = oggpack_read( &opb, 32 );
2557 i_timebase_denominator = oggpack_read( &opb, 32 );
2558 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2560 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2561 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2563 oggpack_adv( &opb, 32 ); /* frame duration */
2565 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2567 /* granule_shift = i_log( frequency_force -1 ) */
2568 p_stream->i_granule_shift = 0;
2569 i_keyframe_frequency_force--;
2570 while( i_keyframe_frequency_force )
2572 p_stream->i_granule_shift++;
2573 i_keyframe_frequency_force >>= 1;
2576 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2577 p_stream->i_keyframe_offset = 0;
2578 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2579 if ( p_stream->f_rate == 0 ) return false;
2584 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2585 ogg_packet *p_oggpacket )
2589 p_stream->fmt.i_cat = AUDIO_ES;
2590 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2592 /* Signal that we want to keep a backup of the vorbis
2593 * stream headers. They will be used when switching between
2595 p_stream->b_force_backup = true;
2597 /* Cheat and get additionnal info ;) */
2598 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2599 oggpack_adv( &opb, 88 );
2600 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2601 fill_channels_info(&p_stream->fmt.audio);
2602 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2603 oggpack_read( &opb, 32 );
2604 oggpack_adv( &opb, 32 );
2605 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2606 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2607 if ( p_stream->f_rate == 0 ) return false;
2610 #ifdef HAVE_LIBVORBIS
2611 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2612 ogg_packet *p_oggpacket, int i_number )
2616 case VORBIS_HEADER_IDENTIFICATION:
2617 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2618 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2619 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2621 FREENULL( p_stream->special.vorbis.p_info );
2622 FREENULL( p_stream->special.vorbis.p_comment );
2625 vorbis_info_init( p_stream->special.vorbis.p_info );
2626 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2629 case VORBIS_HEADER_COMMENT:
2630 case VORBIS_HEADER_SETUP:
2631 if ( !p_stream->special.vorbis.p_info ||
2632 vorbis_synthesis_headerin(
2633 p_stream->special.vorbis.p_info,
2634 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2637 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2646 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2647 ogg_packet *p_oggpacket )
2651 p_stream->fmt.i_cat = AUDIO_ES;
2652 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2654 /* Signal that we want to keep a backup of the speex
2655 * stream headers. They will be used when switching between
2657 p_stream->b_force_backup = true;
2659 /* Cheat and get additionnal info ;) */
2660 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2661 oggpack_adv( &opb, 224 );
2662 oggpack_adv( &opb, 32 ); /* speex_version_id */
2663 oggpack_adv( &opb, 32 ); /* header_size */
2664 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2665 if ( p_stream->f_rate == 0 ) return false;
2666 oggpack_adv( &opb, 32 ); /* mode */
2667 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2668 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2669 fill_channels_info(&p_stream->fmt.audio);
2670 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2671 p_stream->special.speex.i_framesize =
2672 oggpack_read( &opb, 32 ); /* frame_size */
2673 oggpack_adv( &opb, 32 ); /* vbr */
2674 p_stream->special.speex.i_framesperpacket =
2675 oggpack_read( &opb, 32 ); /* frames_per_packet */
2676 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2680 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2681 ogg_packet *p_oggpacket )
2685 p_stream->fmt.i_cat = AUDIO_ES;
2686 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2688 /* Signal that we want to keep a backup of the opus
2689 * stream headers. They will be used when switching between
2691 p_stream->b_force_backup = true;
2693 /* All OggOpus streams are timestamped at 48kHz and
2694 * can be played at 48kHz. */
2695 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2696 p_stream->fmt.i_bitrate = 0;
2698 /* Cheat and get additional info ;) */
2699 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2700 oggpack_adv( &opb, 64 );
2701 oggpack_adv( &opb, 8 ); /* version_id */
2702 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2703 fill_channels_info(&p_stream->fmt.audio);
2704 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2705 /* For Opus, trash the first 80 ms of decoded output as
2706 well, to avoid blowing out speakers if we get unlucky.
2707 Opus predicts content from prior frames, which can go
2708 badly if we seek right where the stream goes from very
2709 quiet to very loud. It will converge after a bit. */
2710 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2713 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2714 ogg_packet *p_oggpacket )
2716 /* Parse the STREAMINFO metadata */
2719 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2722 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2724 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2728 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2731 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2732 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2733 fill_channels_info(&p_stream->fmt.audio);
2735 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2736 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2737 if ( p_stream->f_rate == 0 ) return false;
2741 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2744 /* Fake this as the last metadata block */
2745 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2749 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2750 ogg_packet *p_oggpacket )
2758 p_stream->fmt.i_cat = SPU_ES;
2759 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2761 /* Signal that we want to keep a backup of the kate
2762 * stream headers. They will be used when switching between
2764 p_stream->b_force_backup = true;
2766 /* Cheat and get additionnal info ;) */
2767 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2768 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2769 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2770 oggpack_adv( &opb, 3*8 );
2771 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2772 oggpack_adv( &opb, 8*8 ); /* reserved */
2773 gnum = oggpack_read( &opb, 32 );
2774 gden = oggpack_read( &opb, 32 );
2775 gden = __MAX( gden, 1 );
2776 p_stream->f_rate = (double)gnum/gden;
2777 if ( p_stream->f_rate == 0 ) return false;
2779 p_stream->fmt.psz_language = malloc(16);
2780 if( p_stream->fmt.psz_language )
2782 for( n = 0; n < 16; n++ )
2783 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2784 p_stream->fmt.psz_language[15] = 0; /* just in case */
2788 for( n = 0; n < 16; n++ )
2789 oggpack_read(&opb,8);
2791 p_stream->fmt.psz_description = malloc(16);
2792 if( p_stream->fmt.psz_description )
2794 for( n = 0; n < 16; n++ )
2795 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2796 p_stream->fmt.psz_description[15] = 0; /* just in case */
2798 /* Now find a localized user readable description for this category */
2799 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2802 free( p_stream->fmt.psz_description );
2803 p_stream->fmt.psz_description = psz_desc;
2808 for( n = 0; n < 16; n++ )
2809 oggpack_read(&opb,8);
2815 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2816 ogg_packet *p_oggpacket )
2818 switch( p_oggpacket->packet[5] )
2822 /* Mapping version */
2823 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2825 p_stream->fmt.i_cat = VIDEO_ES;
2826 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2827 p_stream->i_granule_shift = 32;
2828 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2829 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2830 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2831 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2832 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2833 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2834 p_stream->fmt.video.i_frame_rate_base =
2835 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2836 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2837 if ( p_stream->f_rate == 0 ) return false;
2841 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2842 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2849 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2850 bool *b_force_backup, bool *b_packet_out )
2852 if( !strncmp(psz_value, "audio/x-wav", 11) )
2854 /* n.b. WAVs are unsupported right now */
2855 p_stream->fmt.i_cat = UNKNOWN_ES;
2856 free( p_stream->fmt.psz_description );
2857 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2859 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2860 !strncmp(psz_value, "audio/vorbis", 12) )
2862 p_stream->fmt.i_cat = AUDIO_ES;
2863 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2865 *b_force_backup = true;
2867 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2868 !strncmp(psz_value, "audio/speex", 11) )
2870 p_stream->fmt.i_cat = AUDIO_ES;
2871 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2873 *b_force_backup = true;
2875 else if( !strncmp(psz_value, "audio/flac", 10) )
2877 p_stream->fmt.i_cat = AUDIO_ES;
2878 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2880 *b_force_backup = true;
2882 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2883 !strncmp(psz_value, "video/theora", 12) )
2885 p_stream->fmt.i_cat = VIDEO_ES;
2886 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2888 *b_force_backup = true;
2890 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2891 !strncmp(psz_value, "video/daala", 11) )
2893 p_stream->fmt.i_cat = VIDEO_ES;
2894 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2896 *b_force_backup = true;
2898 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2900 p_stream->fmt.i_cat = VIDEO_ES;
2901 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2903 *b_force_backup = true;
2905 else if( !strncmp(psz_value, "video/mpeg", 10) )
2907 /* n.b. MPEG streams are unsupported right now */
2908 p_stream->fmt.i_cat = VIDEO_ES;
2909 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2911 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2912 !strncmp(psz_value, "text/cmml", 9) )
2914 p_stream->fmt.i_cat = SPU_ES;
2915 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2916 *b_packet_out = true;
2918 else if( !strncmp(psz_value, "application/kate", 16) )
2921 p_stream->fmt.i_cat = UNKNOWN_ES;
2922 free( p_stream->fmt.psz_description );
2923 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2925 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2927 p_stream->fmt.i_cat = VIDEO_ES;
2928 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2932 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2933 logical_stream_t *p_stream,
2934 ogg_packet *p_oggpacket )
2936 if( p_oggpacket->bytes >= 28 &&
2937 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2941 uint16_t major_version;
2942 uint16_t minor_version;
2943 uint64_t timebase_numerator;
2944 uint64_t timebase_denominator;
2946 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2948 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2949 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2950 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2951 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2952 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2953 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2955 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2956 "Timebase %"PRId64" / %"PRId64,
2957 major_version, minor_version,
2958 timebase_numerator, timebase_denominator );
2960 else if( p_oggpacket->bytes >= 42 &&
2961 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2963 uint64_t granule_rate_numerator;
2964 uint64_t granule_rate_denominator;
2965 char content_type_string[1024];
2967 /* Read in Annodex header fields */
2969 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2970 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2971 p_stream->i_secondary_header_packets =
2972 GetDWLE( &p_oggpacket->packet[24] );
2974 /* we are guaranteed that the first header field will be
2975 * the content-type (by the Annodex standard) */
2976 content_type_string[0] = '\0';
2977 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2979 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2980 p_oggpacket->bytes - 1 );
2981 if( p && p[0] == '\r' && p[1] == '\n' )
2982 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2983 content_type_string );
2986 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2987 granule_rate_numerator, granule_rate_denominator,
2988 p_stream->i_secondary_header_packets, content_type_string );
2990 p_stream->f_rate = (float) granule_rate_numerator /
2991 (float) granule_rate_denominator;
2993 /* What type of file do we have?
2994 * strcmp is safe to use here because we've extracted
2995 * content_type_string from the stream manually */
2996 bool b_dopacketout = false;
2997 Ogg_ApplyContentType( p_stream, content_type_string,
2998 &p_stream->b_force_backup, &b_dopacketout );
2999 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3003 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3004 ogg_packet *p_oggpacket )
3006 p_demux->p_sys->p_skelstream = p_stream;
3007 /* There can be only 1 skeleton for streams */
3008 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3009 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3010 if ( asprintf( & p_stream->fmt.psz_description,
3011 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3012 p_demux->p_sys->skeleton.major,
3013 p_demux->p_sys->skeleton.minor ) < 0 )
3014 p_stream->fmt.psz_description = NULL;
3017 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3019 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3021 /* Find the matching stream for this skeleton data */
3022 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3023 logical_stream_t *p_target_stream = NULL;
3024 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3026 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3028 p_target_stream = p_demux->p_sys->pp_stream[i];
3032 if ( !p_target_stream ) return;
3034 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3037 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3038 if ( !p_skel ) return;
3039 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3040 p_skel->p_index = NULL;
3041 p_target_stream->p_skel = p_skel;
3044 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3045 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3046 const unsigned char *p = p_messages;
3047 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3049 if ( *p == 0x0D && *(p+1) == 0x0A )
3051 char *psz_message = strndup( (const char *) p_messages,
3055 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3056 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3058 if ( p < p_boundary - 1 ) p_messages = p + 2;
3065 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3066 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3067 unsigned const char *p_end,
3068 uint64_t *pi_value )
3074 while ( p_begin < p_end )
3076 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3077 *pi_value = *pi_value | ( i_read << i_shift );
3079 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3082 *pi_value = GetQWLE( pi_value );
3086 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3088 if ( p_demux->p_sys->skeleton.major < 4
3089 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3092 /* Find the matching stream for this skeleton data */
3093 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3094 logical_stream_t *p_stream = NULL;
3095 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3097 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3099 p_stream = p_demux->p_sys->pp_stream[i];
3103 if ( !p_stream || !p_stream->p_skel ) return;
3104 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3105 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3106 if ( !i_keypoints ) return;
3108 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3109 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3110 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3111 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3112 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3113 uint64_t i_offset = 0;
3114 uint64_t i_time = 0;
3115 uint64_t i_keypoints_found = 0;
3117 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3120 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3122 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3123 i_time += i_val * p_stream->p_skel->i_indexstampden;
3124 i_keypoints_found++;
3127 if ( i_keypoints_found != i_keypoints )
3129 msg_Warn( p_demux, "Invalid Index: missing entries" );
3133 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3134 if ( !p_stream->p_skel->p_index ) return;
3135 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3136 p_oggpacket->bytes - 42 );
3137 p_stream->p_skel->i_index = i_keypoints_found;
3138 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3141 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3143 if ( !p_skel ) return;
3144 for ( int i=0; i< p_skel->i_messages; i++ )
3145 free( p_skel->ppsz_messages[i] );
3146 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3147 free( p_skel->p_index );
3151 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3153 if ( !p_stream->p_skel ) return;
3154 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3156 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3157 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3159 free( p_stream->fmt.psz_description );
3160 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3162 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3165 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3170 /* Return true if there's a skeleton exact match */
3171 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3172 int64_t *pi_lower, int64_t *pi_upper )
3174 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3177 /* Validate range */
3178 if ( i_time < p_stream->p_skel->i_indexfirstnum
3179 * p_stream->p_skel->i_indexstampden ||
3180 i_time > p_stream->p_skel->i_indexlastnum
3181 * p_stream->p_skel->i_indexstampden ) return false;
3183 /* Then Lookup its index */
3184 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3189 } current = { 0, 0 }, prev = { -1, -1 };
3191 uint64_t i_keypoints_found = 0;
3193 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3194 && i_keypoints_found < p_stream->p_skel->i_index )
3197 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3198 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3199 current.i_pos += i_val;
3200 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3201 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3202 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3203 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3205 i_keypoints_found++;
3207 if ( i_time <= current.i_time )
3209 *pi_lower = prev.i_pos;
3210 *pi_upper = current.i_pos;
3211 return ( i_time == current.i_time );
3218 static uint32_t dirac_uint( bs_t *p_bs )
3220 uint32_t u_count = 0, u_value = 0;
3222 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3226 u_value |= bs_read( p_bs, 1 );
3229 return (1<<u_count) - 1 + u_value;
3232 static int dirac_bool( bs_t *p_bs )
3234 return bs_read( p_bs, 1 );
3237 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3238 ogg_packet *p_oggpacket )
3240 static const struct {
3241 uint32_t u_n /* numerator */, u_d /* denominator */;
3242 } p_dirac_frate_tbl[] = { /* table 10.3 */
3243 {1,1}, /* this first value is never used */
3244 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3245 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3247 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3249 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3250 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3252 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3256 p_stream->i_granule_shift = 22; /* not 32 */
3258 /* Backing up stream headers is not required -- seqhdrs are repeated
3259 * thoughout the stream at suitable decoding start points */
3260 p_stream->b_force_backup = false;
3262 /* read in useful bits from sequence header */
3263 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3264 bs_skip( &bs, 13*8); /* parse_info_header */
3265 dirac_uint( &bs ); /* major_version */
3266 dirac_uint( &bs ); /* minor_version */
3267 dirac_uint( &bs ); /* profile */
3268 dirac_uint( &bs ); /* level */
3270 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3271 if( u_video_format >= u_dirac_vidfmt_frate )
3273 /* don't know how to parse this ogg dirac stream */
3277 if( dirac_bool( &bs ) )
3279 dirac_uint( &bs ); /* frame_width */
3280 dirac_uint( &bs ); /* frame_height */
3283 if( dirac_bool( &bs ) )
3285 dirac_uint( &bs ); /* chroma_format */
3288 if( dirac_bool( &bs ) )
3290 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3293 p_stream->special.dirac.b_interlaced = false;
3295 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3296 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3297 u_d = __MAX( u_d, 1 );
3298 if( dirac_bool( &bs ) )
3300 uint32_t u_frame_rate_index = dirac_uint( &bs );
3301 if( u_frame_rate_index >= u_dirac_frate_tbl )
3303 /* something is wrong with this stream */
3306 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3307 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3308 if( u_frame_rate_index == 0 )
3310 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3311 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3314 p_stream->f_rate = (float) u_n / u_d;
3315 if ( p_stream->f_rate == 0 ) return false;
3317 /* probably is an ogg dirac es */
3318 p_stream->fmt.i_cat = VIDEO_ES;
3319 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;