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 /* This is for streams where the granulepos of the header packets
1090 * doesn't match these of the data packets (eg. ogg web radios). */
1091 if( p_stream->i_previous_pcr == 0 &&
1092 p_stream->i_pcr > 3 * DEFAULT_PTS_DELAY )
1095 /* Call the pace control */
1096 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
1097 VLC_TS_0 + p_stream->i_pcr );
1100 p_stream->i_previous_pcr = p_stream->i_pcr;
1102 /* The granulepos is the end date of the sample */
1103 i_pts = p_stream->i_pcr;
1107 /* Convert the granulepos into the next pcr */
1108 i_interpolated_pts = p_stream->i_interpolated_pcr;
1109 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1111 /* SPU streams are typically discontinuous, do not mind large gaps */
1112 if( p_stream->fmt.i_cat != SPU_ES )
1114 if( p_stream->i_pcr >= 0 )
1116 /* This is for streams where the granulepos of the header packets
1117 * doesn't match these of the data packets (eg. ogg web radios). */
1118 if( p_stream->i_previous_pcr == 0 &&
1119 p_stream->i_pcr > 3 * DEFAULT_PTS_DELAY )
1122 /* Call the pace control */
1123 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_stream->i_pcr );
1128 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1129 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1130 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1131 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1132 p_stream->i_pcr >= 0 )
1134 p_stream->i_previous_pcr = p_stream->i_pcr;
1136 /* The granulepos is the start date of the sample */
1137 i_pts = p_stream->i_pcr;
1142 /* This stream isn't currently selected so we don't need to decode it,
1143 * but we did need to store its pcr as it might be selected later on */
1147 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1150 /* may need to preroll after a seek */
1151 if ( p_stream->i_skip_frames > 0 )
1153 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1156 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1157 if( p_stream->i_skip_frames > duration )
1159 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1160 p_block->i_nb_samples = 0;
1161 p_stream->i_skip_frames -= duration;
1165 p_block->i_nb_samples = duration - p_stream->i_skip_frames;
1166 if( p_stream->i_previous_granulepos >=
1167 p_block->i_nb_samples + p_stream->i_pre_skip )
1169 i_pts = VLC_TS_0 + (p_stream->i_previous_granulepos
1170 - p_block->i_nb_samples - p_stream->i_pre_skip) *
1171 CLOCK_FREQ / p_stream->f_rate;
1173 p_stream->i_skip_frames = 0;
1178 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1179 p_stream->i_skip_frames--;
1182 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1183 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1187 if( i_pts == VLC_TS_INVALID ) i_pts = VLC_TS_0;
1188 else if( i_pts == -1 && i_interpolated_pts == VLC_TS_INVALID )
1190 else if( i_pts == -1 && (p_stream->fmt.i_cat == VIDEO_ES || p_stream->fmt.i_codec == VLC_CODEC_OPUS) )
1191 i_pts = i_interpolated_pts; /* FIXME : why is this incorrect for vorbis? */
1192 else if( i_pts == -1 ) i_pts = VLC_TS_INVALID;
1194 if( p_stream->fmt.i_cat == AUDIO_ES )
1196 p_block->i_dts = p_block->i_pts = i_pts;
1197 /* Blatant abuse of the i_length field. */
1198 p_block->i_length = p_stream->i_end_trim;
1200 else if( p_stream->fmt.i_cat == SPU_ES )
1202 p_block->i_dts = p_block->i_pts = i_pts;
1203 p_block->i_length = 0;
1205 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1207 p_block->i_dts = p_block->i_pts = i_pts;
1208 if( (p_oggpacket->granulepos & ((1<<p_stream->i_granule_shift)-1)) == 0 )
1210 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1213 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1215 ogg_int64_t dts = p_oggpacket->granulepos >> 31;
1216 ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
1218 uint64_t u_pnum = dts + delay;
1220 p_block->i_dts = p_stream->i_pcr;
1221 p_block->i_pts = VLC_TS_INVALID;
1222 /* NB, OggDirac granulepos values are in units of 2*picturerate */
1224 /* granulepos for dirac is possibly broken, this value should be ignored */
1225 if( -1 != p_oggpacket->granulepos )
1226 p_block->i_pts = u_pnum * CLOCK_FREQ / p_stream->f_rate / 2;
1230 p_block->i_dts = i_pts;
1231 p_block->i_pts = VLC_TS_INVALID;
1234 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1235 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1236 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1237 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1238 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1239 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1240 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1241 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1242 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1244 if( p_oggpacket->bytes <= 0 )
1246 msg_Dbg( p_demux, "discarding 0 sized packet" );
1247 block_Release( p_block );
1250 /* We remove the header from the packet */
1251 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1252 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1254 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1256 /* But with subtitles we need to retrieve the duration first */
1257 int i, lenbytes = 0;
1259 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1261 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1263 lenbytes = lenbytes << 8;
1264 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1267 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1268 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1269 p_oggpacket->packet[i_header_len + 1] != 0 &&
1270 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1271 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1273 p_block->i_length = (mtime_t)lenbytes * 1000;
1278 if( p_block->i_buffer >= (unsigned int)i_header_len )
1279 p_block->i_buffer -= i_header_len;
1281 p_block->i_buffer = 0;
1284 if ( p_stream->b_reusing )
1286 p_stream->b_reusing = false;
1287 p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
1290 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1292 /* FIXME: the biggest hack I've ever done */
1293 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1294 p_block->i_pts, p_block->i_dts );
1298 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1299 p_oggpacket->bytes - i_header_len );
1301 if ( p_stream->p_es )
1303 /* Because ES creation is delayed for preparsing */
1304 if ( p_stream->p_preparse_block )
1306 es_out_Send( p_demux->out, p_stream->p_es, p_stream->p_preparse_block );
1307 p_stream->p_preparse_block = NULL;
1309 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1312 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1315 /* Re-implemented to avoid linking against libopus from the demuxer. */
1316 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1317 ogg_packet *p_oggpacket )
1319 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1325 if( p_oggpacket->bytes < 1 )
1326 return VLC_EGENERIC;
1327 toc = p_oggpacket->packet[0];
1338 if( p_oggpacket->bytes < 2 )
1339 return VLC_EGENERIC;
1340 nframes = p_oggpacket->packet[1]&0x3F;
1343 i_rate = (int)p_stream->fmt.audio.i_rate;
1345 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1346 else if( ( toc&0x60 ) == 0x60 )
1347 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1349 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1350 nsamples = nframes*frame_size;
1351 if( nsamples*25 > i_rate*3 )
1352 return VLC_EGENERIC;
1356 /****************************************************************************
1357 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1358 * stream and fill p_ogg.
1359 *****************************************************************************
1360 * The initial page of a logical stream is marked as a 'bos' page.
1361 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1362 * together and all of the initial pages must appear before any data pages.
1364 * On success this function returns VLC_SUCCESS.
1365 ****************************************************************************/
1366 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1368 demux_sys_t *p_ogg = p_demux->p_sys ;
1369 ogg_packet oggpacket;
1372 p_ogg->i_total_length = stream_Size ( p_demux->s );
1373 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1376 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1379 if( ogg_page_bos( &p_ogg->current_page ) )
1382 /* All is wonderful in our fine fine little world.
1383 * We found the beginning of our first logical stream. */
1384 while( ogg_page_bos( &p_ogg->current_page ) )
1386 logical_stream_t *p_stream;
1388 p_stream = malloc( sizeof(logical_stream_t) );
1389 if( unlikely( !p_stream ) )
1392 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1394 memset( p_stream, 0, sizeof(logical_stream_t) );
1396 es_format_Init( &p_stream->fmt, 0, 0 );
1397 es_format_Init( &p_stream->fmt_old, 0, 0 );
1398 p_stream->b_initializing = true;
1400 /* Setup the logical stream */
1401 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1402 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1404 /* Extract the initial header from the first page and verify
1405 * the codec type of this Ogg bitstream */
1406 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1408 /* error. stream version mismatch perhaps */
1409 msg_Err( p_demux, "error reading first page of "
1410 "Ogg bitstream data" );
1411 return VLC_EGENERIC;
1414 /* FIXME: check return value */
1415 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1417 /* Check for Vorbis header */
1418 if( oggpacket.bytes >= 7 &&
1419 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1421 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
1422 msg_Dbg( p_demux, "found vorbis header" );
1424 /* Check for Speex header */
1425 else if( oggpacket.bytes >= 5 &&
1426 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1428 Ogg_ReadSpeexHeader( p_stream, &oggpacket );
1429 msg_Dbg( p_demux, "found speex header, channels: %i, "
1430 "rate: %i, bitrate: %i",
1431 p_stream->fmt.audio.i_channels,
1432 (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
1434 /* Check for Opus header */
1435 else if( oggpacket.bytes >= 8 &&
1436 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1438 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1439 msg_Dbg( p_demux, "found opus header, channels: %i, "
1441 p_stream->fmt.audio.i_channels,
1442 (int)p_stream->i_pre_skip);
1443 p_stream->i_skip_frames = p_stream->i_pre_skip;
1445 /* Check for Flac header (< version 1.1.1) */
1446 else if( oggpacket.bytes >= 4 &&
1447 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1449 msg_Dbg( p_demux, "found FLAC header" );
1451 /* Grrrr!!!! Did they really have to put all the
1452 * important info in the second header packet!!!
1453 * (STREAMINFO metadata is in the following packet) */
1454 p_stream->b_force_backup = true;
1456 p_stream->fmt.i_cat = AUDIO_ES;
1457 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1459 /* Check for Flac header (>= version 1.1.1) */
1460 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1461 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1462 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1464 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1465 oggpacket.packet[8];
1466 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1467 "(%i header packets)",
1468 oggpacket.packet[5], oggpacket.packet[6],
1471 p_stream->b_force_backup = true;
1473 p_stream->fmt.i_cat = AUDIO_ES;
1474 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1475 oggpacket.packet += 13; oggpacket.bytes -= 13;
1476 Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
1478 /* Check for Theora header */
1479 else if( oggpacket.bytes >= 7 &&
1480 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1482 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
1485 "found theora header, bitrate: %i, rate: %f",
1486 p_stream->fmt.i_bitrate, p_stream->f_rate );
1488 /* Check for Dirac header */
1489 else if( ( oggpacket.bytes >= 5 &&
1490 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1491 ( oggpacket.bytes >= 9 &&
1492 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1494 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1495 msg_Dbg( p_demux, "found dirac header" );
1498 msg_Warn( p_demux, "found dirac header isn't decodable" );
1503 /* Check for Tarkin header */
1504 else if( oggpacket.bytes >= 7 &&
1505 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1509 msg_Dbg( p_demux, "found tarkin header" );
1510 p_stream->fmt.i_cat = VIDEO_ES;
1511 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1513 /* Cheat and get additionnal info ;) */
1514 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1515 oggpack_adv( &opb, 88 );
1516 oggpack_adv( &opb, 104 );
1517 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1518 p_stream->f_rate = 2; /* FIXME */
1520 "found tarkin header, bitrate: %i, rate: %f",
1521 p_stream->fmt.i_bitrate, p_stream->f_rate );
1523 /* Check for Annodex header */
1524 else if( oggpacket.bytes >= 7 &&
1525 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1527 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1528 /* kill annodex track */
1532 /* Check for Annodex header */
1533 else if( oggpacket.bytes >= 7 &&
1534 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1536 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1538 /* Check for Kate header */
1539 else if( oggpacket.bytes >= 8 &&
1540 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1542 Ogg_ReadKateHeader( p_stream, &oggpacket );
1543 msg_Dbg( p_demux, "found kate header" );
1545 /* Check for OggDS */
1546 else if( oggpacket.bytes >= 142 &&
1547 !memcmp( &oggpacket.packet[1],
1548 "Direct Show Samples embedded in Ogg", 35 ))
1550 /* Old header type */
1551 p_stream->b_oggds = true;
1552 /* Check for video header (old format) */
1553 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1554 oggpacket.bytes >= 184 )
1556 p_stream->fmt.i_cat = VIDEO_ES;
1557 p_stream->fmt.i_codec =
1558 VLC_FOURCC( oggpacket.packet[68],
1559 oggpacket.packet[69],
1560 oggpacket.packet[70],
1561 oggpacket.packet[71] );
1562 msg_Dbg( p_demux, "found video header of type: %.4s",
1563 (char *)&p_stream->fmt.i_codec );
1565 p_stream->fmt.video.i_frame_rate = 10000000;
1566 p_stream->fmt.video.i_frame_rate_base =
1567 GetQWLE((oggpacket.packet+164));
1568 p_stream->f_rate = 10000000.0 /
1569 GetQWLE((oggpacket.packet+164));
1570 p_stream->fmt.video.i_bits_per_pixel =
1571 GetWLE((oggpacket.packet+182));
1572 if( !p_stream->fmt.video.i_bits_per_pixel )
1574 p_stream->fmt.video.i_bits_per_pixel = 24;
1575 p_stream->fmt.video.i_width =
1576 GetDWLE((oggpacket.packet+176));
1577 p_stream->fmt.video.i_height =
1578 GetDWLE((oggpacket.packet+180));
1581 "fps: %f, width:%i; height:%i, bitcount:%i",
1583 p_stream->fmt.video.i_width,
1584 p_stream->fmt.video.i_height,
1585 p_stream->fmt.video.i_bits_per_pixel);
1588 /* Check for audio header (old format) */
1589 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1592 unsigned int i_format_tag;
1594 p_stream->fmt.i_cat = AUDIO_ES;
1596 i_extra_size = GetWLE((oggpacket.packet+140));
1597 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1599 p_stream->fmt.i_extra = i_extra_size;
1600 p_stream->fmt.p_extra = malloc( i_extra_size );
1601 if( p_stream->fmt.p_extra )
1602 memcpy( p_stream->fmt.p_extra,
1603 oggpacket.packet + 142, i_extra_size );
1605 p_stream->fmt.i_extra = 0;
1608 i_format_tag = GetWLE((oggpacket.packet+124));
1609 p_stream->fmt.audio.i_channels =
1610 GetWLE((oggpacket.packet+126));
1611 fill_channels_info(&p_stream->fmt.audio);
1612 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1613 GetDWLE((oggpacket.packet+128));
1614 p_stream->fmt.i_bitrate =
1615 GetDWLE((oggpacket.packet+132)) * 8;
1616 p_stream->fmt.audio.i_blockalign =
1617 GetWLE((oggpacket.packet+136));
1618 p_stream->fmt.audio.i_bitspersample =
1619 GetWLE((oggpacket.packet+138));
1621 wf_tag_to_fourcc( i_format_tag,
1622 &p_stream->fmt.i_codec, 0 );
1624 if( p_stream->fmt.i_codec ==
1625 VLC_FOURCC('u','n','d','f') )
1627 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1628 ( i_format_tag >> 8 ) & 0xff,
1629 i_format_tag & 0xff );
1632 msg_Dbg( p_demux, "found audio header of type: %.4s",
1633 (char *)&p_stream->fmt.i_codec );
1634 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1635 "%dbits/sample %dkb/s",
1637 p_stream->fmt.audio.i_channels,
1638 p_stream->fmt.audio.i_rate,
1639 p_stream->fmt.audio.i_bitspersample,
1640 p_stream->fmt.i_bitrate / 1024 );
1645 msg_Dbg( p_demux, "stream %d has an old header "
1646 "but is of an unknown type", p_ogg->i_streams-1 );
1651 /* Check for OggDS */
1652 else if( oggpacket.bytes >= 44+1 &&
1653 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1655 stream_header_t tmp;
1656 stream_header_t *st = &tmp;
1658 p_stream->b_oggds = true;
1660 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1661 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1662 st->size = GetDWLE( &oggpacket.packet[1+12] );
1663 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1664 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1665 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1666 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1667 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1669 /* Check for video header (new format) */
1670 if( !strncmp( st->streamtype, "video", 5 ) &&
1671 oggpacket.bytes >= 52+1 )
1673 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1674 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1676 p_stream->fmt.i_cat = VIDEO_ES;
1678 /* We need to get rid of the header packet */
1679 ogg_stream_packetout( &p_stream->os, &oggpacket );
1681 p_stream->fmt.i_codec =
1682 VLC_FOURCC( st->subtype[0], st->subtype[1],
1683 st->subtype[2], st->subtype[3] );
1684 msg_Dbg( p_demux, "found video header of type: %.4s",
1685 (char *)&p_stream->fmt.i_codec );
1687 p_stream->fmt.video.i_frame_rate = 10000000;
1688 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1689 if( st->time_unit <= 0 )
1690 st->time_unit = 400000;
1691 p_stream->f_rate = 10000000.0 / st->time_unit;
1692 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1693 p_stream->fmt.video.i_width = st->sh.video.width;
1694 p_stream->fmt.video.i_height = st->sh.video.height;
1697 "fps: %f, width:%i; height:%i, bitcount:%i",
1699 p_stream->fmt.video.i_width,
1700 p_stream->fmt.video.i_height,
1701 p_stream->fmt.video.i_bits_per_pixel );
1703 /* Check for audio header (new format) */
1704 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1705 oggpacket.bytes >= 56+1 )
1711 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1712 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1713 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1715 p_stream->fmt.i_cat = AUDIO_ES;
1717 /* We need to get rid of the header packet */
1718 ogg_stream_packetout( &p_stream->os, &oggpacket );
1720 i_extra_size = st->size - 56;
1722 if( i_extra_size > 0 &&
1723 i_extra_size < oggpacket.bytes - 1 - 56 )
1725 p_stream->fmt.i_extra = i_extra_size;
1726 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1727 if( p_stream->fmt.p_extra )
1728 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1729 p_stream->fmt.i_extra );
1731 p_stream->fmt.i_extra = 0;
1734 memcpy( p_buffer, st->subtype, 4 );
1736 i_format_tag = strtol(p_buffer,NULL,16);
1737 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1738 fill_channels_info(&p_stream->fmt.audio);
1739 if( st->time_unit <= 0 )
1740 st->time_unit = 10000000;
1741 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1742 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1743 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1744 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1746 wf_tag_to_fourcc( i_format_tag,
1747 &p_stream->fmt.i_codec, 0 );
1749 if( p_stream->fmt.i_codec ==
1750 VLC_FOURCC('u','n','d','f') )
1752 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1753 ( i_format_tag >> 8 ) & 0xff,
1754 i_format_tag & 0xff );
1757 msg_Dbg( p_demux, "found audio header of type: %.4s",
1758 (char *)&p_stream->fmt.i_codec );
1759 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1760 "%dbits/sample %dkb/s",
1762 p_stream->fmt.audio.i_channels,
1763 p_stream->fmt.audio.i_rate,
1764 p_stream->fmt.audio.i_bitspersample,
1765 p_stream->fmt.i_bitrate / 1024 );
1767 /* Check for text (subtitles) header */
1768 else if( !strncmp(st->streamtype, "text", 4) )
1770 /* We need to get rid of the header packet */
1771 ogg_stream_packetout( &p_stream->os, &oggpacket );
1773 msg_Dbg( p_demux, "found text subtitle header" );
1774 p_stream->fmt.i_cat = SPU_ES;
1775 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1776 p_stream->f_rate = 1000; /* granulepos is in millisec */
1780 msg_Dbg( p_demux, "stream %d has a header marker "
1781 "but is of an unknown type", p_ogg->i_streams-1 );
1786 else if( oggpacket.bytes >= 8 &&
1787 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1791 msg_Dbg( p_demux, "stream %d is a skeleton",
1792 p_ogg->i_streams-1 );
1793 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1797 msg_Dbg( p_demux, "stream %d is of unknown type",
1798 p_ogg->i_streams-1 );
1803 /* we'll need to get all headers */
1804 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1806 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1807 return VLC_EGENERIC;
1810 /* This is the first data page, which means we are now finished
1811 * with the initial pages. We just need to store it in the relevant
1813 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1815 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1816 &p_ogg->current_page ) == 0 )
1818 p_ogg->b_page_waiting = true;
1827 return VLC_EGENERIC;
1830 /****************************************************************************
1831 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1832 ****************************************************************************/
1833 static void Ogg_CreateES( demux_t *p_demux )
1835 demux_sys_t *p_ogg = p_demux->p_sys;
1836 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1839 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1841 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1843 if ( p_stream->p_es == NULL )
1845 /* Better be safe than sorry when possible with ogm */
1846 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1847 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1848 p_stream->fmt.b_packetized = false;
1850 /* Try first to reuse an old ES */
1852 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1853 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1855 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1857 p_stream->p_es = p_old_stream->p_es;
1858 p_stream->b_finished = false;
1859 p_stream->b_reinit = false;
1860 p_stream->b_initializing = false;
1861 p_stream->b_reusing = true;
1862 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1864 p_old_stream->p_es = NULL;
1865 p_old_stream = NULL;
1866 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
1867 p_stream->p_es, &p_stream->fmt );
1871 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1874 // TODO: something to do here ?
1875 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
1877 /* Set the CMML stream active */
1878 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
1883 if( p_ogg->p_old_stream )
1885 if( p_ogg->p_old_stream->p_es )
1886 msg_Dbg( p_demux, "old stream not reused" );
1887 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
1888 p_ogg->p_old_stream = NULL;
1892 /****************************************************************************
1893 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1894 * Elementary streams.
1895 ****************************************************************************/
1896 static int Ogg_BeginningOfStream( demux_t *p_demux )
1898 demux_sys_t *p_ogg = p_demux->p_sys ;
1901 /* Find the logical streams embedded in the physical stream and
1902 * initialize our p_ogg structure. */
1903 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
1905 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
1906 return VLC_EGENERIC;
1909 p_ogg->i_bitrate = 0;
1911 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1913 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1915 p_stream->p_es = NULL;
1917 /* initialise kframe index */
1920 if ( p_stream->fmt.i_bitrate == 0 &&
1921 ( p_stream->fmt.i_cat == VIDEO_ES ||
1922 p_stream->fmt.i_cat == AUDIO_ES ) )
1923 p_ogg->b_partial_bitrate = true;
1925 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
1927 p_stream->i_pcr = p_stream->i_previous_pcr =
1928 p_stream->i_interpolated_pcr = -1;
1929 p_stream->b_reinit = false;
1932 /* get total frame count for video stream; we will need this for seeking */
1933 p_ogg->i_total_frames = 0;
1938 /****************************************************************************
1939 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1940 ****************************************************************************/
1941 static void Ogg_EndOfStream( demux_t *p_demux )
1943 demux_sys_t *p_ogg = p_demux->p_sys ;
1946 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1947 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
1948 free( p_ogg->pp_stream );
1951 p_ogg->i_bitrate = 0;
1952 p_ogg->i_streams = 0;
1953 p_ogg->pp_stream = NULL;
1954 p_ogg->skeleton.major = 0;
1955 p_ogg->skeleton.minor = 0;
1956 p_ogg->b_preparsing_done = false;
1957 p_ogg->i_pcr_offset = p_ogg->i_pcr;
1961 vlc_meta_Delete( p_ogg->p_meta );
1962 p_ogg->p_meta = NULL;
1964 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
1966 if ( p_ogg->pp_seekpoints[i] )
1967 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
1969 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
1970 p_ogg->i_seekpoints = 0;
1974 * This function delete and release all data associated to a logical_stream_t
1976 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
1978 if( p_stream->p_es )
1979 es_out_Del( p_demux->out, p_stream->p_es );
1981 ogg_stream_clear( &p_stream->os );
1982 free( p_stream->p_headers );
1984 es_format_Clean( &p_stream->fmt_old );
1985 es_format_Clean( &p_stream->fmt );
1987 if ( p_stream->idx != NULL)
1989 oggseek_index_entries_free( p_stream->idx );
1992 Ogg_FreeSkeleton( p_stream->p_skel );
1993 p_stream->p_skel = NULL;
1994 if ( p_demux->p_sys->p_skelstream == p_stream )
1995 p_demux->p_sys->p_skelstream = NULL;
1997 /* Shouldn't happen */
1998 if ( unlikely( p_stream->p_preparse_block ) )
2000 block_ChainRelease( p_stream->p_preparse_block );
2001 p_stream->p_preparse_block = NULL;
2007 * This function check if a we need to reset a decoder in case we are
2010 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2012 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2013 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2014 unsigned i_new_count;
2015 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2018 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2019 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2020 unsigned i_old_count;
2021 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2024 bool b_match = i_new_count == i_old_count;
2025 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2027 /* Ignore vorbis comment */
2030 if( pi_new_size[i] != pi_old_size[i] ||
2031 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2038 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2039 const es_format_t *p_old )
2041 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2042 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2043 unsigned i_new_count;
2044 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2046 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2047 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2048 unsigned i_old_count;
2049 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2051 bool b_match = false;
2052 if( i_new_count == i_old_count && i_new_count > 0 )
2054 static const unsigned char default_map[2] = { 0, 1 };
2055 unsigned char *p_old_head;
2056 unsigned char *p_new_head;
2057 const unsigned char *p_old_map;
2058 const unsigned char *p_new_map;
2059 int i_old_channel_count;
2060 int i_new_channel_count;
2061 int i_old_stream_count;
2062 int i_new_stream_count;
2063 int i_old_coupled_count;
2064 int i_new_coupled_count;
2065 p_old_head = (unsigned char *)pp_old_data[0];
2066 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2067 p_old_map = default_map;
2068 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2070 i_old_channel_count = p_old_head[9];
2071 switch( p_old_head[18] )
2074 i_old_stream_count = 1;
2075 i_old_coupled_count = i_old_channel_count - 1;
2078 if( pi_old_size[0] >= 21U + i_old_channel_count )
2080 i_old_stream_count = p_old_head[19];
2081 i_old_coupled_count = p_old_head[20];
2082 p_old_map = p_old_head + 21;
2087 p_new_head = (unsigned char *)pp_new_data[0];
2088 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2089 p_new_map = default_map;
2090 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2092 i_new_channel_count = p_new_head[9];
2093 switch( p_new_head[18] )
2096 i_new_stream_count = 1;
2097 i_new_coupled_count = i_new_channel_count - 1;
2100 if( pi_new_size[0] >= 21U + i_new_channel_count )
2102 i_new_stream_count = p_new_head[19];
2103 i_new_coupled_count = p_new_head[20];
2104 p_new_map = p_new_head+21;
2109 b_match = i_old_channel_count == i_new_channel_count &&
2110 i_old_stream_count == i_new_stream_count &&
2111 i_old_coupled_count == i_new_coupled_count &&
2112 memcmp(p_old_map, p_new_map,
2113 i_new_channel_count*sizeof(*p_new_map)) == 0;
2119 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2121 bool b_compatible = false;
2122 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2125 /* Only Vorbis and Opus are supported. */
2126 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2127 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2128 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2129 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2132 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2134 return !b_compatible;
2136 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2137 const void *p_headers, unsigned i_headers, unsigned i_skip )
2139 demux_sys_t *p_ogg = p_demux->p_sys;
2141 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2142 void *pp_data[XIPH_MAX_HEADER_COUNT];
2144 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2147 /* TODO how to handle multiple comments properly ? */
2148 if( i_count >= 2 && pi_size[1] > i_skip )
2150 int i_cover_score = 0;
2151 int i_cover_idx = 0;
2152 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2153 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2154 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2156 pf_replay_gain[i] = 0;
2157 pf_replay_peak[i] = 0;
2159 vorbis_ParseComment( &p_ogg->p_meta, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip,
2160 &p_ogg->i_attachments, &p_ogg->attachments,
2161 &i_cover_score, &i_cover_idx,
2162 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2163 &pf_replay_gain, &pf_replay_peak );
2164 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2167 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2168 p_ogg->attachments[i_cover_idx]->psz_name );
2169 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2172 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2174 if ( pf_replay_gain[i] != 0 )
2176 p_fmt->audio_replay_gain.pb_gain[i] = true;
2177 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2178 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2180 if ( pf_replay_peak[i] != 0 )
2182 p_fmt->audio_replay_gain.pb_peak[i] = true;
2183 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2184 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2189 if( p_ogg->i_seekpoints > 1 )
2191 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2194 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2196 demux_sys_t *p_ogg = p_demux->p_sys;
2198 switch( p_fmt->i_codec )
2200 /* 3 headers with the 2° one being the comments */
2201 case VLC_CODEC_VORBIS:
2202 case VLC_CODEC_THEORA:
2203 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2205 case VLC_CODEC_OPUS:
2206 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2208 case VLC_CODEC_SPEEX:
2209 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2212 /* N headers with the 2° one being the comments */
2213 case VLC_CODEC_KATE:
2214 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2215 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2219 case VLC_CODEC_FLAC:
2220 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2224 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2225 case VLC_CODEC_DIRAC:
2230 p_demux->info.i_update |= INPUT_UPDATE_META;
2233 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2234 ogg_packet *p_oggpacket )
2237 int i_fps_numerator;
2238 int i_fps_denominator;
2239 int i_keyframe_frequency_force;
2245 p_stream->fmt.i_cat = VIDEO_ES;
2246 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2248 /* Signal that we want to keep a backup of the theora
2249 * stream headers. They will be used when switching between
2251 p_stream->b_force_backup = true;
2253 /* Cheat and get additionnal info ;) */
2254 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2255 bs_skip( &bitstream, 56 );
2257 i_major = bs_read( &bitstream, 8 ); /* major version num */
2258 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2259 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2261 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2262 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2263 bs_read( &bitstream, 24 ); /* frame width */
2264 bs_read( &bitstream, 24 ); /* frame height */
2265 bs_read( &bitstream, 8 ); /* x offset */
2266 bs_read( &bitstream, 8 ); /* y offset */
2268 i_fps_numerator = bs_read( &bitstream, 32 );
2269 i_fps_denominator = bs_read( &bitstream, 32 );
2270 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2271 bs_read( &bitstream, 24 ); /* aspect_numerator */
2272 bs_read( &bitstream, 24 ); /* aspect_denominator */
2274 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2275 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2277 bs_read( &bitstream, 8 ); /* colorspace */
2278 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2279 bs_read( &bitstream, 6 ); /* quality */
2281 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2283 /* granule_shift = i_log( frequency_force -1 ) */
2284 p_stream->i_granule_shift = 0;
2285 i_keyframe_frequency_force--;
2286 while( i_keyframe_frequency_force )
2288 p_stream->i_granule_shift++;
2289 i_keyframe_frequency_force >>= 1;
2292 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2293 p_stream->i_keyframe_offset = 0;
2294 p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
2296 if ( i_version >= 3002001 )
2298 p_stream->i_keyframe_offset = 1;
2302 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2303 ogg_packet *p_oggpacket )
2307 p_stream->fmt.i_cat = AUDIO_ES;
2308 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2310 /* Signal that we want to keep a backup of the vorbis
2311 * stream headers. They will be used when switching between
2313 p_stream->b_force_backup = true;
2315 /* Cheat and get additionnal info ;) */
2316 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2317 oggpack_adv( &opb, 88 );
2318 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2319 fill_channels_info(&p_stream->fmt.audio);
2320 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2321 oggpack_read( &opb, 32 );
2322 oggpack_adv( &opb, 32 );
2323 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2326 static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2327 ogg_packet *p_oggpacket )
2331 p_stream->fmt.i_cat = AUDIO_ES;
2332 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2334 /* Signal that we want to keep a backup of the speex
2335 * stream headers. They will be used when switching between
2337 p_stream->b_force_backup = true;
2339 /* Cheat and get additionnal info ;) */
2340 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2341 oggpack_adv( &opb, 224 );
2342 oggpack_adv( &opb, 32 ); /* speex_version_id */
2343 oggpack_adv( &opb, 32 ); /* header_size */
2344 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2345 oggpack_adv( &opb, 32 ); /* mode */
2346 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2347 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2348 fill_channels_info(&p_stream->fmt.audio);
2349 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2350 oggpack_adv( &opb, 32 ); /* frame_size */
2351 oggpack_adv( &opb, 32 ); /* vbr */
2352 oggpack_adv( &opb, 32 ); /* frames_per_packet */
2353 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2356 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2357 ogg_packet *p_oggpacket )
2361 p_stream->fmt.i_cat = AUDIO_ES;
2362 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2364 /* Signal that we want to keep a backup of the opus
2365 * stream headers. They will be used when switching between
2367 p_stream->b_force_backup = true;
2369 /* All OggOpus streams are timestamped at 48kHz and
2370 * can be played at 48kHz. */
2371 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2372 p_stream->fmt.i_bitrate = 0;
2374 /* Cheat and get additional info ;) */
2375 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2376 oggpack_adv( &opb, 64 );
2377 oggpack_adv( &opb, 8 ); /* version_id */
2378 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2379 fill_channels_info(&p_stream->fmt.audio);
2380 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2383 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2384 ogg_packet *p_oggpacket )
2386 /* Parse the STREAMINFO metadata */
2389 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2392 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2394 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2398 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2401 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2402 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2403 fill_channels_info(&p_stream->fmt.audio);
2405 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2406 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2410 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2413 /* Fake this as the last metadata block */
2414 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2417 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
2418 ogg_packet *p_oggpacket )
2426 p_stream->fmt.i_cat = SPU_ES;
2427 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2429 /* Signal that we want to keep a backup of the kate
2430 * stream headers. They will be used when switching between
2432 p_stream->b_force_backup = true;
2434 /* Cheat and get additionnal info ;) */
2435 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2436 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2437 p_stream->i_kate_num_headers = oggpack_read( &opb, 8 );
2438 oggpack_adv( &opb, 3*8 );
2439 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2440 oggpack_adv( &opb, 8*8 ); /* reserved */
2441 gnum = oggpack_read( &opb, 32 );
2442 gden = oggpack_read( &opb, 32 );
2443 p_stream->f_rate = (double)gnum/gden;
2445 p_stream->fmt.psz_language = malloc(16);
2446 if( p_stream->fmt.psz_language )
2448 for( n = 0; n < 16; n++ )
2449 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2450 p_stream->fmt.psz_language[15] = 0; /* just in case */
2454 for( n = 0; n < 16; n++ )
2455 oggpack_read(&opb,8);
2457 p_stream->fmt.psz_description = malloc(16);
2458 if( p_stream->fmt.psz_description )
2460 for( n = 0; n < 16; n++ )
2461 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2462 p_stream->fmt.psz_description[15] = 0; /* just in case */
2464 /* Now find a localized user readable description for this category */
2465 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2468 free( p_stream->fmt.psz_description );
2469 p_stream->fmt.psz_description = psz_desc;
2474 for( n = 0; n < 16; n++ )
2475 oggpack_read(&opb,8);
2479 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2480 bool *b_force_backup, bool *b_packet_out )
2482 if( !strncmp(psz_value, "audio/x-wav", 11) )
2484 /* n.b. WAVs are unsupported right now */
2485 p_stream->fmt.i_cat = UNKNOWN_ES;
2486 free( p_stream->fmt.psz_description );
2487 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2489 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2490 !strncmp(psz_value, "audio/vorbis", 12) )
2492 p_stream->fmt.i_cat = AUDIO_ES;
2493 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2495 *b_force_backup = true;
2497 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2498 !strncmp(psz_value, "audio/speex", 11) )
2500 p_stream->fmt.i_cat = AUDIO_ES;
2501 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2503 *b_force_backup = true;
2505 else if( !strncmp(psz_value, "audio/flac", 10) )
2507 p_stream->fmt.i_cat = AUDIO_ES;
2508 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2510 *b_force_backup = true;
2512 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2513 !strncmp(psz_value, "video/theora", 12) )
2515 p_stream->fmt.i_cat = VIDEO_ES;
2516 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2518 *b_force_backup = true;
2520 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2522 p_stream->fmt.i_cat = VIDEO_ES;
2523 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2525 *b_force_backup = true;
2527 else if( !strncmp(psz_value, "video/mpeg", 10) )
2529 /* n.b. MPEG streams are unsupported right now */
2530 p_stream->fmt.i_cat = VIDEO_ES;
2531 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2533 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2534 !strncmp(psz_value, "text/cmml", 9) )
2536 p_stream->fmt.i_cat = SPU_ES;
2537 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2538 *b_packet_out = true;
2540 else if( !strncmp(psz_value, "application/kate", 16) )
2543 p_stream->fmt.i_cat = UNKNOWN_ES;
2544 free( p_stream->fmt.psz_description );
2545 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2549 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2550 logical_stream_t *p_stream,
2551 ogg_packet *p_oggpacket )
2553 if( p_oggpacket->bytes >= 28 &&
2554 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2558 uint16_t major_version;
2559 uint16_t minor_version;
2560 uint64_t timebase_numerator;
2561 uint64_t timebase_denominator;
2563 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2565 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2566 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2567 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2568 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2569 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2570 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2572 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2573 "Timebase %"PRId64" / %"PRId64,
2574 major_version, minor_version,
2575 timebase_numerator, timebase_denominator );
2577 else if( p_oggpacket->bytes >= 42 &&
2578 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2580 uint64_t granule_rate_numerator;
2581 uint64_t granule_rate_denominator;
2582 char content_type_string[1024];
2584 /* Read in Annodex header fields */
2586 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2587 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2588 p_stream->i_secondary_header_packets =
2589 GetDWLE( &p_oggpacket->packet[24] );
2591 /* we are guaranteed that the first header field will be
2592 * the content-type (by the Annodex standard) */
2593 content_type_string[0] = '\0';
2594 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2596 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2597 p_oggpacket->bytes - 1 );
2598 if( p && p[0] == '\r' && p[1] == '\n' )
2599 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2600 content_type_string );
2603 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2604 granule_rate_numerator, granule_rate_denominator,
2605 p_stream->i_secondary_header_packets, content_type_string );
2607 p_stream->f_rate = (float) granule_rate_numerator /
2608 (float) granule_rate_denominator;
2610 /* What type of file do we have?
2611 * strcmp is safe to use here because we've extracted
2612 * content_type_string from the stream manually */
2613 bool b_dopacketout = false;
2614 Ogg_ApplyContentType( p_stream, content_type_string,
2615 &p_stream->b_force_backup, &b_dopacketout );
2616 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2620 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2621 ogg_packet *p_oggpacket )
2623 p_demux->p_sys->p_skelstream = p_stream;
2624 /* There can be only 1 skeleton for streams */
2625 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2626 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2627 if ( asprintf( & p_stream->fmt.psz_description,
2628 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2629 p_demux->p_sys->skeleton.major,
2630 p_demux->p_sys->skeleton.minor ) < 0 )
2631 p_stream->fmt.psz_description = NULL;
2634 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2636 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2638 /* Find the matching stream for this skeleton data */
2639 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2640 logical_stream_t *p_target_stream = NULL;
2641 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2643 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2645 p_target_stream = p_demux->p_sys->pp_stream[i];
2649 if ( !p_target_stream ) return;
2651 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2654 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2655 if ( !p_skel ) return;
2656 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2657 p_skel->p_index = NULL;
2658 p_target_stream->p_skel = p_skel;
2661 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2662 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2663 const unsigned char *p = p_messages;
2664 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2666 if ( *p == 0x0D && *(p+1) == 0x0A )
2668 char *psz_message = strndup( (const char *) p_messages,
2672 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2673 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2675 if ( p < p_boundary - 1 ) p_messages = p + 2;
2682 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2683 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2684 unsigned const char *p_end,
2685 uint64_t *pi_value )
2691 while ( p_begin < p_end )
2693 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2694 *pi_value = *pi_value | ( i_read << i_shift );
2696 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2699 *pi_value = GetQWLE( pi_value );
2703 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2705 if ( p_demux->p_sys->skeleton.major < 4
2706 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2709 /* Find the matching stream for this skeleton data */
2710 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2711 logical_stream_t *p_stream = NULL;
2712 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2714 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2716 p_stream = p_demux->p_sys->pp_stream[i];
2720 if ( !p_stream ) return;
2721 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2722 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2723 if ( !i_keypoints ) return;
2725 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
2726 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
2727 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
2728 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
2729 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2730 uint64_t i_offset = 0;
2731 uint64_t i_time = 0;
2732 uint64_t i_keypoints_found = 0;
2734 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
2737 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2739 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2740 i_time += i_val * p_stream->p_skel->i_indexstampden;
2741 i_keypoints_found++;
2744 if ( i_keypoints_found != i_keypoints )
2746 msg_Warn( p_demux, "Invalid Index: missing entries" );
2750 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
2751 if ( !p_stream->p_skel->p_index ) return;
2752 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
2753 p_oggpacket->bytes - 42 );
2754 p_stream->p_skel->i_index = i_keypoints_found;
2755 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
2758 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
2760 if ( !p_skel ) return;
2761 for ( int i=0; i< p_skel->i_messages; i++ )
2762 free( p_skel->ppsz_messages[i] );
2763 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
2764 free( p_skel->p_index );
2768 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
2770 if ( !p_stream->p_skel ) return;
2771 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
2773 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
2774 if ( ! strncmp( "Name: ", psz_message, 6 ) )
2776 free( p_stream->fmt.psz_description );
2777 p_stream->fmt.psz_description = strdup( psz_message + 6 );
2779 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
2782 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
2787 /* Return true if there's a skeleton exact match */
2788 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
2789 int64_t *pi_lower, int64_t *pi_upper )
2791 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
2794 /* Validate range */
2795 if ( i_time < p_stream->p_skel->i_indexfirstnum
2796 * p_stream->p_skel->i_indexstampden ||
2797 i_time > p_stream->p_skel->i_indexlastnum
2798 * p_stream->p_skel->i_indexstampden ) return false;
2800 /* Then Lookup its index */
2801 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
2806 } current = { 0, 0 }, prev = { -1, -1 };
2808 uint64_t i_keypoints_found = 0;
2810 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
2811 && i_keypoints_found < p_stream->p_skel->i_index )
2814 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2815 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2816 current.i_pos += i_val;
2817 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2818 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2819 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
2820 if ( current.i_pos < 0 || current.i_time < 0 ) break;
2822 i_keypoints_found++;
2824 if ( i_time <= current.i_time )
2826 *pi_lower = prev.i_pos;
2827 *pi_upper = current.i_pos;
2828 return ( i_time == current.i_time );
2835 static uint32_t dirac_uint( bs_t *p_bs )
2837 uint32_t u_count = 0, u_value = 0;
2839 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
2843 u_value |= bs_read( p_bs, 1 );
2846 return (1<<u_count) - 1 + u_value;
2849 static int dirac_bool( bs_t *p_bs )
2851 return bs_read( p_bs, 1 );
2854 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
2855 ogg_packet *p_oggpacket )
2857 static const struct {
2858 uint32_t u_n /* numerator */, u_d /* denominator */;
2859 } p_dirac_frate_tbl[] = { /* table 10.3 */
2860 {1,1}, /* this first value is never used */
2861 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
2862 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
2864 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
2866 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
2867 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
2869 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
2873 p_stream->i_granule_shift = 22; /* not 32 */
2875 /* Backing up stream headers is not required -- seqhdrs are repeated
2876 * thoughout the stream at suitable decoding start points */
2877 p_stream->b_force_backup = false;
2879 /* read in useful bits from sequence header */
2880 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
2881 bs_skip( &bs, 13*8); /* parse_info_header */
2882 dirac_uint( &bs ); /* major_version */
2883 dirac_uint( &bs ); /* minor_version */
2884 dirac_uint( &bs ); /* profile */
2885 dirac_uint( &bs ); /* level */
2887 uint32_t u_video_format = dirac_uint( &bs ); /* index */
2888 if( u_video_format >= u_dirac_vidfmt_frate )
2890 /* don't know how to parse this ogg dirac stream */
2894 if( dirac_bool( &bs ) )
2896 dirac_uint( &bs ); /* frame_width */
2897 dirac_uint( &bs ); /* frame_height */
2900 if( dirac_bool( &bs ) )
2902 dirac_uint( &bs ); /* chroma_format */
2905 if( dirac_bool( &bs ) )
2907 dirac_uint( &bs ); /* scan_format */
2910 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
2911 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
2912 if( dirac_bool( &bs ) )
2914 uint32_t u_frame_rate_index = dirac_uint( &bs );
2915 if( u_frame_rate_index >= u_dirac_frate_tbl )
2917 /* something is wrong with this stream */
2920 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
2921 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
2922 if( u_frame_rate_index == 0 )
2924 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
2925 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
2928 p_stream->f_rate = (float) u_n / u_d;
2930 /* probably is an ogg dirac es */
2931 p_stream->fmt.i_cat = VIDEO_ES;
2932 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;