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 ) )
211 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
215 p_sys->i_length = -1;
216 p_sys->b_preparsing_done = false;
218 stream_Control( p_demux->s, ACCESS_GET_PTS_DELAY, & p_sys->i_access_delay );
220 /* Set exported functions */
221 p_demux->pf_demux = Demux;
222 p_demux->pf_control = Control;
224 /* Initialize the Ogg physical bitstream parser */
225 ogg_sync_init( &p_sys->oy );
228 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
231 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
237 /*****************************************************************************
238 * Close: frees unused data
239 *****************************************************************************/
240 static void Close( vlc_object_t *p_this )
242 demux_t *p_demux = (demux_t *)p_this;
243 demux_sys_t *p_sys = p_demux->p_sys ;
245 /* Cleanup the bitstream parser */
246 ogg_sync_clear( &p_sys->oy );
248 Ogg_EndOfStream( p_demux );
250 if( p_sys->p_old_stream )
251 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
256 /*****************************************************************************
257 * Demux: reads and demuxes data packets
258 *****************************************************************************
259 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
260 *****************************************************************************/
261 static int Demux( demux_t * p_demux )
263 demux_sys_t *p_sys = p_demux->p_sys;
264 ogg_packet oggpacket;
266 bool b_skipping = false;
269 int i_active_streams = p_sys->i_streams;
270 for ( int i=0; i < p_sys->i_streams; i++ )
272 if ( p_sys->pp_stream[i]->b_finished )
276 if ( i_active_streams == 0 )
278 if ( p_sys->i_streams ) /* All finished */
280 msg_Dbg( p_demux, "end of a group of logical streams" );
281 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
282 * only 1 ES is supported (common case for ogg web radio) */
283 if( p_sys->i_streams == 1 )
285 p_sys->p_old_stream = p_sys->pp_stream[0];
286 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
288 Ogg_EndOfStream( p_demux );
289 p_sys->b_chained_boundary = true;
292 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
295 msg_Dbg( p_demux, "beginning of a group of logical streams" );
297 if ( !p_sys->b_chained_boundary )
299 /* Find the real duration */
300 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
302 Oggseek_ProbeEnd( p_demux );
306 p_sys->b_chained_boundary = false;
310 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
312 Ogg_CreateES( p_demux );
313 p_sys->b_es_created = true;
317 * The first data page of a physical stream is stored in the relevant logical stream
318 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
319 * stream it belongs to if we haven't processed this first page yet. If we do, we
320 * will only process that first page whenever we find the second page for this stream.
321 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
322 * the second page will arrive real quick, this is not fine for Kate, whose second
323 * data page will typically arrive much later.
324 * This means it is now possible to seek right at the start of a stream where the last
325 * logical stream is Kate, without having to wait for the second data page to unblock
326 * the first one, which is the one that triggers the 'no more headers to backup' code.
327 * And, as we all know, seeking without having backed up all headers is bad, since the
328 * codec will fail to initialize if it's missing its headers.
330 if( !p_sys->b_page_waiting)
333 * Demux an ogg page from the stream
335 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
337 /* Test for End of Stream */
338 if( ogg_page_eos( &p_sys->current_page ) )
340 /* If we delayed restarting encoders/SET_ES_FMT for more
341 * skeleton provided configuration */
342 if ( p_sys->p_skelstream )
344 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
346 msg_Dbg( p_demux, "End of Skeleton" );
347 p_sys->b_preparsing_done = true;
348 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
350 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
351 Ogg_ApplySkeleton( p_stream );
356 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
358 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
360 p_sys->pp_stream[i_stream]->b_finished = true;
368 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
370 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
373 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
375 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
377 /* if we've just pulled page, look for the right logical stream */
378 if( !p_sys->b_page_waiting )
380 if( p_sys->i_streams == 1 &&
381 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
383 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
384 Ogg_ResetStream( p_stream );
385 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
388 /* Does fail if serialno differs */
389 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
395 /* clear the finished flag if pages after eos (ex: after a seek) */
396 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
397 p_stream->b_finished = false;
400 if ( p_stream->fmt.i_cat == VIDEO_ES )
401 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
402 ogg_page_pageno( &p_sys->current_page ),
403 ogg_page_granulepos( &p_sys->current_page ),
404 ogg_page_packets( &p_sys->current_page ),
405 ogg_page_continued(&p_sys->current_page),
406 p_sys->current_page.body_len )
409 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
412 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
413 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
414 p_stream->fmt.i_cat == VIDEO_ES )
416 assert( p_stream->p_prepcr_blocks == NULL );
417 p_stream->i_prepcr_blocks = 0;
418 p_stream->p_prepcr_blocks = malloc( sizeof(block_t *) * ogg_page_packets( &p_sys->current_page ) );
422 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
424 /* Read info from any secondary header packets, if there are any */
425 if( p_stream->i_secondary_header_packets > 0 )
427 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
428 oggpacket.bytes >= 7 &&
429 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
431 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
432 p_stream->i_secondary_header_packets = 0;
434 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
435 oggpacket.bytes >= 7 &&
436 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
438 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
439 p_stream->i_secondary_header_packets = 0;
441 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
443 p_stream->i_secondary_header_packets = 0;
446 /* update start of data pointer */
447 p_stream->i_data_start = stream_Tell( p_demux->s );
450 /* If any streams have i_skip_frames, only decode (pre-roll)
451 * for those streams, but don't skip headers */
452 if ( b_skipping && p_stream->i_skip_frames == 0
453 && p_stream->i_secondary_header_packets ) continue;
455 if( p_stream->b_reinit )
457 p_stream->b_reinit = false;
458 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
460 p_stream->i_skip_frames = p_stream->i_pre_skip;
464 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
468 if ( p_stream->p_prepcr_blocks )
470 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
471 p_stream->i_previous_pcr = pagestamp;
472 #ifdef HAVE_LIBVORBIS
473 int i_prev_blocksize = 0;
476 for( int i=0; i<p_stream->i_prepcr_blocks; i++ )
478 block_t *p_block = p_stream->p_prepcr_blocks[i];
479 ogg_packet dumb_packet;
480 dumb_packet.bytes = p_block->i_buffer;
481 dumb_packet.packet = p_block->p_buffer;
484 switch( p_stream->fmt.i_codec )
487 i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
488 p_block->i_nb_samples = i_duration;
490 #ifdef HAVE_LIBVORBIS
491 case VLC_CODEC_VORBIS:
493 long i_blocksize = vorbis_packet_blocksize(
494 p_stream->special.vorbis.p_info, &dumb_packet );
495 if ( i_prev_blocksize )
496 i_duration = ( i_blocksize + i_prev_blocksize ) / 4;
498 i_duration = i_blocksize / 2;
499 i_prev_blocksize = i_blocksize;
500 p_block->i_nb_samples = i_duration;
507 bool b_fixed = false;
508 for( int i=p_stream->i_prepcr_blocks - 1; i>=0; i-- )
510 block_t *p_block = p_stream->p_prepcr_blocks[i];
511 switch( p_stream->fmt.i_codec )
514 case VLC_CODEC_VORBIS:
515 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
518 p_block->i_pts = VLC_TS_INVALID;
519 p_block->i_flags |= BLOCK_FLAG_PREROLL;
522 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
526 if ( p_stream->fmt.i_cat == VIDEO_ES )
528 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
529 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
537 if ( pagestamp < 0 ) pagestamp = 0;
538 p_stream->i_pcr = VLC_TS_0 + pagestamp;
539 p_stream->i_pcr += p_sys->i_nzpcr_offset;
540 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
543 FREENULL( p_stream->p_prepcr_blocks );
544 p_stream->i_prepcr_blocks = 0;
546 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
550 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
551 ogg_page_granulepos( &p_sys->current_page ), false );
552 if ( i_pagestamp > -1 )
554 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
555 p_stream->i_pcr += p_sys->i_nzpcr_offset;
558 if( !p_sys->b_page_waiting )
562 /* if a page was waiting, it's now processed */
563 p_sys->b_page_waiting = false;
565 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
566 p_sys->b_preparsing_done = false;
568 p_sys->b_preparsing_done = true;
570 /* We will consider the lowest PCR among tracks, because the audio core badly
571 * handles PCR rewind (mute)
573 mtime_t i_pcr_candidate = VLC_TS_INVALID;
574 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
576 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
578 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
580 /* We have 1 or more streams needing more than 1 page for preparsing */
581 p_sys->b_preparsing_done = false;
584 if( p_stream->fmt.i_cat == SPU_ES )
586 if( p_stream->i_pcr < VLC_TS_0 )
588 if ( p_stream->b_finished || p_stream->b_initializing )
590 if ( p_stream->p_preparse_block )
592 if( i_pcr_candidate < VLC_TS_0
593 || p_stream->i_pcr <= i_pcr_candidate )
595 i_pcr_candidate = p_stream->i_pcr;
599 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
601 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
603 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
604 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
606 p_sys->i_pcr_jitter = i_pcr_jitter;
607 if ( p_sys->i_access_delay < i_pcr_jitter )
608 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
609 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
613 if( ! b_skipping && p_sys->b_preparsing_done )
615 p_sys->i_pcr = i_pcr_candidate;
616 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
623 static void Ogg_ResetStream( logical_stream_t *p_stream )
625 #ifdef HAVE_LIBVORBIS
626 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
628 p_stream->special.vorbis.i_prev_blocksize = 0;
631 /* we'll trash all the data until we find the next pcr */
632 p_stream->b_reinit = true;
633 p_stream->i_pcr = VLC_TS_UNKNOWN;
634 p_stream->i_previous_granulepos = -1;
635 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
636 ogg_stream_reset( &p_stream->os );
637 FREENULL( p_stream->p_prepcr_blocks );
638 p_stream->i_prepcr_blocks = 0;
641 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
643 for( int i = 0; i < p_sys->i_streams; i++ )
644 Ogg_ResetStream( p_sys->pp_stream[i] );
646 ogg_sync_reset( &p_sys->oy );
647 p_sys->i_pcr = VLC_TS_UNKNOWN;
650 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
652 demux_sys_t *p_sys = p_demux->p_sys;
653 logical_stream_t *p_stream = NULL;
654 for( int i=0; i<p_sys->i_streams; i++ )
656 logical_stream_t *p_candidate = p_sys->pp_stream[i];
657 if ( !p_candidate->p_es ) continue;
659 bool b_selected = false;
660 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
661 p_candidate->p_es, &b_selected );
662 if ( !b_selected ) continue;
664 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
666 p_stream = p_candidate;
667 continue; /* Try to find video anyway */
670 if ( p_candidate->fmt.i_cat == VIDEO_ES )
672 p_stream = p_candidate;
679 /*****************************************************************************
681 *****************************************************************************/
682 static int Control( demux_t *p_demux, int i_query, va_list args )
684 demux_sys_t *p_sys = p_demux->p_sys;
693 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
695 vlc_meta_Merge( p_meta, p_sys->p_meta );
698 case DEMUX_HAS_UNSUPPORTED_META:
699 pb_bool = (bool*)va_arg( args, bool* );
704 pi64 = (int64_t*)va_arg( args, int64_t * );
705 *pi64 = p_sys->i_pcr;
709 i64 = (int64_t)va_arg( args, int64_t );
710 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
713 msg_Err( p_demux, "No selected seekable stream found" );
716 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
717 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
719 Ogg_ResetStreamsHelper( p_sys );
720 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
727 case DEMUX_GET_ATTACHMENTS:
729 input_attachment_t ***ppp_attach =
730 (input_attachment_t***)va_arg( args, input_attachment_t*** );
731 int *pi_int = (int*)va_arg( args, int * );
733 if( p_sys->i_attachments <= 0 )
736 *pi_int = p_sys->i_attachments;
737 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
738 for( int i = 0; i < p_sys->i_attachments; i++ )
739 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
743 case DEMUX_GET_POSITION:
744 pf = (double*)va_arg( args, double * );
745 if( p_sys->i_length > 0 )
747 *pf = (double) p_sys->i_pcr /
748 (double) ( p_sys->i_length * (mtime_t)1000000 );
750 else if( stream_Size( p_demux->s ) > 0 )
752 i64 = stream_Tell( p_demux->s );
753 *pf = (double) i64 / stream_Size( p_demux->s );
758 case DEMUX_SET_POSITION:
759 /* forbid seeking if we haven't initialized all logical bitstreams yet;
760 if we allowed, some headers would not get backed up and decoder init
761 would fail, making that logical stream unusable */
762 for ( int i=0; i< p_sys->i_streams; i++ )
764 if ( p_sys->pp_stream[i]->b_initializing )
768 p_stream = Ogg_GetSelectedStream( p_demux );
771 msg_Err( p_demux, "No selected seekable stream found" );
775 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
777 f = (double)va_arg( args, double );
778 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
780 Ogg_ResetStreamsHelper( p_sys );
781 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
785 assert( p_sys->i_length > 0 );
786 i64 = CLOCK_FREQ * p_sys->i_length * f;
787 Ogg_ResetStreamsHelper( p_sys );
788 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
790 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
797 case DEMUX_GET_LENGTH:
798 if ( p_sys->i_length < 0 )
799 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
801 pi64 = (int64_t*)va_arg( args, int64_t * );
802 *pi64 = p_sys->i_length * 1000000;
805 case DEMUX_GET_TITLE_INFO:
807 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
808 int *pi_int = (int*)va_arg( args, int* );
809 int *pi_title_offset = (int*)va_arg( args, int* );
810 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
812 if( p_sys->i_seekpoints > 0 )
815 *ppp_title = malloc( sizeof( input_title_t* ) );
816 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
817 for( int i = 0; i < p_sys->i_seekpoints; i++ )
819 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
820 if ( likely( p_seekpoint_copy ) )
821 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
823 *pi_title_offset = 0;
824 *pi_seekpoint_offset = 0;
828 case DEMUX_SET_TITLE:
830 const int i_title = (int)va_arg( args, int );
835 case DEMUX_SET_SEEKPOINT:
837 const int i_seekpoint = (int)va_arg( args, int );
838 if( i_seekpoint > p_sys->i_seekpoints )
841 for ( int i=0; i< p_sys->i_streams; i++ )
843 if ( p_sys->pp_stream[i]->b_initializing )
847 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
849 p_stream = Ogg_GetSelectedStream( p_demux );
852 msg_Err( p_demux, "No selected seekable stream found" );
856 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
857 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
859 Ogg_ResetStreamsHelper( p_sys );
860 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
862 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
863 p_demux->info.i_seekpoint = i_seekpoint;
871 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
876 /****************************************************************************
877 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
878 ****************************************************************************
879 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
880 * are at the end of stream.
881 ****************************************************************************/
882 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
884 demux_sys_t *p_ogg = p_demux->p_sys ;
888 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
890 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
892 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
896 ogg_sync_wrote( &p_ogg->oy, i_read );
902 /****************************************************************************
903 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
905 ****************************************************************************/
906 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
907 ogg_packet *p_oggpacket )
909 demux_sys_t *p_ogg = p_demux->p_sys;
910 p_stream->i_end_trim = 0;
912 /* Convert the granulepos into a pcr */
913 if ( p_oggpacket->granulepos == 0 )
915 /* We're in headers, and we haven't parsed 1st data packet yet */
916 // p_stream->i_pcr = VLC_TS_UNKNOWN;
918 else if( p_oggpacket->granulepos > 0 )
920 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
921 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
922 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
923 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
924 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
926 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
927 p_oggpacket->granulepos, true );
928 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
930 else if ( p_stream->i_previous_granulepos > 0 )
932 ogg_int64_t sample = p_stream->i_previous_granulepos;
934 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
936 int duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
939 ogg_int64_t end_sample = p_oggpacket->granulepos;
940 if( end_sample < ( sample + duration ) )
941 p_stream->i_end_trim = sample + duration - end_sample;
945 if (sample >= p_stream->i_pre_skip)
946 sample -= p_stream->i_pre_skip;
950 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
951 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
955 else if ( p_oggpacket->granulepos == -1 )
958 /* no granulepos available, try to interpolate the pcr.
959 * If we can't then don't touch the old value. */
960 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
962 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
964 #ifdef HAVE_LIBVORBIS
965 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
966 p_stream->special.vorbis.p_info &&
967 !p_stream->special.vorbis.b_invalid &&
968 p_stream->i_previous_granulepos > 0 )
970 long i_blocksize = vorbis_packet_blocksize(
971 p_stream->special.vorbis.p_info, p_oggpacket );
972 if ( p_stream->special.vorbis.i_prev_blocksize )
973 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
975 i_duration = i_blocksize / 2;
976 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
977 /* duration in samples per channel */
978 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
979 p_stream->i_pcr = p_stream->i_previous_granulepos *
980 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
981 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
984 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
985 p_stream->i_previous_granulepos > 0 &&
987 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
990 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
991 sample = p_stream->i_previous_granulepos;
992 if (sample >= p_stream->i_pre_skip)
993 sample -= p_stream->i_pre_skip;
997 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
998 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1000 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1002 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1003 p_stream->fmt.i_bitrate / 8 );
1007 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1010 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1013 demux_sys_t *p_ogg = p_demux->p_sys;
1014 if ( !p_stream->p_es || p_stream->p_prepcr_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1016 if ( !p_block ) return;
1017 if ( p_stream->p_prepcr_blocks )
1019 assert( p_stream->p_prepcr_blocks );
1020 p_stream->p_prepcr_blocks[p_stream->i_prepcr_blocks++] = p_block;
1022 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1023 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1024 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1028 /* Because ES creation is delayed for preparsing */
1029 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1030 if ( p_stream->p_preparse_block )
1032 block_t *temp = p_stream->p_preparse_block;
1035 if ( temp && i_firstpts < VLC_TS_0 )
1036 i_firstpts = temp->i_pts;
1038 block_t *tosend = temp;
1039 temp = temp->p_next;
1040 tosend->p_next = NULL;
1042 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1043 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1044 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1046 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1048 p_ogg->i_pcr = i_firstpts;
1049 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1052 p_stream->p_preparse_block = NULL;
1057 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1058 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1059 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1064 /****************************************************************************
1065 * Ogg_DecodePacket: Decode an Ogg packet.
1066 ****************************************************************************/
1067 static void Ogg_DecodePacket( demux_t *p_demux,
1068 logical_stream_t *p_stream,
1069 ogg_packet *p_oggpacket )
1073 int i_header_len = 0;
1075 if( p_oggpacket->bytes >= 7 &&
1076 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1078 /* it's an Annodex packet -- skip it (do nothing) */
1081 else if( p_oggpacket->bytes >= 7 &&
1082 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1084 /* it's an AnxData packet -- skip it (do nothing) */
1087 else if( p_oggpacket->bytes >= 8 &&
1088 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1090 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1093 else if( p_oggpacket->bytes >= 6 &&
1094 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1096 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1099 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1100 p_oggpacket->bytes >= 7 &&
1101 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1103 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1107 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1108 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1110 /* Check the ES is selected */
1111 if ( !p_stream->p_es )
1114 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1115 p_stream->p_es, &b_selected );
1117 if( p_stream->b_force_backup )
1120 p_stream->i_packets_backup++;
1121 switch( p_stream->fmt.i_codec )
1123 case VLC_CODEC_VORBIS:
1124 #ifdef HAVE_LIBVORBIS
1125 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1128 case VLC_CODEC_THEORA:
1129 if( p_stream->i_packets_backup == 3 )
1130 p_stream->b_force_backup = false;
1134 case VLC_CODEC_SPEEX:
1135 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1136 p_stream->b_force_backup = false;
1140 case VLC_CODEC_OPUS:
1141 if( p_stream->i_packets_backup == 2 )
1142 p_stream->b_force_backup = false;
1146 case VLC_CODEC_FLAC:
1147 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1149 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1150 p_stream->b_force_backup = false;
1152 else if( p_stream->fmt.audio.i_rate )
1154 p_stream->b_force_backup = false;
1155 if( p_oggpacket->bytes >= 9 )
1157 p_oggpacket->packet += 9;
1158 p_oggpacket->bytes -= 9;
1164 case VLC_CODEC_KATE:
1165 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1166 p_stream->b_force_backup = false;
1171 p_stream->b_force_backup = false;
1176 /* Backup the ogg packet (likely an header packet) */
1179 void *p_org = p_stream->p_headers;
1180 p_stream->i_headers += p_oggpacket->bytes;
1181 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1182 if( p_stream->p_headers )
1184 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1185 p_oggpacket->packet, p_oggpacket->bytes );
1189 #warning Memory leak
1190 p_stream->i_headers = 0;
1191 p_stream->p_headers = NULL;
1195 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1196 p_oggpacket->bytes, p_oggpacket->packet ) )
1198 p_stream->i_headers = 0;
1199 p_stream->p_headers = NULL;
1201 if( p_stream->i_headers > 0 )
1203 if( !p_stream->b_force_backup )
1205 /* Last header received, commit changes */
1206 free( p_stream->fmt.p_extra );
1208 p_stream->fmt.i_extra = p_stream->i_headers;
1209 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1210 if( p_stream->fmt.p_extra )
1211 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1212 p_stream->i_headers );
1214 p_stream->fmt.i_extra = 0;
1216 if( p_stream->i_headers > 0 )
1217 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1218 p_stream->p_headers, p_stream->i_headers );
1220 /* we're not at BOS anymore for this logical stream */
1221 p_stream->b_initializing = false;
1225 b_selected = false; /* Discard the header packet */
1229 p_stream->b_initializing = false;
1232 /* Convert the granulepos into the next pcr */
1233 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1237 /* This stream isn't currently selected so we don't need to decode it,
1238 * but we did need to store its pcr as it might be selected later on */
1242 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1243 p_block->i_pts = p_stream->i_pcr;
1245 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1246 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1248 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1249 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1251 /* may need to preroll after a seek or in case of preskip */
1252 if ( p_stream->i_skip_frames > 0 )
1254 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1256 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1258 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1259 p_stream->i_skip_frames -= p_block->i_nb_samples;
1260 p_block->i_nb_samples = 0;
1264 p_block->i_nb_samples -= p_stream->i_skip_frames;
1265 p_stream->i_skip_frames = 0;
1270 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1271 p_stream->i_skip_frames--;
1275 /* Conditional block fixes */
1276 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1277 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1279 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1281 else if( p_stream->fmt.i_cat == AUDIO_ES )
1283 /* Blatant abuse of the i_length field. */
1284 p_block->i_length = p_stream->i_end_trim;
1286 else if( p_stream->fmt.i_cat == SPU_ES )
1288 p_block->i_length = 0;
1290 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1292 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1293 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1294 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1295 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1296 /* granulepos for dirac is possibly broken, this value should be ignored */
1297 if( 0 >= p_oggpacket->granulepos )
1299 p_block->i_pts = VLC_TS_INVALID;
1300 p_block->i_dts = p_stream->i_pcr;
1304 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1305 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1306 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1307 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1308 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1309 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1310 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1311 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1312 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1313 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1315 if( p_oggpacket->bytes <= 0 )
1317 msg_Dbg( p_demux, "discarding 0 sized packet" );
1318 block_Release( p_block );
1321 /* We remove the header from the packet */
1322 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1323 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1325 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1327 /* But with subtitles we need to retrieve the duration first */
1328 int i, lenbytes = 0;
1330 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1332 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1334 lenbytes = lenbytes << 8;
1335 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1338 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1339 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1340 p_oggpacket->packet[i_header_len + 1] != 0 &&
1341 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1342 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1344 p_block->i_length = (mtime_t)lenbytes * 1000;
1349 if( p_block->i_buffer >= (unsigned int)i_header_len )
1350 p_block->i_buffer -= i_header_len;
1352 p_block->i_buffer = 0;
1356 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1358 /* FIXME: the biggest hack I've ever done */
1359 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1360 p_block->i_pts, p_block->i_dts );
1364 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1365 p_oggpacket->bytes - i_header_len );
1367 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1370 /* Re-implemented to avoid linking against libopus from the demuxer. */
1371 static int Ogg_OpusDataDuration( logical_stream_t *p_stream,
1372 unsigned char *data, long i_datalen )
1374 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1381 return VLC_EGENERIC;
1394 return VLC_EGENERIC;
1395 nframes = data[1]&0x3F;
1398 i_rate = (int)p_stream->fmt.audio.i_rate;
1400 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1401 else if( ( toc&0x60 ) == 0x60 )
1402 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1404 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1405 nsamples = nframes*frame_size;
1406 if( nsamples*25 > i_rate*3 )
1407 return VLC_EGENERIC;
1411 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1412 ogg_packet *p_oggpacket )
1414 return Ogg_OpusDataDuration( p_stream, p_oggpacket->packet, p_oggpacket->bytes );
1417 /****************************************************************************
1418 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1419 * stream and fill p_ogg.
1420 *****************************************************************************
1421 * The initial page of a logical stream is marked as a 'bos' page.
1422 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1423 * together and all of the initial pages must appear before any data pages.
1425 * On success this function returns VLC_SUCCESS.
1426 ****************************************************************************/
1427 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1429 demux_sys_t *p_ogg = p_demux->p_sys ;
1430 ogg_packet oggpacket;
1433 p_ogg->i_total_length = stream_Size ( p_demux->s );
1434 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1437 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1440 if( ogg_page_bos( &p_ogg->current_page ) )
1443 /* All is wonderful in our fine fine little world.
1444 * We found the beginning of our first logical stream. */
1445 while( ogg_page_bos( &p_ogg->current_page ) )
1447 logical_stream_t *p_stream;
1449 p_stream = malloc( sizeof(logical_stream_t) );
1450 if( unlikely( !p_stream ) )
1453 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1455 memset( p_stream, 0, sizeof(logical_stream_t) );
1457 es_format_Init( &p_stream->fmt, 0, 0 );
1458 es_format_Init( &p_stream->fmt_old, 0, 0 );
1459 p_stream->b_initializing = true;
1461 /* Setup the logical stream */
1462 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1463 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1465 /* Extract the initial header from the first page and verify
1466 * the codec type of this Ogg bitstream */
1467 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1469 /* error. stream version mismatch perhaps */
1470 msg_Err( p_demux, "error reading first page of "
1471 "Ogg bitstream data" );
1472 return VLC_EGENERIC;
1475 /* FIXME: check return value */
1476 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1478 /* Check for Vorbis header */
1479 if( oggpacket.bytes >= 7 &&
1480 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1482 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1483 msg_Dbg( p_demux, "found vorbis header" );
1486 msg_Dbg( p_demux, "found invalid vorbis header" );
1487 Ogg_LogicalStreamDelete( p_demux, p_stream );
1491 /* Check for Speex header */
1492 else if( oggpacket.bytes >= 5 &&
1493 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1495 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1496 msg_Dbg( p_demux, "found speex header, channels: %i, "
1497 "rate: %i, bitrate: %i",
1498 p_stream->fmt.audio.i_channels,
1499 (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
1502 msg_Dbg( p_demux, "found invalid Speex header" );
1503 Ogg_LogicalStreamDelete( p_demux, p_stream );
1507 /* Check for Opus header */
1508 else if( oggpacket.bytes >= 8 &&
1509 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1511 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1512 msg_Dbg( p_demux, "found opus header, channels: %i, "
1514 p_stream->fmt.audio.i_channels,
1515 (int)p_stream->i_pre_skip);
1516 p_stream->i_skip_frames = p_stream->i_pre_skip;
1518 /* Check for Flac header (< version 1.1.1) */
1519 else if( oggpacket.bytes >= 4 &&
1520 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1522 msg_Dbg( p_demux, "found FLAC header" );
1524 /* Grrrr!!!! Did they really have to put all the
1525 * important info in the second header packet!!!
1526 * (STREAMINFO metadata is in the following packet) */
1527 p_stream->b_force_backup = true;
1528 p_stream->fmt.i_cat = AUDIO_ES;
1529 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1531 /* Check for Flac header (>= version 1.1.1) */
1532 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1533 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1534 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1536 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1537 oggpacket.packet[8];
1538 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1539 "(%i header packets)",
1540 oggpacket.packet[5], oggpacket.packet[6],
1543 p_stream->b_force_backup = true;
1545 p_stream->fmt.i_cat = AUDIO_ES;
1546 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1547 oggpacket.packet += 13; oggpacket.bytes -= 13;
1548 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1550 msg_Dbg( p_demux, "found invalid Flac header" );
1551 Ogg_LogicalStreamDelete( p_demux, p_stream );
1555 /* Check for Theora header */
1556 else if( oggpacket.bytes >= 7 &&
1557 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1559 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1561 "found theora header, bitrate: %i, rate: %f",
1562 p_stream->fmt.i_bitrate, p_stream->f_rate );
1565 msg_Dbg( p_demux, "found invalid Theora header" );
1566 Ogg_LogicalStreamDelete( p_demux, p_stream );
1570 /* Check for Dirac header */
1571 else if( ( oggpacket.bytes >= 5 &&
1572 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1573 ( oggpacket.bytes >= 9 &&
1574 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1576 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1577 msg_Dbg( p_demux, "found dirac header" );
1580 msg_Warn( p_demux, "found dirac header isn't decodable" );
1581 Ogg_LogicalStreamDelete( p_demux, p_stream );
1585 /* Check for Tarkin header */
1586 else if( oggpacket.bytes >= 7 &&
1587 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1591 msg_Dbg( p_demux, "found tarkin header" );
1592 p_stream->fmt.i_cat = VIDEO_ES;
1593 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1595 /* Cheat and get additionnal info ;) */
1596 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1597 oggpack_adv( &opb, 88 );
1598 oggpack_adv( &opb, 104 );
1599 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1600 p_stream->f_rate = 2; /* FIXME */
1602 "found tarkin header, bitrate: %i, rate: %f",
1603 p_stream->fmt.i_bitrate, p_stream->f_rate );
1605 /* Check for VP8 header */
1606 else if( oggpacket.bytes >= 26 &&
1607 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1609 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1610 msg_Dbg( p_demux, "found VP8 header "
1611 "fps: %f, width:%i; height:%i",
1613 p_stream->fmt.video.i_width,
1614 p_stream->fmt.video.i_height );
1617 msg_Dbg( p_demux, "invalid VP8 header found");
1618 Ogg_LogicalStreamDelete( p_demux, p_stream );
1622 /* Check for Annodex header */
1623 else if( oggpacket.bytes >= 7 &&
1624 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1626 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1627 /* kill annodex track */
1631 /* Check for Annodex header */
1632 else if( oggpacket.bytes >= 7 &&
1633 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1635 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1637 /* Check for Kate header */
1638 else if( oggpacket.bytes >= 8 &&
1639 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1641 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1642 msg_Dbg( p_demux, "found kate header" );
1645 msg_Dbg( p_demux, "invalid kate header found");
1646 Ogg_LogicalStreamDelete( p_demux, p_stream );
1650 /* Check for OggDS */
1651 else if( oggpacket.bytes >= 142 &&
1652 !memcmp( &oggpacket.packet[1],
1653 "Direct Show Samples embedded in Ogg", 35 ))
1655 /* Old header type */
1656 p_stream->b_oggds = true;
1657 /* Check for video header (old format) */
1658 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1659 oggpacket.bytes >= 184 )
1661 p_stream->fmt.i_cat = VIDEO_ES;
1662 p_stream->fmt.i_codec =
1663 VLC_FOURCC( oggpacket.packet[68],
1664 oggpacket.packet[69],
1665 oggpacket.packet[70],
1666 oggpacket.packet[71] );
1667 msg_Dbg( p_demux, "found video header of type: %.4s",
1668 (char *)&p_stream->fmt.i_codec );
1670 p_stream->fmt.video.i_frame_rate = 10000000;
1671 p_stream->fmt.video.i_frame_rate_base =
1672 GetQWLE((oggpacket.packet+164));
1673 p_stream->fmt.video.i_frame_rate_base =
1674 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1675 p_stream->f_rate = 10000000.0 /
1676 p_stream->fmt.video.i_frame_rate_base;
1677 p_stream->fmt.video.i_bits_per_pixel =
1678 GetWLE((oggpacket.packet+182));
1679 if( !p_stream->fmt.video.i_bits_per_pixel )
1681 p_stream->fmt.video.i_bits_per_pixel = 24;
1682 p_stream->fmt.video.i_width =
1683 GetDWLE((oggpacket.packet+176));
1684 p_stream->fmt.video.i_height =
1685 GetDWLE((oggpacket.packet+180));
1688 "fps: %f, width:%i; height:%i, bitcount:%i",
1690 p_stream->fmt.video.i_width,
1691 p_stream->fmt.video.i_height,
1692 p_stream->fmt.video.i_bits_per_pixel);
1695 /* Check for audio header (old format) */
1696 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1699 unsigned int i_format_tag;
1701 p_stream->fmt.i_cat = AUDIO_ES;
1703 i_extra_size = GetWLE((oggpacket.packet+140));
1704 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1706 p_stream->fmt.i_extra = i_extra_size;
1707 p_stream->fmt.p_extra = malloc( i_extra_size );
1708 if( p_stream->fmt.p_extra )
1709 memcpy( p_stream->fmt.p_extra,
1710 oggpacket.packet + 142, i_extra_size );
1712 p_stream->fmt.i_extra = 0;
1715 i_format_tag = GetWLE((oggpacket.packet+124));
1716 p_stream->fmt.audio.i_channels =
1717 GetWLE((oggpacket.packet+126));
1718 fill_channels_info(&p_stream->fmt.audio);
1719 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1720 GetDWLE((oggpacket.packet+128));
1721 p_stream->fmt.i_bitrate =
1722 GetDWLE((oggpacket.packet+132)) * 8;
1723 p_stream->fmt.audio.i_blockalign =
1724 GetWLE((oggpacket.packet+136));
1725 p_stream->fmt.audio.i_bitspersample =
1726 GetWLE((oggpacket.packet+138));
1728 wf_tag_to_fourcc( i_format_tag,
1729 &p_stream->fmt.i_codec, 0 );
1731 if( p_stream->fmt.i_codec ==
1732 VLC_FOURCC('u','n','d','f') )
1734 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1735 ( i_format_tag >> 8 ) & 0xff,
1736 i_format_tag & 0xff );
1739 msg_Dbg( p_demux, "found audio header of type: %.4s",
1740 (char *)&p_stream->fmt.i_codec );
1741 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1742 "%dbits/sample %dkb/s",
1744 p_stream->fmt.audio.i_channels,
1745 p_stream->fmt.audio.i_rate,
1746 p_stream->fmt.audio.i_bitspersample,
1747 p_stream->fmt.i_bitrate / 1024 );
1748 if ( p_stream->f_rate == 0 )
1750 msg_Dbg( p_demux, "invalid oggds audio header" );
1751 Ogg_LogicalStreamDelete( p_demux, p_stream );
1757 msg_Dbg( p_demux, "stream %d has an old header "
1758 "but is of an unknown type", p_ogg->i_streams-1 );
1763 /* Check for OggDS */
1764 else if( oggpacket.bytes >= 44+1 &&
1765 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1767 stream_header_t tmp;
1768 stream_header_t *st = &tmp;
1770 p_stream->b_oggds = true;
1772 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1773 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1774 st->size = GetDWLE( &oggpacket.packet[1+12] );
1775 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1776 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1777 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1778 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1779 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1781 /* Check for video header (new format) */
1782 if( !strncmp( st->streamtype, "video", 5 ) &&
1783 oggpacket.bytes >= 52+1 )
1785 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1786 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1788 p_stream->fmt.i_cat = VIDEO_ES;
1790 /* We need to get rid of the header packet */
1791 ogg_stream_packetout( &p_stream->os, &oggpacket );
1793 p_stream->fmt.i_codec =
1794 VLC_FOURCC( st->subtype[0], st->subtype[1],
1795 st->subtype[2], st->subtype[3] );
1796 msg_Dbg( p_demux, "found video header of type: %.4s",
1797 (char *)&p_stream->fmt.i_codec );
1799 p_stream->fmt.video.i_frame_rate = 10000000;
1800 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1801 if( st->time_unit <= 0 )
1802 st->time_unit = 400000;
1803 p_stream->f_rate = 10000000.0 / st->time_unit;
1804 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1805 p_stream->fmt.video.i_width = st->sh.video.width;
1806 p_stream->fmt.video.i_height = st->sh.video.height;
1809 "fps: %f, width:%i; height:%i, bitcount:%i",
1811 p_stream->fmt.video.i_width,
1812 p_stream->fmt.video.i_height,
1813 p_stream->fmt.video.i_bits_per_pixel );
1815 /* Check for audio header (new format) */
1816 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1817 oggpacket.bytes >= 56+1 )
1823 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1824 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1825 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1827 p_stream->fmt.i_cat = AUDIO_ES;
1829 /* We need to get rid of the header packet */
1830 ogg_stream_packetout( &p_stream->os, &oggpacket );
1832 i_extra_size = st->size - 56;
1834 if( i_extra_size > 0 &&
1835 i_extra_size < oggpacket.bytes - 1 - 56 )
1837 p_stream->fmt.i_extra = i_extra_size;
1838 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1839 if( p_stream->fmt.p_extra )
1840 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1841 p_stream->fmt.i_extra );
1843 p_stream->fmt.i_extra = 0;
1846 memcpy( p_buffer, st->subtype, 4 );
1848 i_format_tag = strtol(p_buffer,NULL,16);
1849 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1850 fill_channels_info(&p_stream->fmt.audio);
1851 if( st->time_unit <= 0 )
1852 st->time_unit = 10000000;
1853 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1854 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1855 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1856 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1858 wf_tag_to_fourcc( i_format_tag,
1859 &p_stream->fmt.i_codec, 0 );
1861 if( p_stream->fmt.i_codec ==
1862 VLC_FOURCC('u','n','d','f') )
1864 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1865 ( i_format_tag >> 8 ) & 0xff,
1866 i_format_tag & 0xff );
1869 msg_Dbg( p_demux, "found audio header of type: %.4s",
1870 (char *)&p_stream->fmt.i_codec );
1871 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1872 "%dbits/sample %dkb/s",
1874 p_stream->fmt.audio.i_channels,
1875 p_stream->fmt.audio.i_rate,
1876 p_stream->fmt.audio.i_bitspersample,
1877 p_stream->fmt.i_bitrate / 1024 );
1878 if ( p_stream->f_rate == 0 )
1880 msg_Dbg( p_demux, "invalid oggds audio header" );
1881 Ogg_LogicalStreamDelete( p_demux, p_stream );
1885 /* Check for text (subtitles) header */
1886 else if( !strncmp(st->streamtype, "text", 4) )
1888 /* We need to get rid of the header packet */
1889 ogg_stream_packetout( &p_stream->os, &oggpacket );
1891 msg_Dbg( p_demux, "found text subtitle header" );
1892 p_stream->fmt.i_cat = SPU_ES;
1893 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1894 p_stream->f_rate = 1000; /* granulepos is in millisec */
1898 msg_Dbg( p_demux, "stream %d has a header marker "
1899 "but is of an unknown type", p_ogg->i_streams-1 );
1904 else if( oggpacket.bytes >= 8 &&
1905 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1909 msg_Dbg( p_demux, "stream %d is a skeleton",
1910 p_ogg->i_streams-1 );
1911 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1915 msg_Dbg( p_demux, "stream %d is of unknown type",
1916 p_ogg->i_streams-1 );
1921 /* we'll need to get all headers */
1922 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1924 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1925 return VLC_EGENERIC;
1928 /* This is the first data page, which means we are now finished
1929 * with the initial pages. We just need to store it in the relevant
1931 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1933 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1934 &p_ogg->current_page ) == 0 )
1936 p_ogg->b_page_waiting = true;
1945 return VLC_EGENERIC;
1948 /****************************************************************************
1949 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1950 ****************************************************************************/
1951 static void Ogg_CreateES( demux_t *p_demux )
1953 demux_sys_t *p_ogg = p_demux->p_sys;
1954 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1957 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1959 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1961 if ( p_stream->p_es == NULL && !p_stream->b_finished )
1963 /* Better be safe than sorry when possible with ogm */
1964 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1965 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1966 p_stream->fmt.b_packetized = false;
1968 /* Try first to reuse an old ES */
1970 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1971 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1973 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1975 p_stream->p_es = p_old_stream->p_es;
1976 p_stream->b_finished = false;
1977 p_stream->b_reinit = false;
1978 p_stream->b_initializing = false;
1979 p_stream->i_pre_skip = 0;
1980 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
1981 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1983 p_old_stream->p_es = NULL;
1984 p_old_stream = NULL;
1985 if ( b_resetdecoder )
1987 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
1988 p_stream->p_es, &p_stream->fmt );
1993 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1996 // TODO: something to do here ?
1997 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
1999 /* Set the CMML stream active */
2000 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2005 if( p_ogg->p_old_stream )
2007 if( p_ogg->p_old_stream->p_es )
2008 msg_Dbg( p_demux, "old stream not reused" );
2009 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2010 p_ogg->p_old_stream = NULL;
2014 /****************************************************************************
2015 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2016 * Elementary streams.
2017 ****************************************************************************/
2018 static int Ogg_BeginningOfStream( demux_t *p_demux )
2020 demux_sys_t *p_ogg = p_demux->p_sys ;
2023 /* Find the logical streams embedded in the physical stream and
2024 * initialize our p_ogg structure. */
2025 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2027 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2028 return VLC_EGENERIC;
2031 p_ogg->i_bitrate = 0;
2033 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2035 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2037 p_stream->p_es = NULL;
2039 /* initialise kframe index */
2042 if ( p_stream->fmt.i_bitrate == 0 &&
2043 ( p_stream->fmt.i_cat == VIDEO_ES ||
2044 p_stream->fmt.i_cat == AUDIO_ES ) )
2045 p_ogg->b_partial_bitrate = true;
2047 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2049 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2050 p_stream->i_previous_granulepos = -1;
2051 p_stream->b_reinit = false;
2054 /* get total frame count for video stream; we will need this for seeking */
2055 p_ogg->i_total_frames = 0;
2060 /****************************************************************************
2061 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2062 ****************************************************************************/
2063 static void Ogg_EndOfStream( demux_t *p_demux )
2065 demux_sys_t *p_ogg = p_demux->p_sys ;
2068 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2069 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2070 free( p_ogg->pp_stream );
2073 p_ogg->i_bitrate = 0;
2074 p_ogg->i_streams = 0;
2075 p_ogg->pp_stream = NULL;
2076 p_ogg->skeleton.major = 0;
2077 p_ogg->skeleton.minor = 0;
2078 p_ogg->b_preparsing_done = false;
2079 p_ogg->b_es_created = false;
2080 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2081 p_ogg->i_pcr - VLC_TS_0 : 0;
2085 vlc_meta_Delete( p_ogg->p_meta );
2086 p_ogg->p_meta = NULL;
2088 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2090 if ( p_ogg->pp_seekpoints[i] )
2091 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2093 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2094 p_ogg->i_seekpoints = 0;
2097 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2099 #ifdef HAVE_LIBVORBIS
2100 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2102 FREENULL( p_stream->special.vorbis.p_info );
2103 FREENULL( p_stream->special.vorbis.p_comment );
2104 p_stream->special.vorbis.b_invalid = false;
2107 VLC_UNUSED( p_stream );
2112 * This function delete and release all data associated to a logical_stream_t
2114 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2116 if( p_stream->p_es )
2117 es_out_Del( p_demux->out, p_stream->p_es );
2119 ogg_stream_clear( &p_stream->os );
2120 free( p_stream->p_headers );
2122 Ogg_CleanSpecificData( p_stream );
2124 es_format_Clean( &p_stream->fmt_old );
2125 es_format_Clean( &p_stream->fmt );
2127 if ( p_stream->idx != NULL)
2129 oggseek_index_entries_free( p_stream->idx );
2132 Ogg_FreeSkeleton( p_stream->p_skel );
2133 p_stream->p_skel = NULL;
2134 if ( p_demux->p_sys->p_skelstream == p_stream )
2135 p_demux->p_sys->p_skelstream = NULL;
2137 /* Shouldn't happen */
2138 if ( unlikely( p_stream->p_preparse_block ) )
2140 block_ChainRelease( p_stream->p_preparse_block );
2141 p_stream->p_preparse_block = NULL;
2143 free( p_stream->p_prepcr_blocks );
2148 * This function check if a we need to reset a decoder in case we are
2151 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2153 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2154 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2155 unsigned i_new_count;
2156 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2159 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2160 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2161 unsigned i_old_count;
2162 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2165 bool b_match = i_new_count == i_old_count;
2166 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2168 /* Ignore vorbis comment */
2171 if( pi_new_size[i] != pi_old_size[i] ||
2172 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2179 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2180 const es_format_t *p_old )
2182 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2183 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2184 unsigned i_new_count;
2185 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2187 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2188 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2189 unsigned i_old_count;
2190 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2192 bool b_match = false;
2193 if( i_new_count == i_old_count && i_new_count > 0 )
2195 static const unsigned char default_map[2] = { 0, 1 };
2196 unsigned char *p_old_head;
2197 unsigned char *p_new_head;
2198 const unsigned char *p_old_map;
2199 const unsigned char *p_new_map;
2200 int i_old_channel_count;
2201 int i_new_channel_count;
2202 int i_old_stream_count;
2203 int i_new_stream_count;
2204 int i_old_coupled_count;
2205 int i_new_coupled_count;
2206 p_old_head = (unsigned char *)pp_old_data[0];
2207 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2208 p_old_map = default_map;
2209 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2211 i_old_channel_count = p_old_head[9];
2212 switch( p_old_head[18] )
2215 i_old_stream_count = 1;
2216 i_old_coupled_count = i_old_channel_count - 1;
2219 if( pi_old_size[0] >= 21U + i_old_channel_count )
2221 i_old_stream_count = p_old_head[19];
2222 i_old_coupled_count = p_old_head[20];
2223 p_old_map = p_old_head + 21;
2228 p_new_head = (unsigned char *)pp_new_data[0];
2229 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2230 p_new_map = default_map;
2231 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2233 i_new_channel_count = p_new_head[9];
2234 switch( p_new_head[18] )
2237 i_new_stream_count = 1;
2238 i_new_coupled_count = i_new_channel_count - 1;
2241 if( pi_new_size[0] >= 21U + i_new_channel_count )
2243 i_new_stream_count = p_new_head[19];
2244 i_new_coupled_count = p_new_head[20];
2245 p_new_map = p_new_head+21;
2250 b_match = i_old_channel_count == i_new_channel_count &&
2251 i_old_stream_count == i_new_stream_count &&
2252 i_old_coupled_count == i_new_coupled_count &&
2253 memcmp(p_old_map, p_new_map,
2254 i_new_channel_count*sizeof(*p_new_map)) == 0;
2260 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2262 bool b_compatible = false;
2263 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2266 /* Only Vorbis and Opus are supported. */
2267 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2268 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2269 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2270 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2273 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2275 return !b_compatible;
2278 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2279 const void *p_headers, unsigned i_headers )
2281 demux_sys_t *p_ogg = p_demux->p_sys;
2282 int i_cover_score = 0;
2283 int i_cover_idx = 0;
2284 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2285 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2286 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2288 pf_replay_gain[i] = 0;
2289 pf_replay_peak[i] = 0;
2291 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2292 &p_ogg->i_attachments, &p_ogg->attachments,
2293 &i_cover_score, &i_cover_idx,
2294 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2295 &pf_replay_gain, &pf_replay_peak );
2296 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2299 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2300 p_ogg->attachments[i_cover_idx]->psz_name );
2301 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2304 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2306 if ( pf_replay_gain[i] != 0 )
2308 p_fmt->audio_replay_gain.pb_gain[i] = true;
2309 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2310 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2312 if ( pf_replay_peak[i] != 0 )
2314 p_fmt->audio_replay_gain.pb_peak[i] = true;
2315 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2316 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2320 if( p_ogg->i_seekpoints > 1 )
2322 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2326 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2327 const void *p_headers, unsigned i_headers, unsigned i_skip )
2329 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2330 void *pp_data[XIPH_MAX_HEADER_COUNT];
2333 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2335 /* TODO how to handle multiple comments properly ? */
2336 if( i_count >= 2 && pi_size[1] > i_skip )
2338 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2342 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2344 demux_sys_t *p_ogg = p_demux->p_sys;
2346 switch( p_fmt->i_codec )
2348 /* 3 headers with the 2° one being the comments */
2349 case VLC_CODEC_VORBIS:
2350 case VLC_CODEC_THEORA:
2351 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2353 case VLC_CODEC_OPUS:
2354 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2356 case VLC_CODEC_SPEEX:
2357 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2360 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2362 /* N headers with the 2° one being the comments */
2363 case VLC_CODEC_KATE:
2364 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2365 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2369 case VLC_CODEC_FLAC:
2370 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2374 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2375 case VLC_CODEC_DIRAC:
2380 p_demux->info.i_update |= INPUT_UPDATE_META;
2383 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2384 ogg_packet *p_oggpacket )
2387 unsigned int i_fps_numerator;
2388 unsigned int i_fps_denominator;
2389 int i_keyframe_frequency_force;
2395 p_stream->fmt.i_cat = VIDEO_ES;
2396 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2398 /* Signal that we want to keep a backup of the theora
2399 * stream headers. They will be used when switching between
2401 p_stream->b_force_backup = true;
2403 /* Cheat and get additionnal info ;) */
2404 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2405 bs_skip( &bitstream, 56 );
2407 i_major = bs_read( &bitstream, 8 ); /* major version num */
2408 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2409 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2411 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2412 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2413 bs_read( &bitstream, 24 ); /* frame width */
2414 bs_read( &bitstream, 24 ); /* frame height */
2415 bs_read( &bitstream, 8 ); /* x offset */
2416 bs_read( &bitstream, 8 ); /* y offset */
2418 i_fps_numerator = bs_read( &bitstream, 32 );
2419 i_fps_denominator = bs_read( &bitstream, 32 );
2420 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2421 bs_read( &bitstream, 24 ); /* aspect_numerator */
2422 bs_read( &bitstream, 24 ); /* aspect_denominator */
2424 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2425 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2427 bs_read( &bitstream, 8 ); /* colorspace */
2428 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2429 bs_read( &bitstream, 6 ); /* quality */
2431 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2433 /* granule_shift = i_log( frequency_force -1 ) */
2434 p_stream->i_granule_shift = 0;
2435 i_keyframe_frequency_force--;
2436 while( i_keyframe_frequency_force )
2438 p_stream->i_granule_shift++;
2439 i_keyframe_frequency_force >>= 1;
2442 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2443 p_stream->i_keyframe_offset = 0;
2444 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2445 if ( p_stream->f_rate == 0 ) return false;
2447 if ( i_version >= 3002001 )
2449 p_stream->i_keyframe_offset = 1;
2454 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2455 ogg_packet *p_oggpacket )
2459 p_stream->fmt.i_cat = AUDIO_ES;
2460 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2462 /* Signal that we want to keep a backup of the vorbis
2463 * stream headers. They will be used when switching between
2465 p_stream->b_force_backup = true;
2467 /* Cheat and get additionnal info ;) */
2468 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2469 oggpack_adv( &opb, 88 );
2470 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2471 fill_channels_info(&p_stream->fmt.audio);
2472 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2473 oggpack_read( &opb, 32 );
2474 oggpack_adv( &opb, 32 );
2475 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2476 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2477 if ( p_stream->f_rate == 0 ) return false;
2480 #ifdef HAVE_LIBVORBIS
2481 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2482 ogg_packet *p_oggpacket, int i_number )
2486 case VORBIS_HEADER_IDENTIFICATION:
2487 p_stream->special.vorbis.p_info = malloc( sizeof(vorbis_info) );
2488 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2489 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2491 FREENULL( p_stream->special.vorbis.p_info );
2492 FREENULL( p_stream->special.vorbis.p_comment );
2493 p_stream->special.vorbis.b_invalid = true;
2496 vorbis_info_init( p_stream->special.vorbis.p_info );
2497 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2500 case VORBIS_HEADER_COMMENT:
2501 case VORBIS_HEADER_SETUP:
2502 if ( p_stream->special.vorbis.p_info && ! p_stream->special.vorbis.b_invalid )
2504 p_stream->special.vorbis.b_invalid = ( 0 != vorbis_synthesis_headerin(
2505 p_stream->special.vorbis.p_info,
2506 p_stream->special.vorbis.p_comment, p_oggpacket ) );
2516 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2517 ogg_packet *p_oggpacket )
2521 p_stream->fmt.i_cat = AUDIO_ES;
2522 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2524 /* Signal that we want to keep a backup of the speex
2525 * stream headers. They will be used when switching between
2527 p_stream->b_force_backup = true;
2529 /* Cheat and get additionnal info ;) */
2530 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2531 oggpack_adv( &opb, 224 );
2532 oggpack_adv( &opb, 32 ); /* speex_version_id */
2533 oggpack_adv( &opb, 32 ); /* header_size */
2534 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2535 if ( p_stream->f_rate == 0 ) return false;
2536 oggpack_adv( &opb, 32 ); /* mode */
2537 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2538 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2539 fill_channels_info(&p_stream->fmt.audio);
2540 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2541 oggpack_adv( &opb, 32 ); /* frame_size */
2542 oggpack_adv( &opb, 32 ); /* vbr */
2543 oggpack_adv( &opb, 32 ); /* frames_per_packet */
2544 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2548 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2549 ogg_packet *p_oggpacket )
2553 p_stream->fmt.i_cat = AUDIO_ES;
2554 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2556 /* Signal that we want to keep a backup of the opus
2557 * stream headers. They will be used when switching between
2559 p_stream->b_force_backup = true;
2561 /* All OggOpus streams are timestamped at 48kHz and
2562 * can be played at 48kHz. */
2563 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2564 p_stream->fmt.i_bitrate = 0;
2566 /* Cheat and get additional info ;) */
2567 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2568 oggpack_adv( &opb, 64 );
2569 oggpack_adv( &opb, 8 ); /* version_id */
2570 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2571 fill_channels_info(&p_stream->fmt.audio);
2572 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2573 /* For Opus, trash the first 80 ms of decoded output as
2574 well, to avoid blowing out speakers if we get unlucky.
2575 Opus predicts content from prior frames, which can go
2576 badly if we seek right where the stream goes from very
2577 quiet to very loud. It will converge after a bit. */
2578 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2581 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2582 ogg_packet *p_oggpacket )
2584 /* Parse the STREAMINFO metadata */
2587 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2590 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2592 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2596 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2599 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2600 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2601 fill_channels_info(&p_stream->fmt.audio);
2603 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2604 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2605 if ( p_stream->f_rate == 0 ) return false;
2609 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2612 /* Fake this as the last metadata block */
2613 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2617 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2618 ogg_packet *p_oggpacket )
2626 p_stream->fmt.i_cat = SPU_ES;
2627 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2629 /* Signal that we want to keep a backup of the kate
2630 * stream headers. They will be used when switching between
2632 p_stream->b_force_backup = true;
2634 /* Cheat and get additionnal info ;) */
2635 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2636 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2637 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2638 oggpack_adv( &opb, 3*8 );
2639 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2640 oggpack_adv( &opb, 8*8 ); /* reserved */
2641 gnum = oggpack_read( &opb, 32 );
2642 gden = oggpack_read( &opb, 32 );
2643 gden = __MAX( gden, 1 );
2644 p_stream->f_rate = (double)gnum/gden;
2645 if ( p_stream->f_rate == 0 ) return false;
2647 p_stream->fmt.psz_language = malloc(16);
2648 if( p_stream->fmt.psz_language )
2650 for( n = 0; n < 16; n++ )
2651 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2652 p_stream->fmt.psz_language[15] = 0; /* just in case */
2656 for( n = 0; n < 16; n++ )
2657 oggpack_read(&opb,8);
2659 p_stream->fmt.psz_description = malloc(16);
2660 if( p_stream->fmt.psz_description )
2662 for( n = 0; n < 16; n++ )
2663 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2664 p_stream->fmt.psz_description[15] = 0; /* just in case */
2666 /* Now find a localized user readable description for this category */
2667 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2670 free( p_stream->fmt.psz_description );
2671 p_stream->fmt.psz_description = psz_desc;
2676 for( n = 0; n < 16; n++ )
2677 oggpack_read(&opb,8);
2683 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2684 ogg_packet *p_oggpacket )
2686 switch( p_oggpacket->packet[5] )
2690 /* Mapping version */
2691 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2693 p_stream->fmt.i_cat = VIDEO_ES;
2694 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2695 p_stream->i_granule_shift = 32;
2696 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2697 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2698 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2699 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2700 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2701 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2702 p_stream->fmt.video.i_frame_rate_base =
2703 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2704 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2705 if ( p_stream->f_rate == 0 ) return false;
2709 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2710 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2717 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2718 bool *b_force_backup, bool *b_packet_out )
2720 if( !strncmp(psz_value, "audio/x-wav", 11) )
2722 /* n.b. WAVs are unsupported right now */
2723 p_stream->fmt.i_cat = UNKNOWN_ES;
2724 free( p_stream->fmt.psz_description );
2725 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2727 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2728 !strncmp(psz_value, "audio/vorbis", 12) )
2730 p_stream->fmt.i_cat = AUDIO_ES;
2731 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2733 *b_force_backup = true;
2735 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2736 !strncmp(psz_value, "audio/speex", 11) )
2738 p_stream->fmt.i_cat = AUDIO_ES;
2739 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2741 *b_force_backup = true;
2743 else if( !strncmp(psz_value, "audio/flac", 10) )
2745 p_stream->fmt.i_cat = AUDIO_ES;
2746 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2748 *b_force_backup = true;
2750 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2751 !strncmp(psz_value, "video/theora", 12) )
2753 p_stream->fmt.i_cat = VIDEO_ES;
2754 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2756 *b_force_backup = true;
2758 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2760 p_stream->fmt.i_cat = VIDEO_ES;
2761 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2763 *b_force_backup = true;
2765 else if( !strncmp(psz_value, "video/mpeg", 10) )
2767 /* n.b. MPEG streams are unsupported right now */
2768 p_stream->fmt.i_cat = VIDEO_ES;
2769 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2771 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2772 !strncmp(psz_value, "text/cmml", 9) )
2774 p_stream->fmt.i_cat = SPU_ES;
2775 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2776 *b_packet_out = true;
2778 else if( !strncmp(psz_value, "application/kate", 16) )
2781 p_stream->fmt.i_cat = UNKNOWN_ES;
2782 free( p_stream->fmt.psz_description );
2783 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2785 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2787 p_stream->fmt.i_cat = VIDEO_ES;
2788 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2792 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2793 logical_stream_t *p_stream,
2794 ogg_packet *p_oggpacket )
2796 if( p_oggpacket->bytes >= 28 &&
2797 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2801 uint16_t major_version;
2802 uint16_t minor_version;
2803 uint64_t timebase_numerator;
2804 uint64_t timebase_denominator;
2806 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2808 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2809 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2810 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2811 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2812 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2813 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2815 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2816 "Timebase %"PRId64" / %"PRId64,
2817 major_version, minor_version,
2818 timebase_numerator, timebase_denominator );
2820 else if( p_oggpacket->bytes >= 42 &&
2821 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2823 uint64_t granule_rate_numerator;
2824 uint64_t granule_rate_denominator;
2825 char content_type_string[1024];
2827 /* Read in Annodex header fields */
2829 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2830 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2831 p_stream->i_secondary_header_packets =
2832 GetDWLE( &p_oggpacket->packet[24] );
2834 /* we are guaranteed that the first header field will be
2835 * the content-type (by the Annodex standard) */
2836 content_type_string[0] = '\0';
2837 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2839 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2840 p_oggpacket->bytes - 1 );
2841 if( p && p[0] == '\r' && p[1] == '\n' )
2842 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2843 content_type_string );
2846 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2847 granule_rate_numerator, granule_rate_denominator,
2848 p_stream->i_secondary_header_packets, content_type_string );
2850 p_stream->f_rate = (float) granule_rate_numerator /
2851 (float) granule_rate_denominator;
2853 /* What type of file do we have?
2854 * strcmp is safe to use here because we've extracted
2855 * content_type_string from the stream manually */
2856 bool b_dopacketout = false;
2857 Ogg_ApplyContentType( p_stream, content_type_string,
2858 &p_stream->b_force_backup, &b_dopacketout );
2859 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2863 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2864 ogg_packet *p_oggpacket )
2866 p_demux->p_sys->p_skelstream = p_stream;
2867 /* There can be only 1 skeleton for streams */
2868 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2869 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2870 if ( asprintf( & p_stream->fmt.psz_description,
2871 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2872 p_demux->p_sys->skeleton.major,
2873 p_demux->p_sys->skeleton.minor ) < 0 )
2874 p_stream->fmt.psz_description = NULL;
2877 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2879 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2881 /* Find the matching stream for this skeleton data */
2882 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2883 logical_stream_t *p_target_stream = NULL;
2884 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2886 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2888 p_target_stream = p_demux->p_sys->pp_stream[i];
2892 if ( !p_target_stream ) return;
2894 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2897 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2898 if ( !p_skel ) return;
2899 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2900 p_skel->p_index = NULL;
2901 p_target_stream->p_skel = p_skel;
2904 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2905 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2906 const unsigned char *p = p_messages;
2907 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2909 if ( *p == 0x0D && *(p+1) == 0x0A )
2911 char *psz_message = strndup( (const char *) p_messages,
2915 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2916 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2918 if ( p < p_boundary - 1 ) p_messages = p + 2;
2925 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2926 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2927 unsigned const char *p_end,
2928 uint64_t *pi_value )
2934 while ( p_begin < p_end )
2936 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2937 *pi_value = *pi_value | ( i_read << i_shift );
2939 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2942 *pi_value = GetQWLE( pi_value );
2946 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2948 if ( p_demux->p_sys->skeleton.major < 4
2949 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2952 /* Find the matching stream for this skeleton data */
2953 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2954 logical_stream_t *p_stream = NULL;
2955 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2957 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2959 p_stream = p_demux->p_sys->pp_stream[i];
2963 if ( !p_stream ) return;
2964 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2965 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2966 if ( !i_keypoints ) return;
2968 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
2969 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
2970 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
2971 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
2972 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2973 uint64_t i_offset = 0;
2974 uint64_t i_time = 0;
2975 uint64_t i_keypoints_found = 0;
2977 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
2980 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2982 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2983 i_time += i_val * p_stream->p_skel->i_indexstampden;
2984 i_keypoints_found++;
2987 if ( i_keypoints_found != i_keypoints )
2989 msg_Warn( p_demux, "Invalid Index: missing entries" );
2993 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
2994 if ( !p_stream->p_skel->p_index ) return;
2995 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
2996 p_oggpacket->bytes - 42 );
2997 p_stream->p_skel->i_index = i_keypoints_found;
2998 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3001 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3003 if ( !p_skel ) return;
3004 for ( int i=0; i< p_skel->i_messages; i++ )
3005 free( p_skel->ppsz_messages[i] );
3006 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3007 free( p_skel->p_index );
3011 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3013 if ( !p_stream->p_skel ) return;
3014 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3016 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3017 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3019 free( p_stream->fmt.psz_description );
3020 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3022 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3025 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3030 /* Return true if there's a skeleton exact match */
3031 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3032 int64_t *pi_lower, int64_t *pi_upper )
3034 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3037 /* Validate range */
3038 if ( i_time < p_stream->p_skel->i_indexfirstnum
3039 * p_stream->p_skel->i_indexstampden ||
3040 i_time > p_stream->p_skel->i_indexlastnum
3041 * p_stream->p_skel->i_indexstampden ) return false;
3043 /* Then Lookup its index */
3044 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3049 } current = { 0, 0 }, prev = { -1, -1 };
3051 uint64_t i_keypoints_found = 0;
3053 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3054 && i_keypoints_found < p_stream->p_skel->i_index )
3057 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3058 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3059 current.i_pos += i_val;
3060 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3061 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3062 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3063 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3065 i_keypoints_found++;
3067 if ( i_time <= current.i_time )
3069 *pi_lower = prev.i_pos;
3070 *pi_upper = current.i_pos;
3071 return ( i_time == current.i_time );
3078 static uint32_t dirac_uint( bs_t *p_bs )
3080 uint32_t u_count = 0, u_value = 0;
3082 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3086 u_value |= bs_read( p_bs, 1 );
3089 return (1<<u_count) - 1 + u_value;
3092 static int dirac_bool( bs_t *p_bs )
3094 return bs_read( p_bs, 1 );
3097 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3098 ogg_packet *p_oggpacket )
3100 static const struct {
3101 uint32_t u_n /* numerator */, u_d /* denominator */;
3102 } p_dirac_frate_tbl[] = { /* table 10.3 */
3103 {1,1}, /* this first value is never used */
3104 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3105 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3107 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3109 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3110 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3112 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3116 p_stream->i_granule_shift = 22; /* not 32 */
3118 /* Backing up stream headers is not required -- seqhdrs are repeated
3119 * thoughout the stream at suitable decoding start points */
3120 p_stream->b_force_backup = false;
3122 /* read in useful bits from sequence header */
3123 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3124 bs_skip( &bs, 13*8); /* parse_info_header */
3125 dirac_uint( &bs ); /* major_version */
3126 dirac_uint( &bs ); /* minor_version */
3127 dirac_uint( &bs ); /* profile */
3128 dirac_uint( &bs ); /* level */
3130 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3131 if( u_video_format >= u_dirac_vidfmt_frate )
3133 /* don't know how to parse this ogg dirac stream */
3137 if( dirac_bool( &bs ) )
3139 dirac_uint( &bs ); /* frame_width */
3140 dirac_uint( &bs ); /* frame_height */
3143 if( dirac_bool( &bs ) )
3145 dirac_uint( &bs ); /* chroma_format */
3148 if( dirac_bool( &bs ) )
3150 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3153 p_stream->special.dirac.b_interlaced = false;
3155 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3156 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3157 u_d = __MAX( u_d, 1 );
3158 if( dirac_bool( &bs ) )
3160 uint32_t u_frame_rate_index = dirac_uint( &bs );
3161 if( u_frame_rate_index >= u_dirac_frate_tbl )
3163 /* something is wrong with this stream */
3166 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3167 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3168 if( u_frame_rate_index == 0 )
3170 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3171 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3174 p_stream->f_rate = (float) u_n / u_d;
3175 if ( p_stream->f_rate == 0 ) return false;
3177 /* probably is an ogg dirac es */
3178 p_stream->fmt.i_cat = VIDEO_ES;
3179 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;