1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_demux.h>
37 #include <vlc_input.h>
41 #include <vlc_codecs.h>
44 #include "xiph_metadata.h"
49 /*****************************************************************************
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close( vlc_object_t * );
56 set_shortname ( "OGG" )
57 set_description( N_("OGG demuxer" ) )
58 set_category( CAT_INPUT )
59 set_subcategory( SUBCAT_INPUT_DEMUX )
60 set_capability( "demux", 50 )
61 set_callbacks( Open, Close )
66 /*****************************************************************************
67 * Definitions of structures and functions used by this plugins
68 *****************************************************************************/
70 /* OggDS headers for the new header format (used in ogm files) */
75 } stream_header_video_t;
81 ogg_int16_t blockalign;
82 ogg_int32_t avgbytespersec;
83 } stream_header_audio_t;
90 ogg_int32_t size; /* size of the structure */
92 ogg_int64_t time_unit; /* in reference time */
93 ogg_int64_t samples_per_unit;
94 ogg_int32_t default_len; /* in media time */
96 ogg_int32_t buffersize;
97 ogg_int16_t bits_per_sample;
103 stream_header_video_t video;
105 stream_header_audio_t audio;
109 #define VORBIS_HEADER_IDENTIFICATION 1
110 #define VORBIS_HEADER_COMMENT 2
111 #define VORBIS_HEADER_SETUP 3
113 /*****************************************************************************
115 *****************************************************************************/
116 static int Demux ( demux_t * );
117 static int Control( demux_t *, int, va_list );
119 /* Bitstream manipulation */
120 static int Ogg_ReadPage ( demux_t *, ogg_page * );
121 static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * );
122 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
123 static int Ogg_OpusPacketDuration( ogg_packet * );
124 static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * );
126 static void Ogg_CreateES( demux_t *p_demux );
127 static int Ogg_BeginningOfStream( demux_t *p_demux );
128 static int Ogg_FindLogicalStreams( demux_t *p_demux );
129 static void Ogg_EndOfStream( demux_t *p_demux );
132 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
133 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
134 static void Ogg_ResetStream( logical_stream_t *p_stream );
137 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
139 /* Logical bitstream headers */
140 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
141 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
142 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
143 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
144 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
145 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
146 static bool Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
147 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
148 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
149 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
150 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
153 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
154 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
155 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
156 static void Ogg_ApplySkeleton( logical_stream_t * );
158 /* Special decoding */
159 static void Ogg_CleanSpecificData( logical_stream_t * );
160 #ifdef HAVE_LIBVORBIS
161 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
164 static void fill_channels_info(audio_format_t *audio)
166 static const int pi_channels_map[9] =
170 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
171 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
172 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
173 | AOUT_CHAN_REARRIGHT,
174 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
175 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
176 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
177 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
178 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
179 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
180 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
181 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
182 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
186 unsigned chans = audio->i_channels;
187 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
188 audio->i_physical_channels =
189 audio->i_original_channels = pi_channels_map[chans];
192 /* Special TS value: don't send or derive any pts/pcr from it.
193 Represents TS state prior first known valid timestamp */
194 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
196 /*****************************************************************************
197 * Open: initializes ogg demux structures
198 *****************************************************************************/
199 static int Open( vlc_object_t * p_this )
201 demux_t *p_demux = (demux_t *)p_this;
203 const uint8_t *p_peek;
205 /* Check if we are dealing with an ogg stream */
206 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
207 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
209 char *psz_mime = stream_ContentType( p_demux->s );
214 else if ( strcmp( psz_mime, "application/ogg" ) &&
215 strcmp( psz_mime, "video/ogg" ) &&
216 strcmp( psz_mime, "audio/ogg" ) )
225 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
229 p_sys->i_length = -1;
230 p_sys->b_preparsing_done = false;
232 stream_Control( p_demux->s, ACCESS_GET_PTS_DELAY, & p_sys->i_access_delay );
234 /* Set exported functions */
235 p_demux->pf_demux = Demux;
236 p_demux->pf_control = Control;
238 /* Initialize the Ogg physical bitstream parser */
239 ogg_sync_init( &p_sys->oy );
242 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
245 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
251 /*****************************************************************************
252 * Close: frees unused data
253 *****************************************************************************/
254 static void Close( vlc_object_t *p_this )
256 demux_t *p_demux = (demux_t *)p_this;
257 demux_sys_t *p_sys = p_demux->p_sys ;
259 /* Cleanup the bitstream parser */
260 ogg_sync_clear( &p_sys->oy );
262 Ogg_EndOfStream( p_demux );
264 if( p_sys->p_old_stream )
265 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
270 /*****************************************************************************
271 * Demux: reads and demuxes data packets
272 *****************************************************************************
273 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
274 *****************************************************************************/
275 static int Demux( demux_t * p_demux )
277 demux_sys_t *p_sys = p_demux->p_sys;
278 ogg_packet oggpacket;
280 bool b_skipping = false;
283 int i_active_streams = p_sys->i_streams;
284 for ( int i=0; i < p_sys->i_streams; i++ )
286 if ( p_sys->pp_stream[i]->b_finished )
290 if ( i_active_streams == 0 )
292 if ( p_sys->i_streams ) /* All finished */
294 msg_Dbg( p_demux, "end of a group of logical streams" );
295 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
296 * only 1 ES is supported (common case for ogg web radio) */
297 if( p_sys->i_streams == 1 )
299 p_sys->p_old_stream = p_sys->pp_stream[0];
300 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
302 Ogg_EndOfStream( p_demux );
303 p_sys->b_chained_boundary = true;
306 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
309 msg_Dbg( p_demux, "beginning of a group of logical streams" );
311 if ( !p_sys->b_chained_boundary )
313 /* Find the real duration */
314 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
316 Oggseek_ProbeEnd( p_demux );
320 p_sys->b_chained_boundary = false;
324 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
326 Ogg_CreateES( p_demux );
327 p_sys->b_es_created = true;
331 * The first data page of a physical stream is stored in the relevant logical stream
332 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
333 * stream it belongs to if we haven't processed this first page yet. If we do, we
334 * will only process that first page whenever we find the second page for this stream.
335 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
336 * the second page will arrive real quick, this is not fine for Kate, whose second
337 * data page will typically arrive much later.
338 * This means it is now possible to seek right at the start of a stream where the last
339 * logical stream is Kate, without having to wait for the second data page to unblock
340 * the first one, which is the one that triggers the 'no more headers to backup' code.
341 * And, as we all know, seeking without having backed up all headers is bad, since the
342 * codec will fail to initialize if it's missing its headers.
344 if( !p_sys->b_page_waiting)
347 * Demux an ogg page from the stream
349 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
351 /* Test for End of Stream */
352 if( ogg_page_eos( &p_sys->current_page ) )
354 /* If we delayed restarting encoders/SET_ES_FMT for more
355 * skeleton provided configuration */
356 if ( p_sys->p_skelstream )
358 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
360 msg_Dbg( p_demux, "End of Skeleton" );
361 p_sys->b_preparsing_done = true;
362 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
364 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
365 Ogg_ApplySkeleton( p_stream );
370 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
372 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
374 p_sys->pp_stream[i_stream]->b_finished = true;
382 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
384 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
387 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
389 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
391 /* if we've just pulled page, look for the right logical stream */
392 if( !p_sys->b_page_waiting )
394 if( p_sys->i_streams == 1 &&
395 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
397 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
398 Ogg_ResetStream( p_stream );
399 p_sys->i_nzpcr_offset = (p_sys->i_pcr >= VLC_TS_INVALID) ?
400 p_sys->i_pcr - VLC_TS_0 : 0;
401 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
404 /* Does fail if serialno differs */
405 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
411 /* clear the finished flag if pages after eos (ex: after a seek) */
412 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
413 p_stream->b_finished = false;
416 if ( p_stream->fmt.i_cat == VIDEO_ES )
417 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
418 ogg_page_pageno( &p_sys->current_page ),
419 ogg_page_granulepos( &p_sys->current_page ),
420 ogg_page_packets( &p_sys->current_page ),
421 ogg_page_continued(&p_sys->current_page),
422 p_sys->current_page.body_len )
425 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
428 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
429 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
430 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
431 p_stream->fmt.i_cat == VIDEO_ES )
433 assert( p_stream->p_prepcr_blocks == NULL );
434 p_stream->i_prepcr_blocks = 0;
435 p_stream->p_prepcr_blocks = malloc( sizeof(block_t *) * ogg_page_packets( &p_sys->current_page ) );
439 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
441 /* Read info from any secondary header packets, if there are any */
442 if( p_stream->i_secondary_header_packets > 0 )
444 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
445 oggpacket.bytes >= 7 &&
446 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
448 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
449 p_stream->i_secondary_header_packets = 0;
451 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
452 oggpacket.bytes >= 6 &&
453 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
455 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
456 p_stream->i_secondary_header_packets = 0;
458 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
459 oggpacket.bytes >= 7 &&
460 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
462 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
463 p_stream->i_secondary_header_packets = 0;
465 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
467 p_stream->i_secondary_header_packets = 0;
470 /* update start of data pointer */
471 p_stream->i_data_start = stream_Tell( p_demux->s );
474 /* If any streams have i_skip_frames, only decode (pre-roll)
475 * for those streams, but don't skip headers */
476 if ( b_skipping && p_stream->i_skip_frames == 0
477 && p_stream->i_secondary_header_packets ) continue;
479 if( p_stream->b_reinit )
481 p_stream->b_reinit = false;
482 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
484 p_stream->i_skip_frames = p_stream->i_pre_skip;
488 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
492 if ( p_stream->p_prepcr_blocks )
494 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
495 p_stream->i_previous_pcr = pagestamp;
496 #ifdef HAVE_LIBVORBIS
497 int i_prev_blocksize = 0;
500 for( int i=0; i<p_stream->i_prepcr_blocks; i++ )
502 block_t *p_block = p_stream->p_prepcr_blocks[i];
503 ogg_packet dumb_packet;
504 dumb_packet.bytes = p_block->i_buffer;
505 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 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
516 #ifdef HAVE_LIBVORBIS
517 case VLC_CODEC_VORBIS:
519 long i_blocksize = vorbis_packet_blocksize(
520 p_stream->special.vorbis.p_info, &dumb_packet );
521 if ( i_prev_blocksize )
522 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
524 p_block->i_nb_samples = i_blocksize / 2;
525 i_prev_blocksize = i_blocksize;
532 bool b_fixed = false;
533 for( int i=p_stream->i_prepcr_blocks - 1; i>=0; i-- )
535 block_t *p_block = p_stream->p_prepcr_blocks[i];
536 switch( p_stream->fmt.i_codec )
538 case VLC_CODEC_SPEEX:
540 case VLC_CODEC_VORBIS:
541 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
544 p_block->i_pts = VLC_TS_INVALID;
545 p_block->i_flags |= BLOCK_FLAG_PREROLL;
548 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
552 if ( p_stream->fmt.i_cat == VIDEO_ES )
554 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
555 p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
563 if ( pagestamp < 0 ) pagestamp = 0;
564 p_stream->i_pcr = VLC_TS_0 + pagestamp;
565 p_stream->i_pcr += p_sys->i_nzpcr_offset;
566 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
569 FREENULL( p_stream->p_prepcr_blocks );
570 p_stream->i_prepcr_blocks = 0;
572 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
576 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
577 ogg_page_granulepos( &p_sys->current_page ), false );
578 if ( i_pagestamp > -1 )
580 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
581 p_stream->i_pcr += p_sys->i_nzpcr_offset;
584 if( !p_sys->b_page_waiting )
588 /* if a page was waiting, it's now processed */
589 p_sys->b_page_waiting = false;
591 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
592 p_sys->b_preparsing_done = false;
594 p_sys->b_preparsing_done = true;
596 /* We will consider the lowest PCR among tracks, because the audio core badly
597 * handles PCR rewind (mute)
599 mtime_t i_pcr_candidate = VLC_TS_INVALID;
600 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
602 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
604 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
606 /* We have 1 or more streams needing more than 1 page for preparsing */
607 p_sys->b_preparsing_done = false;
610 if( p_stream->fmt.i_cat == SPU_ES )
612 if( p_stream->i_pcr < VLC_TS_0 )
614 if ( p_stream->b_finished || p_stream->b_initializing )
616 if ( p_stream->p_preparse_block )
618 if( i_pcr_candidate < VLC_TS_0
619 || p_stream->i_pcr <= i_pcr_candidate )
621 i_pcr_candidate = p_stream->i_pcr;
625 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
627 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
629 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
630 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
632 p_sys->i_pcr_jitter = i_pcr_jitter;
633 if ( p_sys->i_access_delay < i_pcr_jitter )
634 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
635 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
639 if( ! b_skipping && p_sys->b_preparsing_done )
641 p_sys->i_pcr = i_pcr_candidate;
642 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
649 static void Ogg_ResetStream( logical_stream_t *p_stream )
651 #ifdef HAVE_LIBVORBIS
652 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
654 p_stream->special.vorbis.i_prev_blocksize = 0;
657 /* we'll trash all the data until we find the next pcr */
658 p_stream->b_reinit = true;
659 p_stream->i_pcr = VLC_TS_UNKNOWN;
660 p_stream->i_previous_granulepos = -1;
661 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
662 ogg_stream_reset( &p_stream->os );
663 FREENULL( p_stream->p_prepcr_blocks );
664 p_stream->i_prepcr_blocks = 0;
667 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
669 for( int i = 0; i < p_sys->i_streams; i++ )
670 Ogg_ResetStream( p_sys->pp_stream[i] );
672 ogg_sync_reset( &p_sys->oy );
673 p_sys->i_pcr = VLC_TS_UNKNOWN;
676 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
678 demux_sys_t *p_sys = p_demux->p_sys;
679 logical_stream_t *p_stream = NULL;
680 for( int i=0; i<p_sys->i_streams; i++ )
682 logical_stream_t *p_candidate = p_sys->pp_stream[i];
683 if ( !p_candidate->p_es ) continue;
685 bool b_selected = false;
686 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
687 p_candidate->p_es, &b_selected );
688 if ( !b_selected ) continue;
690 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
692 p_stream = p_candidate;
693 continue; /* Try to find video anyway */
696 if ( p_candidate->fmt.i_cat == VIDEO_ES )
698 p_stream = p_candidate;
705 /*****************************************************************************
707 *****************************************************************************/
708 static int Control( demux_t *p_demux, int i_query, va_list args )
710 demux_sys_t *p_sys = p_demux->p_sys;
719 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
721 vlc_meta_Merge( p_meta, p_sys->p_meta );
724 case DEMUX_HAS_UNSUPPORTED_META:
725 pb_bool = (bool*)va_arg( args, bool* );
730 pi64 = (int64_t*)va_arg( args, int64_t * );
731 *pi64 = p_sys->i_pcr;
735 i64 = (int64_t)va_arg( args, int64_t );
736 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
739 msg_Err( p_demux, "No selected seekable stream found" );
742 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
743 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
745 Ogg_ResetStreamsHelper( p_sys );
746 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
753 case DEMUX_GET_ATTACHMENTS:
755 input_attachment_t ***ppp_attach =
756 (input_attachment_t***)va_arg( args, input_attachment_t*** );
757 int *pi_int = (int*)va_arg( args, int * );
759 if( p_sys->i_attachments <= 0 )
762 *pi_int = p_sys->i_attachments;
763 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
764 for( int i = 0; i < p_sys->i_attachments; i++ )
765 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
769 case DEMUX_GET_POSITION:
770 pf = (double*)va_arg( args, double * );
771 if( p_sys->i_length > 0 )
773 *pf = (double) p_sys->i_pcr /
774 (double) ( p_sys->i_length * (mtime_t)1000000 );
776 else if( stream_Size( p_demux->s ) > 0 )
778 i64 = stream_Tell( p_demux->s );
779 *pf = (double) i64 / stream_Size( p_demux->s );
784 case DEMUX_SET_POSITION:
785 /* forbid seeking if we haven't initialized all logical bitstreams yet;
786 if we allowed, some headers would not get backed up and decoder init
787 would fail, making that logical stream unusable */
788 for ( int i=0; i< p_sys->i_streams; i++ )
790 if ( p_sys->pp_stream[i]->b_initializing )
794 p_stream = Ogg_GetSelectedStream( p_demux );
797 msg_Err( p_demux, "No selected seekable stream found" );
801 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
803 f = (double)va_arg( args, double );
804 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
806 Ogg_ResetStreamsHelper( p_sys );
807 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
811 assert( p_sys->i_length > 0 );
812 i64 = CLOCK_FREQ * p_sys->i_length * f;
813 Ogg_ResetStreamsHelper( p_sys );
814 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
816 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
823 case DEMUX_GET_LENGTH:
824 if ( p_sys->i_length < 0 )
825 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
827 pi64 = (int64_t*)va_arg( args, int64_t * );
828 *pi64 = p_sys->i_length * 1000000;
831 case DEMUX_GET_TITLE_INFO:
833 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
834 int *pi_int = (int*)va_arg( args, int* );
835 int *pi_title_offset = (int*)va_arg( args, int* );
836 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
838 if( p_sys->i_seekpoints > 0 )
841 *ppp_title = malloc( sizeof( input_title_t* ) );
842 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
843 for( int i = 0; i < p_sys->i_seekpoints; i++ )
845 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
846 if ( likely( p_seekpoint_copy ) )
847 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
849 *pi_title_offset = 0;
850 *pi_seekpoint_offset = 0;
854 case DEMUX_SET_TITLE:
856 const int i_title = (int)va_arg( args, int );
861 case DEMUX_SET_SEEKPOINT:
863 const int i_seekpoint = (int)va_arg( args, int );
864 if( i_seekpoint > p_sys->i_seekpoints )
867 for ( int i=0; i< p_sys->i_streams; i++ )
869 if ( p_sys->pp_stream[i]->b_initializing )
873 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
875 p_stream = Ogg_GetSelectedStream( p_demux );
878 msg_Err( p_demux, "No selected seekable stream found" );
882 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
883 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
885 Ogg_ResetStreamsHelper( p_sys );
886 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
888 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
889 p_demux->info.i_seekpoint = i_seekpoint;
897 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
902 /****************************************************************************
903 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
904 ****************************************************************************
905 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
906 * are at the end of stream.
907 ****************************************************************************/
908 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
910 demux_sys_t *p_ogg = p_demux->p_sys ;
914 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
916 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
918 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
922 ogg_sync_wrote( &p_ogg->oy, i_read );
928 /****************************************************************************
929 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
931 ****************************************************************************/
932 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
933 ogg_packet *p_oggpacket )
935 demux_sys_t *p_ogg = p_demux->p_sys;
936 p_stream->i_end_trim = 0;
938 /* Convert the granulepos into a pcr */
939 if ( p_oggpacket->granulepos == 0 )
941 /* We're in headers, and we haven't parsed 1st data packet yet */
942 // p_stream->i_pcr = VLC_TS_UNKNOWN;
944 else if( p_oggpacket->granulepos > 0 )
946 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
947 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
948 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
949 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
950 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
951 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
952 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
954 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
955 p_oggpacket->granulepos, true );
956 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
958 else if ( p_stream->i_previous_granulepos > 0 )
960 ogg_int64_t sample = p_stream->i_previous_granulepos;
962 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
964 int duration = Ogg_OpusPacketDuration( p_oggpacket );
967 ogg_int64_t end_sample = p_oggpacket->granulepos;
968 if( end_sample < ( sample + duration ) )
969 p_stream->i_end_trim = sample + duration - end_sample;
973 if (sample >= p_stream->i_pre_skip)
974 sample -= p_stream->i_pre_skip;
978 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
979 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
983 else if ( p_oggpacket->granulepos == -1 )
986 /* no granulepos available, try to interpolate the pcr.
987 * If we can't then don't touch the old value. */
988 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
990 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
992 #ifdef HAVE_LIBVORBIS
993 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
994 p_stream->special.vorbis.p_info &&
995 !p_stream->special.vorbis.b_invalid &&
996 p_stream->i_previous_granulepos > 0 )
998 long i_blocksize = vorbis_packet_blocksize(
999 p_stream->special.vorbis.p_info, p_oggpacket );
1000 if ( p_stream->special.vorbis.i_prev_blocksize )
1001 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1003 i_duration = i_blocksize / 2;
1004 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1005 /* duration in samples per channel */
1006 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1007 p_stream->i_pcr = p_stream->i_previous_granulepos *
1008 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1009 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1012 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1013 p_stream->i_previous_granulepos > 0 )
1015 i_duration = p_stream->special.speex.i_framesize *
1016 p_stream->special.speex.i_framesperpacket;
1017 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1018 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1019 p_stream->i_previous_granulepos, false );
1020 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1022 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1023 p_stream->i_previous_granulepos > 0 &&
1025 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1028 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1029 sample = p_stream->i_previous_granulepos;
1030 if (sample >= p_stream->i_pre_skip)
1031 sample -= p_stream->i_pre_skip;
1035 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1036 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1038 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1040 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1041 p_stream->fmt.i_bitrate / 8 );
1045 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1048 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1051 demux_sys_t *p_ogg = p_demux->p_sys;
1052 if ( !p_stream->p_es || p_stream->p_prepcr_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN )
1054 if ( !p_block ) return;
1055 if ( p_stream->p_prepcr_blocks )
1057 assert( p_stream->p_prepcr_blocks );
1058 p_stream->p_prepcr_blocks[p_stream->i_prepcr_blocks++] = p_block;
1060 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1061 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1062 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1066 /* Because ES creation is delayed for preparsing */
1067 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1068 if ( p_stream->p_preparse_block )
1070 block_t *temp = p_stream->p_preparse_block;
1073 if ( temp && i_firstpts < VLC_TS_0 )
1074 i_firstpts = temp->i_pts;
1076 block_t *tosend = temp;
1077 temp = temp->p_next;
1078 tosend->p_next = NULL;
1080 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1081 tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1082 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1084 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1086 p_ogg->i_pcr = i_firstpts;
1087 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1090 p_stream->p_preparse_block = NULL;
1095 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1096 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1097 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1102 /****************************************************************************
1103 * Ogg_DecodePacket: Decode an Ogg packet.
1104 ****************************************************************************/
1105 static void Ogg_DecodePacket( demux_t *p_demux,
1106 logical_stream_t *p_stream,
1107 ogg_packet *p_oggpacket )
1111 int i_header_len = 0;
1113 if( p_oggpacket->bytes >= 7 &&
1114 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1116 /* it's an Annodex packet -- skip it (do nothing) */
1119 else if( p_oggpacket->bytes >= 7 &&
1120 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1122 /* it's an AnxData packet -- skip it (do nothing) */
1125 else if( p_oggpacket->bytes >= 8 &&
1126 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1128 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1131 else if( p_oggpacket->bytes >= 6 &&
1132 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1134 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1137 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1138 p_oggpacket->bytes >= 7 &&
1139 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1141 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1145 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1146 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1148 /* Check the ES is selected */
1149 if ( !p_stream->p_es )
1152 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1153 p_stream->p_es, &b_selected );
1155 if( p_stream->b_force_backup )
1158 p_stream->i_packets_backup++;
1159 switch( p_stream->fmt.i_codec )
1161 case VLC_CODEC_VORBIS:
1162 #ifdef HAVE_LIBVORBIS
1163 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1166 case VLC_CODEC_THEORA:
1167 if( p_stream->i_packets_backup == 3 )
1168 p_stream->b_force_backup = false;
1172 case VLC_CODEC_DAALA:
1173 if( p_stream->i_packets_backup == 3 )
1174 p_stream->b_force_backup = false;
1178 case VLC_CODEC_SPEEX:
1179 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1180 p_stream->b_force_backup = false;
1184 case VLC_CODEC_OPUS:
1185 if( p_stream->i_packets_backup == 2 )
1186 p_stream->b_force_backup = false;
1190 case VLC_CODEC_FLAC:
1191 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1193 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1194 p_stream->b_force_backup = false;
1196 else if( p_stream->fmt.audio.i_rate )
1198 p_stream->b_force_backup = false;
1199 if( p_oggpacket->bytes >= 9 )
1201 p_oggpacket->packet += 9;
1202 p_oggpacket->bytes -= 9;
1208 case VLC_CODEC_KATE:
1209 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1210 p_stream->b_force_backup = false;
1215 p_stream->b_force_backup = false;
1220 /* Backup the ogg packet (likely an header packet) */
1223 void *p_org = p_stream->p_headers;
1224 p_stream->i_headers += p_oggpacket->bytes;
1225 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1226 if( p_stream->p_headers )
1228 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1229 p_oggpacket->packet, p_oggpacket->bytes );
1233 #warning Memory leak
1234 p_stream->i_headers = 0;
1235 p_stream->p_headers = NULL;
1239 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1240 p_oggpacket->bytes, p_oggpacket->packet ) )
1242 p_stream->i_headers = 0;
1243 p_stream->p_headers = NULL;
1245 if( p_stream->i_headers > 0 )
1247 if( !p_stream->b_force_backup )
1249 /* Last header received, commit changes */
1250 free( p_stream->fmt.p_extra );
1252 p_stream->fmt.i_extra = p_stream->i_headers;
1253 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1254 if( p_stream->fmt.p_extra )
1255 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1256 p_stream->i_headers );
1258 p_stream->fmt.i_extra = 0;
1260 if( p_stream->i_headers > 0 )
1261 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1262 p_stream->p_headers, p_stream->i_headers );
1264 /* we're not at BOS anymore for this logical stream */
1265 p_stream->b_initializing = false;
1269 b_selected = false; /* Discard the header packet */
1273 p_stream->b_initializing = false;
1276 /* Convert the granulepos into the next pcr */
1277 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1281 /* This stream isn't currently selected so we don't need to decode it,
1282 * but we did need to store its pcr as it might be selected later on */
1286 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1287 p_block->i_pts = p_stream->i_pcr;
1289 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1290 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1292 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1293 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1295 /* may need to preroll after a seek or in case of preskip */
1296 if ( p_stream->i_skip_frames > 0 )
1298 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1300 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1302 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1303 p_stream->i_skip_frames -= p_block->i_nb_samples;
1304 p_block->i_nb_samples = 0;
1308 p_block->i_nb_samples -= p_stream->i_skip_frames;
1309 p_stream->i_skip_frames = 0;
1314 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1315 p_stream->i_skip_frames--;
1319 /* Conditional block fixes */
1320 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1321 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1323 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1325 else if( p_stream->fmt.i_cat == AUDIO_ES )
1327 /* Blatant abuse of the i_length field. */
1328 p_block->i_length = p_stream->i_end_trim;
1330 else if( p_stream->fmt.i_cat == SPU_ES )
1332 p_block->i_length = 0;
1334 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1336 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1337 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1338 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1339 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1340 /* granulepos for dirac is possibly broken, this value should be ignored */
1341 if( 0 >= p_oggpacket->granulepos )
1343 p_block->i_pts = VLC_TS_INVALID;
1344 p_block->i_dts = p_stream->i_pcr;
1348 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1349 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1350 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1351 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1352 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1353 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1354 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1355 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1356 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1357 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1358 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1360 if( p_oggpacket->bytes <= 0 )
1362 msg_Dbg( p_demux, "discarding 0 sized packet" );
1363 block_Release( p_block );
1366 /* We remove the header from the packet */
1367 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1368 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1370 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1372 /* But with subtitles we need to retrieve the duration first */
1373 int i, lenbytes = 0;
1375 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1377 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1379 lenbytes = lenbytes << 8;
1380 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1383 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1384 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1385 p_oggpacket->packet[i_header_len + 1] != 0 &&
1386 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1387 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1389 p_block->i_length = (mtime_t)lenbytes * 1000;
1394 if( p_block->i_buffer >= (unsigned int)i_header_len )
1395 p_block->i_buffer -= i_header_len;
1397 p_block->i_buffer = 0;
1401 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1403 /* FIXME: the biggest hack I've ever done */
1404 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1405 p_block->i_pts, p_block->i_dts );
1409 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1410 p_oggpacket->bytes - i_header_len );
1412 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1415 static int Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1417 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1420 /****************************************************************************
1421 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1422 * stream and fill p_ogg.
1423 *****************************************************************************
1424 * The initial page of a logical stream is marked as a 'bos' page.
1425 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1426 * together and all of the initial pages must appear before any data pages.
1428 * On success this function returns VLC_SUCCESS.
1429 ****************************************************************************/
1430 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1432 demux_sys_t *p_ogg = p_demux->p_sys ;
1433 ogg_packet oggpacket;
1436 p_ogg->i_total_length = stream_Size ( p_demux->s );
1437 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1440 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1443 if( ogg_page_bos( &p_ogg->current_page ) )
1446 /* All is wonderful in our fine fine little world.
1447 * We found the beginning of our first logical stream. */
1448 while( ogg_page_bos( &p_ogg->current_page ) )
1450 logical_stream_t *p_stream;
1452 p_stream = malloc( sizeof(logical_stream_t) );
1453 if( unlikely( !p_stream ) )
1456 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1458 memset( p_stream, 0, sizeof(logical_stream_t) );
1460 es_format_Init( &p_stream->fmt, 0, 0 );
1461 es_format_Init( &p_stream->fmt_old, 0, 0 );
1462 p_stream->b_initializing = true;
1464 /* Setup the logical stream */
1465 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1466 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1468 /* Extract the initial header from the first page and verify
1469 * the codec type of this Ogg bitstream */
1470 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1472 /* error. stream version mismatch perhaps */
1473 msg_Err( p_demux, "error reading first page of "
1474 "Ogg bitstream data" );
1475 return VLC_EGENERIC;
1478 /* FIXME: check return value */
1479 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1481 /* Check for Vorbis header */
1482 if( oggpacket.bytes >= 7 &&
1483 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1485 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1486 msg_Dbg( p_demux, "found vorbis header" );
1489 msg_Dbg( p_demux, "found invalid vorbis header" );
1490 Ogg_LogicalStreamDelete( p_demux, p_stream );
1494 /* Check for Speex header */
1495 else if( oggpacket.bytes >= 5 &&
1496 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1498 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1499 msg_Dbg( p_demux, "found speex header, channels: %i, "
1500 "rate: %i, bitrate: %i, frames: %i group %i",
1501 p_stream->fmt.audio.i_channels,
1502 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1503 p_stream->special.speex.i_framesize,
1504 p_stream->special.speex.i_framesperpacket );
1507 msg_Dbg( p_demux, "found invalid Speex header" );
1508 Ogg_LogicalStreamDelete( p_demux, p_stream );
1512 /* Check for Opus header */
1513 else if( oggpacket.bytes >= 8 &&
1514 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1516 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1517 msg_Dbg( p_demux, "found opus header, channels: %i, "
1519 p_stream->fmt.audio.i_channels,
1520 (int)p_stream->i_pre_skip);
1521 p_stream->i_skip_frames = p_stream->i_pre_skip;
1523 /* Check for Flac header (< version 1.1.1) */
1524 else if( oggpacket.bytes >= 4 &&
1525 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1527 msg_Dbg( p_demux, "found FLAC header" );
1529 /* Grrrr!!!! Did they really have to put all the
1530 * important info in the second header packet!!!
1531 * (STREAMINFO metadata is in the following packet) */
1532 p_stream->b_force_backup = true;
1533 p_stream->fmt.i_cat = AUDIO_ES;
1534 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1536 /* Check for Flac header (>= version 1.1.1) */
1537 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1538 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1539 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1541 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1542 oggpacket.packet[8];
1543 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1544 "(%i header packets)",
1545 oggpacket.packet[5], oggpacket.packet[6],
1548 p_stream->b_force_backup = true;
1550 p_stream->fmt.i_cat = AUDIO_ES;
1551 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1552 oggpacket.packet += 13; oggpacket.bytes -= 13;
1553 if ( !Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket ) )
1555 msg_Dbg( p_demux, "found invalid Flac header" );
1556 Ogg_LogicalStreamDelete( p_demux, p_stream );
1560 /* Check for Theora header */
1561 else if( oggpacket.bytes >= 7 &&
1562 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1564 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1566 "found theora header, bitrate: %i, rate: %f",
1567 p_stream->fmt.i_bitrate, p_stream->f_rate );
1570 msg_Dbg( p_demux, "found invalid Theora header" );
1571 Ogg_LogicalStreamDelete( p_demux, p_stream );
1575 /* Check for Daala header */
1576 else if( oggpacket.bytes >= 6 &&
1577 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1579 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1581 "found daala header, bitrate: %i, rate: %f",
1582 p_stream->fmt.i_bitrate, p_stream->f_rate );
1585 msg_Dbg( p_demux, "found invalid Daala header" );
1586 Ogg_LogicalStreamDelete( p_demux, p_stream );
1590 /* Check for Dirac header */
1591 else if( ( oggpacket.bytes >= 5 &&
1592 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1593 ( oggpacket.bytes >= 9 &&
1594 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1596 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1597 msg_Dbg( p_demux, "found dirac header" );
1600 msg_Warn( p_demux, "found dirac header isn't decodable" );
1601 Ogg_LogicalStreamDelete( p_demux, p_stream );
1605 /* Check for Tarkin header */
1606 else if( oggpacket.bytes >= 7 &&
1607 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1611 msg_Dbg( p_demux, "found tarkin header" );
1612 p_stream->fmt.i_cat = VIDEO_ES;
1613 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1615 /* Cheat and get additionnal info ;) */
1616 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1617 oggpack_adv( &opb, 88 );
1618 oggpack_adv( &opb, 104 );
1619 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1620 p_stream->f_rate = 2; /* FIXME */
1622 "found tarkin header, bitrate: %i, rate: %f",
1623 p_stream->fmt.i_bitrate, p_stream->f_rate );
1625 /* Check for VP8 header */
1626 else if( oggpacket.bytes >= 26 &&
1627 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1629 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1630 msg_Dbg( p_demux, "found VP8 header "
1631 "fps: %f, width:%i; height:%i",
1633 p_stream->fmt.video.i_width,
1634 p_stream->fmt.video.i_height );
1637 msg_Dbg( p_demux, "invalid VP8 header found");
1638 Ogg_LogicalStreamDelete( p_demux, p_stream );
1642 /* Check for Annodex header */
1643 else if( oggpacket.bytes >= 7 &&
1644 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1646 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1647 /* kill annodex track */
1651 /* Check for Annodex header */
1652 else if( oggpacket.bytes >= 7 &&
1653 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1655 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1657 /* Check for Kate header */
1658 else if( oggpacket.bytes >= 8 &&
1659 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1661 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1662 msg_Dbg( p_demux, "found kate header" );
1665 msg_Dbg( p_demux, "invalid kate header found");
1666 Ogg_LogicalStreamDelete( p_demux, p_stream );
1670 /* Check for OggDS */
1671 else if( oggpacket.bytes >= 142 &&
1672 !memcmp( &oggpacket.packet[1],
1673 "Direct Show Samples embedded in Ogg", 35 ))
1675 /* Old header type */
1676 p_stream->b_oggds = true;
1677 /* Check for video header (old format) */
1678 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1679 oggpacket.bytes >= 184 )
1681 p_stream->fmt.i_cat = VIDEO_ES;
1682 p_stream->fmt.i_codec =
1683 VLC_FOURCC( oggpacket.packet[68],
1684 oggpacket.packet[69],
1685 oggpacket.packet[70],
1686 oggpacket.packet[71] );
1687 msg_Dbg( p_demux, "found video header of type: %.4s",
1688 (char *)&p_stream->fmt.i_codec );
1690 p_stream->fmt.video.i_frame_rate = 10000000;
1691 p_stream->fmt.video.i_frame_rate_base =
1692 GetQWLE((oggpacket.packet+164));
1693 p_stream->fmt.video.i_frame_rate_base =
1694 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1695 p_stream->f_rate = 10000000.0 /
1696 p_stream->fmt.video.i_frame_rate_base;
1697 p_stream->fmt.video.i_bits_per_pixel =
1698 GetWLE((oggpacket.packet+182));
1699 if( !p_stream->fmt.video.i_bits_per_pixel )
1701 p_stream->fmt.video.i_bits_per_pixel = 24;
1702 p_stream->fmt.video.i_width =
1703 GetDWLE((oggpacket.packet+176));
1704 p_stream->fmt.video.i_height =
1705 GetDWLE((oggpacket.packet+180));
1708 "fps: %f, width:%i; height:%i, bitcount:%i",
1710 p_stream->fmt.video.i_width,
1711 p_stream->fmt.video.i_height,
1712 p_stream->fmt.video.i_bits_per_pixel);
1715 /* Check for audio header (old format) */
1716 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1719 unsigned int i_format_tag;
1721 p_stream->fmt.i_cat = AUDIO_ES;
1723 i_extra_size = GetWLE((oggpacket.packet+140));
1724 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1726 p_stream->fmt.i_extra = i_extra_size;
1727 p_stream->fmt.p_extra = malloc( i_extra_size );
1728 if( p_stream->fmt.p_extra )
1729 memcpy( p_stream->fmt.p_extra,
1730 oggpacket.packet + 142, i_extra_size );
1732 p_stream->fmt.i_extra = 0;
1735 i_format_tag = GetWLE((oggpacket.packet+124));
1736 p_stream->fmt.audio.i_channels =
1737 GetWLE((oggpacket.packet+126));
1738 fill_channels_info(&p_stream->fmt.audio);
1739 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1740 GetDWLE((oggpacket.packet+128));
1741 p_stream->fmt.i_bitrate =
1742 GetDWLE((oggpacket.packet+132)) * 8;
1743 p_stream->fmt.audio.i_blockalign =
1744 GetWLE((oggpacket.packet+136));
1745 p_stream->fmt.audio.i_bitspersample =
1746 GetWLE((oggpacket.packet+138));
1748 wf_tag_to_fourcc( i_format_tag,
1749 &p_stream->fmt.i_codec, 0 );
1751 if( p_stream->fmt.i_codec ==
1752 VLC_FOURCC('u','n','d','f') )
1754 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1755 ( i_format_tag >> 8 ) & 0xff,
1756 i_format_tag & 0xff );
1759 msg_Dbg( p_demux, "found audio header of type: %.4s",
1760 (char *)&p_stream->fmt.i_codec );
1761 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1762 "%dbits/sample %dkb/s",
1764 p_stream->fmt.audio.i_channels,
1765 p_stream->fmt.audio.i_rate,
1766 p_stream->fmt.audio.i_bitspersample,
1767 p_stream->fmt.i_bitrate / 1024 );
1768 if ( p_stream->f_rate == 0 )
1770 msg_Dbg( p_demux, "invalid oggds audio header" );
1771 Ogg_LogicalStreamDelete( p_demux, p_stream );
1777 msg_Dbg( p_demux, "stream %d has an old header "
1778 "but is of an unknown type", p_ogg->i_streams-1 );
1783 /* Check for OggDS */
1784 else if( oggpacket.bytes >= 44+1 &&
1785 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1787 stream_header_t tmp;
1788 stream_header_t *st = &tmp;
1790 p_stream->b_oggds = true;
1792 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1793 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1794 st->size = GetDWLE( &oggpacket.packet[1+12] );
1795 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1796 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1797 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1798 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1799 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1801 /* Check for video header (new format) */
1802 if( !strncmp( st->streamtype, "video", 5 ) &&
1803 oggpacket.bytes >= 52+1 )
1805 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1806 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1808 p_stream->fmt.i_cat = VIDEO_ES;
1810 /* We need to get rid of the header packet */
1811 ogg_stream_packetout( &p_stream->os, &oggpacket );
1813 p_stream->fmt.i_codec =
1814 VLC_FOURCC( st->subtype[0], st->subtype[1],
1815 st->subtype[2], st->subtype[3] );
1816 msg_Dbg( p_demux, "found video header of type: %.4s",
1817 (char *)&p_stream->fmt.i_codec );
1819 p_stream->fmt.video.i_frame_rate = 10000000;
1820 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1821 if( st->time_unit <= 0 )
1822 st->time_unit = 400000;
1823 p_stream->f_rate = 10000000.0 / st->time_unit;
1824 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1825 p_stream->fmt.video.i_width = st->sh.video.width;
1826 p_stream->fmt.video.i_height = st->sh.video.height;
1829 "fps: %f, width:%i; height:%i, bitcount:%i",
1831 p_stream->fmt.video.i_width,
1832 p_stream->fmt.video.i_height,
1833 p_stream->fmt.video.i_bits_per_pixel );
1835 /* Check for audio header (new format) */
1836 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1837 oggpacket.bytes >= 56+1 )
1843 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1844 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1845 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1847 p_stream->fmt.i_cat = AUDIO_ES;
1849 /* We need to get rid of the header packet */
1850 ogg_stream_packetout( &p_stream->os, &oggpacket );
1852 i_extra_size = st->size - 56;
1854 if( i_extra_size > 0 &&
1855 i_extra_size < oggpacket.bytes - 1 - 56 )
1857 p_stream->fmt.i_extra = i_extra_size;
1858 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1859 if( p_stream->fmt.p_extra )
1860 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1861 p_stream->fmt.i_extra );
1863 p_stream->fmt.i_extra = 0;
1866 memcpy( p_buffer, st->subtype, 4 );
1868 i_format_tag = strtol(p_buffer,NULL,16);
1869 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1870 fill_channels_info(&p_stream->fmt.audio);
1871 if( st->time_unit <= 0 )
1872 st->time_unit = 10000000;
1873 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1874 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1875 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1876 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1878 wf_tag_to_fourcc( i_format_tag,
1879 &p_stream->fmt.i_codec, 0 );
1881 if( p_stream->fmt.i_codec ==
1882 VLC_FOURCC('u','n','d','f') )
1884 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1885 ( i_format_tag >> 8 ) & 0xff,
1886 i_format_tag & 0xff );
1889 msg_Dbg( p_demux, "found audio header of type: %.4s",
1890 (char *)&p_stream->fmt.i_codec );
1891 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1892 "%dbits/sample %dkb/s",
1894 p_stream->fmt.audio.i_channels,
1895 p_stream->fmt.audio.i_rate,
1896 p_stream->fmt.audio.i_bitspersample,
1897 p_stream->fmt.i_bitrate / 1024 );
1898 if ( p_stream->f_rate == 0 )
1900 msg_Dbg( p_demux, "invalid oggds audio header" );
1901 Ogg_LogicalStreamDelete( p_demux, p_stream );
1905 /* Check for text (subtitles) header */
1906 else if( !strncmp(st->streamtype, "text", 4) )
1908 /* We need to get rid of the header packet */
1909 ogg_stream_packetout( &p_stream->os, &oggpacket );
1911 msg_Dbg( p_demux, "found text subtitle header" );
1912 p_stream->fmt.i_cat = SPU_ES;
1913 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1914 p_stream->f_rate = 1000; /* granulepos is in millisec */
1918 msg_Dbg( p_demux, "stream %d has a header marker "
1919 "but is of an unknown type", p_ogg->i_streams-1 );
1924 else if( oggpacket.bytes >= 8 &&
1925 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1929 msg_Dbg( p_demux, "stream %d is a skeleton",
1930 p_ogg->i_streams-1 );
1931 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1935 msg_Dbg( p_demux, "stream %d is of unknown type",
1936 p_ogg->i_streams-1 );
1941 /* we'll need to get all headers */
1942 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1944 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1945 return VLC_EGENERIC;
1948 /* This is the first data page, which means we are now finished
1949 * with the initial pages. We just need to store it in the relevant
1951 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1953 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1954 &p_ogg->current_page ) == 0 )
1956 p_ogg->b_page_waiting = true;
1965 return VLC_EGENERIC;
1968 /****************************************************************************
1969 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1970 ****************************************************************************/
1971 static void Ogg_CreateES( demux_t *p_demux )
1973 demux_sys_t *p_ogg = p_demux->p_sys;
1974 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1977 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1979 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1981 if ( p_stream->p_es == NULL && !p_stream->b_finished )
1983 /* Better be safe than sorry when possible with ogm */
1984 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1985 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1986 p_stream->fmt.b_packetized = false;
1988 /* Try first to reuse an old ES */
1990 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1991 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1993 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1995 p_stream->p_es = p_old_stream->p_es;
1996 p_stream->b_finished = false;
1997 p_stream->b_reinit = false;
1998 p_stream->b_initializing = false;
1999 p_stream->i_pre_skip = 0;
2000 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2001 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2003 p_old_stream->p_es = NULL;
2004 p_old_stream = NULL;
2005 if ( b_resetdecoder )
2007 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2008 p_stream->p_es, &p_stream->fmt );
2013 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2016 // TODO: something to do here ?
2017 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2019 /* Set the CMML stream active */
2020 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2025 if( p_ogg->p_old_stream )
2027 if( p_ogg->p_old_stream->p_es )
2028 msg_Dbg( p_demux, "old stream not reused" );
2029 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2030 p_ogg->p_old_stream = NULL;
2034 /****************************************************************************
2035 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2036 * Elementary streams.
2037 ****************************************************************************/
2038 static int Ogg_BeginningOfStream( demux_t *p_demux )
2040 demux_sys_t *p_ogg = p_demux->p_sys ;
2043 /* Find the logical streams embedded in the physical stream and
2044 * initialize our p_ogg structure. */
2045 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2047 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2048 return VLC_EGENERIC;
2051 p_ogg->i_bitrate = 0;
2053 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2055 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2057 p_stream->p_es = NULL;
2059 /* initialise kframe index */
2062 if ( p_stream->fmt.i_bitrate == 0 &&
2063 ( p_stream->fmt.i_cat == VIDEO_ES ||
2064 p_stream->fmt.i_cat == AUDIO_ES ) )
2065 p_ogg->b_partial_bitrate = true;
2067 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2069 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2070 p_stream->i_previous_granulepos = -1;
2071 p_stream->b_reinit = false;
2074 /* get total frame count for video stream; we will need this for seeking */
2075 p_ogg->i_total_frames = 0;
2080 /****************************************************************************
2081 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2082 ****************************************************************************/
2083 static void Ogg_EndOfStream( demux_t *p_demux )
2085 demux_sys_t *p_ogg = p_demux->p_sys ;
2088 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2089 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2090 free( p_ogg->pp_stream );
2093 p_ogg->i_bitrate = 0;
2094 p_ogg->i_streams = 0;
2095 p_ogg->pp_stream = NULL;
2096 p_ogg->skeleton.major = 0;
2097 p_ogg->skeleton.minor = 0;
2098 p_ogg->b_preparsing_done = false;
2099 p_ogg->b_es_created = false;
2100 p_ogg->i_nzpcr_offset = (p_ogg->i_pcr >= VLC_TS_INVALID) ?
2101 p_ogg->i_pcr - VLC_TS_0 : 0;
2105 vlc_meta_Delete( p_ogg->p_meta );
2106 p_ogg->p_meta = NULL;
2108 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2110 if ( p_ogg->pp_seekpoints[i] )
2111 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2113 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2114 p_ogg->i_seekpoints = 0;
2117 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2119 #ifdef HAVE_LIBVORBIS
2120 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2122 FREENULL( p_stream->special.vorbis.p_info );
2123 FREENULL( p_stream->special.vorbis.p_comment );
2124 p_stream->special.vorbis.b_invalid = false;
2127 VLC_UNUSED( p_stream );
2132 * This function delete and release all data associated to a logical_stream_t
2134 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2136 if( p_stream->p_es )
2137 es_out_Del( p_demux->out, p_stream->p_es );
2139 ogg_stream_clear( &p_stream->os );
2140 free( p_stream->p_headers );
2142 Ogg_CleanSpecificData( p_stream );
2144 es_format_Clean( &p_stream->fmt_old );
2145 es_format_Clean( &p_stream->fmt );
2147 if ( p_stream->idx != NULL)
2149 oggseek_index_entries_free( p_stream->idx );
2152 Ogg_FreeSkeleton( p_stream->p_skel );
2153 p_stream->p_skel = NULL;
2154 if ( p_demux->p_sys->p_skelstream == p_stream )
2155 p_demux->p_sys->p_skelstream = NULL;
2157 /* Shouldn't happen */
2158 if ( unlikely( p_stream->p_preparse_block ) )
2160 block_ChainRelease( p_stream->p_preparse_block );
2161 p_stream->p_preparse_block = NULL;
2163 free( p_stream->p_prepcr_blocks );
2168 * This function check if a we need to reset a decoder in case we are
2171 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2173 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2174 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2175 unsigned i_new_count;
2176 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2179 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2180 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2181 unsigned i_old_count;
2182 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2185 bool b_match = i_new_count == i_old_count;
2186 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2188 /* Ignore vorbis comment */
2191 if( pi_new_size[i] != pi_old_size[i] ||
2192 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2199 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2200 const es_format_t *p_old )
2202 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2203 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2204 unsigned i_new_count;
2205 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2207 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2208 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2209 unsigned i_old_count;
2210 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2212 bool b_match = false;
2213 if( i_new_count == i_old_count && i_new_count > 0 )
2215 static const unsigned char default_map[2] = { 0, 1 };
2216 unsigned char *p_old_head;
2217 unsigned char *p_new_head;
2218 const unsigned char *p_old_map;
2219 const unsigned char *p_new_map;
2220 int i_old_channel_count;
2221 int i_new_channel_count;
2222 int i_old_stream_count;
2223 int i_new_stream_count;
2224 int i_old_coupled_count;
2225 int i_new_coupled_count;
2226 p_old_head = (unsigned char *)pp_old_data[0];
2227 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2228 p_old_map = default_map;
2229 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2231 i_old_channel_count = p_old_head[9];
2232 switch( p_old_head[18] )
2235 i_old_stream_count = 1;
2236 i_old_coupled_count = i_old_channel_count - 1;
2239 if( pi_old_size[0] >= 21U + i_old_channel_count )
2241 i_old_stream_count = p_old_head[19];
2242 i_old_coupled_count = p_old_head[20];
2243 p_old_map = p_old_head + 21;
2248 p_new_head = (unsigned char *)pp_new_data[0];
2249 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2250 p_new_map = default_map;
2251 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2253 i_new_channel_count = p_new_head[9];
2254 switch( p_new_head[18] )
2257 i_new_stream_count = 1;
2258 i_new_coupled_count = i_new_channel_count - 1;
2261 if( pi_new_size[0] >= 21U + i_new_channel_count )
2263 i_new_stream_count = p_new_head[19];
2264 i_new_coupled_count = p_new_head[20];
2265 p_new_map = p_new_head+21;
2270 b_match = i_old_channel_count == i_new_channel_count &&
2271 i_old_stream_count == i_new_stream_count &&
2272 i_old_coupled_count == i_new_coupled_count &&
2273 memcmp(p_old_map, p_new_map,
2274 i_new_channel_count*sizeof(*p_new_map)) == 0;
2280 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2282 bool b_compatible = false;
2283 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2286 /* Only Vorbis and Opus are supported. */
2287 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2288 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2289 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2290 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2293 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2295 return !b_compatible;
2298 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2299 const void *p_headers, unsigned i_headers )
2301 demux_sys_t *p_ogg = p_demux->p_sys;
2302 int i_cover_score = 0;
2303 int i_cover_idx = 0;
2304 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2305 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2306 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2308 pf_replay_gain[i] = 0;
2309 pf_replay_peak[i] = 0;
2311 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2312 &p_ogg->i_attachments, &p_ogg->attachments,
2313 &i_cover_score, &i_cover_idx,
2314 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2315 &pf_replay_gain, &pf_replay_peak );
2316 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2319 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2320 p_ogg->attachments[i_cover_idx]->psz_name );
2321 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2324 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2326 if ( pf_replay_gain[i] != 0 )
2328 p_fmt->audio_replay_gain.pb_gain[i] = true;
2329 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2330 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2332 if ( pf_replay_peak[i] != 0 )
2334 p_fmt->audio_replay_gain.pb_peak[i] = true;
2335 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2336 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2340 if( p_ogg->i_seekpoints > 1 )
2342 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2346 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2347 const void *p_headers, unsigned i_headers, unsigned i_skip )
2349 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2350 void *pp_data[XIPH_MAX_HEADER_COUNT];
2353 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2355 /* TODO how to handle multiple comments properly ? */
2356 if( i_count >= 2 && pi_size[1] > i_skip )
2358 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2362 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2364 demux_sys_t *p_ogg = p_demux->p_sys;
2366 switch( p_fmt->i_codec )
2368 /* 3 headers with the 2° one being the comments */
2369 case VLC_CODEC_VORBIS:
2370 case VLC_CODEC_THEORA:
2371 case VLC_CODEC_DAALA:
2372 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2374 case VLC_CODEC_OPUS:
2375 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2377 case VLC_CODEC_SPEEX:
2378 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2381 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2383 /* N headers with the 2° one being the comments */
2384 case VLC_CODEC_KATE:
2385 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2386 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2390 case VLC_CODEC_FLAC:
2391 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2395 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2396 case VLC_CODEC_DIRAC:
2401 p_demux->info.i_update |= INPUT_UPDATE_META;
2404 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2405 ogg_packet *p_oggpacket )
2408 unsigned int i_fps_numerator;
2409 unsigned int i_fps_denominator;
2410 int i_keyframe_frequency_force;
2416 p_stream->fmt.i_cat = VIDEO_ES;
2417 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2419 /* Signal that we want to keep a backup of the theora
2420 * stream headers. They will be used when switching between
2422 p_stream->b_force_backup = true;
2424 /* Cheat and get additionnal info ;) */
2425 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2426 bs_skip( &bitstream, 56 );
2428 i_major = bs_read( &bitstream, 8 ); /* major version num */
2429 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2430 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2432 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2433 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2434 bs_read( &bitstream, 24 ); /* frame width */
2435 bs_read( &bitstream, 24 ); /* frame height */
2436 bs_read( &bitstream, 8 ); /* x offset */
2437 bs_read( &bitstream, 8 ); /* y offset */
2439 i_fps_numerator = bs_read( &bitstream, 32 );
2440 i_fps_denominator = bs_read( &bitstream, 32 );
2441 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2442 bs_read( &bitstream, 24 ); /* aspect_numerator */
2443 bs_read( &bitstream, 24 ); /* aspect_denominator */
2445 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2446 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2448 bs_read( &bitstream, 8 ); /* colorspace */
2449 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2450 bs_read( &bitstream, 6 ); /* quality */
2452 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2454 /* granule_shift = i_log( frequency_force -1 ) */
2455 p_stream->i_granule_shift = 0;
2456 i_keyframe_frequency_force--;
2457 while( i_keyframe_frequency_force )
2459 p_stream->i_granule_shift++;
2460 i_keyframe_frequency_force >>= 1;
2463 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2464 p_stream->i_keyframe_offset = 0;
2465 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2466 if ( p_stream->f_rate == 0 ) return false;
2468 if ( i_version >= 3002001 )
2470 p_stream->i_keyframe_offset = 1;
2475 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2476 ogg_packet *p_oggpacket )
2479 uint32_t i_timebase_numerator;
2480 uint32_t i_timebase_denominator;
2481 int i_keyframe_frequency_force;
2487 p_stream->fmt.i_cat = VIDEO_ES;
2488 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2490 /* Signal that we want to keep a backup of the daala
2491 * stream headers. They will be used when switching between
2493 p_stream->b_force_backup = true;
2495 /* Cheat and get additionnal info ;) */
2496 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2497 oggpack_adv( &opb, 48 );
2499 i_major = oggpack_read( &opb, 8 ); /* major version num */
2500 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2501 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2503 oggpack_adv( &opb, 32 ); /* width */
2504 oggpack_adv( &opb, 32 ); /* height */
2506 oggpack_adv( &opb, 32 ); /* aspect numerator */
2507 oggpack_adv( &opb, 32 ); /* aspect denominator */
2508 i_timebase_numerator = oggpack_read( &opb, 32 );
2510 i_timebase_denominator = oggpack_read( &opb, 32 );
2511 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2513 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2514 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2516 oggpack_adv( &opb, 32 ); /* frame duration */
2518 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2520 /* granule_shift = i_log( frequency_force -1 ) */
2521 p_stream->i_granule_shift = 0;
2522 i_keyframe_frequency_force--;
2523 while( i_keyframe_frequency_force )
2525 p_stream->i_granule_shift++;
2526 i_keyframe_frequency_force >>= 1;
2529 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2530 p_stream->i_keyframe_offset = 0;
2531 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2532 if ( p_stream->f_rate == 0 ) return false;
2537 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2538 ogg_packet *p_oggpacket )
2542 p_stream->fmt.i_cat = AUDIO_ES;
2543 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2545 /* Signal that we want to keep a backup of the vorbis
2546 * stream headers. They will be used when switching between
2548 p_stream->b_force_backup = true;
2550 /* Cheat and get additionnal info ;) */
2551 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2552 oggpack_adv( &opb, 88 );
2553 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2554 fill_channels_info(&p_stream->fmt.audio);
2555 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2556 oggpack_read( &opb, 32 );
2557 oggpack_adv( &opb, 32 );
2558 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2559 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2560 if ( p_stream->f_rate == 0 ) return false;
2563 #ifdef HAVE_LIBVORBIS
2564 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2565 ogg_packet *p_oggpacket, int i_number )
2569 case VORBIS_HEADER_IDENTIFICATION:
2570 p_stream->special.vorbis.p_info = malloc( sizeof(vorbis_info) );
2571 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2572 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2574 FREENULL( p_stream->special.vorbis.p_info );
2575 FREENULL( p_stream->special.vorbis.p_comment );
2576 p_stream->special.vorbis.b_invalid = true;
2579 vorbis_info_init( p_stream->special.vorbis.p_info );
2580 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2583 case VORBIS_HEADER_COMMENT:
2584 case VORBIS_HEADER_SETUP:
2585 if ( p_stream->special.vorbis.p_info && ! p_stream->special.vorbis.b_invalid )
2587 p_stream->special.vorbis.b_invalid = ( 0 != vorbis_synthesis_headerin(
2588 p_stream->special.vorbis.p_info,
2589 p_stream->special.vorbis.p_comment, p_oggpacket ) );
2599 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2600 ogg_packet *p_oggpacket )
2604 p_stream->fmt.i_cat = AUDIO_ES;
2605 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2607 /* Signal that we want to keep a backup of the speex
2608 * stream headers. They will be used when switching between
2610 p_stream->b_force_backup = true;
2612 /* Cheat and get additionnal info ;) */
2613 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2614 oggpack_adv( &opb, 224 );
2615 oggpack_adv( &opb, 32 ); /* speex_version_id */
2616 oggpack_adv( &opb, 32 ); /* header_size */
2617 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2618 if ( p_stream->f_rate == 0 ) return false;
2619 oggpack_adv( &opb, 32 ); /* mode */
2620 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2621 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2622 fill_channels_info(&p_stream->fmt.audio);
2623 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2624 p_stream->special.speex.i_framesize =
2625 oggpack_read( &opb, 32 ); /* frame_size */
2626 oggpack_adv( &opb, 32 ); /* vbr */
2627 p_stream->special.speex.i_framesperpacket =
2628 oggpack_read( &opb, 32 ); /* frames_per_packet */
2629 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2633 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2634 ogg_packet *p_oggpacket )
2638 p_stream->fmt.i_cat = AUDIO_ES;
2639 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2641 /* Signal that we want to keep a backup of the opus
2642 * stream headers. They will be used when switching between
2644 p_stream->b_force_backup = true;
2646 /* All OggOpus streams are timestamped at 48kHz and
2647 * can be played at 48kHz. */
2648 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2649 p_stream->fmt.i_bitrate = 0;
2651 /* Cheat and get additional info ;) */
2652 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2653 oggpack_adv( &opb, 64 );
2654 oggpack_adv( &opb, 8 ); /* version_id */
2655 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2656 fill_channels_info(&p_stream->fmt.audio);
2657 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2658 /* For Opus, trash the first 80 ms of decoded output as
2659 well, to avoid blowing out speakers if we get unlucky.
2660 Opus predicts content from prior frames, which can go
2661 badly if we seek right where the stream goes from very
2662 quiet to very loud. It will converge after a bit. */
2663 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2666 static bool Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2667 ogg_packet *p_oggpacket )
2669 /* Parse the STREAMINFO metadata */
2672 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2675 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2677 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2681 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2684 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2685 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2686 fill_channels_info(&p_stream->fmt.audio);
2688 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2689 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2690 if ( p_stream->f_rate == 0 ) return false;
2694 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2697 /* Fake this as the last metadata block */
2698 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2702 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2703 ogg_packet *p_oggpacket )
2711 p_stream->fmt.i_cat = SPU_ES;
2712 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2714 /* Signal that we want to keep a backup of the kate
2715 * stream headers. They will be used when switching between
2717 p_stream->b_force_backup = true;
2719 /* Cheat and get additionnal info ;) */
2720 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2721 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2722 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2723 oggpack_adv( &opb, 3*8 );
2724 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2725 oggpack_adv( &opb, 8*8 ); /* reserved */
2726 gnum = oggpack_read( &opb, 32 );
2727 gden = oggpack_read( &opb, 32 );
2728 gden = __MAX( gden, 1 );
2729 p_stream->f_rate = (double)gnum/gden;
2730 if ( p_stream->f_rate == 0 ) return false;
2732 p_stream->fmt.psz_language = malloc(16);
2733 if( p_stream->fmt.psz_language )
2735 for( n = 0; n < 16; n++ )
2736 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2737 p_stream->fmt.psz_language[15] = 0; /* just in case */
2741 for( n = 0; n < 16; n++ )
2742 oggpack_read(&opb,8);
2744 p_stream->fmt.psz_description = malloc(16);
2745 if( p_stream->fmt.psz_description )
2747 for( n = 0; n < 16; n++ )
2748 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2749 p_stream->fmt.psz_description[15] = 0; /* just in case */
2751 /* Now find a localized user readable description for this category */
2752 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2755 free( p_stream->fmt.psz_description );
2756 p_stream->fmt.psz_description = psz_desc;
2761 for( n = 0; n < 16; n++ )
2762 oggpack_read(&opb,8);
2768 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2769 ogg_packet *p_oggpacket )
2771 switch( p_oggpacket->packet[5] )
2775 /* Mapping version */
2776 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2778 p_stream->fmt.i_cat = VIDEO_ES;
2779 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2780 p_stream->i_granule_shift = 32;
2781 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2782 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2783 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2784 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2785 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2786 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2787 p_stream->fmt.video.i_frame_rate_base =
2788 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2789 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2790 if ( p_stream->f_rate == 0 ) return false;
2794 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2795 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2802 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2803 bool *b_force_backup, bool *b_packet_out )
2805 if( !strncmp(psz_value, "audio/x-wav", 11) )
2807 /* n.b. WAVs are unsupported right now */
2808 p_stream->fmt.i_cat = UNKNOWN_ES;
2809 free( p_stream->fmt.psz_description );
2810 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2812 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2813 !strncmp(psz_value, "audio/vorbis", 12) )
2815 p_stream->fmt.i_cat = AUDIO_ES;
2816 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2818 *b_force_backup = true;
2820 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2821 !strncmp(psz_value, "audio/speex", 11) )
2823 p_stream->fmt.i_cat = AUDIO_ES;
2824 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2826 *b_force_backup = true;
2828 else if( !strncmp(psz_value, "audio/flac", 10) )
2830 p_stream->fmt.i_cat = AUDIO_ES;
2831 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2833 *b_force_backup = true;
2835 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2836 !strncmp(psz_value, "video/theora", 12) )
2838 p_stream->fmt.i_cat = VIDEO_ES;
2839 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2841 *b_force_backup = true;
2843 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2844 !strncmp(psz_value, "video/daala", 11) )
2846 p_stream->fmt.i_cat = VIDEO_ES;
2847 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2849 *b_force_backup = true;
2851 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2853 p_stream->fmt.i_cat = VIDEO_ES;
2854 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2856 *b_force_backup = true;
2858 else if( !strncmp(psz_value, "video/mpeg", 10) )
2860 /* n.b. MPEG streams are unsupported right now */
2861 p_stream->fmt.i_cat = VIDEO_ES;
2862 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2864 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2865 !strncmp(psz_value, "text/cmml", 9) )
2867 p_stream->fmt.i_cat = SPU_ES;
2868 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2869 *b_packet_out = true;
2871 else if( !strncmp(psz_value, "application/kate", 16) )
2874 p_stream->fmt.i_cat = UNKNOWN_ES;
2875 free( p_stream->fmt.psz_description );
2876 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2878 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2880 p_stream->fmt.i_cat = VIDEO_ES;
2881 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2885 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2886 logical_stream_t *p_stream,
2887 ogg_packet *p_oggpacket )
2889 if( p_oggpacket->bytes >= 28 &&
2890 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2894 uint16_t major_version;
2895 uint16_t minor_version;
2896 uint64_t timebase_numerator;
2897 uint64_t timebase_denominator;
2899 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2901 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2902 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2903 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2904 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2905 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2906 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2908 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2909 "Timebase %"PRId64" / %"PRId64,
2910 major_version, minor_version,
2911 timebase_numerator, timebase_denominator );
2913 else if( p_oggpacket->bytes >= 42 &&
2914 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2916 uint64_t granule_rate_numerator;
2917 uint64_t granule_rate_denominator;
2918 char content_type_string[1024];
2920 /* Read in Annodex header fields */
2922 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2923 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2924 p_stream->i_secondary_header_packets =
2925 GetDWLE( &p_oggpacket->packet[24] );
2927 /* we are guaranteed that the first header field will be
2928 * the content-type (by the Annodex standard) */
2929 content_type_string[0] = '\0';
2930 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2932 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2933 p_oggpacket->bytes - 1 );
2934 if( p && p[0] == '\r' && p[1] == '\n' )
2935 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2936 content_type_string );
2939 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2940 granule_rate_numerator, granule_rate_denominator,
2941 p_stream->i_secondary_header_packets, content_type_string );
2943 p_stream->f_rate = (float) granule_rate_numerator /
2944 (float) granule_rate_denominator;
2946 /* What type of file do we have?
2947 * strcmp is safe to use here because we've extracted
2948 * content_type_string from the stream manually */
2949 bool b_dopacketout = false;
2950 Ogg_ApplyContentType( p_stream, content_type_string,
2951 &p_stream->b_force_backup, &b_dopacketout );
2952 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2956 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2957 ogg_packet *p_oggpacket )
2959 p_demux->p_sys->p_skelstream = p_stream;
2960 /* There can be only 1 skeleton for streams */
2961 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2962 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2963 if ( asprintf( & p_stream->fmt.psz_description,
2964 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2965 p_demux->p_sys->skeleton.major,
2966 p_demux->p_sys->skeleton.minor ) < 0 )
2967 p_stream->fmt.psz_description = NULL;
2970 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2972 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2974 /* Find the matching stream for this skeleton data */
2975 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2976 logical_stream_t *p_target_stream = NULL;
2977 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2979 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2981 p_target_stream = p_demux->p_sys->pp_stream[i];
2985 if ( !p_target_stream ) return;
2987 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2990 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2991 if ( !p_skel ) return;
2992 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2993 p_skel->p_index = NULL;
2994 p_target_stream->p_skel = p_skel;
2997 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2998 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2999 const unsigned char *p = p_messages;
3000 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3002 if ( *p == 0x0D && *(p+1) == 0x0A )
3004 char *psz_message = strndup( (const char *) p_messages,
3008 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3009 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3011 if ( p < p_boundary - 1 ) p_messages = p + 2;
3018 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3019 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3020 unsigned const char *p_end,
3021 uint64_t *pi_value )
3027 while ( p_begin < p_end )
3029 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3030 *pi_value = *pi_value | ( i_read << i_shift );
3032 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3035 *pi_value = GetQWLE( pi_value );
3039 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3041 if ( p_demux->p_sys->skeleton.major < 4
3042 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3045 /* Find the matching stream for this skeleton data */
3046 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3047 logical_stream_t *p_stream = NULL;
3048 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3050 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3052 p_stream = p_demux->p_sys->pp_stream[i];
3056 if ( !p_stream || !p_stream->p_skel ) return;
3057 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3058 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3059 if ( !i_keypoints ) return;
3061 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3062 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3063 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3064 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3065 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3066 uint64_t i_offset = 0;
3067 uint64_t i_time = 0;
3068 uint64_t i_keypoints_found = 0;
3070 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3073 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3075 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3076 i_time += i_val * p_stream->p_skel->i_indexstampden;
3077 i_keypoints_found++;
3080 if ( i_keypoints_found != i_keypoints )
3082 msg_Warn( p_demux, "Invalid Index: missing entries" );
3086 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3087 if ( !p_stream->p_skel->p_index ) return;
3088 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3089 p_oggpacket->bytes - 42 );
3090 p_stream->p_skel->i_index = i_keypoints_found;
3091 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3094 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3096 if ( !p_skel ) return;
3097 for ( int i=0; i< p_skel->i_messages; i++ )
3098 free( p_skel->ppsz_messages[i] );
3099 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3100 free( p_skel->p_index );
3104 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3106 if ( !p_stream->p_skel ) return;
3107 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3109 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3110 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3112 free( p_stream->fmt.psz_description );
3113 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3115 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3118 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3123 /* Return true if there's a skeleton exact match */
3124 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3125 int64_t *pi_lower, int64_t *pi_upper )
3127 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3130 /* Validate range */
3131 if ( i_time < p_stream->p_skel->i_indexfirstnum
3132 * p_stream->p_skel->i_indexstampden ||
3133 i_time > p_stream->p_skel->i_indexlastnum
3134 * p_stream->p_skel->i_indexstampden ) return false;
3136 /* Then Lookup its index */
3137 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3142 } current = { 0, 0 }, prev = { -1, -1 };
3144 uint64_t i_keypoints_found = 0;
3146 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3147 && i_keypoints_found < p_stream->p_skel->i_index )
3150 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3151 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3152 current.i_pos += i_val;
3153 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3154 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3155 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3156 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3158 i_keypoints_found++;
3160 if ( i_time <= current.i_time )
3162 *pi_lower = prev.i_pos;
3163 *pi_upper = current.i_pos;
3164 return ( i_time == current.i_time );
3171 static uint32_t dirac_uint( bs_t *p_bs )
3173 uint32_t u_count = 0, u_value = 0;
3175 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3179 u_value |= bs_read( p_bs, 1 );
3182 return (1<<u_count) - 1 + u_value;
3185 static int dirac_bool( bs_t *p_bs )
3187 return bs_read( p_bs, 1 );
3190 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3191 ogg_packet *p_oggpacket )
3193 static const struct {
3194 uint32_t u_n /* numerator */, u_d /* denominator */;
3195 } p_dirac_frate_tbl[] = { /* table 10.3 */
3196 {1,1}, /* this first value is never used */
3197 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3198 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3200 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3202 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3203 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3205 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3209 p_stream->i_granule_shift = 22; /* not 32 */
3211 /* Backing up stream headers is not required -- seqhdrs are repeated
3212 * thoughout the stream at suitable decoding start points */
3213 p_stream->b_force_backup = false;
3215 /* read in useful bits from sequence header */
3216 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3217 bs_skip( &bs, 13*8); /* parse_info_header */
3218 dirac_uint( &bs ); /* major_version */
3219 dirac_uint( &bs ); /* minor_version */
3220 dirac_uint( &bs ); /* profile */
3221 dirac_uint( &bs ); /* level */
3223 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3224 if( u_video_format >= u_dirac_vidfmt_frate )
3226 /* don't know how to parse this ogg dirac stream */
3230 if( dirac_bool( &bs ) )
3232 dirac_uint( &bs ); /* frame_width */
3233 dirac_uint( &bs ); /* frame_height */
3236 if( dirac_bool( &bs ) )
3238 dirac_uint( &bs ); /* chroma_format */
3241 if( dirac_bool( &bs ) )
3243 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3246 p_stream->special.dirac.b_interlaced = false;
3248 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3249 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3250 u_d = __MAX( u_d, 1 );
3251 if( dirac_bool( &bs ) )
3253 uint32_t u_frame_rate_index = dirac_uint( &bs );
3254 if( u_frame_rate_index >= u_dirac_frate_tbl )
3256 /* something is wrong with this stream */
3259 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3260 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3261 if( u_frame_rate_index == 0 )
3263 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3264 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3267 p_stream->f_rate = (float) u_n / u_d;
3268 if ( p_stream->f_rate == 0 ) return false;
3270 /* probably is an ogg dirac es */
3271 p_stream->fmt.i_cat = VIDEO_ES;
3272 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;