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"
48 /*****************************************************************************
50 *****************************************************************************/
51 static int Open ( vlc_object_t * );
52 static void Close( vlc_object_t * );
55 set_shortname ( "OGG" )
56 set_description( N_("OGG demuxer" ) )
57 set_category( CAT_INPUT )
58 set_subcategory( SUBCAT_INPUT_DEMUX )
59 set_capability( "demux", 50 )
60 set_callbacks( Open, Close )
65 /*****************************************************************************
66 * Definitions of structures and functions used by this plugins
67 *****************************************************************************/
69 /* OggDS headers for the new header format (used in ogm files) */
74 } stream_header_video_t;
80 ogg_int16_t blockalign;
81 ogg_int32_t avgbytespersec;
82 } stream_header_audio_t;
89 ogg_int32_t size; /* size of the structure */
91 ogg_int64_t time_unit; /* in reference time */
92 ogg_int64_t samples_per_unit;
93 ogg_int32_t default_len; /* in media time */
95 ogg_int32_t buffersize;
96 ogg_int16_t bits_per_sample;
102 stream_header_video_t video;
104 stream_header_audio_t audio;
108 #define VORBIS_HEADER_IDENTIFICATION 1
109 #define VORBIS_HEADER_COMMENT 2
110 #define VORBIS_HEADER_SETUP 3
112 /*****************************************************************************
114 *****************************************************************************/
115 static int Demux ( demux_t * );
116 static int Control( demux_t *, int, va_list );
118 /* Bitstream manipulation */
119 static int Ogg_ReadPage ( demux_t *, ogg_page * );
120 static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * );
121 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
122 static int Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * );
123 static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * );
125 static void Ogg_CreateES( demux_t *p_demux );
126 static int Ogg_BeginningOfStream( demux_t *p_demux );
127 static int Ogg_FindLogicalStreams( demux_t *p_demux );
128 static void Ogg_EndOfStream( demux_t *p_demux );
131 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
132 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
133 static void Ogg_ResetStream( logical_stream_t *p_stream );
136 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
138 /* Logical bitstream headers */
139 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
140 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
141 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
142 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
143 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
144 static bool Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
145 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
146 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
147 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
148 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
151 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
152 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
153 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
154 static void Ogg_ApplySkeleton( logical_stream_t * );
156 /* Special decoding */
157 static void Ogg_CleanSpecificData( logical_stream_t * );
158 #ifdef HAVE_LIBVORBIS
159 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
162 static void fill_channels_info(audio_format_t *audio)
164 static const int pi_channels_map[9] =
168 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
169 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
170 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
171 | AOUT_CHAN_REARRIGHT,
172 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
173 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
174 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
175 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
176 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
177 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
178 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
179 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
180 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
184 unsigned chans = audio->i_channels;
185 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
186 audio->i_physical_channels =
187 audio->i_original_channels = pi_channels_map[chans];
190 /* Special TS value: don't send or derive any pts/pcr from it.
191 Represents TS state prior first known valid timestamp */
192 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
194 /*****************************************************************************
195 * Open: initializes ogg demux structures
196 *****************************************************************************/
197 static int Open( vlc_object_t * p_this )
199 demux_t *p_demux = (demux_t *)p_this;
201 const uint8_t *p_peek;
203 /* Check if we are dealing with an ogg stream */
204 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
205 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
207 char *psz_mime = stream_ContentType( p_demux->s );
212 else if ( strcmp( psz_mime, "application/ogg" ) &&
213 strcmp( psz_mime, "video/ogg" ) &&
214 strcmp( psz_mime, "audio/ogg" ) )
223 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
227 p_sys->i_length = -1;
228 p_sys->b_preparsing_done = false;
230 stream_Control( p_demux->s, ACCESS_GET_PTS_DELAY, & p_sys->i_access_delay );
232 /* Set exported functions */
233 p_demux->pf_demux = Demux;
234 p_demux->pf_control = Control;
236 /* Initialize the Ogg physical bitstream parser */
237 ogg_sync_init( &p_sys->oy );
240 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
243 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
249 /*****************************************************************************
250 * Close: frees unused data
251 *****************************************************************************/
252 static void Close( vlc_object_t *p_this )
254 demux_t *p_demux = (demux_t *)p_this;
255 demux_sys_t *p_sys = p_demux->p_sys ;
257 /* Cleanup the bitstream parser */
258 ogg_sync_clear( &p_sys->oy );
260 Ogg_EndOfStream( p_demux );
262 if( p_sys->p_old_stream )
263 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
268 /*****************************************************************************
269 * Demux: reads and demuxes data packets
270 *****************************************************************************
271 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
272 *****************************************************************************/
273 static int Demux( demux_t * p_demux )
275 demux_sys_t *p_sys = p_demux->p_sys;
276 ogg_packet oggpacket;
278 bool b_skipping = false;
281 int i_active_streams = p_sys->i_streams;
282 for ( int i=0; i < p_sys->i_streams; i++ )
284 if ( p_sys->pp_stream[i]->b_finished )
288 if ( i_active_streams == 0 )
290 if ( p_sys->i_streams ) /* All finished */
292 msg_Dbg( p_demux, "end of a group of logical streams" );
293 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
294 * only 1 ES is supported (common case for ogg web radio) */
295 if( p_sys->i_streams == 1 )
297 p_sys->p_old_stream = p_sys->pp_stream[0];
298 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
300 Ogg_EndOfStream( p_demux );
301 p_sys->b_chained_boundary = true;
304 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
307 msg_Dbg( p_demux, "beginning of a group of logical streams" );
309 if ( !p_sys->b_chained_boundary )
311 /* Find the real duration */
312 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
314 Oggseek_ProbeEnd( p_demux );
318 p_sys->b_chained_boundary = false;
322 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
324 Ogg_CreateES( p_demux );
325 p_sys->b_es_created = true;
329 * The first data page of a physical stream is stored in the relevant logical stream
330 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
331 * stream it belongs to if we haven't processed this first page yet. If we do, we
332 * will only process that first page whenever we find the second page for this stream.
333 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
334 * the second page will arrive real quick, this is not fine for Kate, whose second
335 * data page will typically arrive much later.
336 * This means it is now possible to seek right at the start of a stream where the last
337 * logical stream is Kate, without having to wait for the second data page to unblock
338 * the first one, which is the one that triggers the 'no more headers to backup' code.
339 * And, as we all know, seeking without having backed up all headers is bad, since the
340 * codec will fail to initialize if it's missing its headers.
342 if( !p_sys->b_page_waiting)
345 * Demux an ogg page from the stream
347 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
349 /* Test for End of Stream */
350 if( ogg_page_eos( &p_sys->current_page ) )
352 /* If we delayed restarting encoders/SET_ES_FMT for more
353 * skeleton provided configuration */
354 if ( p_sys->p_skelstream )
356 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
358 msg_Dbg( p_demux, "End of Skeleton" );
359 p_sys->b_preparsing_done = true;
360 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
362 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
363 Ogg_ApplySkeleton( p_stream );
368 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
370 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
372 p_sys->pp_stream[i_stream]->b_finished = true;
380 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
382 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
385 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
387 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
389 /* if we've just pulled page, look for the right logical stream */
390 if( !p_sys->b_page_waiting )
392 if( p_sys->i_streams == 1 &&
393 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
395 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
396 Ogg_ResetStream( p_stream );
397 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
400 /* Does fail if serialno differs */
401 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
407 /* clear the finished flag if pages after eos (ex: after a seek) */
408 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
409 p_stream->b_finished = false;
412 if ( p_stream->fmt.i_cat == VIDEO_ES )
413 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
414 ogg_page_pageno( &p_sys->current_page ),
415 ogg_page_granulepos( &p_sys->current_page ),
416 ogg_page_packets( &p_sys->current_page ),
417 ogg_page_continued(&p_sys->current_page),
418 p_sys->current_page.body_len )
421 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
424 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
425 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
426 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
427 p_stream->fmt.i_cat == VIDEO_ES )
429 assert( p_stream->p_prepcr_blocks == NULL );
430 p_stream->i_prepcr_blocks = 0;
431 p_stream->p_prepcr_blocks = malloc( sizeof(block_t *) * ogg_page_packets( &p_sys->current_page ) );
435 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
437 /* Read info from any secondary header packets, if there are any */
438 if( p_stream->i_secondary_header_packets > 0 )
440 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
441 oggpacket.bytes >= 7 &&
442 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
444 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
445 p_stream->i_secondary_header_packets = 0;
447 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
448 oggpacket.bytes >= 7 &&
449 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
451 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
452 p_stream->i_secondary_header_packets = 0;
454 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
456 p_stream->i_secondary_header_packets = 0;
459 /* update start of data pointer */
460 p_stream->i_data_start = stream_Tell( p_demux->s );
463 /* If any streams have i_skip_frames, only decode (pre-roll)
464 * for those streams, but don't skip headers */
465 if ( b_skipping && p_stream->i_skip_frames == 0
466 && p_stream->i_secondary_header_packets ) continue;
468 if( p_stream->b_reinit )
470 p_stream->b_reinit = false;
471 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
473 p_stream->i_skip_frames = p_stream->i_pre_skip;
477 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
481 if ( p_stream->p_prepcr_blocks )
483 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
484 p_stream->i_previous_pcr = pagestamp;
485 #ifdef HAVE_LIBVORBIS
486 int i_prev_blocksize = 0;
489 for( int i=0; i<p_stream->i_prepcr_blocks; i++ )
491 block_t *p_block = p_stream->p_prepcr_blocks[i];
492 ogg_packet dumb_packet;
493 dumb_packet.bytes = p_block->i_buffer;
494 dumb_packet.packet = p_block->p_buffer;
497 switch( p_stream->fmt.i_codec )
499 case VLC_CODEC_SPEEX:
500 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
501 p_stream->special.speex.i_framesperpacket;
504 i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
505 p_block->i_nb_samples = i_duration;
507 #ifdef HAVE_LIBVORBIS
508 case VLC_CODEC_VORBIS:
510 long i_blocksize = vorbis_packet_blocksize(
511 p_stream->special.vorbis.p_info, &dumb_packet );
512 if ( i_prev_blocksize )
513 i_duration = ( i_blocksize + i_prev_blocksize ) / 4;
515 i_duration = i_blocksize / 2;
516 i_prev_blocksize = i_blocksize;
517 p_block->i_nb_samples = i_duration;
524 bool b_fixed = false;
525 for( int i=p_stream->i_prepcr_blocks - 1; i>=0; i-- )
527 block_t *p_block = p_stream->p_prepcr_blocks[i];
528 switch( p_stream->fmt.i_codec )
530 case VLC_CODEC_SPEEX:
532 case VLC_CODEC_VORBIS:
533 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
536 p_block->i_pts = VLC_TS_INVALID;
537 p_block->i_flags |= BLOCK_FLAG_PREROLL;
540 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
544 if ( p_stream->fmt.i_cat == VIDEO_ES )
546 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
547 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
555 if ( pagestamp < 0 ) pagestamp = 0;
556 p_stream->i_pcr = VLC_TS_0 + pagestamp;
557 p_stream->i_pcr += p_sys->i_nzpcr_offset;
558 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
561 FREENULL( p_stream->p_prepcr_blocks );
562 p_stream->i_prepcr_blocks = 0;
564 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
568 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
569 ogg_page_granulepos( &p_sys->current_page ), false );
570 if ( i_pagestamp > -1 )
572 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
573 p_stream->i_pcr += p_sys->i_nzpcr_offset;
576 if( !p_sys->b_page_waiting )
580 /* if a page was waiting, it's now processed */
581 p_sys->b_page_waiting = false;
583 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
584 p_sys->b_preparsing_done = false;
586 p_sys->b_preparsing_done = true;
588 /* We will consider the lowest PCR among tracks, because the audio core badly
589 * handles PCR rewind (mute)
591 mtime_t i_pcr_candidate = VLC_TS_INVALID;
592 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
594 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
596 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
598 /* We have 1 or more streams needing more than 1 page for preparsing */
599 p_sys->b_preparsing_done = false;
602 if( p_stream->fmt.i_cat == SPU_ES )
604 if( p_stream->i_pcr < VLC_TS_0 )
606 if ( p_stream->b_finished || p_stream->b_initializing )
608 if ( p_stream->p_preparse_block )
610 if( i_pcr_candidate < VLC_TS_0
611 || p_stream->i_pcr <= i_pcr_candidate )
613 i_pcr_candidate = p_stream->i_pcr;
617 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
619 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
621 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
622 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
624 p_sys->i_pcr_jitter = i_pcr_jitter;
625 if ( p_sys->i_access_delay < i_pcr_jitter )
626 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
627 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
631 if( ! b_skipping && p_sys->b_preparsing_done )
633 p_sys->i_pcr = i_pcr_candidate;
634 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
641 static void Ogg_ResetStream( logical_stream_t *p_stream )
643 #ifdef HAVE_LIBVORBIS
644 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
646 p_stream->special.vorbis.i_prev_blocksize = 0;
649 /* we'll trash all the data until we find the next pcr */
650 p_stream->b_reinit = true;
651 p_stream->i_pcr = VLC_TS_UNKNOWN;
652 p_stream->i_previous_granulepos = -1;
653 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
654 ogg_stream_reset( &p_stream->os );
655 FREENULL( p_stream->p_prepcr_blocks );
656 p_stream->i_prepcr_blocks = 0;
659 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
661 for( int i = 0; i < p_sys->i_streams; i++ )
662 Ogg_ResetStream( p_sys->pp_stream[i] );
664 ogg_sync_reset( &p_sys->oy );
665 p_sys->i_pcr = VLC_TS_UNKNOWN;
668 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
670 demux_sys_t *p_sys = p_demux->p_sys;
671 logical_stream_t *p_stream = NULL;
672 for( int i=0; i<p_sys->i_streams; i++ )
674 logical_stream_t *p_candidate = p_sys->pp_stream[i];
675 if ( !p_candidate->p_es ) continue;
677 bool b_selected = false;
678 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
679 p_candidate->p_es, &b_selected );
680 if ( !b_selected ) continue;
682 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
684 p_stream = p_candidate;
685 continue; /* Try to find video anyway */
688 if ( p_candidate->fmt.i_cat == VIDEO_ES )
690 p_stream = p_candidate;
697 /*****************************************************************************
699 *****************************************************************************/
700 static int Control( demux_t *p_demux, int i_query, va_list args )
702 demux_sys_t *p_sys = p_demux->p_sys;
711 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
713 vlc_meta_Merge( p_meta, p_sys->p_meta );
716 case DEMUX_HAS_UNSUPPORTED_META:
717 pb_bool = (bool*)va_arg( args, bool* );
722 pi64 = (int64_t*)va_arg( args, int64_t * );
723 *pi64 = p_sys->i_pcr;
727 i64 = (int64_t)va_arg( args, int64_t );
728 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
731 msg_Err( p_demux, "No selected seekable stream found" );
734 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
735 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
737 Ogg_ResetStreamsHelper( p_sys );
738 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
745 case DEMUX_GET_ATTACHMENTS:
747 input_attachment_t ***ppp_attach =
748 (input_attachment_t***)va_arg( args, input_attachment_t*** );
749 int *pi_int = (int*)va_arg( args, int * );
751 if( p_sys->i_attachments <= 0 )
754 *pi_int = p_sys->i_attachments;
755 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
756 for( int i = 0; i < p_sys->i_attachments; i++ )
757 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
761 case DEMUX_GET_POSITION:
762 pf = (double*)va_arg( args, double * );
763 if( p_sys->i_length > 0 )
765 *pf = (double) p_sys->i_pcr /
766 (double) ( p_sys->i_length * (mtime_t)1000000 );
768 else if( stream_Size( p_demux->s ) > 0 )
770 i64 = stream_Tell( p_demux->s );
771 *pf = (double) i64 / stream_Size( p_demux->s );
776 case DEMUX_SET_POSITION:
777 /* forbid seeking if we haven't initialized all logical bitstreams yet;
778 if we allowed, some headers would not get backed up and decoder init
779 would fail, making that logical stream unusable */
780 for ( int i=0; i< p_sys->i_streams; i++ )
782 if ( p_sys->pp_stream[i]->b_initializing )
786 p_stream = Ogg_GetSelectedStream( p_demux );
789 msg_Err( p_demux, "No selected seekable stream found" );
793 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
795 f = (double)va_arg( args, double );
796 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
798 Ogg_ResetStreamsHelper( p_sys );
799 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
803 assert( p_sys->i_length > 0 );
804 i64 = CLOCK_FREQ * p_sys->i_length * f;
805 Ogg_ResetStreamsHelper( p_sys );
806 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
808 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
815 case DEMUX_GET_LENGTH:
816 if ( p_sys->i_length < 0 )
817 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
819 pi64 = (int64_t*)va_arg( args, int64_t * );
820 *pi64 = p_sys->i_length * 1000000;
823 case DEMUX_GET_TITLE_INFO:
825 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
826 int *pi_int = (int*)va_arg( args, int* );
827 int *pi_title_offset = (int*)va_arg( args, int* );
828 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
830 if( p_sys->i_seekpoints > 0 )
833 *ppp_title = malloc( sizeof( input_title_t* ) );
834 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
835 for( int i = 0; i < p_sys->i_seekpoints; i++ )
837 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
838 if ( likely( p_seekpoint_copy ) )
839 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
841 *pi_title_offset = 0;
842 *pi_seekpoint_offset = 0;
846 case DEMUX_SET_TITLE:
848 const int i_title = (int)va_arg( args, int );
853 case DEMUX_SET_SEEKPOINT:
855 const int i_seekpoint = (int)va_arg( args, int );
856 if( i_seekpoint > p_sys->i_seekpoints )
859 for ( int i=0; i< p_sys->i_streams; i++ )
861 if ( p_sys->pp_stream[i]->b_initializing )
865 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
867 p_stream = Ogg_GetSelectedStream( p_demux );
870 msg_Err( p_demux, "No selected seekable stream found" );
874 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
875 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
877 Ogg_ResetStreamsHelper( p_sys );
878 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
880 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
881 p_demux->info.i_seekpoint = i_seekpoint;
889 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
894 /****************************************************************************
895 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
896 ****************************************************************************
897 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
898 * are at the end of stream.
899 ****************************************************************************/
900 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
902 demux_sys_t *p_ogg = p_demux->p_sys ;
906 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
908 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
910 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
914 ogg_sync_wrote( &p_ogg->oy, i_read );
920 /****************************************************************************
921 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
923 ****************************************************************************/
924 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
925 ogg_packet *p_oggpacket )
927 demux_sys_t *p_ogg = p_demux->p_sys;
928 p_stream->i_end_trim = 0;
930 /* Convert the granulepos into a pcr */
931 if ( p_oggpacket->granulepos == 0 )
933 /* We're in headers, and we haven't parsed 1st data packet yet */
934 // p_stream->i_pcr = VLC_TS_UNKNOWN;
936 else if( p_oggpacket->granulepos > 0 )
938 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
939 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
940 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
941 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
942 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
943 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
945 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
946 p_oggpacket->granulepos, true );
947 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
949 else if ( p_stream->i_previous_granulepos > 0 )
951 ogg_int64_t sample = p_stream->i_previous_granulepos;
953 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
955 int duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
958 ogg_int64_t end_sample = p_oggpacket->granulepos;
959 if( end_sample < ( sample + duration ) )
960 p_stream->i_end_trim = sample + duration - end_sample;
964 if (sample >= p_stream->i_pre_skip)
965 sample -= p_stream->i_pre_skip;
969 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
970 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
974 else if ( p_oggpacket->granulepos == -1 )
977 /* no granulepos available, try to interpolate the pcr.
978 * If we can't then don't touch the old value. */
979 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
981 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
983 #ifdef HAVE_LIBVORBIS
984 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
985 p_stream->special.vorbis.p_info &&
986 !p_stream->special.vorbis.b_invalid &&
987 p_stream->i_previous_granulepos > 0 )
989 long i_blocksize = vorbis_packet_blocksize(
990 p_stream->special.vorbis.p_info, p_oggpacket );
991 if ( p_stream->special.vorbis.i_prev_blocksize )
992 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
994 i_duration = i_blocksize / 2;
995 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
996 /* duration in samples per channel */
997 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
998 p_stream->i_pcr = p_stream->i_previous_granulepos *
999 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1000 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1003 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1004 p_stream->i_previous_granulepos > 0 )
1006 i_duration = p_stream->special.speex.i_framesize *
1007 p_stream->special.speex.i_framesperpacket;
1008 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1009 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1010 p_stream->i_previous_granulepos, false );
1011 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1013 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1014 p_stream->i_previous_granulepos > 0 &&
1016 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
1019 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1020 sample = p_stream->i_previous_granulepos;
1021 if (sample >= p_stream->i_pre_skip)
1022 sample -= p_stream->i_pre_skip;
1026 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1027 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1029 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1031 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1032 p_stream->fmt.i_bitrate / 8 );
1036 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1039 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1042 demux_sys_t *p_ogg = p_demux->p_sys;
1043 if ( !p_stream->p_es || p_stream->p_prepcr_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1045 if ( !p_block ) return;
1046 if ( p_stream->p_prepcr_blocks )
1048 assert( p_stream->p_prepcr_blocks );
1049 p_stream->p_prepcr_blocks[p_stream->i_prepcr_blocks++] = p_block;
1051 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1052 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1053 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1057 /* Because ES creation is delayed for preparsing */
1058 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1059 if ( p_stream->p_preparse_block )
1061 block_t *temp = p_stream->p_preparse_block;
1064 if ( temp && i_firstpts < VLC_TS_0 )
1065 i_firstpts = temp->i_pts;
1067 block_t *tosend = temp;
1068 temp = temp->p_next;
1069 tosend->p_next = NULL;
1071 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1072 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1073 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1075 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1077 p_ogg->i_pcr = i_firstpts;
1078 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1081 p_stream->p_preparse_block = NULL;
1086 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1087 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1088 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1093 /****************************************************************************
1094 * Ogg_DecodePacket: Decode an Ogg packet.
1095 ****************************************************************************/
1096 static void Ogg_DecodePacket( demux_t *p_demux,
1097 logical_stream_t *p_stream,
1098 ogg_packet *p_oggpacket )
1102 int i_header_len = 0;
1104 if( p_oggpacket->bytes >= 7 &&
1105 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1107 /* it's an Annodex packet -- skip it (do nothing) */
1110 else if( p_oggpacket->bytes >= 7 &&
1111 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1113 /* it's an AnxData packet -- skip it (do nothing) */
1116 else if( p_oggpacket->bytes >= 8 &&
1117 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1119 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1122 else if( p_oggpacket->bytes >= 6 &&
1123 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1125 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1128 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1129 p_oggpacket->bytes >= 7 &&
1130 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1132 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1136 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1137 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1139 /* Check the ES is selected */
1140 if ( !p_stream->p_es )
1143 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1144 p_stream->p_es, &b_selected );
1146 if( p_stream->b_force_backup )
1149 p_stream->i_packets_backup++;
1150 switch( p_stream->fmt.i_codec )
1152 case VLC_CODEC_VORBIS:
1153 #ifdef HAVE_LIBVORBIS
1154 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1157 case VLC_CODEC_THEORA:
1158 if( p_stream->i_packets_backup == 3 )
1159 p_stream->b_force_backup = false;
1163 case VLC_CODEC_SPEEX:
1164 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1165 p_stream->b_force_backup = false;
1169 case VLC_CODEC_OPUS:
1170 if( p_stream->i_packets_backup == 2 )
1171 p_stream->b_force_backup = false;
1175 case VLC_CODEC_FLAC:
1176 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1178 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1179 p_stream->b_force_backup = false;
1181 else if( p_stream->fmt.audio.i_rate )
1183 p_stream->b_force_backup = false;
1184 if( p_oggpacket->bytes >= 9 )
1186 p_oggpacket->packet += 9;
1187 p_oggpacket->bytes -= 9;
1193 case VLC_CODEC_KATE:
1194 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1195 p_stream->b_force_backup = false;
1200 p_stream->b_force_backup = false;
1205 /* Backup the ogg packet (likely an header packet) */
1208 void *p_org = p_stream->p_headers;
1209 p_stream->i_headers += p_oggpacket->bytes;
1210 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1211 if( p_stream->p_headers )
1213 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1214 p_oggpacket->packet, p_oggpacket->bytes );
1218 #warning Memory leak
1219 p_stream->i_headers = 0;
1220 p_stream->p_headers = NULL;
1224 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1225 p_oggpacket->bytes, p_oggpacket->packet ) )
1227 p_stream->i_headers = 0;
1228 p_stream->p_headers = NULL;
1230 if( p_stream->i_headers > 0 )
1232 if( !p_stream->b_force_backup )
1234 /* Last header received, commit changes */
1235 free( p_stream->fmt.p_extra );
1237 p_stream->fmt.i_extra = p_stream->i_headers;
1238 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1239 if( p_stream->fmt.p_extra )
1240 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1241 p_stream->i_headers );
1243 p_stream->fmt.i_extra = 0;
1245 if( p_stream->i_headers > 0 )
1246 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1247 p_stream->p_headers, p_stream->i_headers );
1249 /* we're not at BOS anymore for this logical stream */
1250 p_stream->b_initializing = false;
1254 b_selected = false; /* Discard the header packet */
1258 p_stream->b_initializing = false;
1261 /* Convert the granulepos into the next pcr */
1262 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1266 /* This stream isn't currently selected so we don't need to decode it,
1267 * but we did need to store its pcr as it might be selected later on */
1271 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1272 p_block->i_pts = p_stream->i_pcr;
1274 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1275 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1277 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1278 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1280 /* may need to preroll after a seek or in case of preskip */
1281 if ( p_stream->i_skip_frames > 0 )
1283 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1285 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1287 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1288 p_stream->i_skip_frames -= p_block->i_nb_samples;
1289 p_block->i_nb_samples = 0;
1293 p_block->i_nb_samples -= p_stream->i_skip_frames;
1294 p_stream->i_skip_frames = 0;
1299 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1300 p_stream->i_skip_frames--;
1304 /* Conditional block fixes */
1305 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1306 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1308 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1310 else if( p_stream->fmt.i_cat == AUDIO_ES )
1312 /* Blatant abuse of the i_length field. */
1313 p_block->i_length = p_stream->i_end_trim;
1315 else if( p_stream->fmt.i_cat == SPU_ES )
1317 p_block->i_length = 0;
1319 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1321 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1322 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1323 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1324 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1325 /* granulepos for dirac is possibly broken, this value should be ignored */
1326 if( 0 >= p_oggpacket->granulepos )
1328 p_block->i_pts = VLC_TS_INVALID;
1329 p_block->i_dts = p_stream->i_pcr;
1333 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1334 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1335 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1336 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1337 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1338 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1339 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1340 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1341 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1342 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1344 if( p_oggpacket->bytes <= 0 )
1346 msg_Dbg( p_demux, "discarding 0 sized packet" );
1347 block_Release( p_block );
1350 /* We remove the header from the packet */
1351 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1352 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1354 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1356 /* But with subtitles we need to retrieve the duration first */
1357 int i, lenbytes = 0;
1359 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1361 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1363 lenbytes = lenbytes << 8;
1364 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1367 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1368 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1369 p_oggpacket->packet[i_header_len + 1] != 0 &&
1370 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1371 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1373 p_block->i_length = (mtime_t)lenbytes * 1000;
1378 if( p_block->i_buffer >= (unsigned int)i_header_len )
1379 p_block->i_buffer -= i_header_len;
1381 p_block->i_buffer = 0;
1385 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1387 /* FIXME: the biggest hack I've ever done */
1388 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1389 p_block->i_pts, p_block->i_dts );
1393 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1394 p_oggpacket->bytes - i_header_len );
1396 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1399 /* Re-implemented to avoid linking against libopus from the demuxer. */
1400 static int Ogg_OpusDataDuration( logical_stream_t *p_stream,
1401 unsigned char *data, long i_datalen )
1403 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1410 return VLC_EGENERIC;
1423 return VLC_EGENERIC;
1424 nframes = data[1]&0x3F;
1427 i_rate = (int)p_stream->fmt.audio.i_rate;
1429 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1430 else if( ( toc&0x60 ) == 0x60 )
1431 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1433 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1434 nsamples = nframes*frame_size;
1435 if( nsamples*25 > i_rate*3 )
1436 return VLC_EGENERIC;
1440 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1441 ogg_packet *p_oggpacket )
1443 return Ogg_OpusDataDuration( p_stream, p_oggpacket->packet, p_oggpacket->bytes );
1446 /****************************************************************************
1447 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1448 * stream and fill p_ogg.
1449 *****************************************************************************
1450 * The initial page of a logical stream is marked as a 'bos' page.
1451 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1452 * together and all of the initial pages must appear before any data pages.
1454 * On success this function returns VLC_SUCCESS.
1455 ****************************************************************************/
1456 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1458 demux_sys_t *p_ogg = p_demux->p_sys ;
1459 ogg_packet oggpacket;
1462 p_ogg->i_total_length = stream_Size ( p_demux->s );
1463 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1466 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1469 if( ogg_page_bos( &p_ogg->current_page ) )
1472 /* All is wonderful in our fine fine little world.
1473 * We found the beginning of our first logical stream. */
1474 while( ogg_page_bos( &p_ogg->current_page ) )
1476 logical_stream_t *p_stream;
1478 p_stream = malloc( sizeof(logical_stream_t) );
1479 if( unlikely( !p_stream ) )
1482 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1484 memset( p_stream, 0, sizeof(logical_stream_t) );
1486 es_format_Init( &p_stream->fmt, 0, 0 );
1487 es_format_Init( &p_stream->fmt_old, 0, 0 );
1488 p_stream->b_initializing = true;
1490 /* Setup the logical stream */
1491 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1492 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1494 /* Extract the initial header from the first page and verify
1495 * the codec type of this Ogg bitstream */
1496 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1498 /* error. stream version mismatch perhaps */
1499 msg_Err( p_demux, "error reading first page of "
1500 "Ogg bitstream data" );
1501 return VLC_EGENERIC;
1504 /* FIXME: check return value */
1505 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1507 /* Check for Vorbis header */
1508 if( oggpacket.bytes >= 7 &&
1509 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1511 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1512 msg_Dbg( p_demux, "found vorbis header" );
1515 msg_Dbg( p_demux, "found invalid vorbis header" );
1516 Ogg_LogicalStreamDelete( p_demux, p_stream );
1520 /* Check for Speex header */
1521 else if( oggpacket.bytes >= 5 &&
1522 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1524 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1525 msg_Dbg( p_demux, "found speex header, channels: %i, "
1526 "rate: %i, bitrate: %i, frames: %i group %i",
1527 p_stream->fmt.audio.i_channels,
1528 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1529 p_stream->special.speex.i_framesize,
1530 p_stream->special.speex.i_framesperpacket );
1533 msg_Dbg( p_demux, "found invalid Speex header" );
1534 Ogg_LogicalStreamDelete( p_demux, p_stream );
1538 /* Check for Opus header */
1539 else if( oggpacket.bytes >= 8 &&
1540 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1542 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1543 msg_Dbg( p_demux, "found opus header, channels: %i, "
1545 p_stream->fmt.audio.i_channels,
1546 (int)p_stream->i_pre_skip);
1547 p_stream->i_skip_frames = p_stream->i_pre_skip;
1549 /* Check for Flac header (< version 1.1.1) */
1550 else if( oggpacket.bytes >= 4 &&
1551 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1553 msg_Dbg( p_demux, "found FLAC header" );
1555 /* Grrrr!!!! Did they really have to put all the
1556 * important info in the second header packet!!!
1557 * (STREAMINFO metadata is in the following packet) */
1558 p_stream->b_force_backup = true;
1559 p_stream->fmt.i_cat = AUDIO_ES;
1560 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1562 /* Check for Flac header (>= version 1.1.1) */
1563 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1564 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1565 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1567 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1568 oggpacket.packet[8];
1569 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1570 "(%i header packets)",
1571 oggpacket.packet[5], oggpacket.packet[6],
1574 p_stream->b_force_backup = true;
1576 p_stream->fmt.i_cat = AUDIO_ES;
1577 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1578 oggpacket.packet += 13; oggpacket.bytes -= 13;
1579 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1581 msg_Dbg( p_demux, "found invalid Flac header" );
1582 Ogg_LogicalStreamDelete( p_demux, p_stream );
1586 /* Check for Theora header */
1587 else if( oggpacket.bytes >= 7 &&
1588 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1590 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1592 "found theora header, bitrate: %i, rate: %f",
1593 p_stream->fmt.i_bitrate, p_stream->f_rate );
1596 msg_Dbg( p_demux, "found invalid Theora header" );
1597 Ogg_LogicalStreamDelete( p_demux, p_stream );
1601 /* Check for Dirac header */
1602 else if( ( oggpacket.bytes >= 5 &&
1603 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1604 ( oggpacket.bytes >= 9 &&
1605 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1607 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1608 msg_Dbg( p_demux, "found dirac header" );
1611 msg_Warn( p_demux, "found dirac header isn't decodable" );
1612 Ogg_LogicalStreamDelete( p_demux, p_stream );
1616 /* Check for Tarkin header */
1617 else if( oggpacket.bytes >= 7 &&
1618 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1622 msg_Dbg( p_demux, "found tarkin header" );
1623 p_stream->fmt.i_cat = VIDEO_ES;
1624 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1626 /* Cheat and get additionnal info ;) */
1627 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1628 oggpack_adv( &opb, 88 );
1629 oggpack_adv( &opb, 104 );
1630 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1631 p_stream->f_rate = 2; /* FIXME */
1633 "found tarkin header, bitrate: %i, rate: %f",
1634 p_stream->fmt.i_bitrate, p_stream->f_rate );
1636 /* Check for VP8 header */
1637 else if( oggpacket.bytes >= 26 &&
1638 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1640 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1641 msg_Dbg( p_demux, "found VP8 header "
1642 "fps: %f, width:%i; height:%i",
1644 p_stream->fmt.video.i_width,
1645 p_stream->fmt.video.i_height );
1648 msg_Dbg( p_demux, "invalid VP8 header found");
1649 Ogg_LogicalStreamDelete( p_demux, p_stream );
1653 /* Check for Annodex header */
1654 else if( oggpacket.bytes >= 7 &&
1655 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1657 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1658 /* kill annodex track */
1662 /* Check for Annodex header */
1663 else if( oggpacket.bytes >= 7 &&
1664 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1666 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1668 /* Check for Kate header */
1669 else if( oggpacket.bytes >= 8 &&
1670 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1672 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1673 msg_Dbg( p_demux, "found kate header" );
1676 msg_Dbg( p_demux, "invalid kate header found");
1677 Ogg_LogicalStreamDelete( p_demux, p_stream );
1681 /* Check for OggDS */
1682 else if( oggpacket.bytes >= 142 &&
1683 !memcmp( &oggpacket.packet[1],
1684 "Direct Show Samples embedded in Ogg", 35 ))
1686 /* Old header type */
1687 p_stream->b_oggds = true;
1688 /* Check for video header (old format) */
1689 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1690 oggpacket.bytes >= 184 )
1692 p_stream->fmt.i_cat = VIDEO_ES;
1693 p_stream->fmt.i_codec =
1694 VLC_FOURCC( oggpacket.packet[68],
1695 oggpacket.packet[69],
1696 oggpacket.packet[70],
1697 oggpacket.packet[71] );
1698 msg_Dbg( p_demux, "found video header of type: %.4s",
1699 (char *)&p_stream->fmt.i_codec );
1701 p_stream->fmt.video.i_frame_rate = 10000000;
1702 p_stream->fmt.video.i_frame_rate_base =
1703 GetQWLE((oggpacket.packet+164));
1704 p_stream->fmt.video.i_frame_rate_base =
1705 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1706 p_stream->f_rate = 10000000.0 /
1707 p_stream->fmt.video.i_frame_rate_base;
1708 p_stream->fmt.video.i_bits_per_pixel =
1709 GetWLE((oggpacket.packet+182));
1710 if( !p_stream->fmt.video.i_bits_per_pixel )
1712 p_stream->fmt.video.i_bits_per_pixel = 24;
1713 p_stream->fmt.video.i_width =
1714 GetDWLE((oggpacket.packet+176));
1715 p_stream->fmt.video.i_height =
1716 GetDWLE((oggpacket.packet+180));
1719 "fps: %f, width:%i; height:%i, bitcount:%i",
1721 p_stream->fmt.video.i_width,
1722 p_stream->fmt.video.i_height,
1723 p_stream->fmt.video.i_bits_per_pixel);
1726 /* Check for audio header (old format) */
1727 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1730 unsigned int i_format_tag;
1732 p_stream->fmt.i_cat = AUDIO_ES;
1734 i_extra_size = GetWLE((oggpacket.packet+140));
1735 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1737 p_stream->fmt.i_extra = i_extra_size;
1738 p_stream->fmt.p_extra = malloc( i_extra_size );
1739 if( p_stream->fmt.p_extra )
1740 memcpy( p_stream->fmt.p_extra,
1741 oggpacket.packet + 142, i_extra_size );
1743 p_stream->fmt.i_extra = 0;
1746 i_format_tag = GetWLE((oggpacket.packet+124));
1747 p_stream->fmt.audio.i_channels =
1748 GetWLE((oggpacket.packet+126));
1749 fill_channels_info(&p_stream->fmt.audio);
1750 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1751 GetDWLE((oggpacket.packet+128));
1752 p_stream->fmt.i_bitrate =
1753 GetDWLE((oggpacket.packet+132)) * 8;
1754 p_stream->fmt.audio.i_blockalign =
1755 GetWLE((oggpacket.packet+136));
1756 p_stream->fmt.audio.i_bitspersample =
1757 GetWLE((oggpacket.packet+138));
1759 wf_tag_to_fourcc( i_format_tag,
1760 &p_stream->fmt.i_codec, 0 );
1762 if( p_stream->fmt.i_codec ==
1763 VLC_FOURCC('u','n','d','f') )
1765 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1766 ( i_format_tag >> 8 ) & 0xff,
1767 i_format_tag & 0xff );
1770 msg_Dbg( p_demux, "found audio header of type: %.4s",
1771 (char *)&p_stream->fmt.i_codec );
1772 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1773 "%dbits/sample %dkb/s",
1775 p_stream->fmt.audio.i_channels,
1776 p_stream->fmt.audio.i_rate,
1777 p_stream->fmt.audio.i_bitspersample,
1778 p_stream->fmt.i_bitrate / 1024 );
1779 if ( p_stream->f_rate == 0 )
1781 msg_Dbg( p_demux, "invalid oggds audio header" );
1782 Ogg_LogicalStreamDelete( p_demux, p_stream );
1788 msg_Dbg( p_demux, "stream %d has an old header "
1789 "but is of an unknown type", p_ogg->i_streams-1 );
1794 /* Check for OggDS */
1795 else if( oggpacket.bytes >= 44+1 &&
1796 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1798 stream_header_t tmp;
1799 stream_header_t *st = &tmp;
1801 p_stream->b_oggds = true;
1803 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1804 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1805 st->size = GetDWLE( &oggpacket.packet[1+12] );
1806 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1807 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1808 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1809 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1810 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1812 /* Check for video header (new format) */
1813 if( !strncmp( st->streamtype, "video", 5 ) &&
1814 oggpacket.bytes >= 52+1 )
1816 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1817 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1819 p_stream->fmt.i_cat = VIDEO_ES;
1821 /* We need to get rid of the header packet */
1822 ogg_stream_packetout( &p_stream->os, &oggpacket );
1824 p_stream->fmt.i_codec =
1825 VLC_FOURCC( st->subtype[0], st->subtype[1],
1826 st->subtype[2], st->subtype[3] );
1827 msg_Dbg( p_demux, "found video header of type: %.4s",
1828 (char *)&p_stream->fmt.i_codec );
1830 p_stream->fmt.video.i_frame_rate = 10000000;
1831 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1832 if( st->time_unit <= 0 )
1833 st->time_unit = 400000;
1834 p_stream->f_rate = 10000000.0 / st->time_unit;
1835 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1836 p_stream->fmt.video.i_width = st->sh.video.width;
1837 p_stream->fmt.video.i_height = st->sh.video.height;
1840 "fps: %f, width:%i; height:%i, bitcount:%i",
1842 p_stream->fmt.video.i_width,
1843 p_stream->fmt.video.i_height,
1844 p_stream->fmt.video.i_bits_per_pixel );
1846 /* Check for audio header (new format) */
1847 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1848 oggpacket.bytes >= 56+1 )
1854 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1855 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1856 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1858 p_stream->fmt.i_cat = AUDIO_ES;
1860 /* We need to get rid of the header packet */
1861 ogg_stream_packetout( &p_stream->os, &oggpacket );
1863 i_extra_size = st->size - 56;
1865 if( i_extra_size > 0 &&
1866 i_extra_size < oggpacket.bytes - 1 - 56 )
1868 p_stream->fmt.i_extra = i_extra_size;
1869 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1870 if( p_stream->fmt.p_extra )
1871 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1872 p_stream->fmt.i_extra );
1874 p_stream->fmt.i_extra = 0;
1877 memcpy( p_buffer, st->subtype, 4 );
1879 i_format_tag = strtol(p_buffer,NULL,16);
1880 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1881 fill_channels_info(&p_stream->fmt.audio);
1882 if( st->time_unit <= 0 )
1883 st->time_unit = 10000000;
1884 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1885 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1886 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1887 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1889 wf_tag_to_fourcc( i_format_tag,
1890 &p_stream->fmt.i_codec, 0 );
1892 if( p_stream->fmt.i_codec ==
1893 VLC_FOURCC('u','n','d','f') )
1895 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1896 ( i_format_tag >> 8 ) & 0xff,
1897 i_format_tag & 0xff );
1900 msg_Dbg( p_demux, "found audio header of type: %.4s",
1901 (char *)&p_stream->fmt.i_codec );
1902 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1903 "%dbits/sample %dkb/s",
1905 p_stream->fmt.audio.i_channels,
1906 p_stream->fmt.audio.i_rate,
1907 p_stream->fmt.audio.i_bitspersample,
1908 p_stream->fmt.i_bitrate / 1024 );
1909 if ( p_stream->f_rate == 0 )
1911 msg_Dbg( p_demux, "invalid oggds audio header" );
1912 Ogg_LogicalStreamDelete( p_demux, p_stream );
1916 /* Check for text (subtitles) header */
1917 else if( !strncmp(st->streamtype, "text", 4) )
1919 /* We need to get rid of the header packet */
1920 ogg_stream_packetout( &p_stream->os, &oggpacket );
1922 msg_Dbg( p_demux, "found text subtitle header" );
1923 p_stream->fmt.i_cat = SPU_ES;
1924 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1925 p_stream->f_rate = 1000; /* granulepos is in millisec */
1929 msg_Dbg( p_demux, "stream %d has a header marker "
1930 "but is of an unknown type", p_ogg->i_streams-1 );
1935 else if( oggpacket.bytes >= 8 &&
1936 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1940 msg_Dbg( p_demux, "stream %d is a skeleton",
1941 p_ogg->i_streams-1 );
1942 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1946 msg_Dbg( p_demux, "stream %d is of unknown type",
1947 p_ogg->i_streams-1 );
1952 /* we'll need to get all headers */
1953 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1955 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1956 return VLC_EGENERIC;
1959 /* This is the first data page, which means we are now finished
1960 * with the initial pages. We just need to store it in the relevant
1962 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1964 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1965 &p_ogg->current_page ) == 0 )
1967 p_ogg->b_page_waiting = true;
1976 return VLC_EGENERIC;
1979 /****************************************************************************
1980 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1981 ****************************************************************************/
1982 static void Ogg_CreateES( demux_t *p_demux )
1984 demux_sys_t *p_ogg = p_demux->p_sys;
1985 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1988 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1990 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1992 if ( p_stream->p_es == NULL && !p_stream->b_finished )
1994 /* Better be safe than sorry when possible with ogm */
1995 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1996 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1997 p_stream->fmt.b_packetized = false;
1999 /* Try first to reuse an old ES */
2001 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2002 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2004 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2006 p_stream->p_es = p_old_stream->p_es;
2007 p_stream->b_finished = false;
2008 p_stream->b_reinit = false;
2009 p_stream->b_initializing = false;
2010 p_stream->i_pre_skip = 0;
2011 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2012 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2014 p_old_stream->p_es = NULL;
2015 p_old_stream = NULL;
2016 if ( b_resetdecoder )
2018 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2019 p_stream->p_es, &p_stream->fmt );
2024 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2027 // TODO: something to do here ?
2028 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2030 /* Set the CMML stream active */
2031 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2036 if( p_ogg->p_old_stream )
2038 if( p_ogg->p_old_stream->p_es )
2039 msg_Dbg( p_demux, "old stream not reused" );
2040 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2041 p_ogg->p_old_stream = NULL;
2045 /****************************************************************************
2046 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2047 * Elementary streams.
2048 ****************************************************************************/
2049 static int Ogg_BeginningOfStream( demux_t *p_demux )
2051 demux_sys_t *p_ogg = p_demux->p_sys ;
2054 /* Find the logical streams embedded in the physical stream and
2055 * initialize our p_ogg structure. */
2056 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2058 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2059 return VLC_EGENERIC;
2062 p_ogg->i_bitrate = 0;
2064 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2066 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2068 p_stream->p_es = NULL;
2070 /* initialise kframe index */
2073 if ( p_stream->fmt.i_bitrate == 0 &&
2074 ( p_stream->fmt.i_cat == VIDEO_ES ||
2075 p_stream->fmt.i_cat == AUDIO_ES ) )
2076 p_ogg->b_partial_bitrate = true;
2078 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2080 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2081 p_stream->i_previous_granulepos = -1;
2082 p_stream->b_reinit = false;
2085 /* get total frame count for video stream; we will need this for seeking */
2086 p_ogg->i_total_frames = 0;
2091 /****************************************************************************
2092 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2093 ****************************************************************************/
2094 static void Ogg_EndOfStream( demux_t *p_demux )
2096 demux_sys_t *p_ogg = p_demux->p_sys ;
2099 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2100 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2101 free( p_ogg->pp_stream );
2104 p_ogg->i_bitrate = 0;
2105 p_ogg->i_streams = 0;
2106 p_ogg->pp_stream = NULL;
2107 p_ogg->skeleton.major = 0;
2108 p_ogg->skeleton.minor = 0;
2109 p_ogg->b_preparsing_done = false;
2110 p_ogg->b_es_created = false;
2111 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2112 p_ogg->i_pcr - VLC_TS_0 : 0;
2116 vlc_meta_Delete( p_ogg->p_meta );
2117 p_ogg->p_meta = NULL;
2119 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2121 if ( p_ogg->pp_seekpoints[i] )
2122 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2124 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2125 p_ogg->i_seekpoints = 0;
2128 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2130 #ifdef HAVE_LIBVORBIS
2131 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2133 FREENULL( p_stream->special.vorbis.p_info );
2134 FREENULL( p_stream->special.vorbis.p_comment );
2135 p_stream->special.vorbis.b_invalid = false;
2138 VLC_UNUSED( p_stream );
2143 * This function delete and release all data associated to a logical_stream_t
2145 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2147 if( p_stream->p_es )
2148 es_out_Del( p_demux->out, p_stream->p_es );
2150 ogg_stream_clear( &p_stream->os );
2151 free( p_stream->p_headers );
2153 Ogg_CleanSpecificData( p_stream );
2155 es_format_Clean( &p_stream->fmt_old );
2156 es_format_Clean( &p_stream->fmt );
2158 if ( p_stream->idx != NULL)
2160 oggseek_index_entries_free( p_stream->idx );
2163 Ogg_FreeSkeleton( p_stream->p_skel );
2164 p_stream->p_skel = NULL;
2165 if ( p_demux->p_sys->p_skelstream == p_stream )
2166 p_demux->p_sys->p_skelstream = NULL;
2168 /* Shouldn't happen */
2169 if ( unlikely( p_stream->p_preparse_block ) )
2171 block_ChainRelease( p_stream->p_preparse_block );
2172 p_stream->p_preparse_block = NULL;
2174 free( p_stream->p_prepcr_blocks );
2179 * This function check if a we need to reset a decoder in case we are
2182 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2184 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2185 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2186 unsigned i_new_count;
2187 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2190 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2191 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2192 unsigned i_old_count;
2193 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2196 bool b_match = i_new_count == i_old_count;
2197 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2199 /* Ignore vorbis comment */
2202 if( pi_new_size[i] != pi_old_size[i] ||
2203 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2210 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2211 const es_format_t *p_old )
2213 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2214 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2215 unsigned i_new_count;
2216 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2218 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2219 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2220 unsigned i_old_count;
2221 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2223 bool b_match = false;
2224 if( i_new_count == i_old_count && i_new_count > 0 )
2226 static const unsigned char default_map[2] = { 0, 1 };
2227 unsigned char *p_old_head;
2228 unsigned char *p_new_head;
2229 const unsigned char *p_old_map;
2230 const unsigned char *p_new_map;
2231 int i_old_channel_count;
2232 int i_new_channel_count;
2233 int i_old_stream_count;
2234 int i_new_stream_count;
2235 int i_old_coupled_count;
2236 int i_new_coupled_count;
2237 p_old_head = (unsigned char *)pp_old_data[0];
2238 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2239 p_old_map = default_map;
2240 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2242 i_old_channel_count = p_old_head[9];
2243 switch( p_old_head[18] )
2246 i_old_stream_count = 1;
2247 i_old_coupled_count = i_old_channel_count - 1;
2250 if( pi_old_size[0] >= 21U + i_old_channel_count )
2252 i_old_stream_count = p_old_head[19];
2253 i_old_coupled_count = p_old_head[20];
2254 p_old_map = p_old_head + 21;
2259 p_new_head = (unsigned char *)pp_new_data[0];
2260 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2261 p_new_map = default_map;
2262 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2264 i_new_channel_count = p_new_head[9];
2265 switch( p_new_head[18] )
2268 i_new_stream_count = 1;
2269 i_new_coupled_count = i_new_channel_count - 1;
2272 if( pi_new_size[0] >= 21U + i_new_channel_count )
2274 i_new_stream_count = p_new_head[19];
2275 i_new_coupled_count = p_new_head[20];
2276 p_new_map = p_new_head+21;
2281 b_match = i_old_channel_count == i_new_channel_count &&
2282 i_old_stream_count == i_new_stream_count &&
2283 i_old_coupled_count == i_new_coupled_count &&
2284 memcmp(p_old_map, p_new_map,
2285 i_new_channel_count*sizeof(*p_new_map)) == 0;
2291 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2293 bool b_compatible = false;
2294 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2297 /* Only Vorbis and Opus are supported. */
2298 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2299 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2300 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2301 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2304 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2306 return !b_compatible;
2309 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2310 const void *p_headers, unsigned i_headers )
2312 demux_sys_t *p_ogg = p_demux->p_sys;
2313 int i_cover_score = 0;
2314 int i_cover_idx = 0;
2315 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2316 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2317 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2319 pf_replay_gain[i] = 0;
2320 pf_replay_peak[i] = 0;
2322 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2323 &p_ogg->i_attachments, &p_ogg->attachments,
2324 &i_cover_score, &i_cover_idx,
2325 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2326 &pf_replay_gain, &pf_replay_peak );
2327 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2330 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2331 p_ogg->attachments[i_cover_idx]->psz_name );
2332 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2335 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2337 if ( pf_replay_gain[i] != 0 )
2339 p_fmt->audio_replay_gain.pb_gain[i] = true;
2340 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2341 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2343 if ( pf_replay_peak[i] != 0 )
2345 p_fmt->audio_replay_gain.pb_peak[i] = true;
2346 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2347 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2351 if( p_ogg->i_seekpoints > 1 )
2353 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2357 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2358 const void *p_headers, unsigned i_headers, unsigned i_skip )
2360 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2361 void *pp_data[XIPH_MAX_HEADER_COUNT];
2364 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2366 /* TODO how to handle multiple comments properly ? */
2367 if( i_count >= 2 && pi_size[1] > i_skip )
2369 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2373 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2375 demux_sys_t *p_ogg = p_demux->p_sys;
2377 switch( p_fmt->i_codec )
2379 /* 3 headers with the 2° one being the comments */
2380 case VLC_CODEC_VORBIS:
2381 case VLC_CODEC_THEORA:
2382 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2384 case VLC_CODEC_OPUS:
2385 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2387 case VLC_CODEC_SPEEX:
2388 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2391 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2393 /* N headers with the 2° one being the comments */
2394 case VLC_CODEC_KATE:
2395 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2396 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2400 case VLC_CODEC_FLAC:
2401 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2405 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2406 case VLC_CODEC_DIRAC:
2411 p_demux->info.i_update |= INPUT_UPDATE_META;
2414 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2415 ogg_packet *p_oggpacket )
2418 unsigned int i_fps_numerator;
2419 unsigned int i_fps_denominator;
2420 int i_keyframe_frequency_force;
2426 p_stream->fmt.i_cat = VIDEO_ES;
2427 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2429 /* Signal that we want to keep a backup of the theora
2430 * stream headers. They will be used when switching between
2432 p_stream->b_force_backup = true;
2434 /* Cheat and get additionnal info ;) */
2435 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2436 bs_skip( &bitstream, 56 );
2438 i_major = bs_read( &bitstream, 8 ); /* major version num */
2439 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2440 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2442 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2443 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2444 bs_read( &bitstream, 24 ); /* frame width */
2445 bs_read( &bitstream, 24 ); /* frame height */
2446 bs_read( &bitstream, 8 ); /* x offset */
2447 bs_read( &bitstream, 8 ); /* y offset */
2449 i_fps_numerator = bs_read( &bitstream, 32 );
2450 i_fps_denominator = bs_read( &bitstream, 32 );
2451 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2452 bs_read( &bitstream, 24 ); /* aspect_numerator */
2453 bs_read( &bitstream, 24 ); /* aspect_denominator */
2455 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2456 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2458 bs_read( &bitstream, 8 ); /* colorspace */
2459 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2460 bs_read( &bitstream, 6 ); /* quality */
2462 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2464 /* granule_shift = i_log( frequency_force -1 ) */
2465 p_stream->i_granule_shift = 0;
2466 i_keyframe_frequency_force--;
2467 while( i_keyframe_frequency_force )
2469 p_stream->i_granule_shift++;
2470 i_keyframe_frequency_force >>= 1;
2473 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2474 p_stream->i_keyframe_offset = 0;
2475 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2476 if ( p_stream->f_rate == 0 ) return false;
2478 if ( i_version >= 3002001 )
2480 p_stream->i_keyframe_offset = 1;
2485 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2486 ogg_packet *p_oggpacket )
2490 p_stream->fmt.i_cat = AUDIO_ES;
2491 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2493 /* Signal that we want to keep a backup of the vorbis
2494 * stream headers. They will be used when switching between
2496 p_stream->b_force_backup = true;
2498 /* Cheat and get additionnal info ;) */
2499 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2500 oggpack_adv( &opb, 88 );
2501 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2502 fill_channels_info(&p_stream->fmt.audio);
2503 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2504 oggpack_read( &opb, 32 );
2505 oggpack_adv( &opb, 32 );
2506 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2507 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2508 if ( p_stream->f_rate == 0 ) return false;
2511 #ifdef HAVE_LIBVORBIS
2512 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2513 ogg_packet *p_oggpacket, int i_number )
2517 case VORBIS_HEADER_IDENTIFICATION:
2518 p_stream->special.vorbis.p_info = malloc( sizeof(vorbis_info) );
2519 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2520 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2522 FREENULL( p_stream->special.vorbis.p_info );
2523 FREENULL( p_stream->special.vorbis.p_comment );
2524 p_stream->special.vorbis.b_invalid = true;
2527 vorbis_info_init( p_stream->special.vorbis.p_info );
2528 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2531 case VORBIS_HEADER_COMMENT:
2532 case VORBIS_HEADER_SETUP:
2533 if ( p_stream->special.vorbis.p_info && ! p_stream->special.vorbis.b_invalid )
2535 p_stream->special.vorbis.b_invalid = ( 0 != vorbis_synthesis_headerin(
2536 p_stream->special.vorbis.p_info,
2537 p_stream->special.vorbis.p_comment, p_oggpacket ) );
2547 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2548 ogg_packet *p_oggpacket )
2552 p_stream->fmt.i_cat = AUDIO_ES;
2553 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2555 /* Signal that we want to keep a backup of the speex
2556 * stream headers. They will be used when switching between
2558 p_stream->b_force_backup = true;
2560 /* Cheat and get additionnal info ;) */
2561 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2562 oggpack_adv( &opb, 224 );
2563 oggpack_adv( &opb, 32 ); /* speex_version_id */
2564 oggpack_adv( &opb, 32 ); /* header_size */
2565 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2566 if ( p_stream->f_rate == 0 ) return false;
2567 oggpack_adv( &opb, 32 ); /* mode */
2568 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2569 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2570 fill_channels_info(&p_stream->fmt.audio);
2571 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2572 p_stream->special.speex.i_framesize =
2573 oggpack_read( &opb, 32 ); /* frame_size */
2574 oggpack_adv( &opb, 32 ); /* vbr */
2575 p_stream->special.speex.i_framesperpacket =
2576 oggpack_read( &opb, 32 ); /* frames_per_packet */
2577 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2581 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2582 ogg_packet *p_oggpacket )
2586 p_stream->fmt.i_cat = AUDIO_ES;
2587 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2589 /* Signal that we want to keep a backup of the opus
2590 * stream headers. They will be used when switching between
2592 p_stream->b_force_backup = true;
2594 /* All OggOpus streams are timestamped at 48kHz and
2595 * can be played at 48kHz. */
2596 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2597 p_stream->fmt.i_bitrate = 0;
2599 /* Cheat and get additional info ;) */
2600 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2601 oggpack_adv( &opb, 64 );
2602 oggpack_adv( &opb, 8 ); /* version_id */
2603 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2604 fill_channels_info(&p_stream->fmt.audio);
2605 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2606 /* For Opus, trash the first 80 ms of decoded output as
2607 well, to avoid blowing out speakers if we get unlucky.
2608 Opus predicts content from prior frames, which can go
2609 badly if we seek right where the stream goes from very
2610 quiet to very loud. It will converge after a bit. */
2611 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2614 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2615 ogg_packet *p_oggpacket )
2617 /* Parse the STREAMINFO metadata */
2620 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2623 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2625 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2629 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2632 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2633 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2634 fill_channels_info(&p_stream->fmt.audio);
2636 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2637 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2638 if ( p_stream->f_rate == 0 ) return false;
2642 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2645 /* Fake this as the last metadata block */
2646 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2650 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2651 ogg_packet *p_oggpacket )
2659 p_stream->fmt.i_cat = SPU_ES;
2660 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2662 /* Signal that we want to keep a backup of the kate
2663 * stream headers. They will be used when switching between
2665 p_stream->b_force_backup = true;
2667 /* Cheat and get additionnal info ;) */
2668 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2669 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2670 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2671 oggpack_adv( &opb, 3*8 );
2672 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2673 oggpack_adv( &opb, 8*8 ); /* reserved */
2674 gnum = oggpack_read( &opb, 32 );
2675 gden = oggpack_read( &opb, 32 );
2676 gden = __MAX( gden, 1 );
2677 p_stream->f_rate = (double)gnum/gden;
2678 if ( p_stream->f_rate == 0 ) return false;
2680 p_stream->fmt.psz_language = malloc(16);
2681 if( p_stream->fmt.psz_language )
2683 for( n = 0; n < 16; n++ )
2684 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2685 p_stream->fmt.psz_language[15] = 0; /* just in case */
2689 for( n = 0; n < 16; n++ )
2690 oggpack_read(&opb,8);
2692 p_stream->fmt.psz_description = malloc(16);
2693 if( p_stream->fmt.psz_description )
2695 for( n = 0; n < 16; n++ )
2696 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2697 p_stream->fmt.psz_description[15] = 0; /* just in case */
2699 /* Now find a localized user readable description for this category */
2700 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2703 free( p_stream->fmt.psz_description );
2704 p_stream->fmt.psz_description = psz_desc;
2709 for( n = 0; n < 16; n++ )
2710 oggpack_read(&opb,8);
2716 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2717 ogg_packet *p_oggpacket )
2719 switch( p_oggpacket->packet[5] )
2723 /* Mapping version */
2724 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2726 p_stream->fmt.i_cat = VIDEO_ES;
2727 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2728 p_stream->i_granule_shift = 32;
2729 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2730 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2731 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2732 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2733 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2734 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2735 p_stream->fmt.video.i_frame_rate_base =
2736 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2737 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2738 if ( p_stream->f_rate == 0 ) return false;
2742 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2743 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2750 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2751 bool *b_force_backup, bool *b_packet_out )
2753 if( !strncmp(psz_value, "audio/x-wav", 11) )
2755 /* n.b. WAVs are unsupported right now */
2756 p_stream->fmt.i_cat = UNKNOWN_ES;
2757 free( p_stream->fmt.psz_description );
2758 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2760 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2761 !strncmp(psz_value, "audio/vorbis", 12) )
2763 p_stream->fmt.i_cat = AUDIO_ES;
2764 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2766 *b_force_backup = true;
2768 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2769 !strncmp(psz_value, "audio/speex", 11) )
2771 p_stream->fmt.i_cat = AUDIO_ES;
2772 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2774 *b_force_backup = true;
2776 else if( !strncmp(psz_value, "audio/flac", 10) )
2778 p_stream->fmt.i_cat = AUDIO_ES;
2779 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2781 *b_force_backup = true;
2783 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2784 !strncmp(psz_value, "video/theora", 12) )
2786 p_stream->fmt.i_cat = VIDEO_ES;
2787 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2789 *b_force_backup = true;
2791 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2793 p_stream->fmt.i_cat = VIDEO_ES;
2794 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2796 *b_force_backup = true;
2798 else if( !strncmp(psz_value, "video/mpeg", 10) )
2800 /* n.b. MPEG streams are unsupported right now */
2801 p_stream->fmt.i_cat = VIDEO_ES;
2802 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2804 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2805 !strncmp(psz_value, "text/cmml", 9) )
2807 p_stream->fmt.i_cat = SPU_ES;
2808 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2809 *b_packet_out = true;
2811 else if( !strncmp(psz_value, "application/kate", 16) )
2814 p_stream->fmt.i_cat = UNKNOWN_ES;
2815 free( p_stream->fmt.psz_description );
2816 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2818 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2820 p_stream->fmt.i_cat = VIDEO_ES;
2821 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2825 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2826 logical_stream_t *p_stream,
2827 ogg_packet *p_oggpacket )
2829 if( p_oggpacket->bytes >= 28 &&
2830 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2834 uint16_t major_version;
2835 uint16_t minor_version;
2836 uint64_t timebase_numerator;
2837 uint64_t timebase_denominator;
2839 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2841 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2842 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2843 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2844 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2845 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2846 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2848 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2849 "Timebase %"PRId64" / %"PRId64,
2850 major_version, minor_version,
2851 timebase_numerator, timebase_denominator );
2853 else if( p_oggpacket->bytes >= 42 &&
2854 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2856 uint64_t granule_rate_numerator;
2857 uint64_t granule_rate_denominator;
2858 char content_type_string[1024];
2860 /* Read in Annodex header fields */
2862 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2863 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2864 p_stream->i_secondary_header_packets =
2865 GetDWLE( &p_oggpacket->packet[24] );
2867 /* we are guaranteed that the first header field will be
2868 * the content-type (by the Annodex standard) */
2869 content_type_string[0] = '\0';
2870 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2872 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2873 p_oggpacket->bytes - 1 );
2874 if( p && p[0] == '\r' && p[1] == '\n' )
2875 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2876 content_type_string );
2879 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2880 granule_rate_numerator, granule_rate_denominator,
2881 p_stream->i_secondary_header_packets, content_type_string );
2883 p_stream->f_rate = (float) granule_rate_numerator /
2884 (float) granule_rate_denominator;
2886 /* What type of file do we have?
2887 * strcmp is safe to use here because we've extracted
2888 * content_type_string from the stream manually */
2889 bool b_dopacketout = false;
2890 Ogg_ApplyContentType( p_stream, content_type_string,
2891 &p_stream->b_force_backup, &b_dopacketout );
2892 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2896 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2897 ogg_packet *p_oggpacket )
2899 p_demux->p_sys->p_skelstream = p_stream;
2900 /* There can be only 1 skeleton for streams */
2901 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2902 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2903 if ( asprintf( & p_stream->fmt.psz_description,
2904 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2905 p_demux->p_sys->skeleton.major,
2906 p_demux->p_sys->skeleton.minor ) < 0 )
2907 p_stream->fmt.psz_description = NULL;
2910 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2912 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2914 /* Find the matching stream for this skeleton data */
2915 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2916 logical_stream_t *p_target_stream = NULL;
2917 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2919 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2921 p_target_stream = p_demux->p_sys->pp_stream[i];
2925 if ( !p_target_stream ) return;
2927 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2930 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2931 if ( !p_skel ) return;
2932 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2933 p_skel->p_index = NULL;
2934 p_target_stream->p_skel = p_skel;
2937 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2938 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2939 const unsigned char *p = p_messages;
2940 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2942 if ( *p == 0x0D && *(p+1) == 0x0A )
2944 char *psz_message = strndup( (const char *) p_messages,
2948 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2949 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2951 if ( p < p_boundary - 1 ) p_messages = p + 2;
2958 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2959 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2960 unsigned const char *p_end,
2961 uint64_t *pi_value )
2967 while ( p_begin < p_end )
2969 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2970 *pi_value = *pi_value | ( i_read << i_shift );
2972 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2975 *pi_value = GetQWLE( pi_value );
2979 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2981 if ( p_demux->p_sys->skeleton.major < 4
2982 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2985 /* Find the matching stream for this skeleton data */
2986 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2987 logical_stream_t *p_stream = NULL;
2988 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2990 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2992 p_stream = p_demux->p_sys->pp_stream[i];
2996 if ( !p_stream ) return;
2997 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2998 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2999 if ( !i_keypoints ) return;
3001 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3002 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3003 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3004 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3005 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3006 uint64_t i_offset = 0;
3007 uint64_t i_time = 0;
3008 uint64_t i_keypoints_found = 0;
3010 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3013 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3015 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3016 i_time += i_val * p_stream->p_skel->i_indexstampden;
3017 i_keypoints_found++;
3020 if ( i_keypoints_found != i_keypoints )
3022 msg_Warn( p_demux, "Invalid Index: missing entries" );
3026 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3027 if ( !p_stream->p_skel->p_index ) return;
3028 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3029 p_oggpacket->bytes - 42 );
3030 p_stream->p_skel->i_index = i_keypoints_found;
3031 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3034 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3036 if ( !p_skel ) return;
3037 for ( int i=0; i< p_skel->i_messages; i++ )
3038 free( p_skel->ppsz_messages[i] );
3039 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3040 free( p_skel->p_index );
3044 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3046 if ( !p_stream->p_skel ) return;
3047 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3049 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3050 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3052 free( p_stream->fmt.psz_description );
3053 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3055 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3058 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3063 /* Return true if there's a skeleton exact match */
3064 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3065 int64_t *pi_lower, int64_t *pi_upper )
3067 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3070 /* Validate range */
3071 if ( i_time < p_stream->p_skel->i_indexfirstnum
3072 * p_stream->p_skel->i_indexstampden ||
3073 i_time > p_stream->p_skel->i_indexlastnum
3074 * p_stream->p_skel->i_indexstampden ) return false;
3076 /* Then Lookup its index */
3077 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3082 } current = { 0, 0 }, prev = { -1, -1 };
3084 uint64_t i_keypoints_found = 0;
3086 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3087 && i_keypoints_found < p_stream->p_skel->i_index )
3090 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3091 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3092 current.i_pos += i_val;
3093 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3094 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3095 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3096 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3098 i_keypoints_found++;
3100 if ( i_time <= current.i_time )
3102 *pi_lower = prev.i_pos;
3103 *pi_upper = current.i_pos;
3104 return ( i_time == current.i_time );
3111 static uint32_t dirac_uint( bs_t *p_bs )
3113 uint32_t u_count = 0, u_value = 0;
3115 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3119 u_value |= bs_read( p_bs, 1 );
3122 return (1<<u_count) - 1 + u_value;
3125 static int dirac_bool( bs_t *p_bs )
3127 return bs_read( p_bs, 1 );
3130 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3131 ogg_packet *p_oggpacket )
3133 static const struct {
3134 uint32_t u_n /* numerator */, u_d /* denominator */;
3135 } p_dirac_frate_tbl[] = { /* table 10.3 */
3136 {1,1}, /* this first value is never used */
3137 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3138 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3140 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3142 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3143 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3145 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3149 p_stream->i_granule_shift = 22; /* not 32 */
3151 /* Backing up stream headers is not required -- seqhdrs are repeated
3152 * thoughout the stream at suitable decoding start points */
3153 p_stream->b_force_backup = false;
3155 /* read in useful bits from sequence header */
3156 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3157 bs_skip( &bs, 13*8); /* parse_info_header */
3158 dirac_uint( &bs ); /* major_version */
3159 dirac_uint( &bs ); /* minor_version */
3160 dirac_uint( &bs ); /* profile */
3161 dirac_uint( &bs ); /* level */
3163 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3164 if( u_video_format >= u_dirac_vidfmt_frate )
3166 /* don't know how to parse this ogg dirac stream */
3170 if( dirac_bool( &bs ) )
3172 dirac_uint( &bs ); /* frame_width */
3173 dirac_uint( &bs ); /* frame_height */
3176 if( dirac_bool( &bs ) )
3178 dirac_uint( &bs ); /* chroma_format */
3181 if( dirac_bool( &bs ) )
3183 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3186 p_stream->special.dirac.b_interlaced = false;
3188 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3189 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3190 u_d = __MAX( u_d, 1 );
3191 if( dirac_bool( &bs ) )
3193 uint32_t u_frame_rate_index = dirac_uint( &bs );
3194 if( u_frame_rate_index >= u_dirac_frate_tbl )
3196 /* something is wrong with this stream */
3199 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3200 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3201 if( u_frame_rate_index == 0 )
3203 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3204 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3207 p_stream->f_rate = (float) u_n / u_d;
3208 if ( p_stream->f_rate == 0 ) return false;
3210 /* probably is an ogg dirac es */
3211 p_stream->fmt.i_cat = VIDEO_ES;
3212 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;