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_demux.h>
36 #include <vlc_input.h>
40 #include <vlc_codecs.h>
43 #include "xiph_metadata.h"
47 /*****************************************************************************
49 *****************************************************************************/
50 static int Open ( vlc_object_t * );
51 static void Close( vlc_object_t * );
54 set_shortname ( "OGG" )
55 set_description( N_("OGG demuxer" ) )
56 set_category( CAT_INPUT )
57 set_subcategory( SUBCAT_INPUT_DEMUX )
58 set_capability( "demux", 50 )
59 set_callbacks( Open, Close )
64 /*****************************************************************************
65 * Definitions of structures and functions used by this plugins
66 *****************************************************************************/
68 /* OggDS headers for the new header format (used in ogm files) */
73 } stream_header_video_t;
79 ogg_int16_t blockalign;
80 ogg_int32_t avgbytespersec;
81 } stream_header_audio_t;
88 ogg_int32_t size; /* size of the structure */
90 ogg_int64_t time_unit; /* in reference time */
91 ogg_int64_t samples_per_unit;
92 ogg_int32_t default_len; /* in media time */
94 ogg_int32_t buffersize;
95 ogg_int16_t bits_per_sample;
101 stream_header_video_t video;
103 stream_header_audio_t audio;
107 /*****************************************************************************
109 *****************************************************************************/
110 static int Demux ( demux_t * );
111 static int Control( demux_t *, int, va_list );
113 /* Bitstream manipulation */
114 static int Ogg_ReadPage ( demux_t *, ogg_page * );
115 static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * );
116 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
117 static int Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * );
119 static void Ogg_CreateES( demux_t *p_demux );
120 static int Ogg_BeginningOfStream( demux_t *p_demux );
121 static int Ogg_FindLogicalStreams( demux_t *p_demux );
122 static void Ogg_EndOfStream( demux_t *p_demux );
125 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
126 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
129 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
131 /* Logical bitstream headers */
132 static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
133 static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
134 static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
135 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
136 static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
137 static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
138 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
139 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
140 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
143 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
144 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
145 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
146 static void Ogg_ApplySkeleton( logical_stream_t * );
148 static void fill_channels_info(audio_format_t *audio)
150 static const int pi_channels_map[9] =
154 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
155 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
156 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
157 | AOUT_CHAN_REARRIGHT,
158 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
159 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
160 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
161 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
162 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
163 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
164 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
165 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
166 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
170 unsigned chans = audio->i_channels;
171 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
172 audio->i_physical_channels =
173 audio->i_original_channels = pi_channels_map[chans];
176 /*****************************************************************************
177 * Open: initializes ogg demux structures
178 *****************************************************************************/
179 static int Open( vlc_object_t * p_this )
181 demux_t *p_demux = (demux_t *)p_this;
183 const uint8_t *p_peek;
185 /* Check if we are dealing with an ogg stream */
186 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
187 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
193 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
197 p_sys->i_length = -1;
198 p_sys->b_preparsing_done = false;
200 /* Set exported functions */
201 p_demux->pf_demux = Demux;
202 p_demux->pf_control = Control;
204 /* Initialize the Ogg physical bitstream parser */
205 ogg_sync_init( &p_sys->oy );
208 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
211 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
217 /*****************************************************************************
218 * Close: frees unused data
219 *****************************************************************************/
220 static void Close( vlc_object_t *p_this )
222 demux_t *p_demux = (demux_t *)p_this;
223 demux_sys_t *p_sys = p_demux->p_sys ;
225 /* Cleanup the bitstream parser */
226 ogg_sync_clear( &p_sys->oy );
228 Ogg_EndOfStream( p_demux );
230 if( p_sys->p_old_stream )
231 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
236 /*****************************************************************************
237 * Demux: reads and demuxes data packets
238 *****************************************************************************
239 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
240 *****************************************************************************/
241 static int Demux( demux_t * p_demux )
243 demux_sys_t *p_sys = p_demux->p_sys;
244 ogg_packet oggpacket;
246 bool b_skipping = false;
249 int i_active_streams = p_sys->i_streams;
250 for ( int i=0; i < p_sys->i_streams; i++ )
252 if ( p_sys->pp_stream[i]->b_finished )
256 if ( i_active_streams == 0 )
258 if ( p_sys->i_streams ) /* All finished */
260 msg_Dbg( p_demux, "end of a group of logical streams" );
261 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
262 * only 1 ES is supported (common case for ogg web radio) */
263 if( p_sys->i_streams == 1 )
265 p_sys->p_old_stream = p_sys->pp_stream[0];
266 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
268 Ogg_EndOfStream( p_demux );
269 p_sys->b_chained_boundary = true;
272 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
275 msg_Dbg( p_demux, "beginning of a group of logical streams" );
277 if ( !p_sys->b_chained_boundary )
279 /* Find the real duration */
280 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
282 Oggseek_ProbeEnd( p_demux );
283 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 );
287 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
288 p_sys->b_chained_boundary = false;
292 if ( p_sys->b_preparsing_done )
294 for ( int i=0; i < p_sys->i_streams; i++ )
296 if ( !p_sys->pp_stream[i]->p_es )
298 Ogg_CreateES( p_demux );
305 * The first data page of a physical stream is stored in the relevant logical stream
306 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
307 * stream it belongs to if we haven't processed this first page yet. If we do, we
308 * will only process that first page whenever we find the second page for this stream.
309 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
310 * the second page will arrive real quick, this is not fine for Kate, whose second
311 * data page will typically arrive much later.
312 * This means it is now possible to seek right at the start of a stream where the last
313 * logical stream is Kate, without having to wait for the second data page to unblock
314 * the first one, which is the one that triggers the 'no more headers to backup' code.
315 * And, as we all know, seeking without having backed up all headers is bad, since the
316 * codec will fail to initialize if it's missing its headers.
318 if( !p_sys->b_page_waiting)
321 * Demux an ogg page from the stream
323 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
325 /* Test for End of Stream */
326 if( ogg_page_eos( &p_sys->current_page ) )
328 /* If we delayed restarting encoders/SET_ES_FMT for more
329 * skeleton provided configuration */
330 if ( p_sys->p_skelstream )
332 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
334 msg_Dbg( p_demux, "End of Skeleton" );
335 p_sys->b_preparsing_done = true;
336 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
338 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
339 Ogg_ApplySkeleton( p_stream );
344 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
346 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
348 p_sys->pp_stream[i_stream]->b_finished = true;
356 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
358 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
361 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
363 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
365 /* if we've just pulled page, look for the right logical stream */
366 if( !p_sys->b_page_waiting )
368 if( p_sys->i_streams == 1 &&
369 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
371 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
372 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
374 p_stream->b_reinit = true;
375 p_stream->i_pcr = VLC_TS_0;
376 p_stream->i_interpolated_pcr = VLC_TS_0;
377 p_stream->i_previous_granulepos = -1;
378 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0);
381 /* Does fail if serialno differs */
382 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
389 /* clear the finished flag if pages after eos (ex: after a seek) */
390 if ( ! ogg_page_eos( &p_sys->current_page ) ) p_stream->b_finished = false;
393 if ( p_stream->fmt.i_cat == VIDEO_ES )
394 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
395 ogg_page_pageno( &p_sys->current_page ),
396 ogg_page_granulepos( &p_sys->current_page ),
397 ogg_page_packets( &p_sys->current_page ),
398 ogg_page_continued(&p_sys->current_page),
399 p_sys->current_page.body_len )
402 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
404 /* Read info from any secondary header packets, if there are any */
405 if( p_stream->i_secondary_header_packets > 0 )
407 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
408 oggpacket.bytes >= 7 &&
409 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
411 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
412 p_stream->i_secondary_header_packets = 0;
414 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
415 oggpacket.bytes >= 7 &&
416 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
418 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
419 p_stream->i_secondary_header_packets = 0;
421 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
423 p_stream->i_secondary_header_packets = 0;
426 /* update start of data pointer */
427 p_stream->i_data_start = stream_Tell( p_demux->s );
430 /* If any streams have i_skip_frames, only decode (pre-roll)
431 * for those streams, but don't skip headers */
432 if ( b_skipping && p_stream->i_skip_frames == 0
433 && p_stream->i_secondary_header_packets ) continue;
435 if( p_stream->b_reinit )
437 if ( Oggseek_PacketPCRFixup( p_stream, &p_sys->current_page,
440 DemuxDebug( msg_Dbg( p_demux, "PCR fixup for %"PRId64,
441 ogg_page_granulepos( &p_sys->current_page ) ) );
445 /* If synchro is re-initialized we need to drop all the packets
446 * until we find a new dated one. */
447 Ogg_UpdatePCR( p_demux, p_stream, &oggpacket );
450 if( p_stream->i_pcr >= 0 )
452 p_stream->b_reinit = false;
453 /* For Opus, trash the first 80 ms of decoded output as
454 well, to avoid blowing out speakers if we get unlucky.
455 Opus predicts content from prior frames, which can go
456 badly if we seek right where the stream goes from very
457 quiet to very loud. It will converge after a bit. */
458 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
460 ogg_int64_t start_time;
462 p_stream->i_skip_frames = 80*48;
463 /* Make sure we never play audio from within the
464 pre-skip at the beginning of the stream. */
466 Ogg_OpusPacketDuration( p_stream, &oggpacket );
467 start_time = p_stream->i_previous_granulepos;
470 start_time = start_time > duration ?
471 start_time - duration : 0;
473 if( p_stream->i_pre_skip > start_time )
475 p_stream->i_skip_frames +=
476 p_stream->i_pre_skip - start_time;
483 msg_Dbg(p_demux, "DEMUX DROPS PACKET (? / %d) pageno %ld granule %"PRId64,
484 ogg_page_packets( &p_sys->current_page ),
485 ogg_page_pageno( &p_sys->current_page ), oggpacket.granulepos );
488 p_stream->i_interpolated_pcr = -1;
489 p_stream->i_previous_granulepos = -1;
493 /* An Ogg/vorbis packet contains an end date granulepos */
494 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
495 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
496 p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
497 p_stream->fmt.i_codec == VLC_CODEC_FLAC )
499 if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
501 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
505 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
506 VLC_TS_0 + p_stream->i_pcr );
512 DemuxDebug( if ( p_sys->b_seeked )
514 if ( Ogg_IsKeyFrame( p_stream, &oggpacket ) )
515 msg_Dbg(p_demux, "** DEMUX ON KEYFRAME **" );
517 ogg_int64_t iframe = ogg_page_granulepos( &p_sys->current_page ) >> p_stream->i_granule_shift;
518 ogg_int64_t pframe = ogg_page_granulepos( &p_sys->current_page ) - ( iframe << p_stream->i_granule_shift );
520 msg_Dbg(p_demux, "DEMUX PACKET (size %d) IS at iframe %"PRId64" pageno %ld pframe %"PRId64" OFFSET %"PRId64" PACKET NO %"PRId64" skipleft=%d",
521 ogg_page_packets( &p_sys->current_page ),
522 iframe, ogg_page_pageno( &p_sys->current_page ), pframe, p_sys->i_input_position, oggpacket.packetno, p_stream->i_skip_frames );
525 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
528 DemuxDebug( p_sys->b_seeked = false; )
530 if( !p_sys->b_page_waiting )
534 /* if a page was waiting, it's now processed */
535 p_sys->b_page_waiting = false;
537 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
538 p_sys->b_preparsing_done = false;
540 p_sys->b_preparsing_done = true;
543 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
545 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
547 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
549 /* We have 1 or more streams needing more than 1 page for preparsing */
550 p_sys->b_preparsing_done = false;
553 if( p_stream->fmt.i_cat == SPU_ES )
555 if( p_stream->i_interpolated_pcr < 0 )
558 if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )
559 p_sys->i_pcr = p_stream->i_interpolated_pcr;
562 if( p_sys->i_pcr >= 0 && ! b_skipping )
563 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_pcr );
568 static void Ogg_ResetStreamHelper( demux_sys_t *p_sys )
570 for( int i = 0; i < p_sys->i_streams; i++ )
572 logical_stream_t *p_stream = p_sys->pp_stream[i];
574 /* we'll trash all the data until we find the next pcr */
575 p_stream->b_reinit = true;
576 p_stream->i_pcr = -1;
577 p_stream->i_interpolated_pcr = -1;
578 p_stream->i_previous_granulepos = -1;
579 ogg_stream_reset( &p_stream->os );
581 ogg_sync_reset( &p_sys->oy );
584 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
586 demux_sys_t *p_sys = p_demux->p_sys;
587 logical_stream_t *p_stream = NULL;
588 for( int i=0; i<p_sys->i_streams; i++ )
590 logical_stream_t *p_candidate = p_sys->pp_stream[i];
592 bool b_selected = false;
593 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
594 p_candidate->p_es, &b_selected );
595 if ( !b_selected ) continue;
597 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
599 p_stream = p_candidate;
600 continue; /* Try to find video anyway */
603 if ( p_candidate->fmt.i_cat == VIDEO_ES )
605 p_stream = p_candidate;
612 /*****************************************************************************
614 *****************************************************************************/
615 static int Control( demux_t *p_demux, int i_query, va_list args )
617 demux_sys_t *p_sys = p_demux->p_sys;
626 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
628 vlc_meta_Merge( p_meta, p_sys->p_meta );
631 case DEMUX_HAS_UNSUPPORTED_META:
632 pb_bool = (bool*)va_arg( args, bool* );
637 pi64 = (int64_t*)va_arg( args, int64_t * );
638 *pi64 = p_sys->i_pcr;
642 i64 = (int64_t)va_arg( args, int64_t );
643 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
646 msg_Err( p_demux, "No selected seekable stream found" );
649 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
650 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
652 Ogg_ResetStreamHelper( p_sys );
653 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
660 case DEMUX_GET_ATTACHMENTS:
662 input_attachment_t ***ppp_attach =
663 (input_attachment_t***)va_arg( args, input_attachment_t*** );
664 int *pi_int = (int*)va_arg( args, int * );
666 if( p_sys->i_attachments <= 0 )
669 *pi_int = p_sys->i_attachments;
670 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
671 for( int i = 0; i < p_sys->i_attachments; i++ )
672 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
676 case DEMUX_GET_POSITION:
677 pf = (double*)va_arg( args, double * );
678 if( p_sys->i_length > 0 )
680 *pf = (double) p_sys->i_pcr /
681 (double) ( p_sys->i_length * (mtime_t)1000000 );
683 else if( stream_Size( p_demux->s ) > 0 )
685 i64 = stream_Tell( p_demux->s );
686 *pf = (double) i64 / stream_Size( p_demux->s );
691 case DEMUX_SET_POSITION:
692 /* forbid seeking if we haven't initialized all logical bitstreams yet;
693 if we allowed, some headers would not get backed up and decoder init
694 would fail, making that logical stream unusable */
695 for ( int i=0; i< p_sys->i_streams; i++ )
697 if ( p_sys->pp_stream[i]->b_initializing )
701 p_stream = Ogg_GetSelectedStream( p_demux );
704 msg_Err( p_demux, "No selected seekable stream found" );
708 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
710 f = (double)va_arg( args, double );
711 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
713 Ogg_ResetStreamHelper( p_sys );
714 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
718 assert( p_sys->i_length > 0 );
719 i64 = CLOCK_FREQ * p_sys->i_length * f;
720 Ogg_ResetStreamHelper( p_sys );
721 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
723 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
730 case DEMUX_GET_LENGTH:
731 if ( p_sys->i_length < 0 )
732 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
734 pi64 = (int64_t*)va_arg( args, int64_t * );
735 *pi64 = p_sys->i_length * 1000000;
738 case DEMUX_GET_TITLE_INFO:
740 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
741 int *pi_int = (int*)va_arg( args, int* );
742 int *pi_title_offset = (int*)va_arg( args, int* );
743 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
745 if( p_sys->i_seekpoints > 0 )
748 *ppp_title = malloc( sizeof( input_title_t* ) );
749 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
750 for( int i = 0; i < p_sys->i_seekpoints; i++ )
752 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
753 if ( likely( p_seekpoint_copy ) )
754 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
756 *pi_title_offset = 0;
757 *pi_seekpoint_offset = 0;
761 case DEMUX_SET_TITLE:
763 const int i_title = (int)va_arg( args, int );
768 case DEMUX_SET_SEEKPOINT:
770 const int i_seekpoint = (int)va_arg( args, int );
771 if( i_seekpoint > p_sys->i_seekpoints )
774 for ( int i=0; i< p_sys->i_streams; i++ )
776 if ( p_sys->pp_stream[i]->b_initializing )
780 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
782 p_stream = Ogg_GetSelectedStream( p_demux );
785 msg_Err( p_demux, "No selected seekable stream found" );
789 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
790 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
792 Ogg_ResetStreamHelper( p_sys );
793 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
795 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
796 p_demux->info.i_seekpoint = i_seekpoint;
804 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
809 /****************************************************************************
810 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
811 ****************************************************************************
812 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
813 * are at the end of stream.
814 ****************************************************************************/
815 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
817 demux_sys_t *p_ogg = p_demux->p_sys ;
821 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
823 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
825 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
829 ogg_sync_wrote( &p_ogg->oy, i_read );
835 /****************************************************************************
836 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
838 ****************************************************************************/
839 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
840 ogg_packet *p_oggpacket )
842 demux_sys_t *p_ogg = p_demux->p_sys;
843 p_stream->i_end_trim = 0;
845 /* Convert the granulepos into a pcr */
846 if( p_oggpacket->granulepos >= 0 )
848 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
849 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
850 p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
852 p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream,
853 p_oggpacket->granulepos, true );
858 sample = p_oggpacket->granulepos;
859 if( p_oggpacket->e_o_s &&
860 p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
861 p_stream->i_previous_granulepos >= 0 )
864 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
867 ogg_int64_t end_sample;
868 end_sample = p_stream->i_previous_granulepos + duration;
869 if( end_sample > sample )
870 p_stream->i_end_trim = (int)(end_sample - sample);
873 if (sample >= p_stream->i_pre_skip)
874 sample -= p_stream->i_pre_skip;
877 p_stream->i_pcr = sample * CLOCK_FREQ / p_stream->f_rate;
880 if ( !p_ogg->i_pcr_offset )
881 p_stream->i_pcr += VLC_TS_0;
883 p_stream->i_pcr += p_ogg->i_pcr_offset;
884 p_stream->i_interpolated_pcr = p_stream->i_pcr;
889 p_stream->i_pcr = -1;
891 /* no granulepos available, try to interpolate the pcr.
892 * If we can't then don't touch the old value. */
893 if( p_stream->fmt.i_cat == VIDEO_ES )
894 /* 1 frame per packet */
895 p_stream->i_interpolated_pcr += (CLOCK_FREQ / p_stream->f_rate);
896 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
897 p_stream->i_previous_granulepos >= 0 &&
899 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
902 p_oggpacket->granulepos =
903 p_stream->i_previous_granulepos + duration;
904 sample = p_oggpacket->granulepos;
905 if (sample >= p_stream->i_pre_skip)
906 sample -= p_stream->i_pre_skip;
909 p_stream->i_interpolated_pcr =
910 VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
911 p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
913 else if( p_stream->fmt.i_bitrate )
915 p_stream->i_interpolated_pcr +=
916 ( p_oggpacket->bytes * CLOCK_FREQ /
917 p_stream->fmt.i_bitrate / 8 );
918 p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
921 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
924 /****************************************************************************
925 * Ogg_DecodePacket: Decode an Ogg packet.
926 ****************************************************************************/
927 static void Ogg_DecodePacket( demux_t *p_demux,
928 logical_stream_t *p_stream,
929 ogg_packet *p_oggpacket )
933 int i_header_len = 0;
934 mtime_t i_pts = -1, i_interpolated_pts;
935 demux_sys_t *p_ogg = p_demux->p_sys;
937 if( p_oggpacket->bytes >= 7 &&
938 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
940 /* it's an Annodex packet -- skip it (do nothing) */
943 else if( p_oggpacket->bytes >= 7 &&
944 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
946 /* it's an AnxData packet -- skip it (do nothing) */
949 else if( p_oggpacket->bytes >= 8 &&
950 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
952 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
955 else if( p_oggpacket->bytes >= 6 &&
956 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
958 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
962 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
963 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
965 /* Check the ES is selected */
966 if ( !p_stream->p_es )
969 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
970 p_stream->p_es, &b_selected );
972 if( p_stream->b_force_backup )
975 p_stream->i_packets_backup++;
976 switch( p_stream->fmt.i_codec )
978 case VLC_CODEC_VORBIS:
979 case VLC_CODEC_THEORA:
980 if( p_stream->i_packets_backup == 3 )
981 p_stream->b_force_backup = false;
985 case VLC_CODEC_SPEEX:
986 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
987 p_stream->b_force_backup = false;
992 if( p_stream->i_packets_backup == 2 )
993 p_stream->b_force_backup = false;
998 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1000 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1001 p_stream->b_force_backup = false;
1003 else if( p_stream->fmt.audio.i_rate )
1005 p_stream->b_force_backup = false;
1006 if( p_oggpacket->bytes >= 9 )
1008 p_oggpacket->packet += 9;
1009 p_oggpacket->bytes -= 9;
1015 case VLC_CODEC_KATE:
1016 if( p_stream->i_packets_backup == p_stream->i_kate_num_headers )
1017 p_stream->b_force_backup = false;
1022 p_stream->b_force_backup = false;
1027 /* Backup the ogg packet (likely an header packet) */
1030 void *p_org = p_stream->p_headers;
1031 p_stream->i_headers += p_oggpacket->bytes;
1032 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1033 if( p_stream->p_headers )
1035 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1036 p_oggpacket->packet, p_oggpacket->bytes );
1040 #warning Memory leak
1041 p_stream->i_headers = 0;
1042 p_stream->p_headers = NULL;
1046 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1047 p_oggpacket->bytes, p_oggpacket->packet ) )
1049 p_stream->i_headers = 0;
1050 p_stream->p_headers = NULL;
1052 if( p_stream->i_headers > 0 )
1054 if( !p_stream->b_force_backup )
1056 /* Last header received, commit changes */
1057 free( p_stream->fmt.p_extra );
1059 p_stream->fmt.i_extra = p_stream->i_headers;
1060 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1061 if( p_stream->fmt.p_extra )
1062 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1063 p_stream->i_headers );
1065 p_stream->fmt.i_extra = 0;
1067 if( p_stream->i_headers > 0 )
1068 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1069 p_stream->p_headers, p_stream->i_headers );
1071 /* we're not at BOS anymore for this logical stream */
1072 p_stream->b_initializing = false;
1076 b_selected = false; /* Discard the header packet */
1079 p_stream->b_initializing = false;
1081 /* Convert the pcr into a pts */
1082 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
1083 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1084 p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
1085 p_stream->fmt.i_codec == VLC_CODEC_FLAC )
1087 if( p_stream->i_pcr >= 0 )
1089 p_stream->i_previous_pcr = p_stream->i_pcr;
1090 /* The granulepos is the end date of the sample */
1091 i_pts = p_stream->i_pcr;
1095 /* Convert the granulepos into the next pcr */
1096 i_interpolated_pts = p_stream->i_interpolated_pcr;
1097 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1099 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1100 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1101 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1102 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1103 p_stream->i_pcr >= 0 )
1105 p_stream->i_previous_pcr = p_stream->i_pcr;
1107 /* The granulepos is the start date of the sample */
1108 i_pts = p_stream->i_pcr;
1113 /* This stream isn't currently selected so we don't need to decode it,
1114 * but we did need to store its pcr as it might be selected later on */
1118 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1121 /* may need to preroll after a seek */
1122 if ( p_stream->i_skip_frames > 0 )
1124 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1127 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1128 if( p_stream->i_skip_frames > duration )
1130 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1131 p_block->i_nb_samples = 0;
1132 p_stream->i_skip_frames -= duration;
1136 p_block->i_nb_samples = duration - p_stream->i_skip_frames;
1137 if( p_stream->i_previous_granulepos >=
1138 p_block->i_nb_samples + p_stream->i_pre_skip )
1140 i_pts = VLC_TS_0 + (p_stream->i_previous_granulepos
1141 - p_block->i_nb_samples - p_stream->i_pre_skip) *
1142 CLOCK_FREQ / p_stream->f_rate;
1144 p_stream->i_skip_frames = 0;
1149 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1150 p_stream->i_skip_frames--;
1153 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1154 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1158 if( i_pts == VLC_TS_INVALID ) i_pts = VLC_TS_0;
1159 else if( i_pts == -1 && i_interpolated_pts == VLC_TS_INVALID )
1161 else if( i_pts == -1 && (p_stream->fmt.i_cat == VIDEO_ES || p_stream->fmt.i_codec == VLC_CODEC_OPUS) )
1162 i_pts = i_interpolated_pts; /* FIXME : why is this incorrect for vorbis? */
1163 else if( i_pts == -1 ) i_pts = VLC_TS_INVALID;
1165 if( p_stream->fmt.i_cat == AUDIO_ES )
1167 p_block->i_dts = p_block->i_pts = i_pts;
1168 /* Blatant abuse of the i_length field. */
1169 p_block->i_length = p_stream->i_end_trim;
1171 else if( p_stream->fmt.i_cat == SPU_ES )
1173 p_block->i_dts = p_block->i_pts = i_pts;
1174 p_block->i_length = 0;
1176 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1178 p_block->i_dts = p_block->i_pts = i_pts;
1179 if( (p_oggpacket->granulepos & ((1<<p_stream->i_granule_shift)-1)) == 0 )
1181 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1184 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1186 ogg_int64_t dts = p_oggpacket->granulepos >> 31;
1187 ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
1189 uint64_t u_pnum = dts + delay;
1191 p_block->i_dts = p_stream->i_pcr;
1192 p_block->i_pts = VLC_TS_INVALID;
1193 /* NB, OggDirac granulepos values are in units of 2*picturerate */
1195 /* granulepos for dirac is possibly broken, this value should be ignored */
1196 if( -1 != p_oggpacket->granulepos )
1197 p_block->i_pts = u_pnum * CLOCK_FREQ / p_stream->f_rate / 2;
1201 p_block->i_dts = i_pts;
1202 p_block->i_pts = VLC_TS_INVALID;
1205 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1206 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1207 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1208 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1209 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1210 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1211 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1212 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1213 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1215 if( p_oggpacket->bytes <= 0 )
1217 msg_Dbg( p_demux, "discarding 0 sized packet" );
1218 block_Release( p_block );
1221 /* We remove the header from the packet */
1222 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1223 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1225 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1227 /* But with subtitles we need to retrieve the duration first */
1228 int i, lenbytes = 0;
1230 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1232 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1234 lenbytes = lenbytes << 8;
1235 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1238 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1239 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1240 p_oggpacket->packet[i_header_len + 1] != 0 &&
1241 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1242 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1244 p_block->i_length = (mtime_t)lenbytes * 1000;
1249 if( p_block->i_buffer >= (unsigned int)i_header_len )
1250 p_block->i_buffer -= i_header_len;
1252 p_block->i_buffer = 0;
1256 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1258 /* FIXME: the biggest hack I've ever done */
1259 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1260 p_block->i_pts, p_block->i_dts );
1264 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1265 p_oggpacket->bytes - i_header_len );
1267 if ( p_stream->p_es )
1269 /* Because ES creation is delayed for preparsing */
1270 if ( p_stream->p_preparse_block )
1272 es_out_Send( p_demux->out, p_stream->p_es, p_stream->p_preparse_block );
1273 p_stream->p_preparse_block = NULL;
1275 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1278 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1281 /* Re-implemented to avoid linking against libopus from the demuxer. */
1282 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1283 ogg_packet *p_oggpacket )
1285 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1291 if( p_oggpacket->bytes < 1 )
1292 return VLC_EGENERIC;
1293 toc = p_oggpacket->packet[0];
1304 if( p_oggpacket->bytes < 2 )
1305 return VLC_EGENERIC;
1306 nframes = p_oggpacket->packet[1]&0x3F;
1309 i_rate = (int)p_stream->fmt.audio.i_rate;
1311 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1312 else if( ( toc&0x60 ) == 0x60 )
1313 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1315 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1316 nsamples = nframes*frame_size;
1317 if( nsamples*25 > i_rate*3 )
1318 return VLC_EGENERIC;
1322 /****************************************************************************
1323 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1324 * stream and fill p_ogg.
1325 *****************************************************************************
1326 * The initial page of a logical stream is marked as a 'bos' page.
1327 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1328 * together and all of the initial pages must appear before any data pages.
1330 * On success this function returns VLC_SUCCESS.
1331 ****************************************************************************/
1332 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1334 demux_sys_t *p_ogg = p_demux->p_sys ;
1335 ogg_packet oggpacket;
1338 p_ogg->i_total_length = stream_Size ( p_demux->s );
1339 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1342 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1345 if( ogg_page_bos( &p_ogg->current_page ) )
1348 /* All is wonderful in our fine fine little world.
1349 * We found the beginning of our first logical stream. */
1350 while( ogg_page_bos( &p_ogg->current_page ) )
1352 logical_stream_t *p_stream;
1354 p_stream = malloc( sizeof(logical_stream_t) );
1355 if( unlikely( !p_stream ) )
1358 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1360 memset( p_stream, 0, sizeof(logical_stream_t) );
1362 es_format_Init( &p_stream->fmt, 0, 0 );
1363 es_format_Init( &p_stream->fmt_old, 0, 0 );
1364 p_stream->b_initializing = true;
1366 /* Setup the logical stream */
1367 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1368 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1370 /* Extract the initial header from the first page and verify
1371 * the codec type of this Ogg bitstream */
1372 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1374 /* error. stream version mismatch perhaps */
1375 msg_Err( p_demux, "error reading first page of "
1376 "Ogg bitstream data" );
1377 return VLC_EGENERIC;
1380 /* FIXME: check return value */
1381 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1383 /* Check for Vorbis header */
1384 if( oggpacket.bytes >= 7 &&
1385 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1387 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
1388 msg_Dbg( p_demux, "found vorbis header" );
1390 /* Check for Speex header */
1391 else if( oggpacket.bytes >= 5 &&
1392 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1394 Ogg_ReadSpeexHeader( p_stream, &oggpacket );
1395 msg_Dbg( p_demux, "found speex header, channels: %i, "
1396 "rate: %i, bitrate: %i",
1397 p_stream->fmt.audio.i_channels,
1398 (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
1400 /* Check for Opus header */
1401 else if( oggpacket.bytes >= 8 &&
1402 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1404 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1405 msg_Dbg( p_demux, "found opus header, channels: %i, "
1407 p_stream->fmt.audio.i_channels,
1408 (int)p_stream->i_pre_skip);
1409 p_stream->i_skip_frames = p_stream->i_pre_skip;
1411 /* Check for Flac header (< version 1.1.1) */
1412 else if( oggpacket.bytes >= 4 &&
1413 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1415 msg_Dbg( p_demux, "found FLAC header" );
1417 /* Grrrr!!!! Did they really have to put all the
1418 * important info in the second header packet!!!
1419 * (STREAMINFO metadata is in the following packet) */
1420 p_stream->b_force_backup = true;
1422 p_stream->fmt.i_cat = AUDIO_ES;
1423 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1425 /* Check for Flac header (>= version 1.1.1) */
1426 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1427 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1428 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1430 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1431 oggpacket.packet[8];
1432 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1433 "(%i header packets)",
1434 oggpacket.packet[5], oggpacket.packet[6],
1437 p_stream->b_force_backup = true;
1439 p_stream->fmt.i_cat = AUDIO_ES;
1440 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1441 oggpacket.packet += 13; oggpacket.bytes -= 13;
1442 Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
1444 /* Check for Theora header */
1445 else if( oggpacket.bytes >= 7 &&
1446 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1448 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
1451 "found theora header, bitrate: %i, rate: %f",
1452 p_stream->fmt.i_bitrate, p_stream->f_rate );
1454 /* Check for Dirac header */
1455 else if( ( oggpacket.bytes >= 5 &&
1456 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1457 ( oggpacket.bytes >= 9 &&
1458 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1460 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1461 msg_Dbg( p_demux, "found dirac header" );
1464 msg_Warn( p_demux, "found dirac header isn't decodable" );
1469 /* Check for Tarkin header */
1470 else if( oggpacket.bytes >= 7 &&
1471 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1475 msg_Dbg( p_demux, "found tarkin header" );
1476 p_stream->fmt.i_cat = VIDEO_ES;
1477 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1479 /* Cheat and get additionnal info ;) */
1480 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1481 oggpack_adv( &opb, 88 );
1482 oggpack_adv( &opb, 104 );
1483 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1484 p_stream->f_rate = 2; /* FIXME */
1486 "found tarkin header, bitrate: %i, rate: %f",
1487 p_stream->fmt.i_bitrate, p_stream->f_rate );
1489 /* Check for Annodex header */
1490 else if( oggpacket.bytes >= 7 &&
1491 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1493 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1494 /* kill annodex track */
1498 /* Check for Annodex header */
1499 else if( oggpacket.bytes >= 7 &&
1500 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1502 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1504 /* Check for Kate header */
1505 else if( oggpacket.bytes >= 8 &&
1506 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1508 Ogg_ReadKateHeader( p_stream, &oggpacket );
1509 msg_Dbg( p_demux, "found kate header" );
1511 /* Check for OggDS */
1512 else if( oggpacket.bytes >= 142 &&
1513 !memcmp( &oggpacket.packet[1],
1514 "Direct Show Samples embedded in Ogg", 35 ))
1516 /* Old header type */
1517 p_stream->b_oggds = true;
1518 /* Check for video header (old format) */
1519 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1520 oggpacket.bytes >= 184 )
1522 p_stream->fmt.i_cat = VIDEO_ES;
1523 p_stream->fmt.i_codec =
1524 VLC_FOURCC( oggpacket.packet[68],
1525 oggpacket.packet[69],
1526 oggpacket.packet[70],
1527 oggpacket.packet[71] );
1528 msg_Dbg( p_demux, "found video header of type: %.4s",
1529 (char *)&p_stream->fmt.i_codec );
1531 p_stream->fmt.video.i_frame_rate = 10000000;
1532 p_stream->fmt.video.i_frame_rate_base =
1533 GetQWLE((oggpacket.packet+164));
1534 p_stream->f_rate = 10000000.0 /
1535 GetQWLE((oggpacket.packet+164));
1536 p_stream->fmt.video.i_bits_per_pixel =
1537 GetWLE((oggpacket.packet+182));
1538 if( !p_stream->fmt.video.i_bits_per_pixel )
1540 p_stream->fmt.video.i_bits_per_pixel = 24;
1541 p_stream->fmt.video.i_width =
1542 GetDWLE((oggpacket.packet+176));
1543 p_stream->fmt.video.i_height =
1544 GetDWLE((oggpacket.packet+180));
1547 "fps: %f, width:%i; height:%i, bitcount:%i",
1549 p_stream->fmt.video.i_width,
1550 p_stream->fmt.video.i_height,
1551 p_stream->fmt.video.i_bits_per_pixel);
1554 /* Check for audio header (old format) */
1555 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1558 unsigned int i_format_tag;
1560 p_stream->fmt.i_cat = AUDIO_ES;
1562 i_extra_size = GetWLE((oggpacket.packet+140));
1563 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1565 p_stream->fmt.i_extra = i_extra_size;
1566 p_stream->fmt.p_extra = malloc( i_extra_size );
1567 if( p_stream->fmt.p_extra )
1568 memcpy( p_stream->fmt.p_extra,
1569 oggpacket.packet + 142, i_extra_size );
1571 p_stream->fmt.i_extra = 0;
1574 i_format_tag = GetWLE((oggpacket.packet+124));
1575 p_stream->fmt.audio.i_channels =
1576 GetWLE((oggpacket.packet+126));
1577 fill_channels_info(&p_stream->fmt.audio);
1578 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1579 GetDWLE((oggpacket.packet+128));
1580 p_stream->fmt.i_bitrate =
1581 GetDWLE((oggpacket.packet+132)) * 8;
1582 p_stream->fmt.audio.i_blockalign =
1583 GetWLE((oggpacket.packet+136));
1584 p_stream->fmt.audio.i_bitspersample =
1585 GetWLE((oggpacket.packet+138));
1587 wf_tag_to_fourcc( i_format_tag,
1588 &p_stream->fmt.i_codec, 0 );
1590 if( p_stream->fmt.i_codec ==
1591 VLC_FOURCC('u','n','d','f') )
1593 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1594 ( i_format_tag >> 8 ) & 0xff,
1595 i_format_tag & 0xff );
1598 msg_Dbg( p_demux, "found audio header of type: %.4s",
1599 (char *)&p_stream->fmt.i_codec );
1600 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1601 "%dbits/sample %dkb/s",
1603 p_stream->fmt.audio.i_channels,
1604 p_stream->fmt.audio.i_rate,
1605 p_stream->fmt.audio.i_bitspersample,
1606 p_stream->fmt.i_bitrate / 1024 );
1611 msg_Dbg( p_demux, "stream %d has an old header "
1612 "but is of an unknown type", p_ogg->i_streams-1 );
1617 /* Check for OggDS */
1618 else if( oggpacket.bytes >= 44+1 &&
1619 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1621 stream_header_t tmp;
1622 stream_header_t *st = &tmp;
1624 p_stream->b_oggds = true;
1626 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1627 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1628 st->size = GetDWLE( &oggpacket.packet[1+12] );
1629 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1630 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1631 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1632 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1633 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1635 /* Check for video header (new format) */
1636 if( !strncmp( st->streamtype, "video", 5 ) &&
1637 oggpacket.bytes >= 52+1 )
1639 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1640 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1642 p_stream->fmt.i_cat = VIDEO_ES;
1644 /* We need to get rid of the header packet */
1645 ogg_stream_packetout( &p_stream->os, &oggpacket );
1647 p_stream->fmt.i_codec =
1648 VLC_FOURCC( st->subtype[0], st->subtype[1],
1649 st->subtype[2], st->subtype[3] );
1650 msg_Dbg( p_demux, "found video header of type: %.4s",
1651 (char *)&p_stream->fmt.i_codec );
1653 p_stream->fmt.video.i_frame_rate = 10000000;
1654 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1655 if( st->time_unit <= 0 )
1656 st->time_unit = 400000;
1657 p_stream->f_rate = 10000000.0 / st->time_unit;
1658 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1659 p_stream->fmt.video.i_width = st->sh.video.width;
1660 p_stream->fmt.video.i_height = st->sh.video.height;
1663 "fps: %f, width:%i; height:%i, bitcount:%i",
1665 p_stream->fmt.video.i_width,
1666 p_stream->fmt.video.i_height,
1667 p_stream->fmt.video.i_bits_per_pixel );
1669 /* Check for audio header (new format) */
1670 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1671 oggpacket.bytes >= 56+1 )
1677 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1678 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1679 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1681 p_stream->fmt.i_cat = AUDIO_ES;
1683 /* We need to get rid of the header packet */
1684 ogg_stream_packetout( &p_stream->os, &oggpacket );
1686 i_extra_size = st->size - 56;
1688 if( i_extra_size > 0 &&
1689 i_extra_size < oggpacket.bytes - 1 - 56 )
1691 p_stream->fmt.i_extra = i_extra_size;
1692 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1693 if( p_stream->fmt.p_extra )
1694 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1695 p_stream->fmt.i_extra );
1697 p_stream->fmt.i_extra = 0;
1700 memcpy( p_buffer, st->subtype, 4 );
1702 i_format_tag = strtol(p_buffer,NULL,16);
1703 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1704 fill_channels_info(&p_stream->fmt.audio);
1705 if( st->time_unit <= 0 )
1706 st->time_unit = 10000000;
1707 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1708 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1709 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1710 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1712 wf_tag_to_fourcc( i_format_tag,
1713 &p_stream->fmt.i_codec, 0 );
1715 if( p_stream->fmt.i_codec ==
1716 VLC_FOURCC('u','n','d','f') )
1718 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1719 ( i_format_tag >> 8 ) & 0xff,
1720 i_format_tag & 0xff );
1723 msg_Dbg( p_demux, "found audio header of type: %.4s",
1724 (char *)&p_stream->fmt.i_codec );
1725 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1726 "%dbits/sample %dkb/s",
1728 p_stream->fmt.audio.i_channels,
1729 p_stream->fmt.audio.i_rate,
1730 p_stream->fmt.audio.i_bitspersample,
1731 p_stream->fmt.i_bitrate / 1024 );
1733 /* Check for text (subtitles) header */
1734 else if( !strncmp(st->streamtype, "text", 4) )
1736 /* We need to get rid of the header packet */
1737 ogg_stream_packetout( &p_stream->os, &oggpacket );
1739 msg_Dbg( p_demux, "found text subtitle header" );
1740 p_stream->fmt.i_cat = SPU_ES;
1741 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1742 p_stream->f_rate = 1000; /* granulepos is in millisec */
1746 msg_Dbg( p_demux, "stream %d has a header marker "
1747 "but is of an unknown type", p_ogg->i_streams-1 );
1752 else if( oggpacket.bytes >= 8 &&
1753 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1757 msg_Dbg( p_demux, "stream %d is a skeleton",
1758 p_ogg->i_streams-1 );
1759 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1763 msg_Dbg( p_demux, "stream %d is of unknown type",
1764 p_ogg->i_streams-1 );
1769 /* we'll need to get all headers */
1770 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1772 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1773 return VLC_EGENERIC;
1776 /* This is the first data page, which means we are now finished
1777 * with the initial pages. We just need to store it in the relevant
1779 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1781 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1782 &p_ogg->current_page ) == 0 )
1784 p_ogg->b_page_waiting = true;
1793 return VLC_EGENERIC;
1796 /****************************************************************************
1797 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1798 ****************************************************************************/
1799 static void Ogg_CreateES( demux_t *p_demux )
1801 demux_sys_t *p_ogg = p_demux->p_sys;
1802 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1805 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1807 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1809 if ( p_stream->p_es == NULL )
1811 /* Better be safe than sorry when possible with ogm */
1812 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1813 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1814 p_stream->fmt.b_packetized = false;
1816 /* Try first to reuse an old ES */
1818 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1819 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1821 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1823 p_stream->p_es = p_old_stream->p_es;
1824 p_stream->b_finished = false;
1825 p_stream->b_reinit = false;
1826 p_stream->b_initializing = false;
1827 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1829 p_old_stream->p_es = NULL;
1830 p_old_stream = NULL;
1831 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
1832 p_stream->p_es, &p_stream->fmt );
1836 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1839 // TODO: something to do here ?
1840 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
1842 /* Set the CMML stream active */
1843 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
1848 if( p_ogg->p_old_stream )
1850 if( p_ogg->p_old_stream->p_es )
1851 msg_Dbg( p_demux, "old stream not reused" );
1852 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
1853 p_ogg->p_old_stream = NULL;
1857 /****************************************************************************
1858 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1859 * Elementary streams.
1860 ****************************************************************************/
1861 static int Ogg_BeginningOfStream( demux_t *p_demux )
1863 demux_sys_t *p_ogg = p_demux->p_sys ;
1866 /* Find the logical streams embedded in the physical stream and
1867 * initialize our p_ogg structure. */
1868 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
1870 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
1871 return VLC_EGENERIC;
1874 p_ogg->i_bitrate = 0;
1876 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1878 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1880 p_stream->p_es = NULL;
1882 /* initialise kframe index */
1885 if ( p_stream->fmt.i_bitrate == 0 &&
1886 ( p_stream->fmt.i_cat == VIDEO_ES ||
1887 p_stream->fmt.i_cat == AUDIO_ES ) )
1888 p_ogg->b_partial_bitrate = true;
1890 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
1892 p_stream->i_pcr = p_stream->i_previous_pcr =
1893 p_stream->i_interpolated_pcr = -1;
1894 p_stream->b_reinit = false;
1897 /* get total frame count for video stream; we will need this for seeking */
1898 p_ogg->i_total_frames = 0;
1903 /****************************************************************************
1904 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1905 ****************************************************************************/
1906 static void Ogg_EndOfStream( demux_t *p_demux )
1908 demux_sys_t *p_ogg = p_demux->p_sys ;
1911 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1912 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
1913 free( p_ogg->pp_stream );
1916 p_ogg->i_bitrate = 0;
1917 p_ogg->i_streams = 0;
1918 p_ogg->pp_stream = NULL;
1919 p_ogg->skeleton.major = 0;
1920 p_ogg->skeleton.minor = 0;
1921 p_ogg->b_preparsing_done = false;
1922 p_ogg->i_pcr_offset = p_ogg->i_pcr;
1926 vlc_meta_Delete( p_ogg->p_meta );
1927 p_ogg->p_meta = NULL;
1929 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
1931 if ( p_ogg->pp_seekpoints[i] )
1932 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
1934 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
1935 p_ogg->i_seekpoints = 0;
1939 * This function delete and release all data associated to a logical_stream_t
1941 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
1943 if( p_stream->p_es )
1944 es_out_Del( p_demux->out, p_stream->p_es );
1946 ogg_stream_clear( &p_stream->os );
1947 free( p_stream->p_headers );
1949 es_format_Clean( &p_stream->fmt_old );
1950 es_format_Clean( &p_stream->fmt );
1952 if ( p_stream->idx != NULL)
1954 oggseek_index_entries_free( p_stream->idx );
1957 Ogg_FreeSkeleton( p_stream->p_skel );
1958 p_stream->p_skel = NULL;
1959 if ( p_demux->p_sys->p_skelstream == p_stream )
1960 p_demux->p_sys->p_skelstream = NULL;
1962 /* Shouldn't happen */
1963 if ( unlikely( p_stream->p_preparse_block ) )
1965 block_ChainRelease( p_stream->p_preparse_block );
1966 p_stream->p_preparse_block = NULL;
1972 * This function check if a we need to reset a decoder in case we are
1975 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
1977 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
1978 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
1979 unsigned i_new_count;
1980 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
1983 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
1984 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
1985 unsigned i_old_count;
1986 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
1989 bool b_match = i_new_count == i_old_count;
1990 for( unsigned i = 0; i < i_new_count && b_match; i++ )
1992 /* Ignore vorbis comment */
1995 if( pi_new_size[i] != pi_old_size[i] ||
1996 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2003 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2004 const es_format_t *p_old )
2006 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2007 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2008 unsigned i_new_count;
2009 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2011 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2012 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2013 unsigned i_old_count;
2014 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2016 bool b_match = false;
2017 if( i_new_count == i_old_count && i_new_count > 0 )
2019 static const unsigned char default_map[2] = { 0, 1 };
2020 unsigned char *p_old_head;
2021 unsigned char *p_new_head;
2022 const unsigned char *p_old_map;
2023 const unsigned char *p_new_map;
2024 int i_old_channel_count;
2025 int i_new_channel_count;
2026 int i_old_stream_count;
2027 int i_new_stream_count;
2028 int i_old_coupled_count;
2029 int i_new_coupled_count;
2030 p_old_head = (unsigned char *)pp_old_data[0];
2031 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2032 p_old_map = default_map;
2033 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2035 i_old_channel_count = p_old_head[9];
2036 switch( p_old_head[18] )
2039 i_old_stream_count = 1;
2040 i_old_coupled_count = i_old_channel_count - 1;
2043 if( pi_old_size[0] >= 21U + i_old_channel_count )
2045 i_old_stream_count = p_old_head[19];
2046 i_old_coupled_count = p_old_head[20];
2047 p_old_map = p_old_head + 21;
2052 p_new_head = (unsigned char *)pp_new_data[0];
2053 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2054 p_new_map = default_map;
2055 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2057 i_new_channel_count = p_new_head[9];
2058 switch( p_new_head[18] )
2061 i_new_stream_count = 1;
2062 i_new_coupled_count = i_new_channel_count - 1;
2065 if( pi_new_size[0] >= 21U + i_new_channel_count )
2067 i_new_stream_count = p_new_head[19];
2068 i_new_coupled_count = p_new_head[20];
2069 p_new_map = p_new_head+21;
2074 b_match = i_old_channel_count == i_new_channel_count &&
2075 i_old_stream_count == i_new_stream_count &&
2076 i_old_coupled_count == i_new_coupled_count &&
2077 memcmp(p_old_map, p_new_map,
2078 i_new_channel_count*sizeof(*p_new_map)) == 0;
2084 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2086 bool b_compatible = false;
2087 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2090 /* Only Vorbis and Opus are supported. */
2091 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2092 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2093 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2094 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2097 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2099 return !b_compatible;
2101 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2102 const void *p_headers, unsigned i_headers, unsigned i_skip )
2104 demux_sys_t *p_ogg = p_demux->p_sys;
2106 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2107 void *pp_data[XIPH_MAX_HEADER_COUNT];
2109 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2112 /* TODO how to handle multiple comments properly ? */
2113 if( i_count >= 2 && pi_size[1] > i_skip )
2115 int i_cover_score = 0;
2116 int i_cover_idx = 0;
2117 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2118 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2119 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2121 pf_replay_gain[i] = 0;
2122 pf_replay_peak[i] = 0;
2124 vorbis_ParseComment( &p_ogg->p_meta, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip,
2125 &p_ogg->i_attachments, &p_ogg->attachments,
2126 &i_cover_score, &i_cover_idx,
2127 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2128 &pf_replay_gain, &pf_replay_peak );
2129 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2132 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2133 p_ogg->attachments[i_cover_idx]->psz_name );
2134 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2137 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2139 if ( pf_replay_gain[i] != 0 )
2141 p_fmt->audio_replay_gain.pb_gain[i] = true;
2142 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2143 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2145 if ( pf_replay_peak[i] != 0 )
2147 p_fmt->audio_replay_gain.pb_peak[i] = true;
2148 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2149 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2154 if( p_ogg->i_seekpoints > 1 )
2156 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2159 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2161 demux_sys_t *p_ogg = p_demux->p_sys;
2163 switch( p_fmt->i_codec )
2165 /* 3 headers with the 2° one being the comments */
2166 case VLC_CODEC_VORBIS:
2167 case VLC_CODEC_THEORA:
2168 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2170 case VLC_CODEC_OPUS:
2171 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2173 case VLC_CODEC_SPEEX:
2174 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2177 /* N headers with the 2° one being the comments */
2178 case VLC_CODEC_KATE:
2179 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2180 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2184 case VLC_CODEC_FLAC:
2185 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2189 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2190 case VLC_CODEC_DIRAC:
2195 p_demux->info.i_update |= INPUT_UPDATE_META;
2198 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2199 ogg_packet *p_oggpacket )
2202 int i_fps_numerator;
2203 int i_fps_denominator;
2204 int i_keyframe_frequency_force;
2210 p_stream->fmt.i_cat = VIDEO_ES;
2211 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2213 /* Signal that we want to keep a backup of the theora
2214 * stream headers. They will be used when switching between
2216 p_stream->b_force_backup = true;
2218 /* Cheat and get additionnal info ;) */
2219 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2220 bs_skip( &bitstream, 56 );
2222 i_major = bs_read( &bitstream, 8 ); /* major version num */
2223 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2224 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2226 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2227 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2228 bs_read( &bitstream, 24 ); /* frame width */
2229 bs_read( &bitstream, 24 ); /* frame height */
2230 bs_read( &bitstream, 8 ); /* x offset */
2231 bs_read( &bitstream, 8 ); /* y offset */
2233 i_fps_numerator = bs_read( &bitstream, 32 );
2234 i_fps_denominator = bs_read( &bitstream, 32 );
2235 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2236 bs_read( &bitstream, 24 ); /* aspect_numerator */
2237 bs_read( &bitstream, 24 ); /* aspect_denominator */
2239 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2240 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2242 bs_read( &bitstream, 8 ); /* colorspace */
2243 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2244 bs_read( &bitstream, 6 ); /* quality */
2246 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2248 /* granule_shift = i_log( frequency_force -1 ) */
2249 p_stream->i_granule_shift = 0;
2250 i_keyframe_frequency_force--;
2251 while( i_keyframe_frequency_force )
2253 p_stream->i_granule_shift++;
2254 i_keyframe_frequency_force >>= 1;
2257 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2258 p_stream->i_keyframe_offset = 0;
2259 p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
2261 if ( i_version >= 3002001 )
2263 p_stream->i_keyframe_offset = 1;
2267 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2268 ogg_packet *p_oggpacket )
2272 p_stream->fmt.i_cat = AUDIO_ES;
2273 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2275 /* Signal that we want to keep a backup of the vorbis
2276 * stream headers. They will be used when switching between
2278 p_stream->b_force_backup = true;
2280 /* Cheat and get additionnal info ;) */
2281 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2282 oggpack_adv( &opb, 88 );
2283 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2284 fill_channels_info(&p_stream->fmt.audio);
2285 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2286 oggpack_read( &opb, 32 );
2287 oggpack_adv( &opb, 32 );
2288 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2291 static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2292 ogg_packet *p_oggpacket )
2296 p_stream->fmt.i_cat = AUDIO_ES;
2297 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2299 /* Signal that we want to keep a backup of the speex
2300 * stream headers. They will be used when switching between
2302 p_stream->b_force_backup = true;
2304 /* Cheat and get additionnal info ;) */
2305 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2306 oggpack_adv( &opb, 224 );
2307 oggpack_adv( &opb, 32 ); /* speex_version_id */
2308 oggpack_adv( &opb, 32 ); /* header_size */
2309 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2310 oggpack_adv( &opb, 32 ); /* mode */
2311 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2312 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2313 fill_channels_info(&p_stream->fmt.audio);
2314 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2315 oggpack_adv( &opb, 32 ); /* frame_size */
2316 oggpack_adv( &opb, 32 ); /* vbr */
2317 oggpack_adv( &opb, 32 ); /* frames_per_packet */
2318 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2321 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2322 ogg_packet *p_oggpacket )
2326 p_stream->fmt.i_cat = AUDIO_ES;
2327 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2329 /* Signal that we want to keep a backup of the opus
2330 * stream headers. They will be used when switching between
2332 p_stream->b_force_backup = true;
2334 /* All OggOpus streams are timestamped at 48kHz and
2335 * can be played at 48kHz. */
2336 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2337 p_stream->fmt.i_bitrate = 0;
2339 /* Cheat and get additional info ;) */
2340 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2341 oggpack_adv( &opb, 64 );
2342 oggpack_adv( &opb, 8 ); /* version_id */
2343 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2344 fill_channels_info(&p_stream->fmt.audio);
2345 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2348 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2349 ogg_packet *p_oggpacket )
2351 /* Parse the STREAMINFO metadata */
2354 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2357 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2359 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2363 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2366 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2367 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2368 fill_channels_info(&p_stream->fmt.audio);
2370 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2371 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2375 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2378 /* Fake this as the last metadata block */
2379 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2382 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
2383 ogg_packet *p_oggpacket )
2391 p_stream->fmt.i_cat = SPU_ES;
2392 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2394 /* Signal that we want to keep a backup of the kate
2395 * stream headers. They will be used when switching between
2397 p_stream->b_force_backup = true;
2399 /* Cheat and get additionnal info ;) */
2400 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2401 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2402 p_stream->i_kate_num_headers = oggpack_read( &opb, 8 );
2403 oggpack_adv( &opb, 3*8 );
2404 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2405 oggpack_adv( &opb, 8*8 ); /* reserved */
2406 gnum = oggpack_read( &opb, 32 );
2407 gden = oggpack_read( &opb, 32 );
2408 p_stream->f_rate = (double)gnum/gden;
2410 p_stream->fmt.psz_language = malloc(16);
2411 if( p_stream->fmt.psz_language )
2413 for( n = 0; n < 16; n++ )
2414 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2415 p_stream->fmt.psz_language[15] = 0; /* just in case */
2419 for( n = 0; n < 16; n++ )
2420 oggpack_read(&opb,8);
2422 p_stream->fmt.psz_description = malloc(16);
2423 if( p_stream->fmt.psz_description )
2425 for( n = 0; n < 16; n++ )
2426 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2427 p_stream->fmt.psz_description[15] = 0; /* just in case */
2429 /* Now find a localized user readable description for this category */
2430 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2433 free( p_stream->fmt.psz_description );
2434 p_stream->fmt.psz_description = psz_desc;
2439 for( n = 0; n < 16; n++ )
2440 oggpack_read(&opb,8);
2444 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2445 bool *b_force_backup, bool *b_packet_out )
2447 if( !strncmp(psz_value, "audio/x-wav", 11) )
2449 /* n.b. WAVs are unsupported right now */
2450 p_stream->fmt.i_cat = UNKNOWN_ES;
2451 free( p_stream->fmt.psz_description );
2452 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2454 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2455 !strncmp(psz_value, "audio/vorbis", 12) )
2457 p_stream->fmt.i_cat = AUDIO_ES;
2458 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2460 *b_force_backup = true;
2462 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2463 !strncmp(psz_value, "audio/speex", 11) )
2465 p_stream->fmt.i_cat = AUDIO_ES;
2466 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2468 *b_force_backup = true;
2470 else if( !strncmp(psz_value, "audio/flac", 10) )
2472 p_stream->fmt.i_cat = AUDIO_ES;
2473 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2475 *b_force_backup = true;
2477 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2478 !strncmp(psz_value, "video/theora", 12) )
2480 p_stream->fmt.i_cat = VIDEO_ES;
2481 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2483 *b_force_backup = true;
2485 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2487 p_stream->fmt.i_cat = VIDEO_ES;
2488 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2490 *b_force_backup = true;
2492 else if( !strncmp(psz_value, "video/mpeg", 10) )
2494 /* n.b. MPEG streams are unsupported right now */
2495 p_stream->fmt.i_cat = VIDEO_ES;
2496 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2498 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2499 !strncmp(psz_value, "text/cmml", 9) )
2501 p_stream->fmt.i_cat = SPU_ES;
2502 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2503 *b_packet_out = true;
2505 else if( !strncmp(psz_value, "application/kate", 16) )
2508 p_stream->fmt.i_cat = UNKNOWN_ES;
2509 free( p_stream->fmt.psz_description );
2510 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2514 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2515 logical_stream_t *p_stream,
2516 ogg_packet *p_oggpacket )
2518 if( p_oggpacket->bytes >= 28 &&
2519 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2523 uint16_t major_version;
2524 uint16_t minor_version;
2525 uint64_t timebase_numerator;
2526 uint64_t timebase_denominator;
2528 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2530 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2531 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2532 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2533 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2534 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2535 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2537 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2538 "Timebase %"PRId64" / %"PRId64,
2539 major_version, minor_version,
2540 timebase_numerator, timebase_denominator );
2542 else if( p_oggpacket->bytes >= 42 &&
2543 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2545 uint64_t granule_rate_numerator;
2546 uint64_t granule_rate_denominator;
2547 char content_type_string[1024];
2549 /* Read in Annodex header fields */
2551 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2552 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2553 p_stream->i_secondary_header_packets =
2554 GetDWLE( &p_oggpacket->packet[24] );
2556 /* we are guaranteed that the first header field will be
2557 * the content-type (by the Annodex standard) */
2558 content_type_string[0] = '\0';
2559 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2561 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2562 p_oggpacket->bytes - 1 );
2563 if( p && p[0] == '\r' && p[1] == '\n' )
2564 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2565 content_type_string );
2568 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2569 granule_rate_numerator, granule_rate_denominator,
2570 p_stream->i_secondary_header_packets, content_type_string );
2572 p_stream->f_rate = (float) granule_rate_numerator /
2573 (float) granule_rate_denominator;
2575 /* What type of file do we have?
2576 * strcmp is safe to use here because we've extracted
2577 * content_type_string from the stream manually */
2578 bool b_dopacketout = false;
2579 Ogg_ApplyContentType( p_stream, content_type_string,
2580 &p_stream->b_force_backup, &b_dopacketout );
2581 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2585 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2586 ogg_packet *p_oggpacket )
2588 p_demux->p_sys->p_skelstream = p_stream;
2589 /* There can be only 1 skeleton for streams */
2590 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2591 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2592 if ( asprintf( & p_stream->fmt.psz_description,
2593 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2594 p_demux->p_sys->skeleton.major,
2595 p_demux->p_sys->skeleton.minor ) < 0 )
2596 p_stream->fmt.psz_description = NULL;
2599 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2601 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2603 /* Find the matching stream for this skeleton data */
2604 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2605 logical_stream_t *p_target_stream = NULL;
2606 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2608 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2610 p_target_stream = p_demux->p_sys->pp_stream[i];
2614 if ( !p_target_stream ) return;
2616 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2619 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2620 if ( !p_skel ) return;
2621 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2622 p_skel->p_index = NULL;
2623 p_target_stream->p_skel = p_skel;
2626 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2627 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2628 const unsigned char *p = p_messages;
2629 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2631 if ( *p == 0x0D && *(p+1) == 0x0A )
2633 char *psz_message = strndup( (const char *) p_messages,
2637 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2638 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2640 if ( p < p_boundary - 1 ) p_messages = p + 2;
2647 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2648 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2649 unsigned const char *p_end,
2650 uint64_t *pi_value )
2656 while ( p_begin < p_end )
2658 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2659 *pi_value = *pi_value | ( i_read << i_shift );
2661 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2664 *pi_value = GetQWLE( pi_value );
2668 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2670 if ( p_demux->p_sys->skeleton.major < 4
2671 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2674 /* Find the matching stream for this skeleton data */
2675 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2676 logical_stream_t *p_stream = NULL;
2677 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2679 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2681 p_stream = p_demux->p_sys->pp_stream[i];
2685 if ( !p_stream ) return;
2686 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2687 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2688 if ( !i_keypoints ) return;
2690 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
2691 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
2692 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
2693 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
2694 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2695 uint64_t i_offset = 0;
2696 uint64_t i_time = 0;
2697 uint64_t i_keypoints_found = 0;
2699 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
2702 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2704 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2705 i_time += i_val * p_stream->p_skel->i_indexstampden;
2706 i_keypoints_found++;
2709 if ( i_keypoints_found != i_keypoints )
2711 msg_Warn( p_demux, "Invalid Index: missing entries" );
2715 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
2716 if ( !p_stream->p_skel->p_index ) return;
2717 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
2718 p_oggpacket->bytes - 42 );
2719 p_stream->p_skel->i_index = i_keypoints_found;
2720 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
2723 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
2725 if ( !p_skel ) return;
2726 for ( int i=0; i< p_skel->i_messages; i++ )
2727 free( p_skel->ppsz_messages[i] );
2728 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
2729 free( p_skel->p_index );
2733 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
2735 if ( !p_stream->p_skel ) return;
2736 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
2738 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
2739 if ( ! strncmp( "Name: ", psz_message, 6 ) )
2741 free( p_stream->fmt.psz_description );
2742 p_stream->fmt.psz_description = strdup( psz_message + 6 );
2744 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
2747 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
2752 /* Return true if there's a skeleton exact match */
2753 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
2754 int64_t *pi_lower, int64_t *pi_upper )
2756 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
2759 /* Validate range */
2760 if ( i_time < p_stream->p_skel->i_indexfirstnum
2761 * p_stream->p_skel->i_indexstampden ||
2762 i_time > p_stream->p_skel->i_indexlastnum
2763 * p_stream->p_skel->i_indexstampden ) return false;
2765 /* Then Lookup its index */
2766 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
2771 } current = { 0, 0 }, prev = { -1, -1 };
2773 uint64_t i_keypoints_found = 0;
2775 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
2776 && i_keypoints_found < p_stream->p_skel->i_index )
2779 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2780 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2781 current.i_pos += i_val;
2782 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2783 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2784 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
2785 if ( current.i_pos < 0 || current.i_time < 0 ) break;
2787 i_keypoints_found++;
2789 if ( i_time <= current.i_time )
2791 *pi_lower = prev.i_pos;
2792 *pi_upper = current.i_pos;
2793 return ( i_time == current.i_time );
2800 static uint32_t dirac_uint( bs_t *p_bs )
2802 uint32_t u_count = 0, u_value = 0;
2804 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
2808 u_value |= bs_read( p_bs, 1 );
2811 return (1<<u_count) - 1 + u_value;
2814 static int dirac_bool( bs_t *p_bs )
2816 return bs_read( p_bs, 1 );
2819 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
2820 ogg_packet *p_oggpacket )
2822 static const struct {
2823 uint32_t u_n /* numerator */, u_d /* denominator */;
2824 } p_dirac_frate_tbl[] = { /* table 10.3 */
2825 {1,1}, /* this first value is never used */
2826 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
2827 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
2829 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
2831 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
2832 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
2834 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
2838 p_stream->i_granule_shift = 22; /* not 32 */
2840 /* Backing up stream headers is not required -- seqhdrs are repeated
2841 * thoughout the stream at suitable decoding start points */
2842 p_stream->b_force_backup = false;
2844 /* read in useful bits from sequence header */
2845 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
2846 bs_skip( &bs, 13*8); /* parse_info_header */
2847 dirac_uint( &bs ); /* major_version */
2848 dirac_uint( &bs ); /* minor_version */
2849 dirac_uint( &bs ); /* profile */
2850 dirac_uint( &bs ); /* level */
2852 uint32_t u_video_format = dirac_uint( &bs ); /* index */
2853 if( u_video_format >= u_dirac_vidfmt_frate )
2855 /* don't know how to parse this ogg dirac stream */
2859 if( dirac_bool( &bs ) )
2861 dirac_uint( &bs ); /* frame_width */
2862 dirac_uint( &bs ); /* frame_height */
2865 if( dirac_bool( &bs ) )
2867 dirac_uint( &bs ); /* chroma_format */
2870 if( dirac_bool( &bs ) )
2872 dirac_uint( &bs ); /* scan_format */
2875 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
2876 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
2877 if( dirac_bool( &bs ) )
2879 uint32_t u_frame_rate_index = dirac_uint( &bs );
2880 if( u_frame_rate_index >= u_dirac_frate_tbl )
2882 /* something is wrong with this stream */
2885 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
2886 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
2887 if( u_frame_rate_index == 0 )
2889 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
2890 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
2893 p_stream->f_rate = (float) u_n / u_d;
2895 /* probably is an ogg dirac es */
2896 p_stream->fmt.i_cat = VIDEO_ES;
2897 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;