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 p_sys->i_nzpcr_offset = (p_sys->i_pcr >= VLC_TS_INVALID) ?
398 p_sys->i_pcr - VLC_TS_0 : 0;
399 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
402 /* Does fail if serialno differs */
403 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
409 /* clear the finished flag if pages after eos (ex: after a seek) */
410 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
411 p_stream->b_finished = false;
414 if ( p_stream->fmt.i_cat == VIDEO_ES )
415 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
416 ogg_page_pageno( &p_sys->current_page ),
417 ogg_page_granulepos( &p_sys->current_page ),
418 ogg_page_packets( &p_sys->current_page ),
419 ogg_page_continued(&p_sys->current_page),
420 p_sys->current_page.body_len )
423 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
426 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
427 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
428 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
429 p_stream->fmt.i_cat == VIDEO_ES )
431 assert( p_stream->p_prepcr_blocks == NULL );
432 p_stream->i_prepcr_blocks = 0;
433 p_stream->p_prepcr_blocks = malloc( sizeof(block_t *) * ogg_page_packets( &p_sys->current_page ) );
437 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
439 /* Read info from any secondary header packets, if there are any */
440 if( p_stream->i_secondary_header_packets > 0 )
442 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
443 oggpacket.bytes >= 7 &&
444 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
446 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
447 p_stream->i_secondary_header_packets = 0;
449 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
450 oggpacket.bytes >= 7 &&
451 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
453 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
454 p_stream->i_secondary_header_packets = 0;
456 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
458 p_stream->i_secondary_header_packets = 0;
461 /* update start of data pointer */
462 p_stream->i_data_start = stream_Tell( p_demux->s );
465 /* If any streams have i_skip_frames, only decode (pre-roll)
466 * for those streams, but don't skip headers */
467 if ( b_skipping && p_stream->i_skip_frames == 0
468 && p_stream->i_secondary_header_packets ) continue;
470 if( p_stream->b_reinit )
472 p_stream->b_reinit = false;
473 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
475 p_stream->i_skip_frames = p_stream->i_pre_skip;
479 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
483 if ( p_stream->p_prepcr_blocks )
485 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
486 p_stream->i_previous_pcr = pagestamp;
487 #ifdef HAVE_LIBVORBIS
488 int i_prev_blocksize = 0;
491 for( int i=0; i<p_stream->i_prepcr_blocks; i++ )
493 block_t *p_block = p_stream->p_prepcr_blocks[i];
494 ogg_packet dumb_packet;
495 dumb_packet.bytes = p_block->i_buffer;
496 dumb_packet.packet = p_block->p_buffer;
499 switch( p_stream->fmt.i_codec )
501 case VLC_CODEC_SPEEX:
502 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
503 p_stream->special.speex.i_framesperpacket;
506 i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
507 p_block->i_nb_samples = i_duration;
509 #ifdef HAVE_LIBVORBIS
510 case VLC_CODEC_VORBIS:
512 long i_blocksize = vorbis_packet_blocksize(
513 p_stream->special.vorbis.p_info, &dumb_packet );
514 if ( i_prev_blocksize )
515 i_duration = ( i_blocksize + i_prev_blocksize ) / 4;
517 i_duration = i_blocksize / 2;
518 i_prev_blocksize = i_blocksize;
519 p_block->i_nb_samples = i_duration;
526 bool b_fixed = false;
527 for( int i=p_stream->i_prepcr_blocks - 1; i>=0; i-- )
529 block_t *p_block = p_stream->p_prepcr_blocks[i];
530 switch( p_stream->fmt.i_codec )
532 case VLC_CODEC_SPEEX:
534 case VLC_CODEC_VORBIS:
535 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
538 p_block->i_pts = VLC_TS_INVALID;
539 p_block->i_flags |= BLOCK_FLAG_PREROLL;
542 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
546 if ( p_stream->fmt.i_cat == VIDEO_ES )
548 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
549 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
557 if ( pagestamp < 0 ) pagestamp = 0;
558 p_stream->i_pcr = VLC_TS_0 + pagestamp;
559 p_stream->i_pcr += p_sys->i_nzpcr_offset;
560 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
563 FREENULL( p_stream->p_prepcr_blocks );
564 p_stream->i_prepcr_blocks = 0;
566 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
570 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
571 ogg_page_granulepos( &p_sys->current_page ), false );
572 if ( i_pagestamp > -1 )
574 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
575 p_stream->i_pcr += p_sys->i_nzpcr_offset;
578 if( !p_sys->b_page_waiting )
582 /* if a page was waiting, it's now processed */
583 p_sys->b_page_waiting = false;
585 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
586 p_sys->b_preparsing_done = false;
588 p_sys->b_preparsing_done = true;
590 /* We will consider the lowest PCR among tracks, because the audio core badly
591 * handles PCR rewind (mute)
593 mtime_t i_pcr_candidate = VLC_TS_INVALID;
594 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
596 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
598 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
600 /* We have 1 or more streams needing more than 1 page for preparsing */
601 p_sys->b_preparsing_done = false;
604 if( p_stream->fmt.i_cat == SPU_ES )
606 if( p_stream->i_pcr < VLC_TS_0 )
608 if ( p_stream->b_finished || p_stream->b_initializing )
610 if ( p_stream->p_preparse_block )
612 if( i_pcr_candidate < VLC_TS_0
613 || p_stream->i_pcr <= i_pcr_candidate )
615 i_pcr_candidate = p_stream->i_pcr;
619 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
621 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
623 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
624 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
626 p_sys->i_pcr_jitter = i_pcr_jitter;
627 if ( p_sys->i_access_delay < i_pcr_jitter )
628 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
629 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
633 if( ! b_skipping && p_sys->b_preparsing_done )
635 p_sys->i_pcr = i_pcr_candidate;
636 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
643 static void Ogg_ResetStream( logical_stream_t *p_stream )
645 #ifdef HAVE_LIBVORBIS
646 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
648 p_stream->special.vorbis.i_prev_blocksize = 0;
651 /* we'll trash all the data until we find the next pcr */
652 p_stream->b_reinit = true;
653 p_stream->i_pcr = VLC_TS_UNKNOWN;
654 p_stream->i_previous_granulepos = -1;
655 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
656 ogg_stream_reset( &p_stream->os );
657 FREENULL( p_stream->p_prepcr_blocks );
658 p_stream->i_prepcr_blocks = 0;
661 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
663 for( int i = 0; i < p_sys->i_streams; i++ )
664 Ogg_ResetStream( p_sys->pp_stream[i] );
666 ogg_sync_reset( &p_sys->oy );
667 p_sys->i_pcr = VLC_TS_UNKNOWN;
670 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
672 demux_sys_t *p_sys = p_demux->p_sys;
673 logical_stream_t *p_stream = NULL;
674 for( int i=0; i<p_sys->i_streams; i++ )
676 logical_stream_t *p_candidate = p_sys->pp_stream[i];
677 if ( !p_candidate->p_es ) continue;
679 bool b_selected = false;
680 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
681 p_candidate->p_es, &b_selected );
682 if ( !b_selected ) continue;
684 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
686 p_stream = p_candidate;
687 continue; /* Try to find video anyway */
690 if ( p_candidate->fmt.i_cat == VIDEO_ES )
692 p_stream = p_candidate;
699 /*****************************************************************************
701 *****************************************************************************/
702 static int Control( demux_t *p_demux, int i_query, va_list args )
704 demux_sys_t *p_sys = p_demux->p_sys;
713 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
715 vlc_meta_Merge( p_meta, p_sys->p_meta );
718 case DEMUX_HAS_UNSUPPORTED_META:
719 pb_bool = (bool*)va_arg( args, bool* );
724 pi64 = (int64_t*)va_arg( args, int64_t * );
725 *pi64 = p_sys->i_pcr;
729 i64 = (int64_t)va_arg( args, int64_t );
730 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
733 msg_Err( p_demux, "No selected seekable stream found" );
736 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
737 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
739 Ogg_ResetStreamsHelper( p_sys );
740 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
747 case DEMUX_GET_ATTACHMENTS:
749 input_attachment_t ***ppp_attach =
750 (input_attachment_t***)va_arg( args, input_attachment_t*** );
751 int *pi_int = (int*)va_arg( args, int * );
753 if( p_sys->i_attachments <= 0 )
756 *pi_int = p_sys->i_attachments;
757 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
758 for( int i = 0; i < p_sys->i_attachments; i++ )
759 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
763 case DEMUX_GET_POSITION:
764 pf = (double*)va_arg( args, double * );
765 if( p_sys->i_length > 0 )
767 *pf = (double) p_sys->i_pcr /
768 (double) ( p_sys->i_length * (mtime_t)1000000 );
770 else if( stream_Size( p_demux->s ) > 0 )
772 i64 = stream_Tell( p_demux->s );
773 *pf = (double) i64 / stream_Size( p_demux->s );
778 case DEMUX_SET_POSITION:
779 /* forbid seeking if we haven't initialized all logical bitstreams yet;
780 if we allowed, some headers would not get backed up and decoder init
781 would fail, making that logical stream unusable */
782 for ( int i=0; i< p_sys->i_streams; i++ )
784 if ( p_sys->pp_stream[i]->b_initializing )
788 p_stream = Ogg_GetSelectedStream( p_demux );
791 msg_Err( p_demux, "No selected seekable stream found" );
795 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
797 f = (double)va_arg( args, double );
798 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
800 Ogg_ResetStreamsHelper( p_sys );
801 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
805 assert( p_sys->i_length > 0 );
806 i64 = CLOCK_FREQ * p_sys->i_length * f;
807 Ogg_ResetStreamsHelper( p_sys );
808 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
810 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
817 case DEMUX_GET_LENGTH:
818 if ( p_sys->i_length < 0 )
819 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
821 pi64 = (int64_t*)va_arg( args, int64_t * );
822 *pi64 = p_sys->i_length * 1000000;
825 case DEMUX_GET_TITLE_INFO:
827 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
828 int *pi_int = (int*)va_arg( args, int* );
829 int *pi_title_offset = (int*)va_arg( args, int* );
830 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
832 if( p_sys->i_seekpoints > 0 )
835 *ppp_title = malloc( sizeof( input_title_t* ) );
836 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
837 for( int i = 0; i < p_sys->i_seekpoints; i++ )
839 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
840 if ( likely( p_seekpoint_copy ) )
841 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
843 *pi_title_offset = 0;
844 *pi_seekpoint_offset = 0;
848 case DEMUX_SET_TITLE:
850 const int i_title = (int)va_arg( args, int );
855 case DEMUX_SET_SEEKPOINT:
857 const int i_seekpoint = (int)va_arg( args, int );
858 if( i_seekpoint > p_sys->i_seekpoints )
861 for ( int i=0; i< p_sys->i_streams; i++ )
863 if ( p_sys->pp_stream[i]->b_initializing )
867 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
869 p_stream = Ogg_GetSelectedStream( p_demux );
872 msg_Err( p_demux, "No selected seekable stream found" );
876 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
877 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
879 Ogg_ResetStreamsHelper( p_sys );
880 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
882 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
883 p_demux->info.i_seekpoint = i_seekpoint;
891 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
896 /****************************************************************************
897 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
898 ****************************************************************************
899 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
900 * are at the end of stream.
901 ****************************************************************************/
902 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
904 demux_sys_t *p_ogg = p_demux->p_sys ;
908 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
910 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
912 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
916 ogg_sync_wrote( &p_ogg->oy, i_read );
922 /****************************************************************************
923 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
925 ****************************************************************************/
926 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
927 ogg_packet *p_oggpacket )
929 demux_sys_t *p_ogg = p_demux->p_sys;
930 p_stream->i_end_trim = 0;
932 /* Convert the granulepos into a pcr */
933 if ( p_oggpacket->granulepos == 0 )
935 /* We're in headers, and we haven't parsed 1st data packet yet */
936 // p_stream->i_pcr = VLC_TS_UNKNOWN;
938 else if( p_oggpacket->granulepos > 0 )
940 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
941 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
942 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
943 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
944 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
945 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
947 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
948 p_oggpacket->granulepos, true );
949 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
951 else if ( p_stream->i_previous_granulepos > 0 )
953 ogg_int64_t sample = p_stream->i_previous_granulepos;
955 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
957 int duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
960 ogg_int64_t end_sample = p_oggpacket->granulepos;
961 if( end_sample < ( sample + duration ) )
962 p_stream->i_end_trim = sample + duration - end_sample;
966 if (sample >= p_stream->i_pre_skip)
967 sample -= p_stream->i_pre_skip;
971 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
972 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
976 else if ( p_oggpacket->granulepos == -1 )
979 /* no granulepos available, try to interpolate the pcr.
980 * If we can't then don't touch the old value. */
981 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
983 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
985 #ifdef HAVE_LIBVORBIS
986 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
987 p_stream->special.vorbis.p_info &&
988 !p_stream->special.vorbis.b_invalid &&
989 p_stream->i_previous_granulepos > 0 )
991 long i_blocksize = vorbis_packet_blocksize(
992 p_stream->special.vorbis.p_info, p_oggpacket );
993 if ( p_stream->special.vorbis.i_prev_blocksize )
994 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
996 i_duration = i_blocksize / 2;
997 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
998 /* duration in samples per channel */
999 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1000 p_stream->i_pcr = p_stream->i_previous_granulepos *
1001 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1002 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1005 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1006 p_stream->i_previous_granulepos > 0 )
1008 i_duration = p_stream->special.speex.i_framesize *
1009 p_stream->special.speex.i_framesperpacket;
1010 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1011 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1012 p_stream->i_previous_granulepos, false );
1013 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1015 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1016 p_stream->i_previous_granulepos > 0 &&
1018 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
1021 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1022 sample = p_stream->i_previous_granulepos;
1023 if (sample >= p_stream->i_pre_skip)
1024 sample -= p_stream->i_pre_skip;
1028 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1029 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1031 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1033 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1034 p_stream->fmt.i_bitrate / 8 );
1038 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1041 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1044 demux_sys_t *p_ogg = p_demux->p_sys;
1045 if ( !p_stream->p_es || p_stream->p_prepcr_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1047 if ( !p_block ) return;
1048 if ( p_stream->p_prepcr_blocks )
1050 assert( p_stream->p_prepcr_blocks );
1051 p_stream->p_prepcr_blocks[p_stream->i_prepcr_blocks++] = p_block;
1053 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1054 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1055 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1059 /* Because ES creation is delayed for preparsing */
1060 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1061 if ( p_stream->p_preparse_block )
1063 block_t *temp = p_stream->p_preparse_block;
1066 if ( temp && i_firstpts < VLC_TS_0 )
1067 i_firstpts = temp->i_pts;
1069 block_t *tosend = temp;
1070 temp = temp->p_next;
1071 tosend->p_next = NULL;
1073 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1074 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1075 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1077 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1079 p_ogg->i_pcr = i_firstpts;
1080 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1083 p_stream->p_preparse_block = NULL;
1088 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1089 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1090 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1095 /****************************************************************************
1096 * Ogg_DecodePacket: Decode an Ogg packet.
1097 ****************************************************************************/
1098 static void Ogg_DecodePacket( demux_t *p_demux,
1099 logical_stream_t *p_stream,
1100 ogg_packet *p_oggpacket )
1104 int i_header_len = 0;
1106 if( p_oggpacket->bytes >= 7 &&
1107 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1109 /* it's an Annodex packet -- skip it (do nothing) */
1112 else if( p_oggpacket->bytes >= 7 &&
1113 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1115 /* it's an AnxData packet -- skip it (do nothing) */
1118 else if( p_oggpacket->bytes >= 8 &&
1119 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1121 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1124 else if( p_oggpacket->bytes >= 6 &&
1125 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1127 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1130 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1131 p_oggpacket->bytes >= 7 &&
1132 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1134 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1138 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1139 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1141 /* Check the ES is selected */
1142 if ( !p_stream->p_es )
1145 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1146 p_stream->p_es, &b_selected );
1148 if( p_stream->b_force_backup )
1151 p_stream->i_packets_backup++;
1152 switch( p_stream->fmt.i_codec )
1154 case VLC_CODEC_VORBIS:
1155 #ifdef HAVE_LIBVORBIS
1156 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1159 case VLC_CODEC_THEORA:
1160 if( p_stream->i_packets_backup == 3 )
1161 p_stream->b_force_backup = false;
1165 case VLC_CODEC_SPEEX:
1166 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1167 p_stream->b_force_backup = false;
1171 case VLC_CODEC_OPUS:
1172 if( p_stream->i_packets_backup == 2 )
1173 p_stream->b_force_backup = false;
1177 case VLC_CODEC_FLAC:
1178 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1180 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1181 p_stream->b_force_backup = false;
1183 else if( p_stream->fmt.audio.i_rate )
1185 p_stream->b_force_backup = false;
1186 if( p_oggpacket->bytes >= 9 )
1188 p_oggpacket->packet += 9;
1189 p_oggpacket->bytes -= 9;
1195 case VLC_CODEC_KATE:
1196 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1197 p_stream->b_force_backup = false;
1202 p_stream->b_force_backup = false;
1207 /* Backup the ogg packet (likely an header packet) */
1210 void *p_org = p_stream->p_headers;
1211 p_stream->i_headers += p_oggpacket->bytes;
1212 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1213 if( p_stream->p_headers )
1215 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1216 p_oggpacket->packet, p_oggpacket->bytes );
1220 #warning Memory leak
1221 p_stream->i_headers = 0;
1222 p_stream->p_headers = NULL;
1226 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1227 p_oggpacket->bytes, p_oggpacket->packet ) )
1229 p_stream->i_headers = 0;
1230 p_stream->p_headers = NULL;
1232 if( p_stream->i_headers > 0 )
1234 if( !p_stream->b_force_backup )
1236 /* Last header received, commit changes */
1237 free( p_stream->fmt.p_extra );
1239 p_stream->fmt.i_extra = p_stream->i_headers;
1240 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1241 if( p_stream->fmt.p_extra )
1242 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1243 p_stream->i_headers );
1245 p_stream->fmt.i_extra = 0;
1247 if( p_stream->i_headers > 0 )
1248 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1249 p_stream->p_headers, p_stream->i_headers );
1251 /* we're not at BOS anymore for this logical stream */
1252 p_stream->b_initializing = false;
1256 b_selected = false; /* Discard the header packet */
1260 p_stream->b_initializing = false;
1263 /* Convert the granulepos into the next pcr */
1264 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1268 /* This stream isn't currently selected so we don't need to decode it,
1269 * but we did need to store its pcr as it might be selected later on */
1273 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1274 p_block->i_pts = p_stream->i_pcr;
1276 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1277 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1279 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1280 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1282 /* may need to preroll after a seek or in case of preskip */
1283 if ( p_stream->i_skip_frames > 0 )
1285 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1287 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1289 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1290 p_stream->i_skip_frames -= p_block->i_nb_samples;
1291 p_block->i_nb_samples = 0;
1295 p_block->i_nb_samples -= p_stream->i_skip_frames;
1296 p_stream->i_skip_frames = 0;
1301 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1302 p_stream->i_skip_frames--;
1306 /* Conditional block fixes */
1307 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1308 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1310 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1312 else if( p_stream->fmt.i_cat == AUDIO_ES )
1314 /* Blatant abuse of the i_length field. */
1315 p_block->i_length = p_stream->i_end_trim;
1317 else if( p_stream->fmt.i_cat == SPU_ES )
1319 p_block->i_length = 0;
1321 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1323 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1324 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1325 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1326 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1327 /* granulepos for dirac is possibly broken, this value should be ignored */
1328 if( 0 >= p_oggpacket->granulepos )
1330 p_block->i_pts = VLC_TS_INVALID;
1331 p_block->i_dts = p_stream->i_pcr;
1335 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1336 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1337 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1338 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1339 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1340 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1341 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1342 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1343 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1344 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1346 if( p_oggpacket->bytes <= 0 )
1348 msg_Dbg( p_demux, "discarding 0 sized packet" );
1349 block_Release( p_block );
1352 /* We remove the header from the packet */
1353 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1354 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1356 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1358 /* But with subtitles we need to retrieve the duration first */
1359 int i, lenbytes = 0;
1361 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1363 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1365 lenbytes = lenbytes << 8;
1366 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1369 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1370 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1371 p_oggpacket->packet[i_header_len + 1] != 0 &&
1372 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1373 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1375 p_block->i_length = (mtime_t)lenbytes * 1000;
1380 if( p_block->i_buffer >= (unsigned int)i_header_len )
1381 p_block->i_buffer -= i_header_len;
1383 p_block->i_buffer = 0;
1387 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1389 /* FIXME: the biggest hack I've ever done */
1390 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1391 p_block->i_pts, p_block->i_dts );
1395 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1396 p_oggpacket->bytes - i_header_len );
1398 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1401 /* Re-implemented to avoid linking against libopus from the demuxer. */
1402 static int Ogg_OpusDataDuration( logical_stream_t *p_stream,
1403 unsigned char *data, long i_datalen )
1405 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1412 return VLC_EGENERIC;
1425 return VLC_EGENERIC;
1426 nframes = data[1]&0x3F;
1429 i_rate = (int)p_stream->fmt.audio.i_rate;
1431 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1432 else if( ( toc&0x60 ) == 0x60 )
1433 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1435 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1436 nsamples = nframes*frame_size;
1437 if( nsamples*25 > i_rate*3 )
1438 return VLC_EGENERIC;
1442 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1443 ogg_packet *p_oggpacket )
1445 return Ogg_OpusDataDuration( p_stream, p_oggpacket->packet, p_oggpacket->bytes );
1448 /****************************************************************************
1449 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1450 * stream and fill p_ogg.
1451 *****************************************************************************
1452 * The initial page of a logical stream is marked as a 'bos' page.
1453 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1454 * together and all of the initial pages must appear before any data pages.
1456 * On success this function returns VLC_SUCCESS.
1457 ****************************************************************************/
1458 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1460 demux_sys_t *p_ogg = p_demux->p_sys ;
1461 ogg_packet oggpacket;
1464 p_ogg->i_total_length = stream_Size ( p_demux->s );
1465 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1468 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1471 if( ogg_page_bos( &p_ogg->current_page ) )
1474 /* All is wonderful in our fine fine little world.
1475 * We found the beginning of our first logical stream. */
1476 while( ogg_page_bos( &p_ogg->current_page ) )
1478 logical_stream_t *p_stream;
1480 p_stream = malloc( sizeof(logical_stream_t) );
1481 if( unlikely( !p_stream ) )
1484 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1486 memset( p_stream, 0, sizeof(logical_stream_t) );
1488 es_format_Init( &p_stream->fmt, 0, 0 );
1489 es_format_Init( &p_stream->fmt_old, 0, 0 );
1490 p_stream->b_initializing = true;
1492 /* Setup the logical stream */
1493 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1494 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1496 /* Extract the initial header from the first page and verify
1497 * the codec type of this Ogg bitstream */
1498 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1500 /* error. stream version mismatch perhaps */
1501 msg_Err( p_demux, "error reading first page of "
1502 "Ogg bitstream data" );
1503 return VLC_EGENERIC;
1506 /* FIXME: check return value */
1507 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1509 /* Check for Vorbis header */
1510 if( oggpacket.bytes >= 7 &&
1511 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1513 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1514 msg_Dbg( p_demux, "found vorbis header" );
1517 msg_Dbg( p_demux, "found invalid vorbis header" );
1518 Ogg_LogicalStreamDelete( p_demux, p_stream );
1522 /* Check for Speex header */
1523 else if( oggpacket.bytes >= 5 &&
1524 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1526 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1527 msg_Dbg( p_demux, "found speex header, channels: %i, "
1528 "rate: %i, bitrate: %i, frames: %i group %i",
1529 p_stream->fmt.audio.i_channels,
1530 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1531 p_stream->special.speex.i_framesize,
1532 p_stream->special.speex.i_framesperpacket );
1535 msg_Dbg( p_demux, "found invalid Speex header" );
1536 Ogg_LogicalStreamDelete( p_demux, p_stream );
1540 /* Check for Opus header */
1541 else if( oggpacket.bytes >= 8 &&
1542 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1544 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1545 msg_Dbg( p_demux, "found opus header, channels: %i, "
1547 p_stream->fmt.audio.i_channels,
1548 (int)p_stream->i_pre_skip);
1549 p_stream->i_skip_frames = p_stream->i_pre_skip;
1551 /* Check for Flac header (< version 1.1.1) */
1552 else if( oggpacket.bytes >= 4 &&
1553 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1555 msg_Dbg( p_demux, "found FLAC header" );
1557 /* Grrrr!!!! Did they really have to put all the
1558 * important info in the second header packet!!!
1559 * (STREAMINFO metadata is in the following packet) */
1560 p_stream->b_force_backup = true;
1561 p_stream->fmt.i_cat = AUDIO_ES;
1562 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1564 /* Check for Flac header (>= version 1.1.1) */
1565 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1566 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1567 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1569 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1570 oggpacket.packet[8];
1571 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1572 "(%i header packets)",
1573 oggpacket.packet[5], oggpacket.packet[6],
1576 p_stream->b_force_backup = true;
1578 p_stream->fmt.i_cat = AUDIO_ES;
1579 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1580 oggpacket.packet += 13; oggpacket.bytes -= 13;
1581 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1583 msg_Dbg( p_demux, "found invalid Flac header" );
1584 Ogg_LogicalStreamDelete( p_demux, p_stream );
1588 /* Check for Theora header */
1589 else if( oggpacket.bytes >= 7 &&
1590 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1592 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1594 "found theora header, bitrate: %i, rate: %f",
1595 p_stream->fmt.i_bitrate, p_stream->f_rate );
1598 msg_Dbg( p_demux, "found invalid Theora header" );
1599 Ogg_LogicalStreamDelete( p_demux, p_stream );
1603 /* Check for Dirac header */
1604 else if( ( oggpacket.bytes >= 5 &&
1605 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1606 ( oggpacket.bytes >= 9 &&
1607 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1609 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1610 msg_Dbg( p_demux, "found dirac header" );
1613 msg_Warn( p_demux, "found dirac header isn't decodable" );
1614 Ogg_LogicalStreamDelete( p_demux, p_stream );
1618 /* Check for Tarkin header */
1619 else if( oggpacket.bytes >= 7 &&
1620 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1624 msg_Dbg( p_demux, "found tarkin header" );
1625 p_stream->fmt.i_cat = VIDEO_ES;
1626 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1628 /* Cheat and get additionnal info ;) */
1629 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1630 oggpack_adv( &opb, 88 );
1631 oggpack_adv( &opb, 104 );
1632 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1633 p_stream->f_rate = 2; /* FIXME */
1635 "found tarkin header, bitrate: %i, rate: %f",
1636 p_stream->fmt.i_bitrate, p_stream->f_rate );
1638 /* Check for VP8 header */
1639 else if( oggpacket.bytes >= 26 &&
1640 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1642 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1643 msg_Dbg( p_demux, "found VP8 header "
1644 "fps: %f, width:%i; height:%i",
1646 p_stream->fmt.video.i_width,
1647 p_stream->fmt.video.i_height );
1650 msg_Dbg( p_demux, "invalid VP8 header found");
1651 Ogg_LogicalStreamDelete( p_demux, p_stream );
1655 /* Check for Annodex header */
1656 else if( oggpacket.bytes >= 7 &&
1657 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1659 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1660 /* kill annodex track */
1664 /* Check for Annodex header */
1665 else if( oggpacket.bytes >= 7 &&
1666 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1668 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1670 /* Check for Kate header */
1671 else if( oggpacket.bytes >= 8 &&
1672 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1674 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1675 msg_Dbg( p_demux, "found kate header" );
1678 msg_Dbg( p_demux, "invalid kate header found");
1679 Ogg_LogicalStreamDelete( p_demux, p_stream );
1683 /* Check for OggDS */
1684 else if( oggpacket.bytes >= 142 &&
1685 !memcmp( &oggpacket.packet[1],
1686 "Direct Show Samples embedded in Ogg", 35 ))
1688 /* Old header type */
1689 p_stream->b_oggds = true;
1690 /* Check for video header (old format) */
1691 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1692 oggpacket.bytes >= 184 )
1694 p_stream->fmt.i_cat = VIDEO_ES;
1695 p_stream->fmt.i_codec =
1696 VLC_FOURCC( oggpacket.packet[68],
1697 oggpacket.packet[69],
1698 oggpacket.packet[70],
1699 oggpacket.packet[71] );
1700 msg_Dbg( p_demux, "found video header of type: %.4s",
1701 (char *)&p_stream->fmt.i_codec );
1703 p_stream->fmt.video.i_frame_rate = 10000000;
1704 p_stream->fmt.video.i_frame_rate_base =
1705 GetQWLE((oggpacket.packet+164));
1706 p_stream->fmt.video.i_frame_rate_base =
1707 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1708 p_stream->f_rate = 10000000.0 /
1709 p_stream->fmt.video.i_frame_rate_base;
1710 p_stream->fmt.video.i_bits_per_pixel =
1711 GetWLE((oggpacket.packet+182));
1712 if( !p_stream->fmt.video.i_bits_per_pixel )
1714 p_stream->fmt.video.i_bits_per_pixel = 24;
1715 p_stream->fmt.video.i_width =
1716 GetDWLE((oggpacket.packet+176));
1717 p_stream->fmt.video.i_height =
1718 GetDWLE((oggpacket.packet+180));
1721 "fps: %f, width:%i; height:%i, bitcount:%i",
1723 p_stream->fmt.video.i_width,
1724 p_stream->fmt.video.i_height,
1725 p_stream->fmt.video.i_bits_per_pixel);
1728 /* Check for audio header (old format) */
1729 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1732 unsigned int i_format_tag;
1734 p_stream->fmt.i_cat = AUDIO_ES;
1736 i_extra_size = GetWLE((oggpacket.packet+140));
1737 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1739 p_stream->fmt.i_extra = i_extra_size;
1740 p_stream->fmt.p_extra = malloc( i_extra_size );
1741 if( p_stream->fmt.p_extra )
1742 memcpy( p_stream->fmt.p_extra,
1743 oggpacket.packet + 142, i_extra_size );
1745 p_stream->fmt.i_extra = 0;
1748 i_format_tag = GetWLE((oggpacket.packet+124));
1749 p_stream->fmt.audio.i_channels =
1750 GetWLE((oggpacket.packet+126));
1751 fill_channels_info(&p_stream->fmt.audio);
1752 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1753 GetDWLE((oggpacket.packet+128));
1754 p_stream->fmt.i_bitrate =
1755 GetDWLE((oggpacket.packet+132)) * 8;
1756 p_stream->fmt.audio.i_blockalign =
1757 GetWLE((oggpacket.packet+136));
1758 p_stream->fmt.audio.i_bitspersample =
1759 GetWLE((oggpacket.packet+138));
1761 wf_tag_to_fourcc( i_format_tag,
1762 &p_stream->fmt.i_codec, 0 );
1764 if( p_stream->fmt.i_codec ==
1765 VLC_FOURCC('u','n','d','f') )
1767 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1768 ( i_format_tag >> 8 ) & 0xff,
1769 i_format_tag & 0xff );
1772 msg_Dbg( p_demux, "found audio header of type: %.4s",
1773 (char *)&p_stream->fmt.i_codec );
1774 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1775 "%dbits/sample %dkb/s",
1777 p_stream->fmt.audio.i_channels,
1778 p_stream->fmt.audio.i_rate,
1779 p_stream->fmt.audio.i_bitspersample,
1780 p_stream->fmt.i_bitrate / 1024 );
1781 if ( p_stream->f_rate == 0 )
1783 msg_Dbg( p_demux, "invalid oggds audio header" );
1784 Ogg_LogicalStreamDelete( p_demux, p_stream );
1790 msg_Dbg( p_demux, "stream %d has an old header "
1791 "but is of an unknown type", p_ogg->i_streams-1 );
1796 /* Check for OggDS */
1797 else if( oggpacket.bytes >= 44+1 &&
1798 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1800 stream_header_t tmp;
1801 stream_header_t *st = &tmp;
1803 p_stream->b_oggds = true;
1805 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1806 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1807 st->size = GetDWLE( &oggpacket.packet[1+12] );
1808 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1809 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1810 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1811 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1812 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1814 /* Check for video header (new format) */
1815 if( !strncmp( st->streamtype, "video", 5 ) &&
1816 oggpacket.bytes >= 52+1 )
1818 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1819 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1821 p_stream->fmt.i_cat = VIDEO_ES;
1823 /* We need to get rid of the header packet */
1824 ogg_stream_packetout( &p_stream->os, &oggpacket );
1826 p_stream->fmt.i_codec =
1827 VLC_FOURCC( st->subtype[0], st->subtype[1],
1828 st->subtype[2], st->subtype[3] );
1829 msg_Dbg( p_demux, "found video header of type: %.4s",
1830 (char *)&p_stream->fmt.i_codec );
1832 p_stream->fmt.video.i_frame_rate = 10000000;
1833 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1834 if( st->time_unit <= 0 )
1835 st->time_unit = 400000;
1836 p_stream->f_rate = 10000000.0 / st->time_unit;
1837 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1838 p_stream->fmt.video.i_width = st->sh.video.width;
1839 p_stream->fmt.video.i_height = st->sh.video.height;
1842 "fps: %f, width:%i; height:%i, bitcount:%i",
1844 p_stream->fmt.video.i_width,
1845 p_stream->fmt.video.i_height,
1846 p_stream->fmt.video.i_bits_per_pixel );
1848 /* Check for audio header (new format) */
1849 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1850 oggpacket.bytes >= 56+1 )
1856 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1857 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1858 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1860 p_stream->fmt.i_cat = AUDIO_ES;
1862 /* We need to get rid of the header packet */
1863 ogg_stream_packetout( &p_stream->os, &oggpacket );
1865 i_extra_size = st->size - 56;
1867 if( i_extra_size > 0 &&
1868 i_extra_size < oggpacket.bytes - 1 - 56 )
1870 p_stream->fmt.i_extra = i_extra_size;
1871 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1872 if( p_stream->fmt.p_extra )
1873 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1874 p_stream->fmt.i_extra );
1876 p_stream->fmt.i_extra = 0;
1879 memcpy( p_buffer, st->subtype, 4 );
1881 i_format_tag = strtol(p_buffer,NULL,16);
1882 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1883 fill_channels_info(&p_stream->fmt.audio);
1884 if( st->time_unit <= 0 )
1885 st->time_unit = 10000000;
1886 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1887 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1888 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1889 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1891 wf_tag_to_fourcc( i_format_tag,
1892 &p_stream->fmt.i_codec, 0 );
1894 if( p_stream->fmt.i_codec ==
1895 VLC_FOURCC('u','n','d','f') )
1897 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1898 ( i_format_tag >> 8 ) & 0xff,
1899 i_format_tag & 0xff );
1902 msg_Dbg( p_demux, "found audio header of type: %.4s",
1903 (char *)&p_stream->fmt.i_codec );
1904 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1905 "%dbits/sample %dkb/s",
1907 p_stream->fmt.audio.i_channels,
1908 p_stream->fmt.audio.i_rate,
1909 p_stream->fmt.audio.i_bitspersample,
1910 p_stream->fmt.i_bitrate / 1024 );
1911 if ( p_stream->f_rate == 0 )
1913 msg_Dbg( p_demux, "invalid oggds audio header" );
1914 Ogg_LogicalStreamDelete( p_demux, p_stream );
1918 /* Check for text (subtitles) header */
1919 else if( !strncmp(st->streamtype, "text", 4) )
1921 /* We need to get rid of the header packet */
1922 ogg_stream_packetout( &p_stream->os, &oggpacket );
1924 msg_Dbg( p_demux, "found text subtitle header" );
1925 p_stream->fmt.i_cat = SPU_ES;
1926 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1927 p_stream->f_rate = 1000; /* granulepos is in millisec */
1931 msg_Dbg( p_demux, "stream %d has a header marker "
1932 "but is of an unknown type", p_ogg->i_streams-1 );
1937 else if( oggpacket.bytes >= 8 &&
1938 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1942 msg_Dbg( p_demux, "stream %d is a skeleton",
1943 p_ogg->i_streams-1 );
1944 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1948 msg_Dbg( p_demux, "stream %d is of unknown type",
1949 p_ogg->i_streams-1 );
1954 /* we'll need to get all headers */
1955 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1957 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1958 return VLC_EGENERIC;
1961 /* This is the first data page, which means we are now finished
1962 * with the initial pages. We just need to store it in the relevant
1964 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1966 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1967 &p_ogg->current_page ) == 0 )
1969 p_ogg->b_page_waiting = true;
1978 return VLC_EGENERIC;
1981 /****************************************************************************
1982 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1983 ****************************************************************************/
1984 static void Ogg_CreateES( demux_t *p_demux )
1986 demux_sys_t *p_ogg = p_demux->p_sys;
1987 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1990 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1992 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1994 if ( p_stream->p_es == NULL && !p_stream->b_finished )
1996 /* Better be safe than sorry when possible with ogm */
1997 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1998 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1999 p_stream->fmt.b_packetized = false;
2001 /* Try first to reuse an old ES */
2003 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2004 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2006 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2008 p_stream->p_es = p_old_stream->p_es;
2009 p_stream->b_finished = false;
2010 p_stream->b_reinit = false;
2011 p_stream->b_initializing = false;
2012 p_stream->i_pre_skip = 0;
2013 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2014 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2016 p_old_stream->p_es = NULL;
2017 p_old_stream = NULL;
2018 if ( b_resetdecoder )
2020 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2021 p_stream->p_es, &p_stream->fmt );
2026 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2029 // TODO: something to do here ?
2030 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2032 /* Set the CMML stream active */
2033 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2038 if( p_ogg->p_old_stream )
2040 if( p_ogg->p_old_stream->p_es )
2041 msg_Dbg( p_demux, "old stream not reused" );
2042 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2043 p_ogg->p_old_stream = NULL;
2047 /****************************************************************************
2048 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2049 * Elementary streams.
2050 ****************************************************************************/
2051 static int Ogg_BeginningOfStream( demux_t *p_demux )
2053 demux_sys_t *p_ogg = p_demux->p_sys ;
2056 /* Find the logical streams embedded in the physical stream and
2057 * initialize our p_ogg structure. */
2058 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2060 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2061 return VLC_EGENERIC;
2064 p_ogg->i_bitrate = 0;
2066 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2068 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2070 p_stream->p_es = NULL;
2072 /* initialise kframe index */
2075 if ( p_stream->fmt.i_bitrate == 0 &&
2076 ( p_stream->fmt.i_cat == VIDEO_ES ||
2077 p_stream->fmt.i_cat == AUDIO_ES ) )
2078 p_ogg->b_partial_bitrate = true;
2080 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2082 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2083 p_stream->i_previous_granulepos = -1;
2084 p_stream->b_reinit = false;
2087 /* get total frame count for video stream; we will need this for seeking */
2088 p_ogg->i_total_frames = 0;
2093 /****************************************************************************
2094 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2095 ****************************************************************************/
2096 static void Ogg_EndOfStream( demux_t *p_demux )
2098 demux_sys_t *p_ogg = p_demux->p_sys ;
2101 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2102 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2103 free( p_ogg->pp_stream );
2106 p_ogg->i_bitrate = 0;
2107 p_ogg->i_streams = 0;
2108 p_ogg->pp_stream = NULL;
2109 p_ogg->skeleton.major = 0;
2110 p_ogg->skeleton.minor = 0;
2111 p_ogg->b_preparsing_done = false;
2112 p_ogg->b_es_created = false;
2113 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2114 p_ogg->i_pcr - VLC_TS_0 : 0;
2118 vlc_meta_Delete( p_ogg->p_meta );
2119 p_ogg->p_meta = NULL;
2121 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2123 if ( p_ogg->pp_seekpoints[i] )
2124 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2126 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2127 p_ogg->i_seekpoints = 0;
2130 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2132 #ifdef HAVE_LIBVORBIS
2133 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2135 FREENULL( p_stream->special.vorbis.p_info );
2136 FREENULL( p_stream->special.vorbis.p_comment );
2137 p_stream->special.vorbis.b_invalid = false;
2140 VLC_UNUSED( p_stream );
2145 * This function delete and release all data associated to a logical_stream_t
2147 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2149 if( p_stream->p_es )
2150 es_out_Del( p_demux->out, p_stream->p_es );
2152 ogg_stream_clear( &p_stream->os );
2153 free( p_stream->p_headers );
2155 Ogg_CleanSpecificData( p_stream );
2157 es_format_Clean( &p_stream->fmt_old );
2158 es_format_Clean( &p_stream->fmt );
2160 if ( p_stream->idx != NULL)
2162 oggseek_index_entries_free( p_stream->idx );
2165 Ogg_FreeSkeleton( p_stream->p_skel );
2166 p_stream->p_skel = NULL;
2167 if ( p_demux->p_sys->p_skelstream == p_stream )
2168 p_demux->p_sys->p_skelstream = NULL;
2170 /* Shouldn't happen */
2171 if ( unlikely( p_stream->p_preparse_block ) )
2173 block_ChainRelease( p_stream->p_preparse_block );
2174 p_stream->p_preparse_block = NULL;
2176 free( p_stream->p_prepcr_blocks );
2181 * This function check if a we need to reset a decoder in case we are
2184 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2186 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2187 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2188 unsigned i_new_count;
2189 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2192 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2193 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2194 unsigned i_old_count;
2195 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2198 bool b_match = i_new_count == i_old_count;
2199 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2201 /* Ignore vorbis comment */
2204 if( pi_new_size[i] != pi_old_size[i] ||
2205 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2212 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2213 const es_format_t *p_old )
2215 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2216 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2217 unsigned i_new_count;
2218 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2220 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2221 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2222 unsigned i_old_count;
2223 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2225 bool b_match = false;
2226 if( i_new_count == i_old_count && i_new_count > 0 )
2228 static const unsigned char default_map[2] = { 0, 1 };
2229 unsigned char *p_old_head;
2230 unsigned char *p_new_head;
2231 const unsigned char *p_old_map;
2232 const unsigned char *p_new_map;
2233 int i_old_channel_count;
2234 int i_new_channel_count;
2235 int i_old_stream_count;
2236 int i_new_stream_count;
2237 int i_old_coupled_count;
2238 int i_new_coupled_count;
2239 p_old_head = (unsigned char *)pp_old_data[0];
2240 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2241 p_old_map = default_map;
2242 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2244 i_old_channel_count = p_old_head[9];
2245 switch( p_old_head[18] )
2248 i_old_stream_count = 1;
2249 i_old_coupled_count = i_old_channel_count - 1;
2252 if( pi_old_size[0] >= 21U + i_old_channel_count )
2254 i_old_stream_count = p_old_head[19];
2255 i_old_coupled_count = p_old_head[20];
2256 p_old_map = p_old_head + 21;
2261 p_new_head = (unsigned char *)pp_new_data[0];
2262 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2263 p_new_map = default_map;
2264 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2266 i_new_channel_count = p_new_head[9];
2267 switch( p_new_head[18] )
2270 i_new_stream_count = 1;
2271 i_new_coupled_count = i_new_channel_count - 1;
2274 if( pi_new_size[0] >= 21U + i_new_channel_count )
2276 i_new_stream_count = p_new_head[19];
2277 i_new_coupled_count = p_new_head[20];
2278 p_new_map = p_new_head+21;
2283 b_match = i_old_channel_count == i_new_channel_count &&
2284 i_old_stream_count == i_new_stream_count &&
2285 i_old_coupled_count == i_new_coupled_count &&
2286 memcmp(p_old_map, p_new_map,
2287 i_new_channel_count*sizeof(*p_new_map)) == 0;
2293 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2295 bool b_compatible = false;
2296 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2299 /* Only Vorbis and Opus are supported. */
2300 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2301 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2302 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2303 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2306 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2308 return !b_compatible;
2311 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2312 const void *p_headers, unsigned i_headers )
2314 demux_sys_t *p_ogg = p_demux->p_sys;
2315 int i_cover_score = 0;
2316 int i_cover_idx = 0;
2317 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2318 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2319 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2321 pf_replay_gain[i] = 0;
2322 pf_replay_peak[i] = 0;
2324 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2325 &p_ogg->i_attachments, &p_ogg->attachments,
2326 &i_cover_score, &i_cover_idx,
2327 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2328 &pf_replay_gain, &pf_replay_peak );
2329 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2332 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2333 p_ogg->attachments[i_cover_idx]->psz_name );
2334 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2337 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2339 if ( pf_replay_gain[i] != 0 )
2341 p_fmt->audio_replay_gain.pb_gain[i] = true;
2342 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2343 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2345 if ( pf_replay_peak[i] != 0 )
2347 p_fmt->audio_replay_gain.pb_peak[i] = true;
2348 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2349 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2353 if( p_ogg->i_seekpoints > 1 )
2355 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2359 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2360 const void *p_headers, unsigned i_headers, unsigned i_skip )
2362 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2363 void *pp_data[XIPH_MAX_HEADER_COUNT];
2366 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2368 /* TODO how to handle multiple comments properly ? */
2369 if( i_count >= 2 && pi_size[1] > i_skip )
2371 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2375 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2377 demux_sys_t *p_ogg = p_demux->p_sys;
2379 switch( p_fmt->i_codec )
2381 /* 3 headers with the 2° one being the comments */
2382 case VLC_CODEC_VORBIS:
2383 case VLC_CODEC_THEORA:
2384 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2386 case VLC_CODEC_OPUS:
2387 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2389 case VLC_CODEC_SPEEX:
2390 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2393 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2395 /* N headers with the 2° one being the comments */
2396 case VLC_CODEC_KATE:
2397 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2398 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2402 case VLC_CODEC_FLAC:
2403 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2407 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2408 case VLC_CODEC_DIRAC:
2413 p_demux->info.i_update |= INPUT_UPDATE_META;
2416 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2417 ogg_packet *p_oggpacket )
2420 unsigned int i_fps_numerator;
2421 unsigned int i_fps_denominator;
2422 int i_keyframe_frequency_force;
2428 p_stream->fmt.i_cat = VIDEO_ES;
2429 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2431 /* Signal that we want to keep a backup of the theora
2432 * stream headers. They will be used when switching between
2434 p_stream->b_force_backup = true;
2436 /* Cheat and get additionnal info ;) */
2437 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2438 bs_skip( &bitstream, 56 );
2440 i_major = bs_read( &bitstream, 8 ); /* major version num */
2441 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2442 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2444 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2445 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2446 bs_read( &bitstream, 24 ); /* frame width */
2447 bs_read( &bitstream, 24 ); /* frame height */
2448 bs_read( &bitstream, 8 ); /* x offset */
2449 bs_read( &bitstream, 8 ); /* y offset */
2451 i_fps_numerator = bs_read( &bitstream, 32 );
2452 i_fps_denominator = bs_read( &bitstream, 32 );
2453 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2454 bs_read( &bitstream, 24 ); /* aspect_numerator */
2455 bs_read( &bitstream, 24 ); /* aspect_denominator */
2457 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2458 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2460 bs_read( &bitstream, 8 ); /* colorspace */
2461 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2462 bs_read( &bitstream, 6 ); /* quality */
2464 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2466 /* granule_shift = i_log( frequency_force -1 ) */
2467 p_stream->i_granule_shift = 0;
2468 i_keyframe_frequency_force--;
2469 while( i_keyframe_frequency_force )
2471 p_stream->i_granule_shift++;
2472 i_keyframe_frequency_force >>= 1;
2475 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2476 p_stream->i_keyframe_offset = 0;
2477 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2478 if ( p_stream->f_rate == 0 ) return false;
2480 if ( i_version >= 3002001 )
2482 p_stream->i_keyframe_offset = 1;
2487 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2488 ogg_packet *p_oggpacket )
2492 p_stream->fmt.i_cat = AUDIO_ES;
2493 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2495 /* Signal that we want to keep a backup of the vorbis
2496 * stream headers. They will be used when switching between
2498 p_stream->b_force_backup = true;
2500 /* Cheat and get additionnal info ;) */
2501 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2502 oggpack_adv( &opb, 88 );
2503 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2504 fill_channels_info(&p_stream->fmt.audio);
2505 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2506 oggpack_read( &opb, 32 );
2507 oggpack_adv( &opb, 32 );
2508 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2509 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2510 if ( p_stream->f_rate == 0 ) return false;
2513 #ifdef HAVE_LIBVORBIS
2514 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2515 ogg_packet *p_oggpacket, int i_number )
2519 case VORBIS_HEADER_IDENTIFICATION:
2520 p_stream->special.vorbis.p_info = malloc( sizeof(vorbis_info) );
2521 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2522 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2524 FREENULL( p_stream->special.vorbis.p_info );
2525 FREENULL( p_stream->special.vorbis.p_comment );
2526 p_stream->special.vorbis.b_invalid = true;
2529 vorbis_info_init( p_stream->special.vorbis.p_info );
2530 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2533 case VORBIS_HEADER_COMMENT:
2534 case VORBIS_HEADER_SETUP:
2535 if ( p_stream->special.vorbis.p_info && ! p_stream->special.vorbis.b_invalid )
2537 p_stream->special.vorbis.b_invalid = ( 0 != vorbis_synthesis_headerin(
2538 p_stream->special.vorbis.p_info,
2539 p_stream->special.vorbis.p_comment, p_oggpacket ) );
2549 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2550 ogg_packet *p_oggpacket )
2554 p_stream->fmt.i_cat = AUDIO_ES;
2555 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2557 /* Signal that we want to keep a backup of the speex
2558 * stream headers. They will be used when switching between
2560 p_stream->b_force_backup = true;
2562 /* Cheat and get additionnal info ;) */
2563 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2564 oggpack_adv( &opb, 224 );
2565 oggpack_adv( &opb, 32 ); /* speex_version_id */
2566 oggpack_adv( &opb, 32 ); /* header_size */
2567 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2568 if ( p_stream->f_rate == 0 ) return false;
2569 oggpack_adv( &opb, 32 ); /* mode */
2570 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2571 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2572 fill_channels_info(&p_stream->fmt.audio);
2573 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2574 p_stream->special.speex.i_framesize =
2575 oggpack_read( &opb, 32 ); /* frame_size */
2576 oggpack_adv( &opb, 32 ); /* vbr */
2577 p_stream->special.speex.i_framesperpacket =
2578 oggpack_read( &opb, 32 ); /* frames_per_packet */
2579 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2583 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2584 ogg_packet *p_oggpacket )
2588 p_stream->fmt.i_cat = AUDIO_ES;
2589 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2591 /* Signal that we want to keep a backup of the opus
2592 * stream headers. They will be used when switching between
2594 p_stream->b_force_backup = true;
2596 /* All OggOpus streams are timestamped at 48kHz and
2597 * can be played at 48kHz. */
2598 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2599 p_stream->fmt.i_bitrate = 0;
2601 /* Cheat and get additional info ;) */
2602 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2603 oggpack_adv( &opb, 64 );
2604 oggpack_adv( &opb, 8 ); /* version_id */
2605 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2606 fill_channels_info(&p_stream->fmt.audio);
2607 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2608 /* For Opus, trash the first 80 ms of decoded output as
2609 well, to avoid blowing out speakers if we get unlucky.
2610 Opus predicts content from prior frames, which can go
2611 badly if we seek right where the stream goes from very
2612 quiet to very loud. It will converge after a bit. */
2613 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2616 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2617 ogg_packet *p_oggpacket )
2619 /* Parse the STREAMINFO metadata */
2622 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2625 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2627 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2631 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2634 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2635 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2636 fill_channels_info(&p_stream->fmt.audio);
2638 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2639 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2640 if ( p_stream->f_rate == 0 ) return false;
2644 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2647 /* Fake this as the last metadata block */
2648 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2652 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2653 ogg_packet *p_oggpacket )
2661 p_stream->fmt.i_cat = SPU_ES;
2662 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2664 /* Signal that we want to keep a backup of the kate
2665 * stream headers. They will be used when switching between
2667 p_stream->b_force_backup = true;
2669 /* Cheat and get additionnal info ;) */
2670 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2671 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2672 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2673 oggpack_adv( &opb, 3*8 );
2674 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2675 oggpack_adv( &opb, 8*8 ); /* reserved */
2676 gnum = oggpack_read( &opb, 32 );
2677 gden = oggpack_read( &opb, 32 );
2678 gden = __MAX( gden, 1 );
2679 p_stream->f_rate = (double)gnum/gden;
2680 if ( p_stream->f_rate == 0 ) return false;
2682 p_stream->fmt.psz_language = malloc(16);
2683 if( p_stream->fmt.psz_language )
2685 for( n = 0; n < 16; n++ )
2686 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2687 p_stream->fmt.psz_language[15] = 0; /* just in case */
2691 for( n = 0; n < 16; n++ )
2692 oggpack_read(&opb,8);
2694 p_stream->fmt.psz_description = malloc(16);
2695 if( p_stream->fmt.psz_description )
2697 for( n = 0; n < 16; n++ )
2698 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2699 p_stream->fmt.psz_description[15] = 0; /* just in case */
2701 /* Now find a localized user readable description for this category */
2702 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2705 free( p_stream->fmt.psz_description );
2706 p_stream->fmt.psz_description = psz_desc;
2711 for( n = 0; n < 16; n++ )
2712 oggpack_read(&opb,8);
2718 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2719 ogg_packet *p_oggpacket )
2721 switch( p_oggpacket->packet[5] )
2725 /* Mapping version */
2726 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2728 p_stream->fmt.i_cat = VIDEO_ES;
2729 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2730 p_stream->i_granule_shift = 32;
2731 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2732 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2733 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2734 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2735 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2736 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2737 p_stream->fmt.video.i_frame_rate_base =
2738 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2739 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2740 if ( p_stream->f_rate == 0 ) return false;
2744 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2745 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2752 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2753 bool *b_force_backup, bool *b_packet_out )
2755 if( !strncmp(psz_value, "audio/x-wav", 11) )
2757 /* n.b. WAVs are unsupported right now */
2758 p_stream->fmt.i_cat = UNKNOWN_ES;
2759 free( p_stream->fmt.psz_description );
2760 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2762 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2763 !strncmp(psz_value, "audio/vorbis", 12) )
2765 p_stream->fmt.i_cat = AUDIO_ES;
2766 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2768 *b_force_backup = true;
2770 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2771 !strncmp(psz_value, "audio/speex", 11) )
2773 p_stream->fmt.i_cat = AUDIO_ES;
2774 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2776 *b_force_backup = true;
2778 else if( !strncmp(psz_value, "audio/flac", 10) )
2780 p_stream->fmt.i_cat = AUDIO_ES;
2781 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2783 *b_force_backup = true;
2785 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2786 !strncmp(psz_value, "video/theora", 12) )
2788 p_stream->fmt.i_cat = VIDEO_ES;
2789 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2791 *b_force_backup = true;
2793 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2795 p_stream->fmt.i_cat = VIDEO_ES;
2796 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2798 *b_force_backup = true;
2800 else if( !strncmp(psz_value, "video/mpeg", 10) )
2802 /* n.b. MPEG streams are unsupported right now */
2803 p_stream->fmt.i_cat = VIDEO_ES;
2804 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2806 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2807 !strncmp(psz_value, "text/cmml", 9) )
2809 p_stream->fmt.i_cat = SPU_ES;
2810 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2811 *b_packet_out = true;
2813 else if( !strncmp(psz_value, "application/kate", 16) )
2816 p_stream->fmt.i_cat = UNKNOWN_ES;
2817 free( p_stream->fmt.psz_description );
2818 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2820 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2822 p_stream->fmt.i_cat = VIDEO_ES;
2823 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2827 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2828 logical_stream_t *p_stream,
2829 ogg_packet *p_oggpacket )
2831 if( p_oggpacket->bytes >= 28 &&
2832 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2836 uint16_t major_version;
2837 uint16_t minor_version;
2838 uint64_t timebase_numerator;
2839 uint64_t timebase_denominator;
2841 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2843 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2844 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2845 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2846 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2847 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2848 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2850 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2851 "Timebase %"PRId64" / %"PRId64,
2852 major_version, minor_version,
2853 timebase_numerator, timebase_denominator );
2855 else if( p_oggpacket->bytes >= 42 &&
2856 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2858 uint64_t granule_rate_numerator;
2859 uint64_t granule_rate_denominator;
2860 char content_type_string[1024];
2862 /* Read in Annodex header fields */
2864 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2865 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2866 p_stream->i_secondary_header_packets =
2867 GetDWLE( &p_oggpacket->packet[24] );
2869 /* we are guaranteed that the first header field will be
2870 * the content-type (by the Annodex standard) */
2871 content_type_string[0] = '\0';
2872 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2874 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2875 p_oggpacket->bytes - 1 );
2876 if( p && p[0] == '\r' && p[1] == '\n' )
2877 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2878 content_type_string );
2881 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2882 granule_rate_numerator, granule_rate_denominator,
2883 p_stream->i_secondary_header_packets, content_type_string );
2885 p_stream->f_rate = (float) granule_rate_numerator /
2886 (float) granule_rate_denominator;
2888 /* What type of file do we have?
2889 * strcmp is safe to use here because we've extracted
2890 * content_type_string from the stream manually */
2891 bool b_dopacketout = false;
2892 Ogg_ApplyContentType( p_stream, content_type_string,
2893 &p_stream->b_force_backup, &b_dopacketout );
2894 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2898 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2899 ogg_packet *p_oggpacket )
2901 p_demux->p_sys->p_skelstream = p_stream;
2902 /* There can be only 1 skeleton for streams */
2903 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2904 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2905 if ( asprintf( & p_stream->fmt.psz_description,
2906 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2907 p_demux->p_sys->skeleton.major,
2908 p_demux->p_sys->skeleton.minor ) < 0 )
2909 p_stream->fmt.psz_description = NULL;
2912 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2914 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2916 /* Find the matching stream for this skeleton data */
2917 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2918 logical_stream_t *p_target_stream = NULL;
2919 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2921 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2923 p_target_stream = p_demux->p_sys->pp_stream[i];
2927 if ( !p_target_stream ) return;
2929 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2932 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2933 if ( !p_skel ) return;
2934 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2935 p_skel->p_index = NULL;
2936 p_target_stream->p_skel = p_skel;
2939 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2940 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2941 const unsigned char *p = p_messages;
2942 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2944 if ( *p == 0x0D && *(p+1) == 0x0A )
2946 char *psz_message = strndup( (const char *) p_messages,
2950 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2951 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2953 if ( p < p_boundary - 1 ) p_messages = p + 2;
2960 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2961 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2962 unsigned const char *p_end,
2963 uint64_t *pi_value )
2969 while ( p_begin < p_end )
2971 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2972 *pi_value = *pi_value | ( i_read << i_shift );
2974 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2977 *pi_value = GetQWLE( pi_value );
2981 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2983 if ( p_demux->p_sys->skeleton.major < 4
2984 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2987 /* Find the matching stream for this skeleton data */
2988 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2989 logical_stream_t *p_stream = NULL;
2990 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2992 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2994 p_stream = p_demux->p_sys->pp_stream[i];
2998 if ( !p_stream ) return;
2999 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3000 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3001 if ( !i_keypoints ) return;
3003 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3004 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3005 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3006 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3007 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3008 uint64_t i_offset = 0;
3009 uint64_t i_time = 0;
3010 uint64_t i_keypoints_found = 0;
3012 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3015 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3017 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3018 i_time += i_val * p_stream->p_skel->i_indexstampden;
3019 i_keypoints_found++;
3022 if ( i_keypoints_found != i_keypoints )
3024 msg_Warn( p_demux, "Invalid Index: missing entries" );
3028 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3029 if ( !p_stream->p_skel->p_index ) return;
3030 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3031 p_oggpacket->bytes - 42 );
3032 p_stream->p_skel->i_index = i_keypoints_found;
3033 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3036 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3038 if ( !p_skel ) return;
3039 for ( int i=0; i< p_skel->i_messages; i++ )
3040 free( p_skel->ppsz_messages[i] );
3041 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3042 free( p_skel->p_index );
3046 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3048 if ( !p_stream->p_skel ) return;
3049 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3051 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3052 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3054 free( p_stream->fmt.psz_description );
3055 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3057 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3060 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3065 /* Return true if there's a skeleton exact match */
3066 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3067 int64_t *pi_lower, int64_t *pi_upper )
3069 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3072 /* Validate range */
3073 if ( i_time < p_stream->p_skel->i_indexfirstnum
3074 * p_stream->p_skel->i_indexstampden ||
3075 i_time > p_stream->p_skel->i_indexlastnum
3076 * p_stream->p_skel->i_indexstampden ) return false;
3078 /* Then Lookup its index */
3079 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3084 } current = { 0, 0 }, prev = { -1, -1 };
3086 uint64_t i_keypoints_found = 0;
3088 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3089 && i_keypoints_found < p_stream->p_skel->i_index )
3092 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3093 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3094 current.i_pos += i_val;
3095 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3096 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3097 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3098 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3100 i_keypoints_found++;
3102 if ( i_time <= current.i_time )
3104 *pi_lower = prev.i_pos;
3105 *pi_upper = current.i_pos;
3106 return ( i_time == current.i_time );
3113 static uint32_t dirac_uint( bs_t *p_bs )
3115 uint32_t u_count = 0, u_value = 0;
3117 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3121 u_value |= bs_read( p_bs, 1 );
3124 return (1<<u_count) - 1 + u_value;
3127 static int dirac_bool( bs_t *p_bs )
3129 return bs_read( p_bs, 1 );
3132 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3133 ogg_packet *p_oggpacket )
3135 static const struct {
3136 uint32_t u_n /* numerator */, u_d /* denominator */;
3137 } p_dirac_frate_tbl[] = { /* table 10.3 */
3138 {1,1}, /* this first value is never used */
3139 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3140 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3142 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3144 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3145 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3147 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3151 p_stream->i_granule_shift = 22; /* not 32 */
3153 /* Backing up stream headers is not required -- seqhdrs are repeated
3154 * thoughout the stream at suitable decoding start points */
3155 p_stream->b_force_backup = false;
3157 /* read in useful bits from sequence header */
3158 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3159 bs_skip( &bs, 13*8); /* parse_info_header */
3160 dirac_uint( &bs ); /* major_version */
3161 dirac_uint( &bs ); /* minor_version */
3162 dirac_uint( &bs ); /* profile */
3163 dirac_uint( &bs ); /* level */
3165 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3166 if( u_video_format >= u_dirac_vidfmt_frate )
3168 /* don't know how to parse this ogg dirac stream */
3172 if( dirac_bool( &bs ) )
3174 dirac_uint( &bs ); /* frame_width */
3175 dirac_uint( &bs ); /* frame_height */
3178 if( dirac_bool( &bs ) )
3180 dirac_uint( &bs ); /* chroma_format */
3183 if( dirac_bool( &bs ) )
3185 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3188 p_stream->special.dirac.b_interlaced = false;
3190 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3191 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3192 u_d = __MAX( u_d, 1 );
3193 if( dirac_bool( &bs ) )
3195 uint32_t u_frame_rate_index = dirac_uint( &bs );
3196 if( u_frame_rate_index >= u_dirac_frate_tbl )
3198 /* something is wrong with this stream */
3201 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3202 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3203 if( u_frame_rate_index == 0 )
3205 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3206 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3209 p_stream->f_rate = (float) u_n / u_d;
3210 if ( p_stream->f_rate == 0 ) return false;
3212 /* probably is an ogg dirac es */
3213 p_stream->fmt.i_cat = VIDEO_ES;
3214 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;