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 unsigned Ogg_OpusPacketDuration( ogg_packet * );
127 static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * );
129 static void Ogg_CreateES( demux_t *p_demux );
130 static int Ogg_BeginningOfStream( demux_t *p_demux );
131 static int Ogg_FindLogicalStreams( demux_t *p_demux );
132 static void Ogg_EndOfStream( demux_t *p_demux );
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 unsigned 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 )
1014 unsigned i_duration;
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( i_header_len >= p_oggpacket->bytes )
1413 msg_Dbg( p_demux, "discarding invalid packet" );
1414 block_Release( p_block );
1418 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1420 /* But with subtitles we need to retrieve the duration first */
1421 int i, lenbytes = 0;
1423 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1425 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1427 lenbytes = lenbytes << 8;
1428 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1431 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1432 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1433 p_oggpacket->packet[i_header_len + 1] != 0 &&
1434 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1435 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1437 p_block->i_length = (mtime_t)lenbytes * 1000;
1442 if( p_block->i_buffer >= (unsigned int)i_header_len )
1443 p_block->i_buffer -= i_header_len;
1445 p_block->i_buffer = 0;
1449 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1451 /* FIXME: the biggest hack I've ever done */
1452 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1453 p_block->i_pts, p_block->i_dts );
1457 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1458 p_oggpacket->bytes - i_header_len );
1460 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1463 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1465 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1468 /****************************************************************************
1469 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1470 * stream and fill p_ogg.
1471 *****************************************************************************
1472 * The initial page of a logical stream is marked as a 'bos' page.
1473 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1474 * together and all of the initial pages must appear before any data pages.
1476 * On success this function returns VLC_SUCCESS.
1477 ****************************************************************************/
1478 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1480 demux_sys_t *p_ogg = p_demux->p_sys ;
1481 ogg_packet oggpacket;
1483 p_ogg->i_total_length = stream_Size ( p_demux->s );
1484 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1487 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1490 if( ogg_page_bos( &p_ogg->current_page ) )
1493 /* All is wonderful in our fine fine little world.
1494 * We found the beginning of our first logical stream. */
1495 while( ogg_page_bos( &p_ogg->current_page ) )
1497 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1498 if( unlikely( !p_stream ) )
1501 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1503 es_format_Init( &p_stream->fmt, 0, 0 );
1504 es_format_Init( &p_stream->fmt_old, 0, 0 );
1505 p_stream->b_initializing = true;
1507 /* Setup the logical stream */
1508 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1509 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1511 /* Extract the initial header from the first page and verify
1512 * the codec type of this Ogg bitstream */
1513 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1515 /* error. stream version mismatch perhaps */
1516 msg_Err( p_demux, "error reading first page of "
1517 "Ogg bitstream data" );
1518 return VLC_EGENERIC;
1521 /* FIXME: check return value */
1522 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1524 /* Check for Vorbis header */
1525 if( oggpacket.bytes >= 7 &&
1526 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1528 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1529 msg_Dbg( p_demux, "found vorbis header" );
1532 msg_Dbg( p_demux, "found invalid vorbis header" );
1533 Ogg_LogicalStreamDelete( p_demux, p_stream );
1538 /* Check for Speex header */
1539 else if( oggpacket.bytes >= 5 &&
1540 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1542 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1543 msg_Dbg( p_demux, "found speex header, channels: %i, "
1544 "rate: %i, bitrate: %i, frames: %i group %i",
1545 p_stream->fmt.audio.i_channels,
1546 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1547 p_stream->special.speex.i_framesize,
1548 p_stream->special.speex.i_framesperpacket );
1551 msg_Dbg( p_demux, "found invalid Speex header" );
1552 Ogg_LogicalStreamDelete( p_demux, p_stream );
1557 /* Check for Opus header */
1558 else if( oggpacket.bytes >= 8 &&
1559 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1561 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1562 msg_Dbg( p_demux, "found opus header, channels: %i, "
1564 p_stream->fmt.audio.i_channels,
1565 (int)p_stream->i_pre_skip);
1566 p_stream->i_skip_frames = p_stream->i_pre_skip;
1568 /* Check for Flac header (< version 1.1.1) */
1569 else if( oggpacket.bytes >= 4 &&
1570 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1572 msg_Dbg( p_demux, "found FLAC header" );
1574 /* Grrrr!!!! Did they really have to put all the
1575 * important info in the second header packet!!!
1576 * (STREAMINFO metadata is in the following packet) */
1577 p_stream->b_force_backup = true;
1578 p_stream->fmt.i_cat = AUDIO_ES;
1579 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1581 /* Check for Flac header (>= version 1.1.1) */
1582 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1583 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1584 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1586 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1587 oggpacket.packet[8];
1588 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1589 "(%i header packets)",
1590 oggpacket.packet[5], oggpacket.packet[6],
1593 p_stream->b_force_backup = true;
1595 p_stream->fmt.i_cat = AUDIO_ES;
1596 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1597 oggpacket.packet += 13; oggpacket.bytes -= 13;
1598 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1600 msg_Dbg( p_demux, "found invalid Flac header" );
1601 Ogg_LogicalStreamDelete( p_demux, p_stream );
1606 /* Check for Theora header */
1607 else if( oggpacket.bytes >= 7 &&
1608 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1610 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1612 "found theora header, bitrate: %i, rate: %f",
1613 p_stream->fmt.i_bitrate, p_stream->f_rate );
1616 msg_Dbg( p_demux, "found invalid Theora header" );
1617 Ogg_LogicalStreamDelete( p_demux, p_stream );
1622 /* Check for Daala header */
1623 else if( oggpacket.bytes >= 6 &&
1624 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1626 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1628 "found daala header, bitrate: %i, rate: %f",
1629 p_stream->fmt.i_bitrate, p_stream->f_rate );
1632 msg_Dbg( p_demux, "found invalid Daala header" );
1633 Ogg_LogicalStreamDelete( p_demux, p_stream );
1638 /* Check for Dirac header */
1639 else if( ( oggpacket.bytes >= 5 &&
1640 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1641 ( oggpacket.bytes >= 9 &&
1642 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1644 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1645 msg_Dbg( p_demux, "found dirac header" );
1648 msg_Warn( p_demux, "found dirac header isn't decodable" );
1649 Ogg_LogicalStreamDelete( p_demux, p_stream );
1654 /* Check for Tarkin header */
1655 else if( oggpacket.bytes >= 7 &&
1656 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1660 msg_Dbg( p_demux, "found tarkin header" );
1661 p_stream->fmt.i_cat = VIDEO_ES;
1662 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1664 /* Cheat and get additionnal info ;) */
1665 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1666 oggpack_adv( &opb, 88 );
1667 oggpack_adv( &opb, 104 );
1668 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1669 p_stream->f_rate = 2; /* FIXME */
1671 "found tarkin header, bitrate: %i, rate: %f",
1672 p_stream->fmt.i_bitrate, p_stream->f_rate );
1674 /* Check for VP8 header */
1675 else if( oggpacket.bytes >= 26 &&
1676 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1678 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1679 msg_Dbg( p_demux, "found VP8 header "
1680 "fps: %f, width:%i; height:%i",
1682 p_stream->fmt.video.i_width,
1683 p_stream->fmt.video.i_height );
1686 msg_Dbg( p_demux, "invalid VP8 header found");
1687 Ogg_LogicalStreamDelete( p_demux, p_stream );
1692 /* Check for Annodex header */
1693 else if( oggpacket.bytes >= 7 &&
1694 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1696 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1697 /* kill annodex track */
1698 FREENULL( p_stream );
1701 /* Check for Annodex header */
1702 else if( oggpacket.bytes >= 7 &&
1703 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1705 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1707 /* Check for Kate header */
1708 else if( oggpacket.bytes >= 8 &&
1709 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1711 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1712 msg_Dbg( p_demux, "found kate header" );
1715 msg_Dbg( p_demux, "invalid kate header found");
1716 Ogg_LogicalStreamDelete( p_demux, p_stream );
1721 /* Check for OggDS */
1722 else if( oggpacket.bytes >= 142 &&
1723 !memcmp( &oggpacket.packet[1],
1724 "Direct Show Samples embedded in Ogg", 35 ))
1726 /* Old header type */
1727 p_stream->b_oggds = true;
1728 /* Check for video header (old format) */
1729 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1730 oggpacket.bytes >= 184 )
1732 p_stream->fmt.i_cat = VIDEO_ES;
1733 p_stream->fmt.i_codec =
1734 VLC_FOURCC( oggpacket.packet[68],
1735 oggpacket.packet[69],
1736 oggpacket.packet[70],
1737 oggpacket.packet[71] );
1738 msg_Dbg( p_demux, "found video header of type: %.4s",
1739 (char *)&p_stream->fmt.i_codec );
1741 p_stream->fmt.video.i_frame_rate = 10000000;
1742 p_stream->fmt.video.i_frame_rate_base =
1743 GetQWLE((oggpacket.packet+164));
1744 p_stream->fmt.video.i_frame_rate_base =
1745 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1746 p_stream->f_rate = 10000000.0 /
1747 p_stream->fmt.video.i_frame_rate_base;
1748 p_stream->fmt.video.i_bits_per_pixel =
1749 GetWLE((oggpacket.packet+182));
1750 if( !p_stream->fmt.video.i_bits_per_pixel )
1752 p_stream->fmt.video.i_bits_per_pixel = 24;
1753 p_stream->fmt.video.i_width =
1754 GetDWLE((oggpacket.packet+176));
1755 p_stream->fmt.video.i_height =
1756 GetDWLE((oggpacket.packet+180));
1759 "fps: %f, width:%i; height:%i, bitcount:%i",
1761 p_stream->fmt.video.i_width,
1762 p_stream->fmt.video.i_height,
1763 p_stream->fmt.video.i_bits_per_pixel);
1766 /* Check for audio header (old format) */
1767 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1770 unsigned int i_format_tag;
1772 p_stream->fmt.i_cat = AUDIO_ES;
1774 i_extra_size = GetWLE((oggpacket.packet+140));
1775 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1777 p_stream->fmt.i_extra = i_extra_size;
1778 p_stream->fmt.p_extra = malloc( i_extra_size );
1779 if( p_stream->fmt.p_extra )
1780 memcpy( p_stream->fmt.p_extra,
1781 oggpacket.packet + 142, i_extra_size );
1783 p_stream->fmt.i_extra = 0;
1786 i_format_tag = GetWLE((oggpacket.packet+124));
1787 p_stream->fmt.audio.i_channels =
1788 GetWLE((oggpacket.packet+126));
1789 fill_channels_info(&p_stream->fmt.audio);
1790 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1791 GetDWLE((oggpacket.packet+128));
1792 p_stream->fmt.i_bitrate =
1793 GetDWLE((oggpacket.packet+132)) * 8;
1794 p_stream->fmt.audio.i_blockalign =
1795 GetWLE((oggpacket.packet+136));
1796 p_stream->fmt.audio.i_bitspersample =
1797 GetWLE((oggpacket.packet+138));
1799 wf_tag_to_fourcc( i_format_tag,
1800 &p_stream->fmt.i_codec, 0 );
1802 if( p_stream->fmt.i_codec ==
1803 VLC_FOURCC('u','n','d','f') )
1805 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1806 ( i_format_tag >> 8 ) & 0xff,
1807 i_format_tag & 0xff );
1810 msg_Dbg( p_demux, "found audio header of type: %.4s",
1811 (char *)&p_stream->fmt.i_codec );
1812 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1813 "%dbits/sample %dkb/s",
1815 p_stream->fmt.audio.i_channels,
1816 p_stream->fmt.audio.i_rate,
1817 p_stream->fmt.audio.i_bitspersample,
1818 p_stream->fmt.i_bitrate / 1024 );
1819 if ( p_stream->f_rate == 0 )
1821 msg_Dbg( p_demux, "invalid oggds audio header" );
1822 Ogg_LogicalStreamDelete( p_demux, p_stream );
1829 msg_Dbg( p_demux, "stream %d has an old header "
1830 "but is of an unknown type", p_ogg->i_streams-1 );
1831 FREENULL( p_stream );
1835 /* Check for OggDS */
1836 else if( oggpacket.bytes >= 44+1 &&
1837 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1839 stream_header_t tmp;
1840 stream_header_t *st = &tmp;
1842 p_stream->b_oggds = true;
1844 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1845 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1846 st->size = GetDWLE( &oggpacket.packet[1+12] );
1847 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1848 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1849 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1850 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1851 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1853 /* Check for video header (new format) */
1854 if( !strncmp( st->streamtype, "video", 5 ) &&
1855 oggpacket.bytes >= 52+1 )
1857 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1858 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1860 p_stream->fmt.i_cat = VIDEO_ES;
1862 /* We need to get rid of the header packet */
1863 ogg_stream_packetout( &p_stream->os, &oggpacket );
1865 p_stream->fmt.i_codec =
1866 VLC_FOURCC( st->subtype[0], st->subtype[1],
1867 st->subtype[2], st->subtype[3] );
1868 msg_Dbg( p_demux, "found video header of type: %.4s",
1869 (char *)&p_stream->fmt.i_codec );
1871 p_stream->fmt.video.i_frame_rate = 10000000;
1872 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1873 if( st->time_unit <= 0 )
1874 st->time_unit = 400000;
1875 p_stream->f_rate = 10000000.0 / st->time_unit;
1876 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1877 p_stream->fmt.video.i_width = st->sh.video.width;
1878 p_stream->fmt.video.i_height = st->sh.video.height;
1881 "fps: %f, width:%i; height:%i, bitcount:%i",
1883 p_stream->fmt.video.i_width,
1884 p_stream->fmt.video.i_height,
1885 p_stream->fmt.video.i_bits_per_pixel );
1887 /* Check for audio header (new format) */
1888 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1889 oggpacket.bytes >= 56+1 )
1895 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1896 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1897 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1899 p_stream->fmt.i_cat = AUDIO_ES;
1901 /* We need to get rid of the header packet */
1902 ogg_stream_packetout( &p_stream->os, &oggpacket );
1904 i_extra_size = st->size - 56;
1906 if( i_extra_size > 0 &&
1907 i_extra_size < oggpacket.bytes - 1 - 56 )
1909 p_stream->fmt.i_extra = i_extra_size;
1910 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1911 if( p_stream->fmt.p_extra )
1912 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1913 p_stream->fmt.i_extra );
1915 p_stream->fmt.i_extra = 0;
1918 memcpy( p_buffer, st->subtype, 4 );
1920 i_format_tag = strtol(p_buffer,NULL,16);
1921 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1922 fill_channels_info(&p_stream->fmt.audio);
1923 if( st->time_unit <= 0 )
1924 st->time_unit = 10000000;
1925 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1926 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1927 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1928 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1930 wf_tag_to_fourcc( i_format_tag,
1931 &p_stream->fmt.i_codec, 0 );
1933 if( p_stream->fmt.i_codec ==
1934 VLC_FOURCC('u','n','d','f') )
1936 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1937 ( i_format_tag >> 8 ) & 0xff,
1938 i_format_tag & 0xff );
1941 msg_Dbg( p_demux, "found audio header of type: %.4s",
1942 (char *)&p_stream->fmt.i_codec );
1943 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1944 "%dbits/sample %dkb/s",
1946 p_stream->fmt.audio.i_channels,
1947 p_stream->fmt.audio.i_rate,
1948 p_stream->fmt.audio.i_bitspersample,
1949 p_stream->fmt.i_bitrate / 1024 );
1950 if ( p_stream->f_rate == 0 )
1952 msg_Dbg( p_demux, "invalid oggds audio header" );
1953 Ogg_LogicalStreamDelete( p_demux, p_stream );
1958 /* Check for text (subtitles) header */
1959 else if( !strncmp(st->streamtype, "text", 4) )
1961 /* We need to get rid of the header packet */
1962 ogg_stream_packetout( &p_stream->os, &oggpacket );
1964 msg_Dbg( p_demux, "found text subtitle header" );
1965 p_stream->fmt.i_cat = SPU_ES;
1966 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1967 p_stream->f_rate = 1000; /* granulepos is in millisec */
1971 msg_Dbg( p_demux, "stream %d has a header marker "
1972 "but is of an unknown type", p_ogg->i_streams-1 );
1973 FREENULL( p_stream );
1977 else if( oggpacket.bytes >= 8 &&
1978 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1982 msg_Dbg( p_demux, "stream %d is a skeleton",
1983 p_ogg->i_streams-1 );
1984 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1988 msg_Dbg( p_demux, "stream %d is of unknown type",
1989 p_ogg->i_streams-1 );
1990 FREENULL( p_stream );
1994 /* we'll need to get all headers */
1996 p_stream->b_initializing &= p_stream->b_force_backup;
1998 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1999 return VLC_EGENERIC;
2002 /* This is the first data page, which means we are now finished
2003 * with the initial pages. We just need to store it in the relevant
2005 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2007 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2008 &p_ogg->current_page ) == 0 )
2010 p_ogg->b_page_waiting = true;
2019 return VLC_EGENERIC;
2022 /****************************************************************************
2023 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2024 ****************************************************************************/
2025 static void Ogg_CreateES( demux_t *p_demux )
2027 demux_sys_t *p_ogg = p_demux->p_sys;
2028 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2031 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2033 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2035 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2037 /* Better be safe than sorry when possible with ogm */
2038 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2039 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2040 p_stream->fmt.b_packetized = false;
2042 /* Try first to reuse an old ES */
2044 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2045 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2047 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2049 p_stream->p_es = p_old_stream->p_es;
2050 p_stream->b_finished = false;
2051 p_stream->b_reinit = false;
2052 p_stream->b_initializing = false;
2053 p_stream->i_pre_skip = 0;
2054 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2055 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2057 p_old_stream->p_es = NULL;
2058 p_old_stream = NULL;
2059 if ( b_resetdecoder )
2061 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2062 p_stream->p_es, &p_stream->fmt );
2067 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2070 // TODO: something to do here ?
2071 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2073 /* Set the CMML stream active */
2074 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2079 if( p_ogg->p_old_stream )
2081 if( p_ogg->p_old_stream->p_es )
2082 msg_Dbg( p_demux, "old stream not reused" );
2083 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2084 p_ogg->p_old_stream = NULL;
2088 /****************************************************************************
2089 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2090 * Elementary streams.
2091 ****************************************************************************/
2092 static int Ogg_BeginningOfStream( demux_t *p_demux )
2094 demux_sys_t *p_ogg = p_demux->p_sys ;
2097 /* Find the logical streams embedded in the physical stream and
2098 * initialize our p_ogg structure. */
2099 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2101 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2102 return VLC_EGENERIC;
2105 p_ogg->i_bitrate = 0;
2107 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2109 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2111 p_stream->p_es = NULL;
2113 /* initialise kframe index */
2116 if ( p_stream->fmt.i_bitrate == 0 &&
2117 ( p_stream->fmt.i_cat == VIDEO_ES ||
2118 p_stream->fmt.i_cat == AUDIO_ES ) )
2119 p_ogg->b_partial_bitrate = true;
2121 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2123 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2124 p_stream->i_previous_granulepos = -1;
2125 p_stream->b_reinit = false;
2128 /* get total frame count for video stream; we will need this for seeking */
2129 p_ogg->i_total_frames = 0;
2134 /****************************************************************************
2135 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2136 ****************************************************************************/
2137 static void Ogg_EndOfStream( demux_t *p_demux )
2139 demux_sys_t *p_ogg = p_demux->p_sys ;
2142 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2143 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2144 free( p_ogg->pp_stream );
2147 p_ogg->i_bitrate = 0;
2148 p_ogg->i_streams = 0;
2149 p_ogg->pp_stream = NULL;
2150 p_ogg->skeleton.major = 0;
2151 p_ogg->skeleton.minor = 0;
2152 p_ogg->b_preparsing_done = false;
2153 p_ogg->b_es_created = false;
2154 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2155 p_ogg->i_pcr - VLC_TS_0 : 0;
2159 vlc_meta_Delete( p_ogg->p_meta );
2160 p_ogg->p_meta = NULL;
2162 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2164 if ( p_ogg->pp_seekpoints[i] )
2165 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2167 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2168 p_ogg->i_seekpoints = 0;
2171 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2173 #ifdef HAVE_LIBVORBIS
2174 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2176 FREENULL( p_stream->special.vorbis.p_info );
2177 FREENULL( p_stream->special.vorbis.p_comment );
2178 p_stream->special.vorbis.i_headers_flags = 0;
2181 VLC_UNUSED( p_stream );
2186 * This function delete and release all data associated to a logical_stream_t
2188 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2190 if( p_stream->p_es )
2191 es_out_Del( p_demux->out, p_stream->p_es );
2193 ogg_stream_clear( &p_stream->os );
2194 free( p_stream->p_headers );
2196 Ogg_CleanSpecificData( p_stream );
2198 es_format_Clean( &p_stream->fmt_old );
2199 es_format_Clean( &p_stream->fmt );
2201 if ( p_stream->idx != NULL)
2203 oggseek_index_entries_free( p_stream->idx );
2206 Ogg_FreeSkeleton( p_stream->p_skel );
2207 p_stream->p_skel = NULL;
2208 if ( p_demux->p_sys->p_skelstream == p_stream )
2209 p_demux->p_sys->p_skelstream = NULL;
2211 /* Shouldn't happen */
2212 if ( unlikely( p_stream->p_preparse_block ) )
2214 block_ChainRelease( p_stream->p_preparse_block );
2215 p_stream->p_preparse_block = NULL;
2217 free( p_stream->prepcr.pp_blocks );
2222 * This function check if a we need to reset a decoder in case we are
2225 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2227 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2228 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2229 unsigned i_new_count;
2230 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2233 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2234 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2235 unsigned i_old_count;
2236 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2239 bool b_match = i_new_count == i_old_count;
2240 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2242 /* Ignore vorbis comment */
2245 if( pi_new_size[i] != pi_old_size[i] ||
2246 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2253 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2254 const es_format_t *p_old )
2256 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2257 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2258 unsigned i_new_count;
2259 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2261 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2262 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2263 unsigned i_old_count;
2264 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2266 bool b_match = false;
2267 if( i_new_count == i_old_count && i_new_count > 0 )
2269 static const unsigned char default_map[2] = { 0, 1 };
2270 unsigned char *p_old_head;
2271 unsigned char *p_new_head;
2272 const unsigned char *p_old_map;
2273 const unsigned char *p_new_map;
2274 int i_old_channel_count;
2275 int i_new_channel_count;
2276 int i_old_stream_count;
2277 int i_new_stream_count;
2278 int i_old_coupled_count;
2279 int i_new_coupled_count;
2280 p_old_head = (unsigned char *)pp_old_data[0];
2281 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2282 p_old_map = default_map;
2283 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2285 i_old_channel_count = p_old_head[9];
2286 switch( p_old_head[18] )
2289 i_old_stream_count = 1;
2290 i_old_coupled_count = i_old_channel_count - 1;
2293 if( pi_old_size[0] >= 21U + i_old_channel_count )
2295 i_old_stream_count = p_old_head[19];
2296 i_old_coupled_count = p_old_head[20];
2297 p_old_map = p_old_head + 21;
2302 p_new_head = (unsigned char *)pp_new_data[0];
2303 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2304 p_new_map = default_map;
2305 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2307 i_new_channel_count = p_new_head[9];
2308 switch( p_new_head[18] )
2311 i_new_stream_count = 1;
2312 i_new_coupled_count = i_new_channel_count - 1;
2315 if( pi_new_size[0] >= 21U + i_new_channel_count )
2317 i_new_stream_count = p_new_head[19];
2318 i_new_coupled_count = p_new_head[20];
2319 p_new_map = p_new_head+21;
2324 b_match = i_old_channel_count == i_new_channel_count &&
2325 i_old_stream_count == i_new_stream_count &&
2326 i_old_coupled_count == i_new_coupled_count &&
2327 memcmp(p_old_map, p_new_map,
2328 i_new_channel_count*sizeof(*p_new_map)) == 0;
2334 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2336 bool b_compatible = false;
2337 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2340 /* Only Vorbis and Opus are supported. */
2341 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2342 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2343 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2344 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2347 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2349 return !b_compatible;
2352 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2353 const void *p_headers, unsigned i_headers )
2355 demux_sys_t *p_ogg = p_demux->p_sys;
2356 int i_cover_score = 0;
2357 int i_cover_idx = 0;
2358 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2359 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2360 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2362 pf_replay_gain[i] = 0;
2363 pf_replay_peak[i] = 0;
2365 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2366 &p_ogg->i_attachments, &p_ogg->attachments,
2367 &i_cover_score, &i_cover_idx,
2368 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2369 &pf_replay_gain, &pf_replay_peak );
2370 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2373 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2374 p_ogg->attachments[i_cover_idx]->psz_name );
2375 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2378 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2380 if ( pf_replay_gain[i] != 0 )
2382 p_fmt->audio_replay_gain.pb_gain[i] = true;
2383 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2384 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2386 if ( pf_replay_peak[i] != 0 )
2388 p_fmt->audio_replay_gain.pb_peak[i] = true;
2389 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2390 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2394 if( p_ogg->i_seekpoints > 1 )
2396 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2400 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2401 const void *p_headers, unsigned i_headers, unsigned i_skip )
2403 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2404 void *pp_data[XIPH_MAX_HEADER_COUNT];
2407 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2409 /* TODO how to handle multiple comments properly ? */
2410 if( i_count >= 2 && pi_size[1] > i_skip )
2412 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2416 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2418 demux_sys_t *p_ogg = p_demux->p_sys;
2420 switch( p_fmt->i_codec )
2422 /* 3 headers with the 2° one being the comments */
2423 case VLC_CODEC_VORBIS:
2424 case VLC_CODEC_THEORA:
2425 case VLC_CODEC_DAALA:
2426 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2428 case VLC_CODEC_OPUS:
2429 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2431 case VLC_CODEC_SPEEX:
2432 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2435 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2437 /* N headers with the 2° one being the comments */
2438 case VLC_CODEC_KATE:
2439 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2440 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2444 case VLC_CODEC_FLAC:
2445 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2449 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2450 case VLC_CODEC_DIRAC:
2455 p_demux->info.i_update |= INPUT_UPDATE_META;
2458 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2459 ogg_packet *p_oggpacket )
2462 unsigned int i_fps_numerator;
2463 unsigned int i_fps_denominator;
2464 int i_keyframe_frequency_force;
2470 p_stream->fmt.i_cat = VIDEO_ES;
2471 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2473 /* Signal that we want to keep a backup of the theora
2474 * stream headers. They will be used when switching between
2476 p_stream->b_force_backup = true;
2478 /* Cheat and get additionnal info ;) */
2479 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2480 bs_skip( &bitstream, 56 );
2482 i_major = bs_read( &bitstream, 8 ); /* major version num */
2483 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2484 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2486 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2487 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2488 bs_read( &bitstream, 24 ); /* frame width */
2489 bs_read( &bitstream, 24 ); /* frame height */
2490 bs_read( &bitstream, 8 ); /* x offset */
2491 bs_read( &bitstream, 8 ); /* y offset */
2493 i_fps_numerator = bs_read( &bitstream, 32 );
2494 i_fps_denominator = bs_read( &bitstream, 32 );
2495 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2496 bs_read( &bitstream, 24 ); /* aspect_numerator */
2497 bs_read( &bitstream, 24 ); /* aspect_denominator */
2499 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2500 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2502 bs_read( &bitstream, 8 ); /* colorspace */
2503 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2504 bs_read( &bitstream, 6 ); /* quality */
2506 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2508 /* granule_shift = i_log( frequency_force -1 ) */
2509 p_stream->i_granule_shift = 0;
2510 i_keyframe_frequency_force--;
2511 while( i_keyframe_frequency_force )
2513 p_stream->i_granule_shift++;
2514 i_keyframe_frequency_force >>= 1;
2517 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2518 p_stream->i_keyframe_offset = 0;
2519 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2520 if ( p_stream->f_rate == 0 ) return false;
2522 if ( i_version >= 3002001 )
2524 p_stream->i_keyframe_offset = 1;
2529 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2530 ogg_packet *p_oggpacket )
2533 uint32_t i_timebase_numerator;
2534 uint32_t i_timebase_denominator;
2535 int i_keyframe_frequency_force;
2541 p_stream->fmt.i_cat = VIDEO_ES;
2542 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2544 /* Signal that we want to keep a backup of the daala
2545 * stream headers. They will be used when switching between
2547 p_stream->b_force_backup = true;
2549 /* Cheat and get additionnal info ;) */
2550 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2551 oggpack_adv( &opb, 48 );
2553 i_major = oggpack_read( &opb, 8 ); /* major version num */
2554 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2555 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2557 oggpack_adv( &opb, 32 ); /* width */
2558 oggpack_adv( &opb, 32 ); /* height */
2560 oggpack_adv( &opb, 32 ); /* aspect numerator */
2561 oggpack_adv( &opb, 32 ); /* aspect denominator */
2562 i_timebase_numerator = oggpack_read( &opb, 32 );
2564 i_timebase_denominator = oggpack_read( &opb, 32 );
2565 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2567 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2568 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2570 oggpack_adv( &opb, 32 ); /* frame duration */
2572 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2574 /* granule_shift = i_log( frequency_force -1 ) */
2575 p_stream->i_granule_shift = 0;
2576 i_keyframe_frequency_force--;
2577 while( i_keyframe_frequency_force )
2579 p_stream->i_granule_shift++;
2580 i_keyframe_frequency_force >>= 1;
2583 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2584 p_stream->i_keyframe_offset = 0;
2585 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2586 if ( p_stream->f_rate == 0 ) return false;
2591 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2592 ogg_packet *p_oggpacket )
2596 p_stream->fmt.i_cat = AUDIO_ES;
2597 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2599 /* Signal that we want to keep a backup of the vorbis
2600 * stream headers. They will be used when switching between
2602 p_stream->b_force_backup = true;
2604 /* Cheat and get additionnal info ;) */
2605 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2606 oggpack_adv( &opb, 88 );
2607 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2608 fill_channels_info(&p_stream->fmt.audio);
2609 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2610 oggpack_read( &opb, 32 );
2611 oggpack_adv( &opb, 32 );
2612 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2613 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2614 if ( p_stream->f_rate == 0 ) return false;
2617 #ifdef HAVE_LIBVORBIS
2618 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2619 ogg_packet *p_oggpacket, int i_number )
2623 case VORBIS_HEADER_IDENTIFICATION:
2624 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2625 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2626 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2628 FREENULL( p_stream->special.vorbis.p_info );
2629 FREENULL( p_stream->special.vorbis.p_comment );
2632 vorbis_info_init( p_stream->special.vorbis.p_info );
2633 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2636 case VORBIS_HEADER_COMMENT:
2637 case VORBIS_HEADER_SETUP:
2638 if ( !p_stream->special.vorbis.p_info ||
2639 vorbis_synthesis_headerin(
2640 p_stream->special.vorbis.p_info,
2641 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2644 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2653 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2654 ogg_packet *p_oggpacket )
2658 p_stream->fmt.i_cat = AUDIO_ES;
2659 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2661 /* Signal that we want to keep a backup of the speex
2662 * stream headers. They will be used when switching between
2664 p_stream->b_force_backup = true;
2666 /* Cheat and get additionnal info ;) */
2667 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2668 oggpack_adv( &opb, 224 );
2669 oggpack_adv( &opb, 32 ); /* speex_version_id */
2670 oggpack_adv( &opb, 32 ); /* header_size */
2671 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2672 if ( p_stream->f_rate == 0 ) return false;
2673 oggpack_adv( &opb, 32 ); /* mode */
2674 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2675 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2676 fill_channels_info(&p_stream->fmt.audio);
2677 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2678 p_stream->special.speex.i_framesize =
2679 oggpack_read( &opb, 32 ); /* frame_size */
2680 oggpack_adv( &opb, 32 ); /* vbr */
2681 p_stream->special.speex.i_framesperpacket =
2682 oggpack_read( &opb, 32 ); /* frames_per_packet */
2683 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2687 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2688 ogg_packet *p_oggpacket )
2692 p_stream->fmt.i_cat = AUDIO_ES;
2693 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2695 /* Signal that we want to keep a backup of the opus
2696 * stream headers. They will be used when switching between
2698 p_stream->b_force_backup = true;
2700 /* All OggOpus streams are timestamped at 48kHz and
2701 * can be played at 48kHz. */
2702 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2703 p_stream->fmt.i_bitrate = 0;
2705 /* Cheat and get additional info ;) */
2706 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2707 oggpack_adv( &opb, 64 );
2708 oggpack_adv( &opb, 8 ); /* version_id */
2709 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2710 fill_channels_info(&p_stream->fmt.audio);
2711 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2712 /* For Opus, trash the first 80 ms of decoded output as
2713 well, to avoid blowing out speakers if we get unlucky.
2714 Opus predicts content from prior frames, which can go
2715 badly if we seek right where the stream goes from very
2716 quiet to very loud. It will converge after a bit. */
2717 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2720 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2721 ogg_packet *p_oggpacket )
2723 /* Parse the STREAMINFO metadata */
2726 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2729 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2731 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2735 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2738 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2739 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2740 fill_channels_info(&p_stream->fmt.audio);
2742 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2743 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2744 if ( p_stream->f_rate == 0 ) return false;
2748 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2751 /* Fake this as the last metadata block */
2752 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2756 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2757 ogg_packet *p_oggpacket )
2765 p_stream->fmt.i_cat = SPU_ES;
2766 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2768 /* Signal that we want to keep a backup of the kate
2769 * stream headers. They will be used when switching between
2771 p_stream->b_force_backup = true;
2773 /* Cheat and get additionnal info ;) */
2774 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2775 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2776 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2777 oggpack_adv( &opb, 3*8 );
2778 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2779 oggpack_adv( &opb, 8*8 ); /* reserved */
2780 gnum = oggpack_read( &opb, 32 );
2781 gden = oggpack_read( &opb, 32 );
2782 gden = __MAX( gden, 1 );
2783 p_stream->f_rate = (double)gnum/gden;
2784 if ( p_stream->f_rate == 0 ) return false;
2786 p_stream->fmt.psz_language = malloc(16);
2787 if( p_stream->fmt.psz_language )
2789 for( n = 0; n < 16; n++ )
2790 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2791 p_stream->fmt.psz_language[15] = 0; /* just in case */
2795 for( n = 0; n < 16; n++ )
2796 oggpack_read(&opb,8);
2798 p_stream->fmt.psz_description = malloc(16);
2799 if( p_stream->fmt.psz_description )
2801 for( n = 0; n < 16; n++ )
2802 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2803 p_stream->fmt.psz_description[15] = 0; /* just in case */
2805 /* Now find a localized user readable description for this category */
2806 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2809 free( p_stream->fmt.psz_description );
2810 p_stream->fmt.psz_description = psz_desc;
2815 for( n = 0; n < 16; n++ )
2816 oggpack_read(&opb,8);
2822 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2823 ogg_packet *p_oggpacket )
2825 switch( p_oggpacket->packet[5] )
2829 /* Mapping version */
2830 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2832 p_stream->fmt.i_cat = VIDEO_ES;
2833 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2834 p_stream->i_granule_shift = 32;
2835 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2836 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2837 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2838 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2839 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2840 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2841 p_stream->fmt.video.i_frame_rate_base =
2842 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2843 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2844 if ( p_stream->f_rate == 0 ) return false;
2848 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2849 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2856 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2857 bool *b_force_backup, bool *b_packet_out )
2859 if( !strncmp(psz_value, "audio/x-wav", 11) )
2861 /* n.b. WAVs are unsupported right now */
2862 p_stream->fmt.i_cat = UNKNOWN_ES;
2863 free( p_stream->fmt.psz_description );
2864 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2866 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2867 !strncmp(psz_value, "audio/vorbis", 12) )
2869 p_stream->fmt.i_cat = AUDIO_ES;
2870 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2872 *b_force_backup = true;
2874 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2875 !strncmp(psz_value, "audio/speex", 11) )
2877 p_stream->fmt.i_cat = AUDIO_ES;
2878 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2880 *b_force_backup = true;
2882 else if( !strncmp(psz_value, "audio/flac", 10) )
2884 p_stream->fmt.i_cat = AUDIO_ES;
2885 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2887 *b_force_backup = true;
2889 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2890 !strncmp(psz_value, "video/theora", 12) )
2892 p_stream->fmt.i_cat = VIDEO_ES;
2893 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2895 *b_force_backup = true;
2897 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2898 !strncmp(psz_value, "video/daala", 11) )
2900 p_stream->fmt.i_cat = VIDEO_ES;
2901 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2903 *b_force_backup = true;
2905 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2907 p_stream->fmt.i_cat = VIDEO_ES;
2908 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2910 *b_force_backup = true;
2912 else if( !strncmp(psz_value, "video/mpeg", 10) )
2914 /* n.b. MPEG streams are unsupported right now */
2915 p_stream->fmt.i_cat = VIDEO_ES;
2916 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2918 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2919 !strncmp(psz_value, "text/cmml", 9) )
2921 p_stream->fmt.i_cat = SPU_ES;
2922 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2923 *b_packet_out = true;
2925 else if( !strncmp(psz_value, "application/kate", 16) )
2928 p_stream->fmt.i_cat = UNKNOWN_ES;
2929 free( p_stream->fmt.psz_description );
2930 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2932 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2934 p_stream->fmt.i_cat = VIDEO_ES;
2935 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2939 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2940 logical_stream_t *p_stream,
2941 ogg_packet *p_oggpacket )
2943 if( p_oggpacket->bytes >= 28 &&
2944 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2948 uint16_t major_version;
2949 uint16_t minor_version;
2950 uint64_t timebase_numerator;
2951 uint64_t timebase_denominator;
2953 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2955 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2956 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2957 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2958 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2959 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2960 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2962 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2963 "Timebase %"PRId64" / %"PRId64,
2964 major_version, minor_version,
2965 timebase_numerator, timebase_denominator );
2967 else if( p_oggpacket->bytes >= 42 &&
2968 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2970 uint64_t granule_rate_numerator;
2971 uint64_t granule_rate_denominator;
2972 char content_type_string[1024];
2974 /* Read in Annodex header fields */
2976 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2977 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2978 p_stream->i_secondary_header_packets =
2979 GetDWLE( &p_oggpacket->packet[24] );
2981 /* we are guaranteed that the first header field will be
2982 * the content-type (by the Annodex standard) */
2983 content_type_string[0] = '\0';
2984 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2986 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2987 p_oggpacket->bytes - 1 );
2988 if( p && p[0] == '\r' && p[1] == '\n' )
2989 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2990 content_type_string );
2993 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2994 granule_rate_numerator, granule_rate_denominator,
2995 p_stream->i_secondary_header_packets, content_type_string );
2997 p_stream->f_rate = (float) granule_rate_numerator /
2998 (float) granule_rate_denominator;
3000 /* What type of file do we have?
3001 * strcmp is safe to use here because we've extracted
3002 * content_type_string from the stream manually */
3003 bool b_dopacketout = false;
3004 Ogg_ApplyContentType( p_stream, content_type_string,
3005 &p_stream->b_force_backup, &b_dopacketout );
3006 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3010 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3011 ogg_packet *p_oggpacket )
3013 p_demux->p_sys->p_skelstream = p_stream;
3014 /* There can be only 1 skeleton for streams */
3015 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3016 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3017 if ( asprintf( & p_stream->fmt.psz_description,
3018 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3019 p_demux->p_sys->skeleton.major,
3020 p_demux->p_sys->skeleton.minor ) < 0 )
3021 p_stream->fmt.psz_description = NULL;
3024 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3026 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3028 /* Find the matching stream for this skeleton data */
3029 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3030 logical_stream_t *p_target_stream = NULL;
3031 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3033 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3035 p_target_stream = p_demux->p_sys->pp_stream[i];
3039 if ( !p_target_stream ) return;
3041 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3044 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3045 if ( !p_skel ) return;
3046 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3047 p_skel->p_index = NULL;
3048 p_target_stream->p_skel = p_skel;
3051 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3052 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3053 const unsigned char *p = p_messages;
3054 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3056 if ( *p == 0x0D && *(p+1) == 0x0A )
3058 char *psz_message = strndup( (const char *) p_messages,
3062 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3063 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3065 if ( p < p_boundary - 1 ) p_messages = p + 2;
3072 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3073 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3074 unsigned const char *p_end,
3075 uint64_t *pi_value )
3081 while ( p_begin < p_end )
3083 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3084 *pi_value = *pi_value | ( i_read << i_shift );
3086 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3089 *pi_value = GetQWLE( pi_value );
3093 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3095 if ( p_demux->p_sys->skeleton.major < 4
3096 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3099 /* Find the matching stream for this skeleton data */
3100 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3101 logical_stream_t *p_stream = NULL;
3102 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3104 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3106 p_stream = p_demux->p_sys->pp_stream[i];
3110 if ( !p_stream || !p_stream->p_skel ) return;
3111 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3112 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3113 if ( !i_keypoints ) return;
3115 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3116 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3117 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3118 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3119 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3120 uint64_t i_offset = 0;
3121 uint64_t i_time = 0;
3122 uint64_t i_keypoints_found = 0;
3124 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3127 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3129 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3130 i_time += i_val * p_stream->p_skel->i_indexstampden;
3131 i_keypoints_found++;
3134 if ( i_keypoints_found != i_keypoints )
3136 msg_Warn( p_demux, "Invalid Index: missing entries" );
3140 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3141 if ( !p_stream->p_skel->p_index ) return;
3142 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3143 p_oggpacket->bytes - 42 );
3144 p_stream->p_skel->i_index = i_keypoints_found;
3145 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3148 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3150 if ( !p_skel ) return;
3151 for ( int i=0; i< p_skel->i_messages; i++ )
3152 free( p_skel->ppsz_messages[i] );
3153 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3154 free( p_skel->p_index );
3158 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3160 if ( !p_stream->p_skel ) return;
3161 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3163 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3164 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3166 free( p_stream->fmt.psz_description );
3167 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3169 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3172 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3177 /* Return true if there's a skeleton exact match */
3178 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3179 int64_t *pi_lower, int64_t *pi_upper )
3181 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3184 /* Validate range */
3185 if ( i_time < p_stream->p_skel->i_indexfirstnum
3186 * p_stream->p_skel->i_indexstampden ||
3187 i_time > p_stream->p_skel->i_indexlastnum
3188 * p_stream->p_skel->i_indexstampden ) return false;
3190 /* Then Lookup its index */
3191 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3196 } current = { 0, 0 }, prev = { -1, -1 };
3198 uint64_t i_keypoints_found = 0;
3200 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3201 && i_keypoints_found < p_stream->p_skel->i_index )
3204 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3205 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3206 current.i_pos += i_val;
3207 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3208 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3209 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3210 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3212 i_keypoints_found++;
3214 if ( i_time <= current.i_time )
3216 *pi_lower = prev.i_pos;
3217 *pi_upper = current.i_pos;
3218 return ( i_time == current.i_time );
3225 static uint32_t dirac_uint( bs_t *p_bs )
3227 uint32_t u_count = 0, u_value = 0;
3229 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3233 u_value |= bs_read( p_bs, 1 );
3236 return (1<<u_count) - 1 + u_value;
3239 static int dirac_bool( bs_t *p_bs )
3241 return bs_read( p_bs, 1 );
3244 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3245 ogg_packet *p_oggpacket )
3247 static const struct {
3248 uint32_t u_n /* numerator */, u_d /* denominator */;
3249 } p_dirac_frate_tbl[] = { /* table 10.3 */
3250 {1,1}, /* this first value is never used */
3251 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3252 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3254 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3256 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3257 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3259 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3263 p_stream->i_granule_shift = 22; /* not 32 */
3265 /* Backing up stream headers is not required -- seqhdrs are repeated
3266 * thoughout the stream at suitable decoding start points */
3267 p_stream->b_force_backup = false;
3269 /* read in useful bits from sequence header */
3270 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3271 bs_skip( &bs, 13*8); /* parse_info_header */
3272 dirac_uint( &bs ); /* major_version */
3273 dirac_uint( &bs ); /* minor_version */
3274 dirac_uint( &bs ); /* profile */
3275 dirac_uint( &bs ); /* level */
3277 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3278 if( u_video_format >= u_dirac_vidfmt_frate )
3280 /* don't know how to parse this ogg dirac stream */
3284 if( dirac_bool( &bs ) )
3286 dirac_uint( &bs ); /* frame_width */
3287 dirac_uint( &bs ); /* frame_height */
3290 if( dirac_bool( &bs ) )
3292 dirac_uint( &bs ); /* chroma_format */
3295 if( dirac_bool( &bs ) )
3297 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3300 p_stream->special.dirac.b_interlaced = false;
3302 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3303 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3304 u_d = __MAX( u_d, 1 );
3305 if( dirac_bool( &bs ) )
3307 uint32_t u_frame_rate_index = dirac_uint( &bs );
3308 if( u_frame_rate_index >= u_dirac_frate_tbl )
3310 /* something is wrong with this stream */
3313 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3314 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3315 if( u_frame_rate_index == 0 )
3317 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3318 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3321 p_stream->f_rate = (float) u_n / u_d;
3322 if ( p_stream->f_rate == 0 ) return false;
3324 /* probably is an ogg dirac es */
3325 p_stream->fmt.i_cat = VIDEO_ES;
3326 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;