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 bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
141 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
144 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
145 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
146 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
147 static void Ogg_ApplySkeleton( logical_stream_t * );
149 static void fill_channels_info(audio_format_t *audio)
151 static const int pi_channels_map[9] =
155 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
156 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
157 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
158 | AOUT_CHAN_REARRIGHT,
159 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
160 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
161 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
162 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
163 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
164 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
165 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
166 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
167 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
171 unsigned chans = audio->i_channels;
172 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
173 audio->i_physical_channels =
174 audio->i_original_channels = pi_channels_map[chans];
177 /* Special TS value: don't send or derive any pts/pcr from it.
178 Represents TS state prior first known valid timestamp */
179 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
181 /*****************************************************************************
182 * Open: initializes ogg demux structures
183 *****************************************************************************/
184 static int Open( vlc_object_t * p_this )
186 demux_t *p_demux = (demux_t *)p_this;
188 const uint8_t *p_peek;
190 /* Check if we are dealing with an ogg stream */
191 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
192 if( !p_demux->b_force && memcmp( p_peek, "OggS", 4 ) )
198 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
202 p_sys->i_length = -1;
203 p_sys->b_preparsing_done = false;
205 /* Set exported functions */
206 p_demux->pf_demux = Demux;
207 p_demux->pf_control = Control;
209 /* Initialize the Ogg physical bitstream parser */
210 ogg_sync_init( &p_sys->oy );
213 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
216 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
222 /*****************************************************************************
223 * Close: frees unused data
224 *****************************************************************************/
225 static void Close( vlc_object_t *p_this )
227 demux_t *p_demux = (demux_t *)p_this;
228 demux_sys_t *p_sys = p_demux->p_sys ;
230 /* Cleanup the bitstream parser */
231 ogg_sync_clear( &p_sys->oy );
233 Ogg_EndOfStream( p_demux );
235 if( p_sys->p_old_stream )
236 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
241 /*****************************************************************************
242 * Demux: reads and demuxes data packets
243 *****************************************************************************
244 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
245 *****************************************************************************/
246 static int Demux( demux_t * p_demux )
248 demux_sys_t *p_sys = p_demux->p_sys;
249 ogg_packet oggpacket;
251 bool b_skipping = false;
254 int i_active_streams = p_sys->i_streams;
255 for ( int i=0; i < p_sys->i_streams; i++ )
257 if ( p_sys->pp_stream[i]->b_finished )
261 if ( i_active_streams == 0 )
263 if ( p_sys->i_streams ) /* All finished */
265 msg_Dbg( p_demux, "end of a group of logical streams" );
266 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
267 * only 1 ES is supported (common case for ogg web radio) */
268 if( p_sys->i_streams == 1 )
270 p_sys->p_old_stream = p_sys->pp_stream[0];
271 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
273 Ogg_EndOfStream( p_demux );
274 p_sys->b_chained_boundary = true;
277 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
280 msg_Dbg( p_demux, "beginning of a group of logical streams" );
282 if ( !p_sys->b_chained_boundary )
284 /* Find the real duration */
285 stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
287 Oggseek_ProbeEnd( p_demux );
291 p_sys->b_chained_boundary = false;
295 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
297 Ogg_CreateES( p_demux );
298 p_sys->b_es_created = true;
302 * The first data page of a physical stream is stored in the relevant logical stream
303 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
304 * stream it belongs to if we haven't processed this first page yet. If we do, we
305 * will only process that first page whenever we find the second page for this stream.
306 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
307 * the second page will arrive real quick, this is not fine for Kate, whose second
308 * data page will typically arrive much later.
309 * This means it is now possible to seek right at the start of a stream where the last
310 * logical stream is Kate, without having to wait for the second data page to unblock
311 * the first one, which is the one that triggers the 'no more headers to backup' code.
312 * And, as we all know, seeking without having backed up all headers is bad, since the
313 * codec will fail to initialize if it's missing its headers.
315 if( !p_sys->b_page_waiting)
318 * Demux an ogg page from the stream
320 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
322 /* Test for End of Stream */
323 if( ogg_page_eos( &p_sys->current_page ) )
325 /* If we delayed restarting encoders/SET_ES_FMT for more
326 * skeleton provided configuration */
327 if ( p_sys->p_skelstream )
329 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
331 msg_Dbg( p_demux, "End of Skeleton" );
332 p_sys->b_preparsing_done = true;
333 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
335 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
336 Ogg_ApplySkeleton( p_stream );
341 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
343 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
345 p_sys->pp_stream[i_stream]->b_finished = true;
353 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
355 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
358 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
360 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
362 /* if we've just pulled page, look for the right logical stream */
363 if( !p_sys->b_page_waiting )
365 if( p_sys->i_streams == 1 &&
366 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
368 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
369 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
371 p_stream->b_reinit = true;
372 p_stream->i_pcr = VLC_TS_UNKNOWN;
373 p_stream->i_interpolated_pcr = VLC_TS_UNKNOWN;
374 p_stream->i_previous_granulepos = -1;
375 es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0);
378 /* Does fail if serialno differs */
379 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
386 /* clear the finished flag if pages after eos (ex: after a seek) */
387 if ( ! ogg_page_eos( &p_sys->current_page ) ) p_stream->b_finished = false;
390 if ( p_stream->fmt.i_cat == VIDEO_ES )
391 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
392 ogg_page_pageno( &p_sys->current_page ),
393 ogg_page_granulepos( &p_sys->current_page ),
394 ogg_page_packets( &p_sys->current_page ),
395 ogg_page_continued(&p_sys->current_page),
396 p_sys->current_page.body_len )
399 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
401 /* Read info from any secondary header packets, if there are any */
402 if( p_stream->i_secondary_header_packets > 0 )
404 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
405 oggpacket.bytes >= 7 &&
406 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
408 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
409 p_stream->i_secondary_header_packets = 0;
411 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
412 oggpacket.bytes >= 7 &&
413 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
415 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
416 p_stream->i_secondary_header_packets = 0;
418 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
420 p_stream->i_secondary_header_packets = 0;
423 /* update start of data pointer */
424 p_stream->i_data_start = stream_Tell( p_demux->s );
427 /* If any streams have i_skip_frames, only decode (pre-roll)
428 * for those streams, but don't skip headers */
429 if ( b_skipping && p_stream->i_skip_frames == 0
430 && p_stream->i_secondary_header_packets ) continue;
432 if( p_stream->b_reinit )
434 if ( Oggseek_PacketPCRFixup( p_stream, &p_sys->current_page,
437 DemuxDebug( msg_Dbg( p_demux, "PCR fixup for %"PRId64,
438 ogg_page_granulepos( &p_sys->current_page ) ) );
442 /* If synchro is re-initialized we need to drop all the packets
443 * until we find a new dated one. */
444 Ogg_UpdatePCR( p_demux, p_stream, &oggpacket );
447 if( p_stream->i_pcr >= 0 )
449 p_stream->b_reinit = false;
450 /* For Opus, trash the first 80 ms of decoded output as
451 well, to avoid blowing out speakers if we get unlucky.
452 Opus predicts content from prior frames, which can go
453 badly if we seek right where the stream goes from very
454 quiet to very loud. It will converge after a bit. */
455 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
457 ogg_int64_t start_time;
459 p_stream->i_skip_frames = 80*48;
460 /* Make sure we never play audio from within the
461 pre-skip at the beginning of the stream. */
463 Ogg_OpusPacketDuration( p_stream, &oggpacket );
464 start_time = p_stream->i_previous_granulepos;
467 start_time = start_time > duration ?
468 start_time - duration : 0;
470 if( p_stream->i_pre_skip > start_time )
472 p_stream->i_skip_frames +=
473 p_stream->i_pre_skip - start_time;
480 msg_Dbg(p_demux, "DEMUX DROPS PACKET (? / %d) pageno %ld granule %"PRId64,
481 ogg_page_packets( &p_sys->current_page ),
482 ogg_page_pageno( &p_sys->current_page ), oggpacket.granulepos );
485 p_stream->i_interpolated_pcr = -1;
486 p_stream->i_previous_granulepos = -1;
490 /* An Ogg/vorbis packet contains an end date granulepos */
491 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
492 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
493 p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
494 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
495 p_stream->fmt.i_codec == VLC_CODEC_FLAC )
497 if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
499 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
503 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
504 VLC_TS_0 + p_stream->i_pcr );
510 DemuxDebug( if ( p_sys->b_seeked )
512 if ( Ogg_IsKeyFrame( p_stream, &oggpacket ) )
513 msg_Dbg(p_demux, "** DEMUX ON KEYFRAME **" );
515 ogg_int64_t iframe = ogg_page_granulepos( &p_sys->current_page ) >> p_stream->i_granule_shift;
516 ogg_int64_t pframe = ogg_page_granulepos( &p_sys->current_page ) - ( iframe << p_stream->i_granule_shift );
518 msg_Dbg(p_demux, "DEMUX PACKET (size %d) IS at iframe %"PRId64" pageno %ld pframe %"PRId64" OFFSET %"PRId64" PACKET NO %"PRId64" skipleft=%d",
519 ogg_page_packets( &p_sys->current_page ),
520 iframe, ogg_page_pageno( &p_sys->current_page ), pframe, p_sys->i_input_position, oggpacket.packetno, p_stream->i_skip_frames );
523 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
526 DemuxDebug( p_sys->b_seeked = false; )
528 if( !p_sys->b_page_waiting )
532 /* if a page was waiting, it's now processed */
533 p_sys->b_page_waiting = false;
535 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
536 p_sys->b_preparsing_done = false;
538 p_sys->b_preparsing_done = true;
540 /* We will consider the lowest PCR among tracks, because the audio core badly
541 * handles PCR rewind (mute)
543 mtime_t i_pcr_candidate = VLC_TS_INVALID;
544 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
546 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
548 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
550 /* We have 1 or more streams needing more than 1 page for preparsing */
551 p_sys->b_preparsing_done = false;
554 if( p_stream->fmt.i_cat == SPU_ES )
556 if( p_stream->i_interpolated_pcr < VLC_TS_0 )
558 if ( p_stream->b_finished || p_stream->b_initializing )
561 if( i_pcr_candidate < VLC_TS_0
562 || p_stream->i_interpolated_pcr <= i_pcr_candidate )
564 i_pcr_candidate = p_stream->i_interpolated_pcr;
568 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
570 p_sys->i_pcr = i_pcr_candidate;
572 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
578 static void Ogg_ResetStreamHelper( demux_sys_t *p_sys )
580 for( int i = 0; i < p_sys->i_streams; i++ )
582 logical_stream_t *p_stream = p_sys->pp_stream[i];
584 /* we'll trash all the data until we find the next pcr */
585 p_stream->b_reinit = true;
586 p_stream->i_pcr = VLC_TS_UNKNOWN;
587 p_stream->i_interpolated_pcr = VLC_TS_UNKNOWN;
588 p_stream->i_previous_granulepos = -1;
589 ogg_stream_reset( &p_stream->os );
591 ogg_sync_reset( &p_sys->oy );
594 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
596 demux_sys_t *p_sys = p_demux->p_sys;
597 logical_stream_t *p_stream = NULL;
598 for( int i=0; i<p_sys->i_streams; i++ )
600 logical_stream_t *p_candidate = p_sys->pp_stream[i];
601 if ( !p_candidate->p_es ) continue;
603 bool b_selected = false;
604 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
605 p_candidate->p_es, &b_selected );
606 if ( !b_selected ) continue;
608 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
610 p_stream = p_candidate;
611 continue; /* Try to find video anyway */
614 if ( p_candidate->fmt.i_cat == VIDEO_ES )
616 p_stream = p_candidate;
623 /*****************************************************************************
625 *****************************************************************************/
626 static int Control( demux_t *p_demux, int i_query, va_list args )
628 demux_sys_t *p_sys = p_demux->p_sys;
637 p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
639 vlc_meta_Merge( p_meta, p_sys->p_meta );
642 case DEMUX_HAS_UNSUPPORTED_META:
643 pb_bool = (bool*)va_arg( args, bool* );
648 pi64 = (int64_t*)va_arg( args, int64_t * );
649 *pi64 = p_sys->i_pcr;
653 i64 = (int64_t)va_arg( args, int64_t );
654 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
657 msg_Err( p_demux, "No selected seekable stream found" );
660 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
661 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
663 Ogg_ResetStreamHelper( p_sys );
664 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
671 case DEMUX_GET_ATTACHMENTS:
673 input_attachment_t ***ppp_attach =
674 (input_attachment_t***)va_arg( args, input_attachment_t*** );
675 int *pi_int = (int*)va_arg( args, int * );
677 if( p_sys->i_attachments <= 0 )
680 *pi_int = p_sys->i_attachments;
681 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
682 for( int i = 0; i < p_sys->i_attachments; i++ )
683 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
687 case DEMUX_GET_POSITION:
688 pf = (double*)va_arg( args, double * );
689 if( p_sys->i_length > 0 )
691 *pf = (double) p_sys->i_pcr /
692 (double) ( p_sys->i_length * (mtime_t)1000000 );
694 else if( stream_Size( p_demux->s ) > 0 )
696 i64 = stream_Tell( p_demux->s );
697 *pf = (double) i64 / stream_Size( p_demux->s );
702 case DEMUX_SET_POSITION:
703 /* forbid seeking if we haven't initialized all logical bitstreams yet;
704 if we allowed, some headers would not get backed up and decoder init
705 would fail, making that logical stream unusable */
706 for ( int i=0; i< p_sys->i_streams; i++ )
708 if ( p_sys->pp_stream[i]->b_initializing )
712 p_stream = Ogg_GetSelectedStream( p_demux );
715 msg_Err( p_demux, "No selected seekable stream found" );
719 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
721 f = (double)va_arg( args, double );
722 if ( p_sys->i_length <= 0 || !b /* || ! ACCESS_CAN_FASTSEEK */ )
724 Ogg_ResetStreamHelper( p_sys );
725 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
729 assert( p_sys->i_length > 0 );
730 i64 = CLOCK_FREQ * p_sys->i_length * f;
731 Ogg_ResetStreamHelper( p_sys );
732 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
734 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
741 case DEMUX_GET_LENGTH:
742 if ( p_sys->i_length < 0 )
743 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
745 pi64 = (int64_t*)va_arg( args, int64_t * );
746 *pi64 = p_sys->i_length * 1000000;
749 case DEMUX_GET_TITLE_INFO:
751 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
752 int *pi_int = (int*)va_arg( args, int* );
753 int *pi_title_offset = (int*)va_arg( args, int* );
754 int *pi_seekpoint_offset = (int*)va_arg( args, int* );
756 if( p_sys->i_seekpoints > 0 )
759 *ppp_title = malloc( sizeof( input_title_t* ) );
760 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
761 for( int i = 0; i < p_sys->i_seekpoints; i++ )
763 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
764 if ( likely( p_seekpoint_copy ) )
765 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
767 *pi_title_offset = 0;
768 *pi_seekpoint_offset = 0;
772 case DEMUX_SET_TITLE:
774 const int i_title = (int)va_arg( args, int );
779 case DEMUX_SET_SEEKPOINT:
781 const int i_seekpoint = (int)va_arg( args, int );
782 if( i_seekpoint > p_sys->i_seekpoints )
785 for ( int i=0; i< p_sys->i_streams; i++ )
787 if ( p_sys->pp_stream[i]->b_initializing )
791 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
793 p_stream = Ogg_GetSelectedStream( p_demux );
796 msg_Err( p_demux, "No selected seekable stream found" );
800 stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
801 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
803 Ogg_ResetStreamHelper( p_sys );
804 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
806 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
807 p_demux->info.i_seekpoint = i_seekpoint;
815 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
820 /****************************************************************************
821 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
822 ****************************************************************************
823 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
824 * are at the end of stream.
825 ****************************************************************************/
826 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
828 demux_sys_t *p_ogg = p_demux->p_sys ;
832 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
834 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
836 i_read = stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
840 ogg_sync_wrote( &p_ogg->oy, i_read );
846 /****************************************************************************
847 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
849 ****************************************************************************/
850 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
851 ogg_packet *p_oggpacket )
853 demux_sys_t *p_ogg = p_demux->p_sys;
854 p_stream->i_end_trim = 0;
856 /* Convert the granulepos into a pcr */
857 if ( p_oggpacket->granulepos == 0 )
859 /* We're in headers, and we haven't parsed 1st data packet yet */
860 p_stream->i_pcr = VLC_TS_UNKNOWN;
861 p_stream->i_interpolated_pcr = VLC_TS_UNKNOWN;
863 else if( p_oggpacket->granulepos > 0 )
865 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
866 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
867 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
868 p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
870 p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream,
871 p_oggpacket->granulepos, true );
876 sample = p_oggpacket->granulepos;
877 if( p_oggpacket->e_o_s &&
878 p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
879 p_stream->i_previous_granulepos >= 0 )
882 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
885 ogg_int64_t end_sample;
886 end_sample = p_stream->i_previous_granulepos + duration;
887 if( end_sample > sample )
888 p_stream->i_end_trim = (int)(end_sample - sample);
891 if (sample >= p_stream->i_pre_skip)
892 sample -= p_stream->i_pre_skip;
895 p_stream->i_pcr = sample * CLOCK_FREQ / p_stream->f_rate;
898 if ( !p_ogg->i_pcr_offset )
899 p_stream->i_pcr += VLC_TS_0;
901 p_stream->i_pcr += p_ogg->i_pcr_offset;
902 p_stream->i_interpolated_pcr = p_stream->i_pcr;
907 p_stream->i_pcr = VLC_TS_INVALID;
909 /* no granulepos available, try to interpolate the pcr.
910 * If we can't then don't touch the old value. */
911 if( p_stream->fmt.i_cat == VIDEO_ES )
912 /* 1 frame per packet */
913 p_stream->i_interpolated_pcr += (CLOCK_FREQ / p_stream->f_rate);
914 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
915 p_stream->i_previous_granulepos >= 0 &&
917 Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 )
920 p_oggpacket->granulepos =
921 p_stream->i_previous_granulepos + duration;
922 sample = p_oggpacket->granulepos;
923 if (sample >= p_stream->i_pre_skip)
924 sample -= p_stream->i_pre_skip;
927 p_stream->i_interpolated_pcr =
928 VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
929 p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
931 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
933 p_stream->i_interpolated_pcr +=
934 ( p_oggpacket->bytes * CLOCK_FREQ /
935 p_stream->fmt.i_bitrate / 8 );
936 p_stream->i_interpolated_pcr += p_ogg->i_pcr_offset;
939 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
942 /****************************************************************************
943 * Ogg_DecodePacket: Decode an Ogg packet.
944 ****************************************************************************/
945 static void Ogg_DecodePacket( demux_t *p_demux,
946 logical_stream_t *p_stream,
947 ogg_packet *p_oggpacket )
951 int i_header_len = 0;
952 mtime_t i_pts = VLC_TS_UNKNOWN, i_interpolated_pts;
953 demux_sys_t *p_ogg = p_demux->p_sys;
955 if( p_oggpacket->bytes >= 7 &&
956 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
958 /* it's an Annodex packet -- skip it (do nothing) */
961 else if( p_oggpacket->bytes >= 7 &&
962 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
964 /* it's an AnxData packet -- skip it (do nothing) */
967 else if( p_oggpacket->bytes >= 8 &&
968 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
970 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
973 else if( p_oggpacket->bytes >= 6 &&
974 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
976 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
979 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
980 p_oggpacket->bytes >= 7 &&
981 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
983 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
987 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
988 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
990 /* Check the ES is selected */
991 if ( !p_stream->p_es )
994 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
995 p_stream->p_es, &b_selected );
997 if( p_stream->b_force_backup )
1000 p_stream->i_packets_backup++;
1001 switch( p_stream->fmt.i_codec )
1003 case VLC_CODEC_VORBIS:
1004 case VLC_CODEC_THEORA:
1005 if( p_stream->i_packets_backup == 3 )
1006 p_stream->b_force_backup = false;
1010 case VLC_CODEC_SPEEX:
1011 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1012 p_stream->b_force_backup = false;
1016 case VLC_CODEC_OPUS:
1017 if( p_stream->i_packets_backup == 2 )
1018 p_stream->b_force_backup = false;
1022 case VLC_CODEC_FLAC:
1023 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
1025 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
1026 p_stream->b_force_backup = false;
1028 else if( p_stream->fmt.audio.i_rate )
1030 p_stream->b_force_backup = false;
1031 if( p_oggpacket->bytes >= 9 )
1033 p_oggpacket->packet += 9;
1034 p_oggpacket->bytes -= 9;
1040 case VLC_CODEC_KATE:
1041 if( p_stream->i_packets_backup == p_stream->i_kate_num_headers )
1042 p_stream->b_force_backup = false;
1047 p_stream->b_force_backup = false;
1052 /* Backup the ogg packet (likely an header packet) */
1055 void *p_org = p_stream->p_headers;
1056 p_stream->i_headers += p_oggpacket->bytes;
1057 p_stream->p_headers = realloc( p_stream->p_headers, p_stream->i_headers );
1058 if( p_stream->p_headers )
1060 memcpy( (unsigned char *)p_stream->p_headers + p_stream->i_headers - p_oggpacket->bytes,
1061 p_oggpacket->packet, p_oggpacket->bytes );
1065 #warning Memory leak
1066 p_stream->i_headers = 0;
1067 p_stream->p_headers = NULL;
1071 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1072 p_oggpacket->bytes, p_oggpacket->packet ) )
1074 p_stream->i_headers = 0;
1075 p_stream->p_headers = NULL;
1077 if( p_stream->i_headers > 0 )
1079 if( !p_stream->b_force_backup )
1081 /* Last header received, commit changes */
1082 free( p_stream->fmt.p_extra );
1084 p_stream->fmt.i_extra = p_stream->i_headers;
1085 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1086 if( p_stream->fmt.p_extra )
1087 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1088 p_stream->i_headers );
1090 p_stream->fmt.i_extra = 0;
1092 if( p_stream->i_headers > 0 )
1093 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1094 p_stream->p_headers, p_stream->i_headers );
1096 /* we're not at BOS anymore for this logical stream */
1097 p_stream->b_initializing = false;
1101 b_selected = false; /* Discard the header packet */
1104 p_stream->b_initializing = false;
1106 /* Convert the pcr into a pts */
1107 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
1108 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1109 p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
1110 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1111 p_stream->fmt.i_codec == VLC_CODEC_FLAC )
1113 if( p_stream->i_pcr > VLC_TS_INVALID )
1115 p_stream->i_previous_pcr = p_stream->i_pcr;
1116 /* The granulepos is the end date of the sample */
1117 i_pts = p_stream->i_pcr;
1121 /* Convert the granulepos into the next pcr */
1122 i_interpolated_pts = p_stream->i_interpolated_pcr;
1123 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1125 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1126 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1127 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1128 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1129 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1130 p_stream->i_pcr >= 0 )
1132 p_stream->i_previous_pcr = p_stream->i_pcr;
1134 /* The granulepos is the start date of the sample */
1135 i_pts = p_stream->i_pcr;
1140 /* This stream isn't currently selected so we don't need to decode it,
1141 * but we did need to store its pcr as it might be selected later on */
1145 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1148 /* may need to preroll after a seek */
1149 if ( p_stream->i_skip_frames > 0 )
1151 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1154 duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1155 if( p_stream->i_skip_frames > duration )
1157 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1158 p_block->i_nb_samples = 0;
1159 p_stream->i_skip_frames -= duration;
1163 p_block->i_nb_samples = duration - p_stream->i_skip_frames;
1164 if( p_stream->i_previous_granulepos >=
1165 p_block->i_nb_samples + p_stream->i_pre_skip )
1167 i_pts = VLC_TS_0 + (p_stream->i_previous_granulepos
1168 - p_block->i_nb_samples - p_stream->i_pre_skip) *
1169 CLOCK_FREQ / p_stream->f_rate;
1171 p_stream->i_skip_frames = 0;
1176 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1177 p_stream->i_skip_frames--;
1180 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1181 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket );
1184 if( i_pts == VLC_TS_UNKNOWN )
1185 i_pts = VLC_TS_INVALID;
1187 if( p_stream->fmt.i_cat == AUDIO_ES )
1189 p_block->i_dts = p_block->i_pts = i_pts;
1190 /* Blatant abuse of the i_length field. */
1191 p_block->i_length = p_stream->i_end_trim;
1193 else if( p_stream->fmt.i_cat == SPU_ES )
1195 p_block->i_dts = p_block->i_pts = i_pts;
1196 p_block->i_length = 0;
1198 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1200 p_block->i_dts = p_block->i_pts = i_pts;
1201 if( (p_oggpacket->granulepos & ((1<<p_stream->i_granule_shift)-1)) == 0 )
1203 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1206 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1208 ogg_int64_t dts = p_oggpacket->granulepos >> 31;
1209 ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
1211 uint64_t u_pnum = dts + delay;
1213 p_block->i_dts = p_stream->i_pcr;
1214 p_block->i_pts = VLC_TS_INVALID;
1215 /* NB, OggDirac granulepos values are in units of 2*picturerate */
1217 /* granulepos for dirac is possibly broken, this value should be ignored */
1218 if( -1 != p_oggpacket->granulepos )
1219 p_block->i_pts = u_pnum * CLOCK_FREQ / p_stream->f_rate / 2;
1221 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 )
1223 p_block->i_pts = p_stream->i_interpolated_pcr;
1224 p_block->i_dts = p_block->i_pts;
1225 if( p_oggpacket->granulepos > 0 && Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1227 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1232 p_block->i_dts = i_pts;
1233 p_block->i_pts = VLC_TS_INVALID;
1236 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1237 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1238 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1239 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1240 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1241 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1242 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1243 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1244 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1245 p_stream->fmt.i_codec != VLC_CODEC_KATE )
1247 if( p_oggpacket->bytes <= 0 )
1249 msg_Dbg( p_demux, "discarding 0 sized packet" );
1250 block_Release( p_block );
1253 /* We remove the header from the packet */
1254 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1255 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1257 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1259 /* But with subtitles we need to retrieve the duration first */
1260 int i, lenbytes = 0;
1262 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1264 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1266 lenbytes = lenbytes << 8;
1267 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1270 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1271 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1272 p_oggpacket->packet[i_header_len + 1] != 0 &&
1273 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1274 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1276 p_block->i_length = (mtime_t)lenbytes * 1000;
1281 if( p_block->i_buffer >= (unsigned int)i_header_len )
1282 p_block->i_buffer -= i_header_len;
1284 p_block->i_buffer = 0;
1288 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1290 /* FIXME: the biggest hack I've ever done */
1291 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1292 p_block->i_pts, p_block->i_dts );
1296 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1297 p_oggpacket->bytes - i_header_len );
1299 if ( p_ogg->i_streams == 1 && p_block->i_pts > VLC_TS_INVALID && p_ogg->i_pcr < VLC_TS_0 )
1301 p_ogg->i_pcr = p_block->i_pts;
1302 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1305 if ( p_stream->p_es )
1307 /* Because ES creation is delayed for preparsing */
1308 if ( p_stream->p_preparse_block )
1310 es_out_Send( p_demux->out, p_stream->p_es, p_stream->p_preparse_block );
1311 p_stream->p_preparse_block = NULL;
1313 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1316 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1319 /* Re-implemented to avoid linking against libopus from the demuxer. */
1320 static int Ogg_OpusPacketDuration( logical_stream_t *p_stream,
1321 ogg_packet *p_oggpacket )
1323 static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 };
1329 if( p_oggpacket->bytes < 1 )
1330 return VLC_EGENERIC;
1331 toc = p_oggpacket->packet[0];
1342 if( p_oggpacket->bytes < 2 )
1343 return VLC_EGENERIC;
1344 nframes = p_oggpacket->packet[1]&0x3F;
1347 i_rate = (int)p_stream->fmt.audio.i_rate;
1349 frame_size = (i_rate << (toc >> 3 & 3)) / 400;
1350 else if( ( toc&0x60 ) == 0x60 )
1351 frame_size = i_rate/(100 >> (toc >> 3 & 1));
1353 frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3];
1354 nsamples = nframes*frame_size;
1355 if( nsamples*25 > i_rate*3 )
1356 return VLC_EGENERIC;
1360 /****************************************************************************
1361 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1362 * stream and fill p_ogg.
1363 *****************************************************************************
1364 * The initial page of a logical stream is marked as a 'bos' page.
1365 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1366 * together and all of the initial pages must appear before any data pages.
1368 * On success this function returns VLC_SUCCESS.
1369 ****************************************************************************/
1370 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1372 demux_sys_t *p_ogg = p_demux->p_sys ;
1373 ogg_packet oggpacket;
1376 p_ogg->i_total_length = stream_Size ( p_demux->s );
1377 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1380 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1383 if( ogg_page_bos( &p_ogg->current_page ) )
1386 /* All is wonderful in our fine fine little world.
1387 * We found the beginning of our first logical stream. */
1388 while( ogg_page_bos( &p_ogg->current_page ) )
1390 logical_stream_t *p_stream;
1392 p_stream = malloc( sizeof(logical_stream_t) );
1393 if( unlikely( !p_stream ) )
1396 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1398 memset( p_stream, 0, sizeof(logical_stream_t) );
1400 es_format_Init( &p_stream->fmt, 0, 0 );
1401 es_format_Init( &p_stream->fmt_old, 0, 0 );
1402 p_stream->b_initializing = true;
1404 /* Setup the logical stream */
1405 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1406 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1408 /* Extract the initial header from the first page and verify
1409 * the codec type of this Ogg bitstream */
1410 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1412 /* error. stream version mismatch perhaps */
1413 msg_Err( p_demux, "error reading first page of "
1414 "Ogg bitstream data" );
1415 return VLC_EGENERIC;
1418 /* FIXME: check return value */
1419 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1421 /* Check for Vorbis header */
1422 if( oggpacket.bytes >= 7 &&
1423 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1425 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
1426 msg_Dbg( p_demux, "found vorbis header" );
1428 /* Check for Speex header */
1429 else if( oggpacket.bytes >= 5 &&
1430 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1432 Ogg_ReadSpeexHeader( p_stream, &oggpacket );
1433 msg_Dbg( p_demux, "found speex header, channels: %i, "
1434 "rate: %i, bitrate: %i",
1435 p_stream->fmt.audio.i_channels,
1436 (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
1438 /* Check for Opus header */
1439 else if( oggpacket.bytes >= 8 &&
1440 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1442 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1443 msg_Dbg( p_demux, "found opus header, channels: %i, "
1445 p_stream->fmt.audio.i_channels,
1446 (int)p_stream->i_pre_skip);
1447 p_stream->i_skip_frames = p_stream->i_pre_skip;
1449 /* Check for Flac header (< version 1.1.1) */
1450 else if( oggpacket.bytes >= 4 &&
1451 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1453 msg_Dbg( p_demux, "found FLAC header" );
1455 /* Grrrr!!!! Did they really have to put all the
1456 * important info in the second header packet!!!
1457 * (STREAMINFO metadata is in the following packet) */
1458 p_stream->b_force_backup = true;
1460 p_stream->fmt.i_cat = AUDIO_ES;
1461 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1463 /* Check for Flac header (>= version 1.1.1) */
1464 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1465 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1466 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1468 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1469 oggpacket.packet[8];
1470 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1471 "(%i header packets)",
1472 oggpacket.packet[5], oggpacket.packet[6],
1475 p_stream->b_force_backup = true;
1477 p_stream->fmt.i_cat = AUDIO_ES;
1478 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1479 oggpacket.packet += 13; oggpacket.bytes -= 13;
1480 Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
1482 /* Check for Theora header */
1483 else if( oggpacket.bytes >= 7 &&
1484 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1486 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
1489 "found theora header, bitrate: %i, rate: %f",
1490 p_stream->fmt.i_bitrate, p_stream->f_rate );
1492 /* Check for Dirac header */
1493 else if( ( oggpacket.bytes >= 5 &&
1494 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1495 ( oggpacket.bytes >= 9 &&
1496 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1498 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1499 msg_Dbg( p_demux, "found dirac header" );
1502 msg_Warn( p_demux, "found dirac header isn't decodable" );
1507 /* Check for Tarkin header */
1508 else if( oggpacket.bytes >= 7 &&
1509 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1513 msg_Dbg( p_demux, "found tarkin header" );
1514 p_stream->fmt.i_cat = VIDEO_ES;
1515 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1517 /* Cheat and get additionnal info ;) */
1518 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1519 oggpack_adv( &opb, 88 );
1520 oggpack_adv( &opb, 104 );
1521 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1522 p_stream->f_rate = 2; /* FIXME */
1524 "found tarkin header, bitrate: %i, rate: %f",
1525 p_stream->fmt.i_bitrate, p_stream->f_rate );
1527 /* Check for VP8 header */
1528 else if( oggpacket.bytes >= 26 &&
1529 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1531 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1532 msg_Dbg( p_demux, "found VP8 header "
1533 "fps: %f, width:%i; height:%i",
1535 p_stream->fmt.video.i_width,
1536 p_stream->fmt.video.i_height );
1538 p_stream->fmt.i_cat = UNKNOWN_ES;
1540 /* Check for Annodex header */
1541 else if( oggpacket.bytes >= 7 &&
1542 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1544 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1545 /* kill annodex track */
1549 /* Check for Annodex header */
1550 else if( oggpacket.bytes >= 7 &&
1551 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1553 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1555 /* Check for Kate header */
1556 else if( oggpacket.bytes >= 8 &&
1557 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1559 Ogg_ReadKateHeader( p_stream, &oggpacket );
1560 msg_Dbg( p_demux, "found kate header" );
1562 /* Check for OggDS */
1563 else if( oggpacket.bytes >= 142 &&
1564 !memcmp( &oggpacket.packet[1],
1565 "Direct Show Samples embedded in Ogg", 35 ))
1567 /* Old header type */
1568 p_stream->b_oggds = true;
1569 /* Check for video header (old format) */
1570 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1571 oggpacket.bytes >= 184 )
1573 p_stream->fmt.i_cat = VIDEO_ES;
1574 p_stream->fmt.i_codec =
1575 VLC_FOURCC( oggpacket.packet[68],
1576 oggpacket.packet[69],
1577 oggpacket.packet[70],
1578 oggpacket.packet[71] );
1579 msg_Dbg( p_demux, "found video header of type: %.4s",
1580 (char *)&p_stream->fmt.i_codec );
1582 p_stream->fmt.video.i_frame_rate = 10000000;
1583 p_stream->fmt.video.i_frame_rate_base =
1584 GetQWLE((oggpacket.packet+164));
1585 p_stream->f_rate = 10000000.0 /
1586 GetQWLE((oggpacket.packet+164));
1587 p_stream->fmt.video.i_bits_per_pixel =
1588 GetWLE((oggpacket.packet+182));
1589 if( !p_stream->fmt.video.i_bits_per_pixel )
1591 p_stream->fmt.video.i_bits_per_pixel = 24;
1592 p_stream->fmt.video.i_width =
1593 GetDWLE((oggpacket.packet+176));
1594 p_stream->fmt.video.i_height =
1595 GetDWLE((oggpacket.packet+180));
1598 "fps: %f, width:%i; height:%i, bitcount:%i",
1600 p_stream->fmt.video.i_width,
1601 p_stream->fmt.video.i_height,
1602 p_stream->fmt.video.i_bits_per_pixel);
1605 /* Check for audio header (old format) */
1606 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1609 unsigned int i_format_tag;
1611 p_stream->fmt.i_cat = AUDIO_ES;
1613 i_extra_size = GetWLE((oggpacket.packet+140));
1614 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1616 p_stream->fmt.i_extra = i_extra_size;
1617 p_stream->fmt.p_extra = malloc( i_extra_size );
1618 if( p_stream->fmt.p_extra )
1619 memcpy( p_stream->fmt.p_extra,
1620 oggpacket.packet + 142, i_extra_size );
1622 p_stream->fmt.i_extra = 0;
1625 i_format_tag = GetWLE((oggpacket.packet+124));
1626 p_stream->fmt.audio.i_channels =
1627 GetWLE((oggpacket.packet+126));
1628 fill_channels_info(&p_stream->fmt.audio);
1629 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1630 GetDWLE((oggpacket.packet+128));
1631 p_stream->fmt.i_bitrate =
1632 GetDWLE((oggpacket.packet+132)) * 8;
1633 p_stream->fmt.audio.i_blockalign =
1634 GetWLE((oggpacket.packet+136));
1635 p_stream->fmt.audio.i_bitspersample =
1636 GetWLE((oggpacket.packet+138));
1638 wf_tag_to_fourcc( i_format_tag,
1639 &p_stream->fmt.i_codec, 0 );
1641 if( p_stream->fmt.i_codec ==
1642 VLC_FOURCC('u','n','d','f') )
1644 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1645 ( i_format_tag >> 8 ) & 0xff,
1646 i_format_tag & 0xff );
1649 msg_Dbg( p_demux, "found audio header of type: %.4s",
1650 (char *)&p_stream->fmt.i_codec );
1651 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1652 "%dbits/sample %dkb/s",
1654 p_stream->fmt.audio.i_channels,
1655 p_stream->fmt.audio.i_rate,
1656 p_stream->fmt.audio.i_bitspersample,
1657 p_stream->fmt.i_bitrate / 1024 );
1662 msg_Dbg( p_demux, "stream %d has an old header "
1663 "but is of an unknown type", p_ogg->i_streams-1 );
1668 /* Check for OggDS */
1669 else if( oggpacket.bytes >= 44+1 &&
1670 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1672 stream_header_t tmp;
1673 stream_header_t *st = &tmp;
1675 p_stream->b_oggds = true;
1677 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1678 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1679 st->size = GetDWLE( &oggpacket.packet[1+12] );
1680 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1681 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1682 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1683 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1684 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1686 /* Check for video header (new format) */
1687 if( !strncmp( st->streamtype, "video", 5 ) &&
1688 oggpacket.bytes >= 52+1 )
1690 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1691 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1693 p_stream->fmt.i_cat = VIDEO_ES;
1695 /* We need to get rid of the header packet */
1696 ogg_stream_packetout( &p_stream->os, &oggpacket );
1698 p_stream->fmt.i_codec =
1699 VLC_FOURCC( st->subtype[0], st->subtype[1],
1700 st->subtype[2], st->subtype[3] );
1701 msg_Dbg( p_demux, "found video header of type: %.4s",
1702 (char *)&p_stream->fmt.i_codec );
1704 p_stream->fmt.video.i_frame_rate = 10000000;
1705 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1706 if( st->time_unit <= 0 )
1707 st->time_unit = 400000;
1708 p_stream->f_rate = 10000000.0 / st->time_unit;
1709 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1710 p_stream->fmt.video.i_width = st->sh.video.width;
1711 p_stream->fmt.video.i_height = st->sh.video.height;
1714 "fps: %f, width:%i; height:%i, bitcount:%i",
1716 p_stream->fmt.video.i_width,
1717 p_stream->fmt.video.i_height,
1718 p_stream->fmt.video.i_bits_per_pixel );
1720 /* Check for audio header (new format) */
1721 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1722 oggpacket.bytes >= 56+1 )
1728 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1729 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1730 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1732 p_stream->fmt.i_cat = AUDIO_ES;
1734 /* We need to get rid of the header packet */
1735 ogg_stream_packetout( &p_stream->os, &oggpacket );
1737 i_extra_size = st->size - 56;
1739 if( i_extra_size > 0 &&
1740 i_extra_size < oggpacket.bytes - 1 - 56 )
1742 p_stream->fmt.i_extra = i_extra_size;
1743 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1744 if( p_stream->fmt.p_extra )
1745 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1746 p_stream->fmt.i_extra );
1748 p_stream->fmt.i_extra = 0;
1751 memcpy( p_buffer, st->subtype, 4 );
1753 i_format_tag = strtol(p_buffer,NULL,16);
1754 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1755 fill_channels_info(&p_stream->fmt.audio);
1756 if( st->time_unit <= 0 )
1757 st->time_unit = 10000000;
1758 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1759 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1760 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1761 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1763 wf_tag_to_fourcc( i_format_tag,
1764 &p_stream->fmt.i_codec, 0 );
1766 if( p_stream->fmt.i_codec ==
1767 VLC_FOURCC('u','n','d','f') )
1769 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1770 ( i_format_tag >> 8 ) & 0xff,
1771 i_format_tag & 0xff );
1774 msg_Dbg( p_demux, "found audio header of type: %.4s",
1775 (char *)&p_stream->fmt.i_codec );
1776 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1777 "%dbits/sample %dkb/s",
1779 p_stream->fmt.audio.i_channels,
1780 p_stream->fmt.audio.i_rate,
1781 p_stream->fmt.audio.i_bitspersample,
1782 p_stream->fmt.i_bitrate / 1024 );
1784 /* Check for text (subtitles) header */
1785 else if( !strncmp(st->streamtype, "text", 4) )
1787 /* We need to get rid of the header packet */
1788 ogg_stream_packetout( &p_stream->os, &oggpacket );
1790 msg_Dbg( p_demux, "found text subtitle header" );
1791 p_stream->fmt.i_cat = SPU_ES;
1792 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
1793 p_stream->f_rate = 1000; /* granulepos is in millisec */
1797 msg_Dbg( p_demux, "stream %d has a header marker "
1798 "but is of an unknown type", p_ogg->i_streams-1 );
1803 else if( oggpacket.bytes >= 8 &&
1804 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
1808 msg_Dbg( p_demux, "stream %d is a skeleton",
1809 p_ogg->i_streams-1 );
1810 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
1814 msg_Dbg( p_demux, "stream %d is of unknown type",
1815 p_ogg->i_streams-1 );
1820 /* we'll need to get all headers */
1821 p_ogg->pp_stream[i_stream]->b_initializing &= p_ogg->pp_stream[i_stream]->b_force_backup;
1823 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
1824 return VLC_EGENERIC;
1827 /* This is the first data page, which means we are now finished
1828 * with the initial pages. We just need to store it in the relevant
1830 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
1832 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
1833 &p_ogg->current_page ) == 0 )
1835 p_ogg->b_page_waiting = true;
1844 return VLC_EGENERIC;
1847 /****************************************************************************
1848 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1849 ****************************************************************************/
1850 static void Ogg_CreateES( demux_t *p_demux )
1852 demux_sys_t *p_ogg = p_demux->p_sys;
1853 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
1856 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1858 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1860 if ( p_stream->p_es == NULL && !p_stream->b_finished )
1862 /* Better be safe than sorry when possible with ogm */
1863 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
1864 p_stream->fmt.i_codec == VLC_CODEC_A52 )
1865 p_stream->fmt.b_packetized = false;
1867 /* Try first to reuse an old ES */
1869 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
1870 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
1872 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
1874 p_stream->p_es = p_old_stream->p_es;
1875 p_stream->b_finished = false;
1876 p_stream->b_reinit = false;
1877 p_stream->b_initializing = false;
1878 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
1879 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
1881 p_old_stream->p_es = NULL;
1882 p_old_stream = NULL;
1883 if ( b_resetdecoder )
1885 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
1886 p_stream->p_es, &p_stream->fmt );
1891 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1894 // TODO: something to do here ?
1895 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
1897 /* Set the CMML stream active */
1898 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
1903 if( p_ogg->p_old_stream )
1905 if( p_ogg->p_old_stream->p_es )
1906 msg_Dbg( p_demux, "old stream not reused" );
1907 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
1908 p_ogg->p_old_stream = NULL;
1912 /****************************************************************************
1913 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1914 * Elementary streams.
1915 ****************************************************************************/
1916 static int Ogg_BeginningOfStream( demux_t *p_demux )
1918 demux_sys_t *p_ogg = p_demux->p_sys ;
1921 /* Find the logical streams embedded in the physical stream and
1922 * initialize our p_ogg structure. */
1923 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
1925 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
1926 return VLC_EGENERIC;
1929 p_ogg->i_bitrate = 0;
1931 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1933 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
1935 p_stream->p_es = NULL;
1937 /* initialise kframe index */
1940 if ( p_stream->fmt.i_bitrate == 0 &&
1941 ( p_stream->fmt.i_cat == VIDEO_ES ||
1942 p_stream->fmt.i_cat == AUDIO_ES ) )
1943 p_ogg->b_partial_bitrate = true;
1945 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
1947 p_stream->i_pcr = p_stream->i_previous_pcr =
1948 p_stream->i_interpolated_pcr = VLC_TS_UNKNOWN;
1949 p_stream->b_reinit = false;
1952 /* get total frame count for video stream; we will need this for seeking */
1953 p_ogg->i_total_frames = 0;
1958 /****************************************************************************
1959 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1960 ****************************************************************************/
1961 static void Ogg_EndOfStream( demux_t *p_demux )
1963 demux_sys_t *p_ogg = p_demux->p_sys ;
1966 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
1967 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
1968 free( p_ogg->pp_stream );
1971 p_ogg->i_bitrate = 0;
1972 p_ogg->i_streams = 0;
1973 p_ogg->pp_stream = NULL;
1974 p_ogg->skeleton.major = 0;
1975 p_ogg->skeleton.minor = 0;
1976 p_ogg->b_preparsing_done = false;
1977 p_ogg->b_es_created = false;
1978 p_ogg->i_pcr_offset = p_ogg->i_pcr;
1982 vlc_meta_Delete( p_ogg->p_meta );
1983 p_ogg->p_meta = NULL;
1985 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
1987 if ( p_ogg->pp_seekpoints[i] )
1988 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
1990 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
1991 p_ogg->i_seekpoints = 0;
1995 * This function delete and release all data associated to a logical_stream_t
1997 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
1999 if( p_stream->p_es )
2000 es_out_Del( p_demux->out, p_stream->p_es );
2002 ogg_stream_clear( &p_stream->os );
2003 free( p_stream->p_headers );
2005 es_format_Clean( &p_stream->fmt_old );
2006 es_format_Clean( &p_stream->fmt );
2008 if ( p_stream->idx != NULL)
2010 oggseek_index_entries_free( p_stream->idx );
2013 Ogg_FreeSkeleton( p_stream->p_skel );
2014 p_stream->p_skel = NULL;
2015 if ( p_demux->p_sys->p_skelstream == p_stream )
2016 p_demux->p_sys->p_skelstream = NULL;
2018 /* Shouldn't happen */
2019 if ( unlikely( p_stream->p_preparse_block ) )
2021 block_ChainRelease( p_stream->p_preparse_block );
2022 p_stream->p_preparse_block = NULL;
2028 * This function check if a we need to reset a decoder in case we are
2031 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2033 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2034 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2035 unsigned i_new_count;
2036 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2039 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2040 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2041 unsigned i_old_count;
2042 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2045 bool b_match = i_new_count == i_old_count;
2046 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2048 /* Ignore vorbis comment */
2051 if( pi_new_size[i] != pi_old_size[i] ||
2052 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2059 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2060 const es_format_t *p_old )
2062 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2063 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2064 unsigned i_new_count;
2065 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2067 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2068 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2069 unsigned i_old_count;
2070 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2072 bool b_match = false;
2073 if( i_new_count == i_old_count && i_new_count > 0 )
2075 static const unsigned char default_map[2] = { 0, 1 };
2076 unsigned char *p_old_head;
2077 unsigned char *p_new_head;
2078 const unsigned char *p_old_map;
2079 const unsigned char *p_new_map;
2080 int i_old_channel_count;
2081 int i_new_channel_count;
2082 int i_old_stream_count;
2083 int i_new_stream_count;
2084 int i_old_coupled_count;
2085 int i_new_coupled_count;
2086 p_old_head = (unsigned char *)pp_old_data[0];
2087 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2088 p_old_map = default_map;
2089 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2091 i_old_channel_count = p_old_head[9];
2092 switch( p_old_head[18] )
2095 i_old_stream_count = 1;
2096 i_old_coupled_count = i_old_channel_count - 1;
2099 if( pi_old_size[0] >= 21U + i_old_channel_count )
2101 i_old_stream_count = p_old_head[19];
2102 i_old_coupled_count = p_old_head[20];
2103 p_old_map = p_old_head + 21;
2108 p_new_head = (unsigned char *)pp_new_data[0];
2109 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2110 p_new_map = default_map;
2111 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2113 i_new_channel_count = p_new_head[9];
2114 switch( p_new_head[18] )
2117 i_new_stream_count = 1;
2118 i_new_coupled_count = i_new_channel_count - 1;
2121 if( pi_new_size[0] >= 21U + i_new_channel_count )
2123 i_new_stream_count = p_new_head[19];
2124 i_new_coupled_count = p_new_head[20];
2125 p_new_map = p_new_head+21;
2130 b_match = i_old_channel_count == i_new_channel_count &&
2131 i_old_stream_count == i_new_stream_count &&
2132 i_old_coupled_count == i_new_coupled_count &&
2133 memcmp(p_old_map, p_new_map,
2134 i_new_channel_count*sizeof(*p_new_map)) == 0;
2140 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2142 bool b_compatible = false;
2143 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2146 /* Only Vorbis and Opus are supported. */
2147 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2148 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2149 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2150 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2153 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2155 return !b_compatible;
2158 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2159 const void *p_headers, unsigned i_headers )
2161 demux_sys_t *p_ogg = p_demux->p_sys;
2162 int i_cover_score = 0;
2163 int i_cover_idx = 0;
2164 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2165 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2166 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2168 pf_replay_gain[i] = 0;
2169 pf_replay_peak[i] = 0;
2171 vorbis_ParseComment( &p_ogg->p_meta, p_headers, i_headers,
2172 &p_ogg->i_attachments, &p_ogg->attachments,
2173 &i_cover_score, &i_cover_idx,
2174 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2175 &pf_replay_gain, &pf_replay_peak );
2176 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2179 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2180 p_ogg->attachments[i_cover_idx]->psz_name );
2181 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2184 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2186 if ( pf_replay_gain[i] != 0 )
2188 p_fmt->audio_replay_gain.pb_gain[i] = true;
2189 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2190 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2192 if ( pf_replay_peak[i] != 0 )
2194 p_fmt->audio_replay_gain.pb_peak[i] = true;
2195 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2196 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2200 if( p_ogg->i_seekpoints > 1 )
2202 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2206 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2207 const void *p_headers, unsigned i_headers, unsigned i_skip )
2209 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2210 void *pp_data[XIPH_MAX_HEADER_COUNT];
2213 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2215 /* TODO how to handle multiple comments properly ? */
2216 if( i_count >= 2 && pi_size[1] > i_skip )
2218 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2222 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2224 demux_sys_t *p_ogg = p_demux->p_sys;
2226 switch( p_fmt->i_codec )
2228 /* 3 headers with the 2° one being the comments */
2229 case VLC_CODEC_VORBIS:
2230 case VLC_CODEC_THEORA:
2231 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2233 case VLC_CODEC_OPUS:
2234 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2236 case VLC_CODEC_SPEEX:
2237 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2240 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2242 /* N headers with the 2° one being the comments */
2243 case VLC_CODEC_KATE:
2244 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2245 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2249 case VLC_CODEC_FLAC:
2250 msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
2254 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2255 case VLC_CODEC_DIRAC:
2260 p_demux->info.i_update |= INPUT_UPDATE_META;
2263 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2264 ogg_packet *p_oggpacket )
2267 int i_fps_numerator;
2268 int i_fps_denominator;
2269 int i_keyframe_frequency_force;
2275 p_stream->fmt.i_cat = VIDEO_ES;
2276 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2278 /* Signal that we want to keep a backup of the theora
2279 * stream headers. They will be used when switching between
2281 p_stream->b_force_backup = true;
2283 /* Cheat and get additionnal info ;) */
2284 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2285 bs_skip( &bitstream, 56 );
2287 i_major = bs_read( &bitstream, 8 ); /* major version num */
2288 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2289 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2291 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2292 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2293 bs_read( &bitstream, 24 ); /* frame width */
2294 bs_read( &bitstream, 24 ); /* frame height */
2295 bs_read( &bitstream, 8 ); /* x offset */
2296 bs_read( &bitstream, 8 ); /* y offset */
2298 i_fps_numerator = bs_read( &bitstream, 32 );
2299 i_fps_denominator = bs_read( &bitstream, 32 );
2300 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2301 bs_read( &bitstream, 24 ); /* aspect_numerator */
2302 bs_read( &bitstream, 24 ); /* aspect_denominator */
2304 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2305 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2307 bs_read( &bitstream, 8 ); /* colorspace */
2308 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2309 bs_read( &bitstream, 6 ); /* quality */
2311 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2313 /* granule_shift = i_log( frequency_force -1 ) */
2314 p_stream->i_granule_shift = 0;
2315 i_keyframe_frequency_force--;
2316 while( i_keyframe_frequency_force )
2318 p_stream->i_granule_shift++;
2319 i_keyframe_frequency_force >>= 1;
2322 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2323 p_stream->i_keyframe_offset = 0;
2324 p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
2326 if ( i_version >= 3002001 )
2328 p_stream->i_keyframe_offset = 1;
2332 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2333 ogg_packet *p_oggpacket )
2337 p_stream->fmt.i_cat = AUDIO_ES;
2338 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2340 /* Signal that we want to keep a backup of the vorbis
2341 * stream headers. They will be used when switching between
2343 p_stream->b_force_backup = true;
2345 /* Cheat and get additionnal info ;) */
2346 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2347 oggpack_adv( &opb, 88 );
2348 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2349 fill_channels_info(&p_stream->fmt.audio);
2350 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2351 oggpack_read( &opb, 32 );
2352 oggpack_adv( &opb, 32 );
2353 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2356 static void Ogg_ReadSpeexHeader( 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_SPEEX;
2364 /* Signal that we want to keep a backup of the speex
2365 * stream headers. They will be used when switching between
2367 p_stream->b_force_backup = true;
2369 /* Cheat and get additionnal info ;) */
2370 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2371 oggpack_adv( &opb, 224 );
2372 oggpack_adv( &opb, 32 ); /* speex_version_id */
2373 oggpack_adv( &opb, 32 ); /* header_size */
2374 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2375 oggpack_adv( &opb, 32 ); /* mode */
2376 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2377 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2378 fill_channels_info(&p_stream->fmt.audio);
2379 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2380 oggpack_adv( &opb, 32 ); /* frame_size */
2381 oggpack_adv( &opb, 32 ); /* vbr */
2382 oggpack_adv( &opb, 32 ); /* frames_per_packet */
2383 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2386 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2387 ogg_packet *p_oggpacket )
2391 p_stream->fmt.i_cat = AUDIO_ES;
2392 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2394 /* Signal that we want to keep a backup of the opus
2395 * stream headers. They will be used when switching between
2397 p_stream->b_force_backup = true;
2399 /* All OggOpus streams are timestamped at 48kHz and
2400 * can be played at 48kHz. */
2401 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2402 p_stream->fmt.i_bitrate = 0;
2404 /* Cheat and get additional info ;) */
2405 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2406 oggpack_adv( &opb, 64 );
2407 oggpack_adv( &opb, 8 ); /* version_id */
2408 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2409 fill_channels_info(&p_stream->fmt.audio);
2410 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2413 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
2414 ogg_packet *p_oggpacket )
2416 /* Parse the STREAMINFO metadata */
2419 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2422 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2424 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2428 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2431 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2432 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2433 fill_channels_info(&p_stream->fmt.audio);
2435 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2436 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2440 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2443 /* Fake this as the last metadata block */
2444 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2447 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
2448 ogg_packet *p_oggpacket )
2456 p_stream->fmt.i_cat = SPU_ES;
2457 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2459 /* Signal that we want to keep a backup of the kate
2460 * stream headers. They will be used when switching between
2462 p_stream->b_force_backup = true;
2464 /* Cheat and get additionnal info ;) */
2465 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2466 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2467 p_stream->i_kate_num_headers = oggpack_read( &opb, 8 );
2468 oggpack_adv( &opb, 3*8 );
2469 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2470 oggpack_adv( &opb, 8*8 ); /* reserved */
2471 gnum = oggpack_read( &opb, 32 );
2472 gden = oggpack_read( &opb, 32 );
2473 p_stream->f_rate = (double)gnum/gden;
2475 p_stream->fmt.psz_language = malloc(16);
2476 if( p_stream->fmt.psz_language )
2478 for( n = 0; n < 16; n++ )
2479 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2480 p_stream->fmt.psz_language[15] = 0; /* just in case */
2484 for( n = 0; n < 16; n++ )
2485 oggpack_read(&opb,8);
2487 p_stream->fmt.psz_description = malloc(16);
2488 if( p_stream->fmt.psz_description )
2490 for( n = 0; n < 16; n++ )
2491 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2492 p_stream->fmt.psz_description[15] = 0; /* just in case */
2494 /* Now find a localized user readable description for this category */
2495 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2498 free( p_stream->fmt.psz_description );
2499 p_stream->fmt.psz_description = psz_desc;
2504 for( n = 0; n < 16; n++ )
2505 oggpack_read(&opb,8);
2509 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2510 ogg_packet *p_oggpacket )
2512 switch( p_oggpacket->packet[5] )
2516 /* Mapping version */
2517 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2519 p_stream->fmt.i_cat = VIDEO_ES;
2520 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2521 p_stream->i_granule_shift = 32;
2522 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2523 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2524 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2525 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2526 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2527 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2528 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2532 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2533 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2540 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2541 bool *b_force_backup, bool *b_packet_out )
2543 if( !strncmp(psz_value, "audio/x-wav", 11) )
2545 /* n.b. WAVs are unsupported right now */
2546 p_stream->fmt.i_cat = UNKNOWN_ES;
2547 free( p_stream->fmt.psz_description );
2548 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2550 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2551 !strncmp(psz_value, "audio/vorbis", 12) )
2553 p_stream->fmt.i_cat = AUDIO_ES;
2554 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2556 *b_force_backup = true;
2558 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2559 !strncmp(psz_value, "audio/speex", 11) )
2561 p_stream->fmt.i_cat = AUDIO_ES;
2562 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2564 *b_force_backup = true;
2566 else if( !strncmp(psz_value, "audio/flac", 10) )
2568 p_stream->fmt.i_cat = AUDIO_ES;
2569 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2571 *b_force_backup = true;
2573 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2574 !strncmp(psz_value, "video/theora", 12) )
2576 p_stream->fmt.i_cat = VIDEO_ES;
2577 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2579 *b_force_backup = true;
2581 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2583 p_stream->fmt.i_cat = VIDEO_ES;
2584 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
2586 *b_force_backup = true;
2588 else if( !strncmp(psz_value, "video/mpeg", 10) )
2590 /* n.b. MPEG streams are unsupported right now */
2591 p_stream->fmt.i_cat = VIDEO_ES;
2592 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
2594 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
2595 !strncmp(psz_value, "text/cmml", 9) )
2597 p_stream->fmt.i_cat = SPU_ES;
2598 p_stream->fmt.i_codec = VLC_CODEC_CMML;
2599 *b_packet_out = true;
2601 else if( !strncmp(psz_value, "application/kate", 16) )
2604 p_stream->fmt.i_cat = UNKNOWN_ES;
2605 free( p_stream->fmt.psz_description );
2606 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
2608 else if( !strncmp(psz_value, "video/x-vp8", 11) )
2610 p_stream->fmt.i_cat = VIDEO_ES;
2611 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2615 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
2616 logical_stream_t *p_stream,
2617 ogg_packet *p_oggpacket )
2619 if( p_oggpacket->bytes >= 28 &&
2620 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
2624 uint16_t major_version;
2625 uint16_t minor_version;
2626 uint64_t timebase_numerator;
2627 uint64_t timebase_denominator;
2629 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
2631 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2632 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
2633 major_version = oggpack_read( &opb, 2*8 ); /* major version */
2634 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
2635 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
2636 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
2638 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
2639 "Timebase %"PRId64" / %"PRId64,
2640 major_version, minor_version,
2641 timebase_numerator, timebase_denominator );
2643 else if( p_oggpacket->bytes >= 42 &&
2644 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
2646 uint64_t granule_rate_numerator;
2647 uint64_t granule_rate_denominator;
2648 char content_type_string[1024];
2650 /* Read in Annodex header fields */
2652 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
2653 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
2654 p_stream->i_secondary_header_packets =
2655 GetDWLE( &p_oggpacket->packet[24] );
2657 /* we are guaranteed that the first header field will be
2658 * the content-type (by the Annodex standard) */
2659 content_type_string[0] = '\0';
2660 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
2662 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
2663 p_oggpacket->bytes - 1 );
2664 if( p && p[0] == '\r' && p[1] == '\n' )
2665 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
2666 content_type_string );
2669 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
2670 granule_rate_numerator, granule_rate_denominator,
2671 p_stream->i_secondary_header_packets, content_type_string );
2673 p_stream->f_rate = (float) granule_rate_numerator /
2674 (float) granule_rate_denominator;
2676 /* What type of file do we have?
2677 * strcmp is safe to use here because we've extracted
2678 * content_type_string from the stream manually */
2679 bool b_dopacketout = false;
2680 Ogg_ApplyContentType( p_stream, content_type_string,
2681 &p_stream->b_force_backup, &b_dopacketout );
2682 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
2686 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
2687 ogg_packet *p_oggpacket )
2689 p_demux->p_sys->p_skelstream = p_stream;
2690 /* There can be only 1 skeleton for streams */
2691 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
2692 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
2693 if ( asprintf( & p_stream->fmt.psz_description,
2694 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
2695 p_demux->p_sys->skeleton.major,
2696 p_demux->p_sys->skeleton.minor ) < 0 )
2697 p_stream->fmt.psz_description = NULL;
2700 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
2702 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
2704 /* Find the matching stream for this skeleton data */
2705 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
2706 logical_stream_t *p_target_stream = NULL;
2707 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2709 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2711 p_target_stream = p_demux->p_sys->pp_stream[i];
2715 if ( !p_target_stream ) return;
2717 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
2720 p_skel = malloc( sizeof( ogg_skeleton_t ) );
2721 if ( !p_skel ) return;
2722 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
2723 p_skel->p_index = NULL;
2724 p_target_stream->p_skel = p_skel;
2727 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
2728 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2729 const unsigned char *p = p_messages;
2730 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
2732 if ( *p == 0x0D && *(p+1) == 0x0A )
2734 char *psz_message = strndup( (const char *) p_messages,
2738 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
2739 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
2741 if ( p < p_boundary - 1 ) p_messages = p + 2;
2748 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2749 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
2750 unsigned const char *p_end,
2751 uint64_t *pi_value )
2757 while ( p_begin < p_end )
2759 i_read = *p_begin & 0x7F; /* High bit is start of integer */
2760 *pi_value = *pi_value | ( i_read << i_shift );
2762 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
2765 *pi_value = GetQWLE( pi_value );
2769 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
2771 if ( p_demux->p_sys->skeleton.major < 4
2772 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
2775 /* Find the matching stream for this skeleton data */
2776 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
2777 logical_stream_t *p_stream = NULL;
2778 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
2780 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
2782 p_stream = p_demux->p_sys->pp_stream[i];
2786 if ( !p_stream ) return;
2787 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
2788 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
2789 if ( !i_keypoints ) return;
2791 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
2792 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
2793 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
2794 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
2795 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
2796 uint64_t i_offset = 0;
2797 uint64_t i_time = 0;
2798 uint64_t i_keypoints_found = 0;
2800 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
2803 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2805 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
2806 i_time += i_val * p_stream->p_skel->i_indexstampden;
2807 i_keypoints_found++;
2810 if ( i_keypoints_found != i_keypoints )
2812 msg_Warn( p_demux, "Invalid Index: missing entries" );
2816 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
2817 if ( !p_stream->p_skel->p_index ) return;
2818 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
2819 p_oggpacket->bytes - 42 );
2820 p_stream->p_skel->i_index = i_keypoints_found;
2821 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
2824 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
2826 if ( !p_skel ) return;
2827 for ( int i=0; i< p_skel->i_messages; i++ )
2828 free( p_skel->ppsz_messages[i] );
2829 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
2830 free( p_skel->p_index );
2834 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
2836 if ( !p_stream->p_skel ) return;
2837 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
2839 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
2840 if ( ! strncmp( "Name: ", psz_message, 6 ) )
2842 free( p_stream->fmt.psz_description );
2843 p_stream->fmt.psz_description = strdup( psz_message + 6 );
2845 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
2848 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
2853 /* Return true if there's a skeleton exact match */
2854 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
2855 int64_t *pi_lower, int64_t *pi_upper )
2857 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
2860 /* Validate range */
2861 if ( i_time < p_stream->p_skel->i_indexfirstnum
2862 * p_stream->p_skel->i_indexstampden ||
2863 i_time > p_stream->p_skel->i_indexlastnum
2864 * p_stream->p_skel->i_indexstampden ) return false;
2866 /* Then Lookup its index */
2867 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
2872 } current = { 0, 0 }, prev = { -1, -1 };
2874 uint64_t i_keypoints_found = 0;
2876 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
2877 && i_keypoints_found < p_stream->p_skel->i_index )
2880 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2881 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2882 current.i_pos += i_val;
2883 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
2884 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
2885 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
2886 if ( current.i_pos < 0 || current.i_time < 0 ) break;
2888 i_keypoints_found++;
2890 if ( i_time <= current.i_time )
2892 *pi_lower = prev.i_pos;
2893 *pi_upper = current.i_pos;
2894 return ( i_time == current.i_time );
2901 static uint32_t dirac_uint( bs_t *p_bs )
2903 uint32_t u_count = 0, u_value = 0;
2905 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
2909 u_value |= bs_read( p_bs, 1 );
2912 return (1<<u_count) - 1 + u_value;
2915 static int dirac_bool( bs_t *p_bs )
2917 return bs_read( p_bs, 1 );
2920 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
2921 ogg_packet *p_oggpacket )
2923 static const struct {
2924 uint32_t u_n /* numerator */, u_d /* denominator */;
2925 } p_dirac_frate_tbl[] = { /* table 10.3 */
2926 {1,1}, /* this first value is never used */
2927 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
2928 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
2930 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
2932 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
2933 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
2935 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
2939 p_stream->i_granule_shift = 22; /* not 32 */
2941 /* Backing up stream headers is not required -- seqhdrs are repeated
2942 * thoughout the stream at suitable decoding start points */
2943 p_stream->b_force_backup = false;
2945 /* read in useful bits from sequence header */
2946 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
2947 bs_skip( &bs, 13*8); /* parse_info_header */
2948 dirac_uint( &bs ); /* major_version */
2949 dirac_uint( &bs ); /* minor_version */
2950 dirac_uint( &bs ); /* profile */
2951 dirac_uint( &bs ); /* level */
2953 uint32_t u_video_format = dirac_uint( &bs ); /* index */
2954 if( u_video_format >= u_dirac_vidfmt_frate )
2956 /* don't know how to parse this ogg dirac stream */
2960 if( dirac_bool( &bs ) )
2962 dirac_uint( &bs ); /* frame_width */
2963 dirac_uint( &bs ); /* frame_height */
2966 if( dirac_bool( &bs ) )
2968 dirac_uint( &bs ); /* chroma_format */
2971 if( dirac_bool( &bs ) )
2973 dirac_uint( &bs ); /* scan_format */
2976 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
2977 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
2978 if( dirac_bool( &bs ) )
2980 uint32_t u_frame_rate_index = dirac_uint( &bs );
2981 if( u_frame_rate_index >= u_dirac_frate_tbl )
2983 /* something is wrong with this stream */
2986 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
2987 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
2988 if( u_frame_rate_index == 0 )
2990 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
2991 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
2994 p_stream->f_rate = (float) u_n / u_d;
2996 /* probably is an ogg dirac es */
2997 p_stream->fmt.i_cat = VIDEO_ES;
2998 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;