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_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
140 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
141 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
142 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
143 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
144 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
145 static bool Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
146 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
147 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
148 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
149 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
152 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
153 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
154 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
155 static void Ogg_ApplySkeleton( logical_stream_t * );
157 /* Special decoding */
158 static void Ogg_CleanSpecificData( logical_stream_t * );
159 #ifdef HAVE_LIBVORBIS
160 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
163 static void fill_channels_info(audio_format_t *audio)
165 static const int pi_channels_map[9] =
169 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
170 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
171 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
172 | AOUT_CHAN_REARRIGHT,
173 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
174 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
175 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
176 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
177 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
178 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
179 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
180 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
181 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
185 unsigned chans = audio->i_channels;
186 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
187 audio->i_physical_channels =
188 audio->i_original_channels = pi_channels_map[chans];
191 /* Special TS value: don't send or derive any pts/pcr from it.
192 Represents TS state prior first known valid timestamp */
193 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
195 /*****************************************************************************
196 * Open: initializes ogg demux structures
197 *****************************************************************************/
198 static int Open( vlc_object_t * p_this )
200 demux_t *p_demux = (demux_t *)p_this;
202 const uint8_t *p_peek;
204 /* Check if we are dealing with an ogg stream */
205 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
206 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
208 char *psz_mime = stream_ContentType( p_demux->s );
213 else if ( strcmp( psz_mime, "application/ogg" ) &&
214 strcmp( psz_mime, "video/ogg" ) &&
215 strcmp( psz_mime, "audio/ogg" ) )
224 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
228 p_sys->i_length = -1;
229 p_sys->b_preparsing_done = false;
231 stream_Control( p_demux->s, ACCESS_GET_PTS_DELAY, & p_sys->i_access_delay );
233 /* Set exported functions */
234 p_demux->pf_demux = Demux;
235 p_demux->pf_control = Control;
237 /* Initialize the Ogg physical bitstream parser */
238 ogg_sync_init( &p_sys->oy );
241 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
244 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
250 /*****************************************************************************
251 * Close: frees unused data
252 *****************************************************************************/
253 static void Close( vlc_object_t *p_this )
255 demux_t *p_demux = (demux_t *)p_this;
256 demux_sys_t *p_sys = p_demux->p_sys ;
258 /* Cleanup the bitstream parser */
259 ogg_sync_clear( &p_sys->oy );
261 Ogg_EndOfStream( p_demux );
263 if( p_sys->p_old_stream )
264 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
269 /*****************************************************************************
270 * Demux: reads and demuxes data packets
271 *****************************************************************************
272 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
273 *****************************************************************************/
274 static int Demux( demux_t * p_demux )
276 demux_sys_t *p_sys = p_demux->p_sys;
277 ogg_packet oggpacket;
279 bool b_skipping = false;
282 int i_active_streams = p_sys->i_streams;
283 for ( int i=0; i < p_sys->i_streams; i++ )
285 if ( p_sys->pp_stream[i]->b_finished )
289 if ( i_active_streams == 0 )
291 if ( p_sys->i_streams ) /* All finished */
293 msg_Dbg( p_demux, "end of a group of logical streams" );
294 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
295 * only 1 ES is supported (common case for ogg web radio) */
296 if( p_sys->i_streams == 1 )
298 p_sys->p_old_stream = p_sys->pp_stream[0];
299 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
301 Ogg_EndOfStream( p_demux );
302 p_sys->b_chained_boundary = true;
305 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
308 msg_Dbg( p_demux, "beginning of a group of logical streams" );
310 if ( !p_sys->b_chained_boundary )
312 /* Find the real duration */
313 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
315 Oggseek_ProbeEnd( p_demux );
319 p_sys->b_chained_boundary = false;
323 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
325 Ogg_CreateES( p_demux );
326 p_sys->b_es_created = true;
330 * The first data page of a physical stream is stored in the relevant logical stream
331 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
332 * stream it belongs to if we haven't processed this first page yet. If we do, we
333 * will only process that first page whenever we find the second page for this stream.
334 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
335 * the second page will arrive real quick, this is not fine for Kate, whose second
336 * data page will typically arrive much later.
337 * This means it is now possible to seek right at the start of a stream where the last
338 * logical stream is Kate, without having to wait for the second data page to unblock
339 * the first one, which is the one that triggers the 'no more headers to backup' code.
340 * And, as we all know, seeking without having backed up all headers is bad, since the
341 * codec will fail to initialize if it's missing its headers.
343 if( !p_sys->b_page_waiting)
346 * Demux an ogg page from the stream
348 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
350 /* Test for End of Stream */
351 if( ogg_page_eos( &p_sys->current_page ) )
353 /* If we delayed restarting encoders/SET_ES_FMT for more
354 * skeleton provided configuration */
355 if ( p_sys->p_skelstream )
357 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
359 msg_Dbg( p_demux, "End of Skeleton" );
360 p_sys->b_preparsing_done = true;
361 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
363 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
364 Ogg_ApplySkeleton( p_stream );
369 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
371 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
373 p_sys->pp_stream[i_stream]->b_finished = true;
381 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
383 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
386 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
388 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
390 /* if we've just pulled page, look for the right logical stream */
391 if( !p_sys->b_page_waiting )
393 if( p_sys->i_streams == 1 &&
394 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
396 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
397 Ogg_ResetStream( p_stream );
398 p_sys->i_nzpcr_offset = (p_sys->i_pcr >= VLC_TS_INVALID) ?
399 p_sys->i_pcr - VLC_TS_0 : 0;
400 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
403 /* Does fail if serialno differs */
404 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
410 /* clear the finished flag if pages after eos (ex: after a seek) */
411 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
412 p_stream->b_finished = false;
415 if ( p_stream->fmt.i_cat == VIDEO_ES )
416 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
417 ogg_page_pageno( &p_sys->current_page ),
418 ogg_page_granulepos( &p_sys->current_page ),
419 ogg_page_packets( &p_sys->current_page ),
420 ogg_page_continued(&p_sys->current_page),
421 p_sys->current_page.body_len )
424 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
427 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
428 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
429 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
430 p_stream->fmt.i_cat == VIDEO_ES )
432 assert( p_stream->p_prepcr_blocks == NULL );
433 p_stream->i_prepcr_blocks = 0;
434 p_stream->p_prepcr_blocks = malloc( sizeof(block_t *) * ogg_page_packets( &p_sys->current_page ) );
438 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
440 /* Read info from any secondary header packets, if there are any */
441 if( p_stream->i_secondary_header_packets > 0 )
443 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
444 oggpacket.bytes >= 7 &&
445 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
447 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
448 p_stream->i_secondary_header_packets = 0;
450 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
451 oggpacket.bytes >= 6 &&
452 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
454 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
455 p_stream->i_secondary_header_packets = 0;
457 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
458 oggpacket.bytes >= 7 &&
459 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
461 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
462 p_stream->i_secondary_header_packets = 0;
464 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
466 p_stream->i_secondary_header_packets = 0;
469 /* update start of data pointer */
470 p_stream->i_data_start = stream_Tell( p_demux->s );
473 /* If any streams have i_skip_frames, only decode (pre-roll)
474 * for those streams, but don't skip headers */
475 if ( b_skipping && p_stream->i_skip_frames == 0
476 && p_stream->i_secondary_header_packets ) continue;
478 if( p_stream->b_reinit )
480 p_stream->b_reinit = false;
481 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
483 p_stream->i_skip_frames = p_stream->i_pre_skip;
487 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
491 if ( p_stream->p_prepcr_blocks )
493 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
494 p_stream->i_previous_pcr = pagestamp;
495 #ifdef HAVE_LIBVORBIS
496 int i_prev_blocksize = 0;
499 for( int i=0; i<p_stream->i_prepcr_blocks; i++ )
501 block_t *p_block = p_stream->p_prepcr_blocks[i];
502 ogg_packet dumb_packet;
503 dumb_packet.bytes = p_block->i_buffer;
504 dumb_packet.packet = p_block->p_buffer;
507 switch( p_stream->fmt.i_codec )
509 case VLC_CODEC_SPEEX:
510 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
511 p_stream->special.speex.i_framesperpacket;
514 i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet );
515 p_block->i_nb_samples = i_duration;
517 #ifdef HAVE_LIBVORBIS
518 case VLC_CODEC_VORBIS:
520 long i_blocksize = vorbis_packet_blocksize(
521 p_stream->special.vorbis.p_info, &dumb_packet );
522 if ( i_prev_blocksize )
523 i_duration = ( i_blocksize + i_prev_blocksize ) / 4;
525 i_duration = i_blocksize / 2;
526 i_prev_blocksize = i_blocksize;
527 p_block->i_nb_samples = i_duration;
534 bool b_fixed = false;
535 for( int i=p_stream->i_prepcr_blocks - 1; i>=0; i-- )
537 block_t *p_block = p_stream->p_prepcr_blocks[i];
538 switch( p_stream->fmt.i_codec )
540 case VLC_CODEC_SPEEX:
542 case VLC_CODEC_VORBIS:
543 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
546 p_block->i_pts = VLC_TS_INVALID;
547 p_block->i_flags |= BLOCK_FLAG_PREROLL;
550 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
554 if ( p_stream->fmt.i_cat == VIDEO_ES )
556 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
557 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
565 if ( pagestamp < 0 ) pagestamp = 0;
566 p_stream->i_pcr = VLC_TS_0 + pagestamp;
567 p_stream->i_pcr += p_sys->i_nzpcr_offset;
568 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
571 FREENULL( p_stream->p_prepcr_blocks );
572 p_stream->i_prepcr_blocks = 0;
574 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
578 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
579 ogg_page_granulepos( &p_sys->current_page ), false );
580 if ( i_pagestamp > -1 )
582 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
583 p_stream->i_pcr += p_sys->i_nzpcr_offset;
586 if( !p_sys->b_page_waiting )
590 /* if a page was waiting, it's now processed */
591 p_sys->b_page_waiting = false;
593 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
594 p_sys->b_preparsing_done = false;
596 p_sys->b_preparsing_done = true;
598 /* We will consider the lowest PCR among tracks, because the audio core badly
599 * handles PCR rewind (mute)
601 mtime_t i_pcr_candidate = VLC_TS_INVALID;
602 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
604 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
606 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
608 /* We have 1 or more streams needing more than 1 page for preparsing */
609 p_sys->b_preparsing_done = false;
612 if( p_stream->fmt.i_cat == SPU_ES )
614 if( p_stream->i_pcr < VLC_TS_0 )
616 if ( p_stream->b_finished || p_stream->b_initializing )
618 if ( p_stream->p_preparse_block )
620 if( i_pcr_candidate < VLC_TS_0
621 || p_stream->i_pcr <= i_pcr_candidate )
623 i_pcr_candidate = p_stream->i_pcr;
627 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
629 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
631 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
632 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
634 p_sys->i_pcr_jitter = i_pcr_jitter;
635 if ( p_sys->i_access_delay < i_pcr_jitter )
636 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
637 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
641 if( ! b_skipping && p_sys->b_preparsing_done )
643 p_sys->i_pcr = i_pcr_candidate;
644 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
651 static void Ogg_ResetStream( logical_stream_t *p_stream )
653 #ifdef HAVE_LIBVORBIS
654 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
656 p_stream->special.vorbis.i_prev_blocksize = 0;
659 /* we'll trash all the data until we find the next pcr */
660 p_stream->b_reinit = true;
661 p_stream->i_pcr = VLC_TS_UNKNOWN;
662 p_stream->i_previous_granulepos = -1;
663 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
664 ogg_stream_reset( &p_stream->os );
665 FREENULL( p_stream->p_prepcr_blocks );
666 p_stream->i_prepcr_blocks = 0;
669 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
671 for( int i = 0; i < p_sys->i_streams; i++ )
672 Ogg_ResetStream( p_sys->pp_stream[i] );
674 ogg_sync_reset( &p_sys->oy );
675 p_sys->i_pcr = VLC_TS_UNKNOWN;
678 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
680 demux_sys_t *p_sys = p_demux->p_sys;
681 logical_stream_t *p_stream = NULL;
682 for( int i=0; i<p_sys->i_streams; i++ )
684 logical_stream_t *p_candidate = p_sys->pp_stream[i];
685 if ( !p_candidate->p_es ) continue;
687 bool b_selected = false;
688 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
689 p_candidate->p_es, &b_selected );
690 if ( !b_selected ) continue;
692 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
694 p_stream = p_candidate;
695 continue; /* Try to find video anyway */
698 if ( p_candidate->fmt.i_cat == VIDEO_ES )
700 p_stream = p_candidate;
707 /*****************************************************************************
709 *****************************************************************************/
710 static int Control( demux_t *p_demux, int i_query, va_list args )
712 demux_sys_t *p_sys = p_demux->p_sys;
721 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
723 vlc_meta_Merge( p_meta, p_sys->p_meta );
726 case DEMUX_HAS_UNSUPPORTED_META:
727 pb_bool = (bool*)va_arg( args, bool* );
732 pi64 = (int64_t*)va_arg( args, int64_t * );
733 *pi64 = p_sys->i_pcr;
737 i64 = (int64_t)va_arg( args, int64_t );
738 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
741 msg_Err( p_demux, "No selected seekable stream found" );
744 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
745 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
747 Ogg_ResetStreamsHelper( p_sys );
748 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
755 case DEMUX_GET_ATTACHMENTS:
757 input_attachment_t ***ppp_attach =
758 (input_attachment_t***)va_arg( args, input_attachment_t*** );
759 int *pi_int = (int*)va_arg( args, int * );
761 if( p_sys->i_attachments <= 0 )
764 *pi_int = p_sys->i_attachments;
765 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
766 for( int i = 0; i < p_sys->i_attachments; i++ )
767 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
771 case DEMUX_GET_POSITION:
772 pf = (double*)va_arg( args, double * );
773 if( p_sys->i_length > 0 )
775 *pf = (double) p_sys->i_pcr /
776 (double) ( p_sys->i_length * (mtime_t)1000000 );
778 else if( stream_Size( p_demux->s ) > 0 )
780 i64 = stream_Tell( p_demux->s );
781 *pf = (double) i64 / stream_Size( p_demux->s );
786 case DEMUX_SET_POSITION:
787 /* forbid seeking if we haven't initialized all logical bitstreams yet;
788 if we allowed, some headers would not get backed up and decoder init
789 would fail, making that logical stream unusable */
790 for ( int i=0; i< p_sys->i_streams; i++ )
792 if ( p_sys->pp_stream[i]->b_initializing )
796 p_stream = Ogg_GetSelectedStream( p_demux );
799 msg_Err( p_demux, "No selected seekable stream found" );
803 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
805 f = (double)va_arg( args, double );
806 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
808 Ogg_ResetStreamsHelper( p_sys );
809 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
813 assert( p_sys->i_length > 0 );
814 i64 = CLOCK_FREQ * p_sys->i_length * f;
815 Ogg_ResetStreamsHelper( p_sys );
816 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
818 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
825 case DEMUX_GET_LENGTH:
826 if ( p_sys->i_length < 0 )
827 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
829 pi64 = (int64_t*)va_arg( args, int64_t * );
830 *pi64 = p_sys->i_length * 1000000;
833 case DEMUX_GET_TITLE_INFO:
835 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
836 int *pi_int = (int*)va_arg( args, int* );
837 int *pi_title_offset = (int*)va_arg( args, int* );
838 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
840 if( p_sys->i_seekpoints > 0 )
843 *ppp_title = malloc( sizeof( input_title_t* ) );
844 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
845 for( int i = 0; i < p_sys->i_seekpoints; i++ )
847 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
848 if ( likely( p_seekpoint_copy ) )
849 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
851 *pi_title_offset = 0;
852 *pi_seekpoint_offset = 0;
856 case DEMUX_SET_TITLE:
858 const int i_title = (int)va_arg( args, int );
863 case DEMUX_SET_SEEKPOINT:
865 const int i_seekpoint = (int)va_arg( args, int );
866 if( i_seekpoint > p_sys->i_seekpoints )
869 for ( int i=0; i< p_sys->i_streams; i++ )
871 if ( p_sys->pp_stream[i]->b_initializing )
875 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
877 p_stream = Ogg_GetSelectedStream( p_demux );
880 msg_Err( p_demux, "No selected seekable stream found" );
884 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
885 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
887 Ogg_ResetStreamsHelper( p_sys );
888 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
890 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
891 p_demux->info.i_seekpoint = i_seekpoint;
899 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
904 /****************************************************************************
905 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
906 ****************************************************************************
907 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
908 * are at the end of stream.
909 ****************************************************************************/
910 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
912 demux_sys_t *p_ogg = p_demux->p_sys ;
916 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
918 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
920 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
924 ogg_sync_wrote( &p_ogg->oy, i_read );
930 /****************************************************************************
931 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
933 ****************************************************************************/
934 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
935 ogg_packet *p_oggpacket )
937 demux_sys_t *p_ogg = p_demux->p_sys;
938 p_stream->i_end_trim = 0;
940 /* Convert the granulepos into a pcr */
941 if ( p_oggpacket->granulepos == 0 )
943 /* We're in headers, and we haven't parsed 1st data packet yet */
944 // p_stream->i_pcr = VLC_TS_UNKNOWN;
946 else if( p_oggpacket->granulepos > 0 )
948 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
949 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
950 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
951 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
952 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
953 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
954 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
956 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
957 p_oggpacket->granulepos, true );
958 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
960 else if ( p_stream->i_previous_granulepos > 0 )
962 ogg_int64_t sample = p_stream->i_previous_granulepos;
964 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
966 int duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
969 ogg_int64_t end_sample = p_oggpacket->granulepos;
970 if( end_sample < ( sample + duration ) )
971 p_stream->i_end_trim = sample + duration - end_sample;
975 if (sample >= p_stream->i_pre_skip)
976 sample -= p_stream->i_pre_skip;
980 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
981 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
985 else if ( p_oggpacket->granulepos == -1 )
988 /* no granulepos available, try to interpolate the pcr.
989 * If we can't then don't touch the old value. */
990 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
992 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
994 #ifdef HAVE_LIBVORBIS
995 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
996 p_stream->special.vorbis.p_info &&
997 !p_stream->special.vorbis.b_invalid &&
998 p_stream->i_previous_granulepos > 0 )
1000 long i_blocksize = vorbis_packet_blocksize(
1001 p_stream->special.vorbis.p_info, p_oggpacket );
1002 if ( p_stream->special.vorbis.i_prev_blocksize )
1003 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1005 i_duration = i_blocksize / 2;
1006 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1007 /* duration in samples per channel */
1008 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1009 p_stream->i_pcr = p_stream->i_previous_granulepos *
1010 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1011 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1014 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1015 p_stream->i_previous_granulepos > 0 )
1017 i_duration = p_stream->special.speex.i_framesize *
1018 p_stream->special.speex.i_framesperpacket;
1019 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1020 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1021 p_stream->i_previous_granulepos, false );
1022 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1024 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1025 p_stream->i_previous_granulepos > 0 &&
1027 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
1030 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1031 sample = p_stream->i_previous_granulepos;
1032 if (sample >= p_stream->i_pre_skip)
1033 sample -= p_stream->i_pre_skip;
1037 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1038 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1040 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1042 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1043 p_stream->fmt.i_bitrate / 8 );
1047 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1050 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1053 demux_sys_t *p_ogg = p_demux->p_sys;
1054 if ( !p_stream->p_es || p_stream->p_prepcr_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1056 if ( !p_block ) return;
1057 if ( p_stream->p_prepcr_blocks )
1059 assert( p_stream->p_prepcr_blocks );
1060 p_stream->p_prepcr_blocks[p_stream->i_prepcr_blocks++] = p_block;
1062 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1063 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1064 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1068 /* Because ES creation is delayed for preparsing */
1069 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1070 if ( p_stream->p_preparse_block )
1072 block_t *temp = p_stream->p_preparse_block;
1075 if ( temp && i_firstpts < VLC_TS_0 )
1076 i_firstpts = temp->i_pts;
1078 block_t *tosend = temp;
1079 temp = temp->p_next;
1080 tosend->p_next = NULL;
1082 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1083 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1084 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1086 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1088 p_ogg->i_pcr = i_firstpts;
1089 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1092 p_stream->p_preparse_block = NULL;
1097 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1098 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1099 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1104 /****************************************************************************
1105 * Ogg_DecodePacket: Decode an Ogg packet.
1106 ****************************************************************************/
1107 static void Ogg_DecodePacket( demux_t *p_demux,
1108 logical_stream_t *p_stream,
1109 ogg_packet *p_oggpacket )
1113 int i_header_len = 0;
1115 if( p_oggpacket->bytes >= 7 &&
1116 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1118 /* it's an Annodex packet -- skip it (do nothing) */
1121 else if( p_oggpacket->bytes >= 7 &&
1122 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1124 /* it's an AnxData packet -- skip it (do nothing) */
1127 else if( p_oggpacket->bytes >= 8 &&
1128 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1130 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1133 else if( p_oggpacket->bytes >= 6 &&
1134 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1136 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1139 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1140 p_oggpacket->bytes >= 7 &&
1141 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1143 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1147 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1148 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1150 /* Check the ES is selected */
1151 if ( !p_stream->p_es )
1154 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1155 p_stream->p_es, &b_selected );
1157 if( p_stream->b_force_backup )
1160 p_stream->i_packets_backup++;
1161 switch( p_stream->fmt.i_codec )
1163 case VLC_CODEC_VORBIS:
1164 #ifdef HAVE_LIBVORBIS
1165 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1168 case VLC_CODEC_THEORA:
1169 if( p_stream->i_packets_backup == 3 )
1170 p_stream->b_force_backup = false;
1174 case VLC_CODEC_DAALA:
1175 if( p_stream->i_packets_backup == 3 )
1176 p_stream->b_force_backup = false;
1180 case VLC_CODEC_SPEEX:
1181 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1182 p_stream->b_force_backup = false;
1186 case VLC_CODEC_OPUS:
1187 if( p_stream->i_packets_backup == 2 )
1188 p_stream->b_force_backup = false;
1192 case VLC_CODEC_FLAC:
1193 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1195 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1196 p_stream->b_force_backup = false;
1198 else if( p_stream->fmt.audio.i_rate )
1200 p_stream->b_force_backup = false;
1201 if( p_oggpacket->bytes >= 9 )
1203 p_oggpacket->packet += 9;
1204 p_oggpacket->bytes -= 9;
1210 case VLC_CODEC_KATE:
1211 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1212 p_stream->b_force_backup = false;
1217 p_stream->b_force_backup = false;
1222 /* Backup the ogg packet (likely an header packet) */
1225 void *p_org = p_stream->p_headers;
1226 p_stream->i_headers += p_oggpacket->bytes;
1227 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1228 if( p_stream->p_headers )
1230 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1231 p_oggpacket->packet, p_oggpacket->bytes );
1235 #warning Memory leak
1236 p_stream->i_headers = 0;
1237 p_stream->p_headers = NULL;
1241 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1242 p_oggpacket->bytes, p_oggpacket->packet ) )
1244 p_stream->i_headers = 0;
1245 p_stream->p_headers = NULL;
1247 if( p_stream->i_headers > 0 )
1249 if( !p_stream->b_force_backup )
1251 /* Last header received, commit changes */
1252 free( p_stream->fmt.p_extra );
1254 p_stream->fmt.i_extra = p_stream->i_headers;
1255 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1256 if( p_stream->fmt.p_extra )
1257 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1258 p_stream->i_headers );
1260 p_stream->fmt.i_extra = 0;
1262 if( p_stream->i_headers > 0 )
1263 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1264 p_stream->p_headers, p_stream->i_headers );
1266 /* we're not at BOS anymore for this logical stream */
1267 p_stream->b_initializing = false;
1271 b_selected = false; /* Discard the header packet */
1275 p_stream->b_initializing = false;
1278 /* Convert the granulepos into the next pcr */
1279 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1283 /* This stream isn't currently selected so we don't need to decode it,
1284 * but we did need to store its pcr as it might be selected later on */
1288 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1289 p_block->i_pts = p_stream->i_pcr;
1291 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1292 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1294 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1295 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1297 /* may need to preroll after a seek or in case of preskip */
1298 if ( p_stream->i_skip_frames > 0 )
1300 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1302 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1304 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1305 p_stream->i_skip_frames -= p_block->i_nb_samples;
1306 p_block->i_nb_samples = 0;
1310 p_block->i_nb_samples -= p_stream->i_skip_frames;
1311 p_stream->i_skip_frames = 0;
1316 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1317 p_stream->i_skip_frames--;
1321 /* Conditional block fixes */
1322 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1323 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1325 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1327 else if( p_stream->fmt.i_cat == AUDIO_ES )
1329 /* Blatant abuse of the i_length field. */
1330 p_block->i_length = p_stream->i_end_trim;
1332 else if( p_stream->fmt.i_cat == SPU_ES )
1334 p_block->i_length = 0;
1336 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1338 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1339 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1340 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1341 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1342 /* granulepos for dirac is possibly broken, this value should be ignored */
1343 if( 0 >= p_oggpacket->granulepos )
1345 p_block->i_pts = VLC_TS_INVALID;
1346 p_block->i_dts = p_stream->i_pcr;
1350 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1351 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1352 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1353 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1354 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1355 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1356 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1357 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1358 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1359 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1360 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1362 if( p_oggpacket->bytes <= 0 )
1364 msg_Dbg( p_demux, "discarding 0 sized packet" );
1365 block_Release( p_block );
1368 /* We remove the header from the packet */
1369 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1370 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1372 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1374 /* But with subtitles we need to retrieve the duration first */
1375 int i, lenbytes = 0;
1377 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1379 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1381 lenbytes = lenbytes << 8;
1382 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1385 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1386 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1387 p_oggpacket->packet[i_header_len + 1] != 0 &&
1388 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1389 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1391 p_block->i_length = (mtime_t)lenbytes * 1000;
1396 if( p_block->i_buffer >= (unsigned int)i_header_len )
1397 p_block->i_buffer -= i_header_len;
1399 p_block->i_buffer = 0;
1403 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1405 /* FIXME: the biggest hack I've ever done */
1406 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1407 p_block->i_pts, p_block->i_dts );
1411 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1412 p_oggpacket->bytes - i_header_len );
1414 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1417 /* Re-implemented to avoid linking against libopus from the demuxer. */
1418 static int Ogg_OpusDataDuration( logical_stream_t *p_stream,
1419 unsigned char *data, long i_datalen )
1421 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1428 return VLC_EGENERIC;
1441 return VLC_EGENERIC;
1442 nframes = data[1]&0x3F;
1445 i_rate = (int)p_stream->fmt.audio.i_rate;
1447 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1448 else if( ( toc&0x60 ) == 0x60 )
1449 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1451 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1452 nsamples = nframes*frame_size;
1453 if( nsamples*25 > i_rate*3 )
1454 return VLC_EGENERIC;
1458 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1459 ogg_packet *p_oggpacket )
1461 return Ogg_OpusDataDuration( p_stream, p_oggpacket->packet, p_oggpacket->bytes );
1464 /****************************************************************************
1465 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1466 * stream and fill p_ogg.
1467 *****************************************************************************
1468 * The initial page of a logical stream is marked as a 'bos' page.
1469 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1470 * together and all of the initial pages must appear before any data pages.
1472 * On success this function returns VLC_SUCCESS.
1473 ****************************************************************************/
1474 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1476 demux_sys_t *p_ogg = p_demux->p_sys ;
1477 ogg_packet oggpacket;
1480 p_ogg->i_total_length = stream_Size ( p_demux->s );
1481 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1484 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1487 if( ogg_page_bos( &p_ogg->current_page ) )
1490 /* All is wonderful in our fine fine little world.
1491 * We found the beginning of our first logical stream. */
1492 while( ogg_page_bos( &p_ogg->current_page ) )
1494 logical_stream_t *p_stream;
1496 p_stream = malloc( sizeof(logical_stream_t) );
1497 if( unlikely( !p_stream ) )
1500 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1502 memset( p_stream, 0, sizeof(logical_stream_t) );
1504 es_format_Init( &p_stream->fmt, 0, 0 );
1505 es_format_Init( &p_stream->fmt_old, 0, 0 );
1506 p_stream->b_initializing = true;
1508 /* Setup the logical stream */
1509 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1510 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1512 /* Extract the initial header from the first page and verify
1513 * the codec type of this Ogg bitstream */
1514 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1516 /* error. stream version mismatch perhaps */
1517 msg_Err( p_demux, "error reading first page of "
1518 "Ogg bitstream data" );
1519 return VLC_EGENERIC;
1522 /* FIXME: check return value */
1523 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1525 /* Check for Vorbis header */
1526 if( oggpacket.bytes >= 7 &&
1527 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1529 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1530 msg_Dbg( p_demux, "found vorbis header" );
1533 msg_Dbg( p_demux, "found invalid vorbis header" );
1534 Ogg_LogicalStreamDelete( p_demux, p_stream );
1538 /* Check for Speex header */
1539 else if( oggpacket.bytes >= 5 &&
1540 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1542 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1543 msg_Dbg( p_demux, "found speex header, channels: %i, "
1544 "rate: %i, bitrate: %i, frames: %i group %i",
1545 p_stream->fmt.audio.i_channels,
1546 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1547 p_stream->special.speex.i_framesize,
1548 p_stream->special.speex.i_framesperpacket );
1551 msg_Dbg( p_demux, "found invalid Speex header" );
1552 Ogg_LogicalStreamDelete( p_demux, p_stream );
1556 /* Check for Opus header */
1557 else if( oggpacket.bytes >= 8 &&
1558 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1560 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1561 msg_Dbg( p_demux, "found opus header, channels: %i, "
1563 p_stream->fmt.audio.i_channels,
1564 (int)p_stream->i_pre_skip);
1565 p_stream->i_skip_frames = p_stream->i_pre_skip;
1567 /* Check for Flac header (< version 1.1.1) */
1568 else if( oggpacket.bytes >= 4 &&
1569 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1571 msg_Dbg( p_demux, "found FLAC header" );
1573 /* Grrrr!!!! Did they really have to put all the
1574 * important info in the second header packet!!!
1575 * (STREAMINFO metadata is in the following packet) */
1576 p_stream->b_force_backup = true;
1577 p_stream->fmt.i_cat = AUDIO_ES;
1578 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1580 /* Check for Flac header (>= version 1.1.1) */
1581 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1582 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1583 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1585 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1586 oggpacket.packet[8];
1587 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1588 "(%i header packets)",
1589 oggpacket.packet[5], oggpacket.packet[6],
1592 p_stream->b_force_backup = true;
1594 p_stream->fmt.i_cat = AUDIO_ES;
1595 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1596 oggpacket.packet += 13; oggpacket.bytes -= 13;
1597 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1599 msg_Dbg( p_demux, "found invalid Flac header" );
1600 Ogg_LogicalStreamDelete( p_demux, p_stream );
1604 /* Check for Theora header */
1605 else if( oggpacket.bytes >= 7 &&
1606 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1608 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1610 "found theora header, bitrate: %i, rate: %f",
1611 p_stream->fmt.i_bitrate, p_stream->f_rate );
1614 msg_Dbg( p_demux, "found invalid Theora header" );
1615 Ogg_LogicalStreamDelete( p_demux, p_stream );
1619 /* Check for Daala header */
1620 else if( oggpacket.bytes >= 6 &&
1621 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1623 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1625 "found daala header, bitrate: %i, rate: %f",
1626 p_stream->fmt.i_bitrate, p_stream->f_rate );
1629 msg_Dbg( p_demux, "found invalid Daala header" );
1630 Ogg_LogicalStreamDelete( p_demux, p_stream );
1634 /* Check for Dirac header */
1635 else if( ( oggpacket.bytes >= 5 &&
1636 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1637 ( oggpacket.bytes >= 9 &&
1638 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1640 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1641 msg_Dbg( p_demux, "found dirac header" );
1644 msg_Warn( p_demux, "found dirac header isn't decodable" );
1645 Ogg_LogicalStreamDelete( p_demux, p_stream );
1649 /* Check for Tarkin header */
1650 else if( oggpacket.bytes >= 7 &&
1651 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1655 msg_Dbg( p_demux, "found tarkin header" );
1656 p_stream->fmt.i_cat = VIDEO_ES;
1657 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1659 /* Cheat and get additionnal info ;) */
1660 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1661 oggpack_adv( &opb, 88 );
1662 oggpack_adv( &opb, 104 );
1663 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1664 p_stream->f_rate = 2; /* FIXME */
1666 "found tarkin header, bitrate: %i, rate: %f",
1667 p_stream->fmt.i_bitrate, p_stream->f_rate );
1669 /* Check for VP8 header */
1670 else if( oggpacket.bytes >= 26 &&
1671 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1673 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1674 msg_Dbg( p_demux, "found VP8 header "
1675 "fps: %f, width:%i; height:%i",
1677 p_stream->fmt.video.i_width,
1678 p_stream->fmt.video.i_height );
1681 msg_Dbg( p_demux, "invalid VP8 header found");
1682 Ogg_LogicalStreamDelete( p_demux, p_stream );
1686 /* Check for Annodex header */
1687 else if( oggpacket.bytes >= 7 &&
1688 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1690 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1691 /* kill annodex track */
1695 /* Check for Annodex header */
1696 else if( oggpacket.bytes >= 7 &&
1697 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1699 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1701 /* Check for Kate header */
1702 else if( oggpacket.bytes >= 8 &&
1703 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1705 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1706 msg_Dbg( p_demux, "found kate header" );
1709 msg_Dbg( p_demux, "invalid kate header found");
1710 Ogg_LogicalStreamDelete( p_demux, p_stream );
1714 /* Check for OggDS */
1715 else if( oggpacket.bytes >= 142 &&
1716 !memcmp( &oggpacket.packet[1],
1717 "Direct Show Samples embedded in Ogg", 35 ))
1719 /* Old header type */
1720 p_stream->b_oggds = true;
1721 /* Check for video header (old format) */
1722 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1723 oggpacket.bytes >= 184 )
1725 p_stream->fmt.i_cat = VIDEO_ES;
1726 p_stream->fmt.i_codec =
1727 VLC_FOURCC( oggpacket.packet[68],
1728 oggpacket.packet[69],
1729 oggpacket.packet[70],
1730 oggpacket.packet[71] );
1731 msg_Dbg( p_demux, "found video header of type: %.4s",
1732 (char *)&p_stream->fmt.i_codec );
1734 p_stream->fmt.video.i_frame_rate = 10000000;
1735 p_stream->fmt.video.i_frame_rate_base =
1736 GetQWLE((oggpacket.packet+164));
1737 p_stream->fmt.video.i_frame_rate_base =
1738 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1739 p_stream->f_rate = 10000000.0 /
1740 p_stream->fmt.video.i_frame_rate_base;
1741 p_stream->fmt.video.i_bits_per_pixel =
1742 GetWLE((oggpacket.packet+182));
1743 if( !p_stream->fmt.video.i_bits_per_pixel )
1745 p_stream->fmt.video.i_bits_per_pixel = 24;
1746 p_stream->fmt.video.i_width =
1747 GetDWLE((oggpacket.packet+176));
1748 p_stream->fmt.video.i_height =
1749 GetDWLE((oggpacket.packet+180));
1752 "fps: %f, width:%i; height:%i, bitcount:%i",
1754 p_stream->fmt.video.i_width,
1755 p_stream->fmt.video.i_height,
1756 p_stream->fmt.video.i_bits_per_pixel);
1759 /* Check for audio header (old format) */
1760 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1763 unsigned int i_format_tag;
1765 p_stream->fmt.i_cat = AUDIO_ES;
1767 i_extra_size = GetWLE((oggpacket.packet+140));
1768 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1770 p_stream->fmt.i_extra = i_extra_size;
1771 p_stream->fmt.p_extra = malloc( i_extra_size );
1772 if( p_stream->fmt.p_extra )
1773 memcpy( p_stream->fmt.p_extra,
1774 oggpacket.packet + 142, i_extra_size );
1776 p_stream->fmt.i_extra = 0;
1779 i_format_tag = GetWLE((oggpacket.packet+124));
1780 p_stream->fmt.audio.i_channels =
1781 GetWLE((oggpacket.packet+126));
1782 fill_channels_info(&p_stream->fmt.audio);
1783 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1784 GetDWLE((oggpacket.packet+128));
1785 p_stream->fmt.i_bitrate =
1786 GetDWLE((oggpacket.packet+132)) * 8;
1787 p_stream->fmt.audio.i_blockalign =
1788 GetWLE((oggpacket.packet+136));
1789 p_stream->fmt.audio.i_bitspersample =
1790 GetWLE((oggpacket.packet+138));
1792 wf_tag_to_fourcc( i_format_tag,
1793 &p_stream->fmt.i_codec, 0 );
1795 if( p_stream->fmt.i_codec ==
1796 VLC_FOURCC('u','n','d','f') )
1798 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1799 ( i_format_tag >> 8 ) & 0xff,
1800 i_format_tag & 0xff );
1803 msg_Dbg( p_demux, "found audio header of type: %.4s",
1804 (char *)&p_stream->fmt.i_codec );
1805 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1806 "%dbits/sample %dkb/s",
1808 p_stream->fmt.audio.i_channels,
1809 p_stream->fmt.audio.i_rate,
1810 p_stream->fmt.audio.i_bitspersample,
1811 p_stream->fmt.i_bitrate / 1024 );
1812 if ( p_stream->f_rate == 0 )
1814 msg_Dbg( p_demux, "invalid oggds audio header" );
1815 Ogg_LogicalStreamDelete( p_demux, p_stream );
1821 msg_Dbg( p_demux, "stream %d has an old header "
1822 "but is of an unknown type", p_ogg->i_streams-1 );
1827 /* Check for OggDS */
1828 else if( oggpacket.bytes >= 44+1 &&
1829 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1831 stream_header_t tmp;
1832 stream_header_t *st = &tmp;
1834 p_stream->b_oggds = true;
1836 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1837 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1838 st->size = GetDWLE( &oggpacket.packet[1+12] );
1839 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1840 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1841 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1842 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1843 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1845 /* Check for video header (new format) */
1846 if( !strncmp( st->streamtype, "video", 5 ) &&
1847 oggpacket.bytes >= 52+1 )
1849 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1850 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1852 p_stream->fmt.i_cat = VIDEO_ES;
1854 /* We need to get rid of the header packet */
1855 ogg_stream_packetout( &p_stream->os, &oggpacket );
1857 p_stream->fmt.i_codec =
1858 VLC_FOURCC( st->subtype[0], st->subtype[1],
1859 st->subtype[2], st->subtype[3] );
1860 msg_Dbg( p_demux, "found video header of type: %.4s",
1861 (char *)&p_stream->fmt.i_codec );
1863 p_stream->fmt.video.i_frame_rate = 10000000;
1864 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1865 if( st->time_unit <= 0 )
1866 st->time_unit = 400000;
1867 p_stream->f_rate = 10000000.0 / st->time_unit;
1868 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1869 p_stream->fmt.video.i_width = st->sh.video.width;
1870 p_stream->fmt.video.i_height = st->sh.video.height;
1873 "fps: %f, width:%i; height:%i, bitcount:%i",
1875 p_stream->fmt.video.i_width,
1876 p_stream->fmt.video.i_height,
1877 p_stream->fmt.video.i_bits_per_pixel );
1879 /* Check for audio header (new format) */
1880 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1881 oggpacket.bytes >= 56+1 )
1887 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1888 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1889 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1891 p_stream->fmt.i_cat = AUDIO_ES;
1893 /* We need to get rid of the header packet */
1894 ogg_stream_packetout( &p_stream->os, &oggpacket );
1896 i_extra_size = st->size - 56;
1898 if( i_extra_size > 0 &&
1899 i_extra_size < oggpacket.bytes - 1 - 56 )
1901 p_stream->fmt.i_extra = i_extra_size;
1902 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1903 if( p_stream->fmt.p_extra )
1904 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1905 p_stream->fmt.i_extra );
1907 p_stream->fmt.i_extra = 0;
1910 memcpy( p_buffer, st->subtype, 4 );
1912 i_format_tag = strtol(p_buffer,NULL,16);
1913 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1914 fill_channels_info(&p_stream->fmt.audio);
1915 if( st->time_unit <= 0 )
1916 st->time_unit = 10000000;
1917 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1918 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1919 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1920 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1922 wf_tag_to_fourcc( i_format_tag,
1923 &p_stream->fmt.i_codec, 0 );
1925 if( p_stream->fmt.i_codec ==
1926 VLC_FOURCC('u','n','d','f') )
1928 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1929 ( i_format_tag >> 8 ) & 0xff,
1930 i_format_tag & 0xff );
1933 msg_Dbg( p_demux, "found audio header of type: %.4s",
1934 (char *)&p_stream->fmt.i_codec );
1935 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1936 "%dbits/sample %dkb/s",
1938 p_stream->fmt.audio.i_channels,
1939 p_stream->fmt.audio.i_rate,
1940 p_stream->fmt.audio.i_bitspersample,
1941 p_stream->fmt.i_bitrate / 1024 );
1942 if ( p_stream->f_rate == 0 )
1944 msg_Dbg( p_demux, "invalid oggds audio header" );
1945 Ogg_LogicalStreamDelete( p_demux, p_stream );
1949 /* Check for text (subtitles) header */
1950 else if( !strncmp(st->streamtype, "text", 4) )
1952 /* We need to get rid of the header packet */
1953 ogg_stream_packetout( &p_stream->os, &oggpacket );
1955 msg_Dbg( p_demux, "found text subtitle header" );
1956 p_stream->fmt.i_cat = SPU_ES;
1957 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1958 p_stream->f_rate = 1000; /* granulepos is in millisec */
1962 msg_Dbg( p_demux, "stream %d has a header marker "
1963 "but is of an unknown type", p_ogg->i_streams-1 );
1968 else if( oggpacket.bytes >= 8 &&
1969 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1973 msg_Dbg( p_demux, "stream %d is a skeleton",
1974 p_ogg->i_streams-1 );
1975 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1979 msg_Dbg( p_demux, "stream %d is of unknown type",
1980 p_ogg->i_streams-1 );
1985 /* we'll need to get all headers */
1986 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1988 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1989 return VLC_EGENERIC;
1992 /* This is the first data page, which means we are now finished
1993 * with the initial pages. We just need to store it in the relevant
1995 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1997 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1998 &p_ogg->current_page ) == 0 )
2000 p_ogg->b_page_waiting = true;
2009 return VLC_EGENERIC;
2012 /****************************************************************************
2013 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2014 ****************************************************************************/
2015 static void Ogg_CreateES( demux_t *p_demux )
2017 demux_sys_t *p_ogg = p_demux->p_sys;
2018 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2021 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2023 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2025 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2027 /* Better be safe than sorry when possible with ogm */
2028 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2029 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2030 p_stream->fmt.b_packetized = false;
2032 /* Try first to reuse an old ES */
2034 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2035 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2037 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2039 p_stream->p_es = p_old_stream->p_es;
2040 p_stream->b_finished = false;
2041 p_stream->b_reinit = false;
2042 p_stream->b_initializing = false;
2043 p_stream->i_pre_skip = 0;
2044 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2045 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2047 p_old_stream->p_es = NULL;
2048 p_old_stream = NULL;
2049 if ( b_resetdecoder )
2051 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2052 p_stream->p_es, &p_stream->fmt );
2057 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2060 // TODO: something to do here ?
2061 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2063 /* Set the CMML stream active */
2064 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2069 if( p_ogg->p_old_stream )
2071 if( p_ogg->p_old_stream->p_es )
2072 msg_Dbg( p_demux, "old stream not reused" );
2073 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2074 p_ogg->p_old_stream = NULL;
2078 /****************************************************************************
2079 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2080 * Elementary streams.
2081 ****************************************************************************/
2082 static int Ogg_BeginningOfStream( demux_t *p_demux )
2084 demux_sys_t *p_ogg = p_demux->p_sys ;
2087 /* Find the logical streams embedded in the physical stream and
2088 * initialize our p_ogg structure. */
2089 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2091 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2092 return VLC_EGENERIC;
2095 p_ogg->i_bitrate = 0;
2097 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2099 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2101 p_stream->p_es = NULL;
2103 /* initialise kframe index */
2106 if ( p_stream->fmt.i_bitrate == 0 &&
2107 ( p_stream->fmt.i_cat == VIDEO_ES ||
2108 p_stream->fmt.i_cat == AUDIO_ES ) )
2109 p_ogg->b_partial_bitrate = true;
2111 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2113 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2114 p_stream->i_previous_granulepos = -1;
2115 p_stream->b_reinit = false;
2118 /* get total frame count for video stream; we will need this for seeking */
2119 p_ogg->i_total_frames = 0;
2124 /****************************************************************************
2125 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2126 ****************************************************************************/
2127 static void Ogg_EndOfStream( demux_t *p_demux )
2129 demux_sys_t *p_ogg = p_demux->p_sys ;
2132 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2133 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2134 free( p_ogg->pp_stream );
2137 p_ogg->i_bitrate = 0;
2138 p_ogg->i_streams = 0;
2139 p_ogg->pp_stream = NULL;
2140 p_ogg->skeleton.major = 0;
2141 p_ogg->skeleton.minor = 0;
2142 p_ogg->b_preparsing_done = false;
2143 p_ogg->b_es_created = false;
2144 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2145 p_ogg->i_pcr - VLC_TS_0 : 0;
2149 vlc_meta_Delete( p_ogg->p_meta );
2150 p_ogg->p_meta = NULL;
2152 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2154 if ( p_ogg->pp_seekpoints[i] )
2155 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2157 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2158 p_ogg->i_seekpoints = 0;
2161 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2163 #ifdef HAVE_LIBVORBIS
2164 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2166 FREENULL( p_stream->special.vorbis.p_info );
2167 FREENULL( p_stream->special.vorbis.p_comment );
2168 p_stream->special.vorbis.b_invalid = false;
2171 VLC_UNUSED( p_stream );
2176 * This function delete and release all data associated to a logical_stream_t
2178 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2180 if( p_stream->p_es )
2181 es_out_Del( p_demux->out, p_stream->p_es );
2183 ogg_stream_clear( &p_stream->os );
2184 free( p_stream->p_headers );
2186 Ogg_CleanSpecificData( p_stream );
2188 es_format_Clean( &p_stream->fmt_old );
2189 es_format_Clean( &p_stream->fmt );
2191 if ( p_stream->idx != NULL)
2193 oggseek_index_entries_free( p_stream->idx );
2196 Ogg_FreeSkeleton( p_stream->p_skel );
2197 p_stream->p_skel = NULL;
2198 if ( p_demux->p_sys->p_skelstream == p_stream )
2199 p_demux->p_sys->p_skelstream = NULL;
2201 /* Shouldn't happen */
2202 if ( unlikely( p_stream->p_preparse_block ) )
2204 block_ChainRelease( p_stream->p_preparse_block );
2205 p_stream->p_preparse_block = NULL;
2207 free( p_stream->p_prepcr_blocks );
2212 * This function check if a we need to reset a decoder in case we are
2215 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2217 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2218 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2219 unsigned i_new_count;
2220 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2223 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2224 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2225 unsigned i_old_count;
2226 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2229 bool b_match = i_new_count == i_old_count;
2230 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2232 /* Ignore vorbis comment */
2235 if( pi_new_size[i] != pi_old_size[i] ||
2236 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2243 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2244 const es_format_t *p_old )
2246 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2247 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2248 unsigned i_new_count;
2249 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2251 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2252 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2253 unsigned i_old_count;
2254 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2256 bool b_match = false;
2257 if( i_new_count == i_old_count && i_new_count > 0 )
2259 static const unsigned char default_map[2] = { 0, 1 };
2260 unsigned char *p_old_head;
2261 unsigned char *p_new_head;
2262 const unsigned char *p_old_map;
2263 const unsigned char *p_new_map;
2264 int i_old_channel_count;
2265 int i_new_channel_count;
2266 int i_old_stream_count;
2267 int i_new_stream_count;
2268 int i_old_coupled_count;
2269 int i_new_coupled_count;
2270 p_old_head = (unsigned char *)pp_old_data[0];
2271 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2272 p_old_map = default_map;
2273 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2275 i_old_channel_count = p_old_head[9];
2276 switch( p_old_head[18] )
2279 i_old_stream_count = 1;
2280 i_old_coupled_count = i_old_channel_count - 1;
2283 if( pi_old_size[0] >= 21U + i_old_channel_count )
2285 i_old_stream_count = p_old_head[19];
2286 i_old_coupled_count = p_old_head[20];
2287 p_old_map = p_old_head + 21;
2292 p_new_head = (unsigned char *)pp_new_data[0];
2293 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2294 p_new_map = default_map;
2295 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2297 i_new_channel_count = p_new_head[9];
2298 switch( p_new_head[18] )
2301 i_new_stream_count = 1;
2302 i_new_coupled_count = i_new_channel_count - 1;
2305 if( pi_new_size[0] >= 21U + i_new_channel_count )
2307 i_new_stream_count = p_new_head[19];
2308 i_new_coupled_count = p_new_head[20];
2309 p_new_map = p_new_head+21;
2314 b_match = i_old_channel_count == i_new_channel_count &&
2315 i_old_stream_count == i_new_stream_count &&
2316 i_old_coupled_count == i_new_coupled_count &&
2317 memcmp(p_old_map, p_new_map,
2318 i_new_channel_count*sizeof(*p_new_map)) == 0;
2324 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2326 bool b_compatible = false;
2327 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2330 /* Only Vorbis and Opus are supported. */
2331 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2332 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2333 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2334 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2337 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2339 return !b_compatible;
2342 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2343 const void *p_headers, unsigned i_headers )
2345 demux_sys_t *p_ogg = p_demux->p_sys;
2346 int i_cover_score = 0;
2347 int i_cover_idx = 0;
2348 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2349 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2350 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2352 pf_replay_gain[i] = 0;
2353 pf_replay_peak[i] = 0;
2355 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2356 &p_ogg->i_attachments, &p_ogg->attachments,
2357 &i_cover_score, &i_cover_idx,
2358 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2359 &pf_replay_gain, &pf_replay_peak );
2360 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2363 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2364 p_ogg->attachments[i_cover_idx]->psz_name );
2365 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2368 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2370 if ( pf_replay_gain[i] != 0 )
2372 p_fmt->audio_replay_gain.pb_gain[i] = true;
2373 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2374 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2376 if ( pf_replay_peak[i] != 0 )
2378 p_fmt->audio_replay_gain.pb_peak[i] = true;
2379 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2380 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2384 if( p_ogg->i_seekpoints > 1 )
2386 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2390 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2391 const void *p_headers, unsigned i_headers, unsigned i_skip )
2393 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2394 void *pp_data[XIPH_MAX_HEADER_COUNT];
2397 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2399 /* TODO how to handle multiple comments properly ? */
2400 if( i_count >= 2 && pi_size[1] > i_skip )
2402 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2406 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2408 demux_sys_t *p_ogg = p_demux->p_sys;
2410 switch( p_fmt->i_codec )
2412 /* 3 headers with the 2° one being the comments */
2413 case VLC_CODEC_VORBIS:
2414 case VLC_CODEC_THEORA:
2415 case VLC_CODEC_DAALA:
2416 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2418 case VLC_CODEC_OPUS:
2419 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2421 case VLC_CODEC_SPEEX:
2422 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2425 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2427 /* N headers with the 2° one being the comments */
2428 case VLC_CODEC_KATE:
2429 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2430 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2434 case VLC_CODEC_FLAC:
2435 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2439 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2440 case VLC_CODEC_DIRAC:
2445 p_demux->info.i_update |= INPUT_UPDATE_META;
2448 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2449 ogg_packet *p_oggpacket )
2452 unsigned int i_fps_numerator;
2453 unsigned int i_fps_denominator;
2454 int i_keyframe_frequency_force;
2460 p_stream->fmt.i_cat = VIDEO_ES;
2461 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2463 /* Signal that we want to keep a backup of the theora
2464 * stream headers. They will be used when switching between
2466 p_stream->b_force_backup = true;
2468 /* Cheat and get additionnal info ;) */
2469 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2470 bs_skip( &bitstream, 56 );
2472 i_major = bs_read( &bitstream, 8 ); /* major version num */
2473 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2474 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2476 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2477 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2478 bs_read( &bitstream, 24 ); /* frame width */
2479 bs_read( &bitstream, 24 ); /* frame height */
2480 bs_read( &bitstream, 8 ); /* x offset */
2481 bs_read( &bitstream, 8 ); /* y offset */
2483 i_fps_numerator = bs_read( &bitstream, 32 );
2484 i_fps_denominator = bs_read( &bitstream, 32 );
2485 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2486 bs_read( &bitstream, 24 ); /* aspect_numerator */
2487 bs_read( &bitstream, 24 ); /* aspect_denominator */
2489 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2490 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2492 bs_read( &bitstream, 8 ); /* colorspace */
2493 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2494 bs_read( &bitstream, 6 ); /* quality */
2496 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2498 /* granule_shift = i_log( frequency_force -1 ) */
2499 p_stream->i_granule_shift = 0;
2500 i_keyframe_frequency_force--;
2501 while( i_keyframe_frequency_force )
2503 p_stream->i_granule_shift++;
2504 i_keyframe_frequency_force >>= 1;
2507 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2508 p_stream->i_keyframe_offset = 0;
2509 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2510 if ( p_stream->f_rate == 0 ) return false;
2512 if ( i_version >= 3002001 )
2514 p_stream->i_keyframe_offset = 1;
2519 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2520 ogg_packet *p_oggpacket )
2523 uint32_t i_timebase_numerator;
2524 uint32_t i_timebase_denominator;
2525 int i_keyframe_frequency_force;
2531 p_stream->fmt.i_cat = VIDEO_ES;
2532 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2534 /* Signal that we want to keep a backup of the daala
2535 * stream headers. They will be used when switching between
2537 p_stream->b_force_backup = true;
2539 /* Cheat and get additionnal info ;) */
2540 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2541 oggpack_adv( &opb, 48 );
2543 i_major = oggpack_read( &opb, 8 ); /* major version num */
2544 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2545 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2547 oggpack_adv( &opb, 32 ); /* width */
2548 oggpack_adv( &opb, 32 ); /* height */
2550 oggpack_adv( &opb, 32 ); /* aspect numerator */
2551 oggpack_adv( &opb, 32 ); /* aspect denominator */
2552 i_timebase_numerator = oggpack_read( &opb, 32 );
2554 i_timebase_denominator = oggpack_read( &opb, 32 );
2555 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2557 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2558 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2560 oggpack_adv( &opb, 32 ); /* frame duration */
2562 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2564 /* granule_shift = i_log( frequency_force -1 ) */
2565 p_stream->i_granule_shift = 0;
2566 i_keyframe_frequency_force--;
2567 while( i_keyframe_frequency_force )
2569 p_stream->i_granule_shift++;
2570 i_keyframe_frequency_force >>= 1;
2573 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2574 p_stream->i_keyframe_offset = 0;
2575 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2576 if ( p_stream->f_rate == 0 ) return false;
2581 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2582 ogg_packet *p_oggpacket )
2586 p_stream->fmt.i_cat = AUDIO_ES;
2587 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2589 /* Signal that we want to keep a backup of the vorbis
2590 * stream headers. They will be used when switching between
2592 p_stream->b_force_backup = true;
2594 /* Cheat and get additionnal info ;) */
2595 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2596 oggpack_adv( &opb, 88 );
2597 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2598 fill_channels_info(&p_stream->fmt.audio);
2599 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2600 oggpack_read( &opb, 32 );
2601 oggpack_adv( &opb, 32 );
2602 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2603 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2604 if ( p_stream->f_rate == 0 ) return false;
2607 #ifdef HAVE_LIBVORBIS
2608 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2609 ogg_packet *p_oggpacket, int i_number )
2613 case VORBIS_HEADER_IDENTIFICATION:
2614 p_stream->special.vorbis.p_info = malloc( sizeof(vorbis_info) );
2615 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2616 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2618 FREENULL( p_stream->special.vorbis.p_info );
2619 FREENULL( p_stream->special.vorbis.p_comment );
2620 p_stream->special.vorbis.b_invalid = true;
2623 vorbis_info_init( p_stream->special.vorbis.p_info );
2624 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2627 case VORBIS_HEADER_COMMENT:
2628 case VORBIS_HEADER_SETUP:
2629 if ( p_stream->special.vorbis.p_info && ! p_stream->special.vorbis.b_invalid )
2631 p_stream->special.vorbis.b_invalid = ( 0 != vorbis_synthesis_headerin(
2632 p_stream->special.vorbis.p_info,
2633 p_stream->special.vorbis.p_comment, p_oggpacket ) );
2643 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2644 ogg_packet *p_oggpacket )
2648 p_stream->fmt.i_cat = AUDIO_ES;
2649 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2651 /* Signal that we want to keep a backup of the speex
2652 * stream headers. They will be used when switching between
2654 p_stream->b_force_backup = true;
2656 /* Cheat and get additionnal info ;) */
2657 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2658 oggpack_adv( &opb, 224 );
2659 oggpack_adv( &opb, 32 ); /* speex_version_id */
2660 oggpack_adv( &opb, 32 ); /* header_size */
2661 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2662 if ( p_stream->f_rate == 0 ) return false;
2663 oggpack_adv( &opb, 32 ); /* mode */
2664 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2665 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2666 fill_channels_info(&p_stream->fmt.audio);
2667 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2668 p_stream->special.speex.i_framesize =
2669 oggpack_read( &opb, 32 ); /* frame_size */
2670 oggpack_adv( &opb, 32 ); /* vbr */
2671 p_stream->special.speex.i_framesperpacket =
2672 oggpack_read( &opb, 32 ); /* frames_per_packet */
2673 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2677 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2678 ogg_packet *p_oggpacket )
2682 p_stream->fmt.i_cat = AUDIO_ES;
2683 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2685 /* Signal that we want to keep a backup of the opus
2686 * stream headers. They will be used when switching between
2688 p_stream->b_force_backup = true;
2690 /* All OggOpus streams are timestamped at 48kHz and
2691 * can be played at 48kHz. */
2692 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2693 p_stream->fmt.i_bitrate = 0;
2695 /* Cheat and get additional info ;) */
2696 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2697 oggpack_adv( &opb, 64 );
2698 oggpack_adv( &opb, 8 ); /* version_id */
2699 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2700 fill_channels_info(&p_stream->fmt.audio);
2701 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2702 /* For Opus, trash the first 80 ms of decoded output as
2703 well, to avoid blowing out speakers if we get unlucky.
2704 Opus predicts content from prior frames, which can go
2705 badly if we seek right where the stream goes from very
2706 quiet to very loud. It will converge after a bit. */
2707 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2710 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2711 ogg_packet *p_oggpacket )
2713 /* Parse the STREAMINFO metadata */
2716 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2719 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2721 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2725 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2728 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2729 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2730 fill_channels_info(&p_stream->fmt.audio);
2732 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2733 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2734 if ( p_stream->f_rate == 0 ) return false;
2738 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2741 /* Fake this as the last metadata block */
2742 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2746 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2747 ogg_packet *p_oggpacket )
2755 p_stream->fmt.i_cat = SPU_ES;
2756 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2758 /* Signal that we want to keep a backup of the kate
2759 * stream headers. They will be used when switching between
2761 p_stream->b_force_backup = true;
2763 /* Cheat and get additionnal info ;) */
2764 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2765 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2766 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2767 oggpack_adv( &opb, 3*8 );
2768 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2769 oggpack_adv( &opb, 8*8 ); /* reserved */
2770 gnum = oggpack_read( &opb, 32 );
2771 gden = oggpack_read( &opb, 32 );
2772 gden = __MAX( gden, 1 );
2773 p_stream->f_rate = (double)gnum/gden;
2774 if ( p_stream->f_rate == 0 ) return false;
2776 p_stream->fmt.psz_language = malloc(16);
2777 if( p_stream->fmt.psz_language )
2779 for( n = 0; n < 16; n++ )
2780 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2781 p_stream->fmt.psz_language[15] = 0; /* just in case */
2785 for( n = 0; n < 16; n++ )
2786 oggpack_read(&opb,8);
2788 p_stream->fmt.psz_description = malloc(16);
2789 if( p_stream->fmt.psz_description )
2791 for( n = 0; n < 16; n++ )
2792 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2793 p_stream->fmt.psz_description[15] = 0; /* just in case */
2795 /* Now find a localized user readable description for this category */
2796 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2799 free( p_stream->fmt.psz_description );
2800 p_stream->fmt.psz_description = psz_desc;
2805 for( n = 0; n < 16; n++ )
2806 oggpack_read(&opb,8);
2812 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2813 ogg_packet *p_oggpacket )
2815 switch( p_oggpacket->packet[5] )
2819 /* Mapping version */
2820 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2822 p_stream->fmt.i_cat = VIDEO_ES;
2823 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2824 p_stream->i_granule_shift = 32;
2825 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2826 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2827 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2828 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2829 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2830 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2831 p_stream->fmt.video.i_frame_rate_base =
2832 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2833 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2834 if ( p_stream->f_rate == 0 ) return false;
2838 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2839 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2846 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2847 bool *b_force_backup, bool *b_packet_out )
2849 if( !strncmp(psz_value, "audio/x-wav", 11) )
2851 /* n.b. WAVs are unsupported right now */
2852 p_stream->fmt.i_cat = UNKNOWN_ES;
2853 free( p_stream->fmt.psz_description );
2854 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2856 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2857 !strncmp(psz_value, "audio/vorbis", 12) )
2859 p_stream->fmt.i_cat = AUDIO_ES;
2860 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2862 *b_force_backup = true;
2864 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2865 !strncmp(psz_value, "audio/speex", 11) )
2867 p_stream->fmt.i_cat = AUDIO_ES;
2868 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2870 *b_force_backup = true;
2872 else if( !strncmp(psz_value, "audio/flac", 10) )
2874 p_stream->fmt.i_cat = AUDIO_ES;
2875 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2877 *b_force_backup = true;
2879 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2880 !strncmp(psz_value, "video/theora", 12) )
2882 p_stream->fmt.i_cat = VIDEO_ES;
2883 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2885 *b_force_backup = true;
2887 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2888 !strncmp(psz_value, "video/daala", 11) )
2890 p_stream->fmt.i_cat = VIDEO_ES;
2891 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2893 *b_force_backup = true;
2895 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2897 p_stream->fmt.i_cat = VIDEO_ES;
2898 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2900 *b_force_backup = true;
2902 else if( !strncmp(psz_value, "video/mpeg", 10) )
2904 /* n.b. MPEG streams are unsupported right now */
2905 p_stream->fmt.i_cat = VIDEO_ES;
2906 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2908 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2909 !strncmp(psz_value, "text/cmml", 9) )
2911 p_stream->fmt.i_cat = SPU_ES;
2912 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2913 *b_packet_out = true;
2915 else if( !strncmp(psz_value, "application/kate", 16) )
2918 p_stream->fmt.i_cat = UNKNOWN_ES;
2919 free( p_stream->fmt.psz_description );
2920 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2922 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2924 p_stream->fmt.i_cat = VIDEO_ES;
2925 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2929 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2930 logical_stream_t *p_stream,
2931 ogg_packet *p_oggpacket )
2933 if( p_oggpacket->bytes >= 28 &&
2934 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2938 uint16_t major_version;
2939 uint16_t minor_version;
2940 uint64_t timebase_numerator;
2941 uint64_t timebase_denominator;
2943 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2945 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2946 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2947 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2948 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2949 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2950 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2952 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2953 "Timebase %"PRId64" / %"PRId64,
2954 major_version, minor_version,
2955 timebase_numerator, timebase_denominator );
2957 else if( p_oggpacket->bytes >= 42 &&
2958 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2960 uint64_t granule_rate_numerator;
2961 uint64_t granule_rate_denominator;
2962 char content_type_string[1024];
2964 /* Read in Annodex header fields */
2966 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2967 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2968 p_stream->i_secondary_header_packets =
2969 GetDWLE( &p_oggpacket->packet[24] );
2971 /* we are guaranteed that the first header field will be
2972 * the content-type (by the Annodex standard) */
2973 content_type_string[0] = '\0';
2974 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2976 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2977 p_oggpacket->bytes - 1 );
2978 if( p && p[0] == '\r' && p[1] == '\n' )
2979 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2980 content_type_string );
2983 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2984 granule_rate_numerator, granule_rate_denominator,
2985 p_stream->i_secondary_header_packets, content_type_string );
2987 p_stream->f_rate = (float) granule_rate_numerator /
2988 (float) granule_rate_denominator;
2990 /* What type of file do we have?
2991 * strcmp is safe to use here because we've extracted
2992 * content_type_string from the stream manually */
2993 bool b_dopacketout = false;
2994 Ogg_ApplyContentType( p_stream, content_type_string,
2995 &p_stream->b_force_backup, &b_dopacketout );
2996 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3000 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3001 ogg_packet *p_oggpacket )
3003 p_demux->p_sys->p_skelstream = p_stream;
3004 /* There can be only 1 skeleton for streams */
3005 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3006 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3007 if ( asprintf( & p_stream->fmt.psz_description,
3008 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3009 p_demux->p_sys->skeleton.major,
3010 p_demux->p_sys->skeleton.minor ) < 0 )
3011 p_stream->fmt.psz_description = NULL;
3014 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3016 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3018 /* Find the matching stream for this skeleton data */
3019 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3020 logical_stream_t *p_target_stream = NULL;
3021 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3023 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3025 p_target_stream = p_demux->p_sys->pp_stream[i];
3029 if ( !p_target_stream ) return;
3031 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3034 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3035 if ( !p_skel ) return;
3036 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3037 p_skel->p_index = NULL;
3038 p_target_stream->p_skel = p_skel;
3041 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3042 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3043 const unsigned char *p = p_messages;
3044 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3046 if ( *p == 0x0D && *(p+1) == 0x0A )
3048 char *psz_message = strndup( (const char *) p_messages,
3052 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3053 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3055 if ( p < p_boundary - 1 ) p_messages = p + 2;
3062 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3063 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3064 unsigned const char *p_end,
3065 uint64_t *pi_value )
3071 while ( p_begin < p_end )
3073 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3074 *pi_value = *pi_value | ( i_read << i_shift );
3076 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3079 *pi_value = GetQWLE( pi_value );
3083 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3085 if ( p_demux->p_sys->skeleton.major < 4
3086 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3089 /* Find the matching stream for this skeleton data */
3090 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3091 logical_stream_t *p_stream = NULL;
3092 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3094 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3096 p_stream = p_demux->p_sys->pp_stream[i];
3100 if ( !p_stream ) return;
3101 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3102 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3103 if ( !i_keypoints ) return;
3105 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3106 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3107 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3108 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3109 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3110 uint64_t i_offset = 0;
3111 uint64_t i_time = 0;
3112 uint64_t i_keypoints_found = 0;
3114 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3117 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3119 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3120 i_time += i_val * p_stream->p_skel->i_indexstampden;
3121 i_keypoints_found++;
3124 if ( i_keypoints_found != i_keypoints )
3126 msg_Warn( p_demux, "Invalid Index: missing entries" );
3130 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3131 if ( !p_stream->p_skel->p_index ) return;
3132 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3133 p_oggpacket->bytes - 42 );
3134 p_stream->p_skel->i_index = i_keypoints_found;
3135 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3138 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3140 if ( !p_skel ) return;
3141 for ( int i=0; i< p_skel->i_messages; i++ )
3142 free( p_skel->ppsz_messages[i] );
3143 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3144 free( p_skel->p_index );
3148 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3150 if ( !p_stream->p_skel ) return;
3151 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3153 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3154 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3156 free( p_stream->fmt.psz_description );
3157 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3159 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3162 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3167 /* Return true if there's a skeleton exact match */
3168 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3169 int64_t *pi_lower, int64_t *pi_upper )
3171 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3174 /* Validate range */
3175 if ( i_time < p_stream->p_skel->i_indexfirstnum
3176 * p_stream->p_skel->i_indexstampden ||
3177 i_time > p_stream->p_skel->i_indexlastnum
3178 * p_stream->p_skel->i_indexstampden ) return false;
3180 /* Then Lookup its index */
3181 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3186 } current = { 0, 0 }, prev = { -1, -1 };
3188 uint64_t i_keypoints_found = 0;
3190 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3191 && i_keypoints_found < p_stream->p_skel->i_index )
3194 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3195 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3196 current.i_pos += i_val;
3197 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3198 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3199 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3200 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3202 i_keypoints_found++;
3204 if ( i_time <= current.i_time )
3206 *pi_lower = prev.i_pos;
3207 *pi_upper = current.i_pos;
3208 return ( i_time == current.i_time );
3215 static uint32_t dirac_uint( bs_t *p_bs )
3217 uint32_t u_count = 0, u_value = 0;
3219 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3223 u_value |= bs_read( p_bs, 1 );
3226 return (1<<u_count) - 1 + u_value;
3229 static int dirac_bool( bs_t *p_bs )
3231 return bs_read( p_bs, 1 );
3234 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3235 ogg_packet *p_oggpacket )
3237 static const struct {
3238 uint32_t u_n /* numerator */, u_d /* denominator */;
3239 } p_dirac_frate_tbl[] = { /* table 10.3 */
3240 {1,1}, /* this first value is never used */
3241 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3242 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3244 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3246 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3247 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3249 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3253 p_stream->i_granule_shift = 22; /* not 32 */
3255 /* Backing up stream headers is not required -- seqhdrs are repeated
3256 * thoughout the stream at suitable decoding start points */
3257 p_stream->b_force_backup = false;
3259 /* read in useful bits from sequence header */
3260 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3261 bs_skip( &bs, 13*8); /* parse_info_header */
3262 dirac_uint( &bs ); /* major_version */
3263 dirac_uint( &bs ); /* minor_version */
3264 dirac_uint( &bs ); /* profile */
3265 dirac_uint( &bs ); /* level */
3267 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3268 if( u_video_format >= u_dirac_vidfmt_frate )
3270 /* don't know how to parse this ogg dirac stream */
3274 if( dirac_bool( &bs ) )
3276 dirac_uint( &bs ); /* frame_width */
3277 dirac_uint( &bs ); /* frame_height */
3280 if( dirac_bool( &bs ) )
3282 dirac_uint( &bs ); /* chroma_format */
3285 if( dirac_bool( &bs ) )
3287 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3290 p_stream->special.dirac.b_interlaced = false;
3292 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3293 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3294 u_d = __MAX( u_d, 1 );
3295 if( dirac_bool( &bs ) )
3297 uint32_t u_frame_rate_index = dirac_uint( &bs );
3298 if( u_frame_rate_index >= u_dirac_frate_tbl )
3300 /* something is wrong with this stream */
3303 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3304 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3305 if( u_frame_rate_index == 0 )
3307 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3308 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3311 p_stream->f_rate = (float) u_n / u_d;
3312 if ( p_stream->f_rate == 0 ) return false;
3314 /* probably is an ogg dirac es */
3315 p_stream->fmt.i_cat = VIDEO_ES;
3316 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;