contrib/gpg-error: simplify darwin triplet handling
[vlc.git] / modules / demux / ogg.c
blobc81f5bb1b37343180ca299836b8bb3995f315aaf
1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@netcourrier.com>
7 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #ifdef HAVE_LIBVORBIS
32 #include <vorbis/codec.h>
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_demux.h>
39 #include <vlc_meta.h>
40 #include <vlc_input.h>
42 #include <ogg/ogg.h>
44 #include <vlc_codecs.h>
45 #include <vlc_bits.h>
46 #include "xiph.h"
47 #include "xiph_metadata.h"
48 #include "ogg.h"
49 #include "oggseek.h"
50 #include "ogg_granule.h"
51 #include "opus.h"
53 /*****************************************************************************
54 * Module descriptor
55 *****************************************************************************/
56 static int Open ( vlc_object_t * );
57 static void Close( vlc_object_t * );
59 vlc_module_begin ()
60 set_shortname ( "OGG" )
61 set_description( N_("OGG demuxer" ) )
62 set_category( CAT_INPUT )
63 set_subcategory( SUBCAT_INPUT_DEMUX )
64 set_capability( "demux", 50 )
65 set_callbacks( Open, Close )
66 add_shortcut( "ogg" )
67 vlc_module_end ()
70 /*****************************************************************************
71 * Definitions of structures and functions used by this plugins
72 *****************************************************************************/
74 /* OggDS headers for the new header format (used in ogm files) */
75 typedef struct
77 ogg_int32_t width;
78 ogg_int32_t height;
79 } stream_header_video_t;
81 typedef struct
83 ogg_int16_t channels;
84 ogg_int16_t padding;
85 ogg_int16_t blockalign;
86 ogg_int32_t avgbytespersec;
87 } stream_header_audio_t;
89 typedef struct
91 char streamtype[8];
92 char subtype[4];
94 ogg_int32_t size; /* size of the structure */
96 ogg_int64_t time_unit; /* in reference time */
97 ogg_int64_t samples_per_unit;
98 ogg_int32_t default_len; /* in media time */
100 ogg_int32_t buffersize;
101 ogg_int16_t bits_per_sample;
102 ogg_int16_t padding;
104 union
106 /* Video specific */
107 stream_header_video_t video;
108 /* Audio specific */
109 stream_header_audio_t audio;
110 } sh;
111 } stream_header_t;
113 #define VORBIS_HEADER_IDENTIFICATION 1
114 #define VORBIS_HEADER_COMMENT 2
115 #define VORBIS_HEADER_SETUP 3
116 #define VORBIS_HEADER_TO_FLAG(i) (1 << (i - 1))
117 #define VORBIS_HEADERS_VALID(p_stream) \
118 ((p_stream->special.vorbis.i_headers_flags & 0x07) == 0x07) // 0b111
120 /*****************************************************************************
121 * Local prototypes
122 *****************************************************************************/
123 static int Demux ( demux_t * );
124 static int Control( demux_t *, int, va_list );
126 /* Bitstream manipulation */
127 static int Ogg_ReadPage ( demux_t *, ogg_page * );
128 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
129 static unsigned Ogg_OpusPacketDuration( ogg_packet * );
130 static void Ogg_QueueBlocks( demux_t *, logical_stream_t *, block_t * );
131 static void Ogg_SendQueuedBlock( demux_t *, logical_stream_t * );
133 static inline bool Ogg_HasQueuedBlocks( const logical_stream_t *p_stream )
135 return ( p_stream->queue.p_blocks != NULL );
138 static void Ogg_CreateES( demux_t *p_demux, bool );
139 static int Ogg_BeginningOfStream( demux_t *p_demux );
140 static int Ogg_FindLogicalStreams( demux_t *p_demux );
141 static void Ogg_EndOfStream( demux_t *p_demux );
143 /* */
144 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream );
145 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
146 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
147 static void Ogg_ResetStream( logical_stream_t *p_stream );
149 /* */
150 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
152 /* Logical bitstream headers */
153 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
154 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
155 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
156 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
157 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
158 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
159 static bool Ogg_ReadFlacStreamInfo( demux_t *, logical_stream_t *, ogg_packet * );
160 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
161 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
162 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
163 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
164 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *, ogg_packet * );
166 /* Skeleton */
167 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
168 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
169 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
170 static void Ogg_ApplySkeleton( logical_stream_t * );
172 /* Special decoding */
173 static void Ogg_CleanSpecificData( logical_stream_t * );
174 #ifdef HAVE_LIBVORBIS
175 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
176 #endif
178 static void fill_channels_info(audio_format_t *audio)
180 static const int pi_channels_map[9] =
183 AOUT_CHAN_CENTER,
184 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
185 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
186 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
187 | AOUT_CHAN_REARRIGHT,
188 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
189 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
190 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
191 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
192 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
193 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
194 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
195 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
196 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
197 | AOUT_CHAN_LFE,
200 unsigned chans = audio->i_channels;
201 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
202 audio->i_physical_channels = pi_channels_map[chans];
205 /*****************************************************************************
206 * Open: initializes ogg demux structures
207 *****************************************************************************/
208 static int Open( vlc_object_t * p_this )
210 demux_t *p_demux = (demux_t *)p_this;
211 demux_sys_t *p_sys;
212 const uint8_t *p_peek;
214 /* Check if we are dealing with an ogg stream */
215 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
216 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
218 char *psz_mime = stream_ContentType( p_demux->s );
219 if( !psz_mime )
221 return VLC_EGENERIC;
223 else if ( strcmp( psz_mime, "application/ogg" ) &&
224 strcmp( psz_mime, "video/ogg" ) &&
225 strcmp( psz_mime, "audio/ogg" ) )
227 free( psz_mime );
228 return VLC_EGENERIC;
230 free( psz_mime );
233 /* */
234 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
235 if( !p_sys )
236 return VLC_ENOMEM;
238 p_sys->i_length = -1;
239 p_sys->b_preparsing_done = false;
241 /* Set exported functions */
242 p_demux->pf_demux = Demux;
243 p_demux->pf_control = Control;
245 /* Initialize the Ogg physical bitstream parser */
246 ogg_sync_init( &p_sys->oy );
248 /* */
249 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
251 /* Enforce exclusive mode, only one track can be selected at once. */
252 es_out_Control( p_demux->out, ES_OUT_SET_ES_CAT_POLICY, AUDIO_ES,
253 ES_OUT_ES_POLICY_EXCLUSIVE );
255 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
257 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
258 Ogg_CreateES( p_demux, true );
260 return VLC_SUCCESS;
263 /*****************************************************************************
264 * Close: frees unused data
265 *****************************************************************************/
266 static void Close( vlc_object_t *p_this )
268 demux_t *p_demux = (demux_t *)p_this;
269 demux_sys_t *p_sys = p_demux->p_sys ;
271 /* Cleanup the bitstream parser */
272 ogg_sync_clear( &p_sys->oy );
274 Ogg_EndOfStream( p_demux );
276 if( p_sys->p_old_stream )
277 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
279 free( p_sys );
282 static vlc_tick_t Ogg_GetLastDTS( demux_t * p_demux )
284 demux_sys_t *p_sys = p_demux->p_sys;
286 vlc_tick_t i_dts = VLC_TICK_INVALID;
287 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
289 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
290 if ( p_stream->b_initializing )
291 continue;
292 if( p_stream->i_pcr > i_dts )
293 i_dts = p_stream->i_pcr;
296 return i_dts;
299 static vlc_tick_t Ogg_GeneratePCR( demux_t * p_demux, bool b_drain )
301 demux_sys_t *p_sys = p_demux->p_sys;
302 /* We will consider the lowest PCR among tracks, because the audio core badly
303 * handles PCR rewind (mute)
305 vlc_tick_t i_pcr_candidate = VLC_TICK_INVALID;
306 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
308 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
309 if( p_stream->fmt.i_cat == SPU_ES )
310 continue;
311 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
312 continue;
313 if( p_stream->i_pcr == VLC_TICK_INVALID )
314 continue;
315 if ( (!b_drain && p_stream->b_finished) || p_stream->b_initializing )
316 continue;
317 if( i_pcr_candidate == VLC_TICK_INVALID ||
318 p_stream->i_pcr < i_pcr_candidate )
320 i_pcr_candidate = p_stream->i_pcr;
324 return i_pcr_candidate;
327 static void Ogg_OutputQueues( demux_t *p_demux, bool b_drain )
329 demux_sys_t *p_sys = p_demux->p_sys;
330 vlc_tick_t i_pcr;
332 /* Generate First PCR */
333 if( p_sys->i_pcr == VLC_TICK_INVALID )
335 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
336 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
338 p_sys->i_pcr = i_pcr;
339 if( likely( !p_sys->b_slave ) )
340 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
344 if( p_sys->i_pcr != VLC_TICK_INVALID )
346 bool b_continue;
349 b_continue = false;
350 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
352 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
353 if( Ogg_HasQueuedBlocks( p_stream ) )
354 Ogg_SendQueuedBlock( p_demux, p_stream );
355 b_continue |= Ogg_HasQueuedBlocks( p_stream );
358 /* Generate Current PCR */
359 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
360 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
362 p_sys->i_pcr = i_pcr;
363 if( likely( !p_sys->b_slave ) )
364 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
366 } while ( b_continue );
371 /*****************************************************************************
372 * Demux: reads and demuxes data packets
373 *****************************************************************************
374 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
375 *****************************************************************************/
376 static int Demux( demux_t * p_demux )
378 demux_sys_t *p_sys = p_demux->p_sys;
379 ogg_packet oggpacket;
380 int i_stream;
381 bool b_canseek;
383 int i_active_streams = p_sys->i_streams;
384 for ( int i=0; i < p_sys->i_streams; i++ )
386 if ( p_sys->pp_stream[i]->b_finished )
387 i_active_streams--;
390 if ( i_active_streams == 0 )
392 if ( p_sys->i_streams ) /* All finished */
394 msg_Dbg( p_demux, "end of a group of %d logical streams", p_sys->i_streams );
396 Ogg_OutputQueues( p_demux, true );
398 vlc_tick_t i_lastdts = Ogg_GetLastDTS( p_demux );
400 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
401 * only 1 ES is supported (common case for ogg web radio) */
402 if( p_sys->i_streams == 1 && p_sys->pp_stream[0]->p_es )
404 if( p_sys->p_old_stream ) /* if no setupEs has reused */
405 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
406 p_sys->p_old_stream = p_sys->pp_stream[0];
407 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
410 Ogg_EndOfStream( p_demux );
411 p_sys->b_chained_boundary = true;
413 if( i_lastdts != VLC_TICK_INVALID )
415 p_sys->i_nzpcr_offset = i_lastdts - VLC_TICK_0;
416 if( likely( !p_sys->b_slave ) )
417 es_out_SetPCR( p_demux->out, i_lastdts );
419 p_sys->i_pcr = VLC_TICK_INVALID;
422 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
423 return VLC_DEMUXER_EOF;
425 msg_Dbg( p_demux, "beginning of a group of logical streams" );
427 if ( !p_sys->b_chained_boundary )
429 /* Find the real duration */
430 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
431 if ( b_canseek )
432 Oggseek_ProbeEnd( p_demux );
434 else
436 p_sys->b_chained_boundary = false;
440 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
441 Ogg_CreateES( p_demux, false );
444 * The first data page of a physical stream is stored in the relevant logical stream
445 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
446 * stream it belongs to if we haven't processed this first page yet. If we do, we
447 * will only process that first page whenever we find the second page for this stream.
448 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
449 * the second page will arrive real quick, this is not fine for Kate, whose second
450 * data page will typically arrive much later.
451 * This means it is now possible to seek right at the start of a stream where the last
452 * logical stream is Kate, without having to wait for the second data page to unblock
453 * the first one, which is the one that triggers the 'no more headers to backup' code.
454 * And, as we all know, seeking without having backed up all headers is bad, since the
455 * codec will fail to initialize if it's missing its headers.
457 if( !p_sys->b_page_waiting)
460 * Demux an ogg page from the stream
462 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
463 return VLC_DEMUXER_EOF; /* EOF */
464 /* Test for End of Stream */
465 if( ogg_page_eos( &p_sys->current_page ) )
467 /* If we delayed restarting encoders/SET_ES_FMT for more
468 * skeleton provided configuration */
469 if ( p_sys->p_skelstream )
471 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
473 msg_Dbg( p_demux, "End of Skeleton" );
474 p_sys->b_preparsing_done = true;
475 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
477 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
478 Ogg_ApplySkeleton( p_stream );
483 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
485 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
487 p_sys->pp_stream[i_stream]->b_finished = true;
488 break;
494 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
496 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
498 /* if we've just pulled page, look for the right logical stream */
499 if( !p_sys->b_page_waiting )
501 if( p_sys->i_streams == 1 &&
502 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
504 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
505 Ogg_ResetStream( p_stream );
506 if( p_stream->i_pcr != VLC_TICK_INVALID )
507 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TICK_0;
508 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
511 /* Does fail if serialno differs */
512 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
514 continue;
518 /* clear the finished flag if pages after eos (ex: after a seek) */
519 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
520 p_stream->b_finished = false;
522 DemuxDebug(
523 if ( p_stream->fmt.i_cat == VIDEO_ES )
524 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
525 ogg_page_pageno( &p_sys->current_page ),
526 ogg_page_granulepos( &p_sys->current_page ),
527 ogg_page_packets( &p_sys->current_page ),
528 ogg_page_continued(&p_sys->current_page),
529 p_sys->current_page.body_len )
532 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
534 /* Read info from any secondary header packets, if there are any */
535 if( p_stream->i_secondary_header_packets > 0 )
537 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
538 oggpacket.bytes >= 7 &&
539 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
541 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
542 p_stream->i_secondary_header_packets = 0;
544 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
545 oggpacket.bytes >= 6 &&
546 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
548 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
549 p_stream->i_secondary_header_packets = 0;
551 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
552 oggpacket.bytes >= 7 &&
553 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
555 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
556 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
557 p_stream->i_secondary_header_packets = 0;
560 /* update start of data pointer */
561 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
564 if( p_stream->b_reinit )
566 p_stream->b_reinit = false;
567 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
569 p_stream->i_skip_frames = p_stream->i_pre_skip;
573 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
577 if( !p_sys->b_page_waiting )
578 break;
581 /* if a page was waiting, it's now processed */
582 p_sys->b_page_waiting = false;
584 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
585 p_sys->b_preparsing_done = false;
586 else
587 p_sys->b_preparsing_done = true;
589 if( p_sys->b_preparsing_done )
591 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
593 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
594 if ( p_stream->b_initializing )
596 /* We have 1 or more streams needing more than 1 page for preparsing */
597 p_sys->b_preparsing_done = false;
598 break;
603 if( p_sys->b_preparsing_done )
604 Ogg_OutputQueues( p_demux, false );
606 return VLC_DEMUXER_SUCCESS;
609 static void Ogg_ResetStream( logical_stream_t *p_stream )
611 #ifdef HAVE_LIBVORBIS
612 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
614 p_stream->special.vorbis.i_prev_blocksize = 0;
616 #endif
617 /* we'll trash all the data until we find the next pcr */
618 p_stream->b_reinit = true;
619 p_stream->i_pcr = VLC_TICK_INVALID;
620 p_stream->i_next_block_flags = 0;
621 p_stream->b_interpolation_failed = false;
622 date_Set( &p_stream->dts, VLC_TICK_INVALID );
623 ogg_stream_reset( &p_stream->os );
624 block_ChainRelease( p_stream->queue.p_blocks );
625 p_stream->queue.p_blocks = NULL;
626 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
629 static void Ogg_PreparePostSeek( demux_sys_t *p_sys )
631 for( int i = 0; i < p_sys->i_streams; i++ )
633 Ogg_ResetStream( p_sys->pp_stream[i] );
634 p_sys->pp_stream[i]->i_next_block_flags = BLOCK_FLAG_DISCONTINUITY;
637 ogg_sync_reset( &p_sys->oy );
638 p_sys->i_pcr = VLC_TICK_INVALID;
641 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
643 demux_sys_t *p_sys = p_demux->p_sys;
644 logical_stream_t *p_stream = NULL;
645 for( int i=0; i<p_sys->i_streams; i++ )
647 logical_stream_t *p_candidate = p_sys->pp_stream[i];
648 if ( !p_candidate->p_es ) continue;
650 bool b_selected = false;
651 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
652 p_candidate->p_es, &b_selected );
653 if ( !b_selected ) continue;
655 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
657 p_stream = p_candidate;
658 continue; /* Try to find video anyway */
661 if ( p_candidate->fmt.i_cat == VIDEO_ES )
663 p_stream = p_candidate;
664 break;
667 return p_stream;
670 /*****************************************************************************
671 * Control:
672 *****************************************************************************/
673 static int Control( demux_t *p_demux, int i_query, va_list args )
675 demux_sys_t *p_sys = p_demux->p_sys;
676 vlc_meta_t *p_meta;
677 vlc_tick_t i64;
678 double f;
679 bool *pb_bool, b, acc;
680 logical_stream_t *p_stream;
682 switch( i_query )
684 case DEMUX_CAN_SEEK:
685 return vlc_stream_vaControl( p_demux->s, i_query, args );
687 case DEMUX_GET_META:
688 p_meta = va_arg( args, vlc_meta_t * );
689 if( p_sys->p_meta )
690 vlc_meta_Merge( p_meta, p_sys->p_meta );
691 return VLC_SUCCESS;
693 case DEMUX_HAS_UNSUPPORTED_META:
694 pb_bool = va_arg( args, bool* );
695 *pb_bool = true;
696 return VLC_SUCCESS;
698 case DEMUX_SET_NEXT_DEMUX_TIME:
699 p_sys->b_slave = true;
700 return VLC_EGENERIC;
702 case DEMUX_GET_TIME:
703 if( p_sys->i_pcr != VLC_TICK_INVALID || p_sys->b_slave )
705 *va_arg( args, vlc_tick_t * ) = p_sys->i_pcr;
706 return VLC_SUCCESS;
708 return VLC_EGENERIC;
710 case DEMUX_SET_TIME:
712 i64 = va_arg( args, vlc_tick_t );
713 acc = va_arg( args, int );
714 p_stream = Ogg_GetSelectedStream( p_demux );
715 if ( !p_stream )
717 msg_Err( p_demux, "No selected seekable stream found" );
718 return VLC_EGENERIC;
720 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
721 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TICK_0 + i64, b ) )
723 Ogg_PreparePostSeek( p_sys );
724 if( acc )
725 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
726 VLC_TICK_0 + i64 );
727 return VLC_SUCCESS;
729 else
730 return VLC_EGENERIC;
733 case DEMUX_GET_ATTACHMENTS:
735 input_attachment_t ***ppp_attach =
736 va_arg( args, input_attachment_t *** );
737 int *pi_int = va_arg( args, int * );
739 if( p_sys->i_attachments <= 0 )
740 return VLC_EGENERIC;
742 *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
743 if (!**ppp_attach)
744 return VLC_ENOMEM;
745 *pi_int = p_sys->i_attachments;
746 for( int i = 0; i < p_sys->i_attachments; i++ )
747 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
748 return VLC_SUCCESS;
751 case DEMUX_GET_POSITION: {
752 double pos = 0.;
753 uint64_t size;
755 if( p_sys->i_length > 0 && p_sys->i_pcr != VLC_TICK_INVALID )
757 vlc_tick_t duration = vlc_tick_from_sec( p_sys->i_length );
758 pos = (double) p_sys->i_pcr / (double) duration;
760 else if( vlc_stream_GetSize( p_demux->s, &size ) == 0 && size > 0 )
762 uint64_t offset = vlc_stream_Tell( p_demux->s );
763 pos = (double) offset / (double) size;
766 *va_arg( args, double * ) = pos;
767 return VLC_SUCCESS;
770 case DEMUX_SET_POSITION:
771 /* forbid seeking if we haven't initialized all logical bitstreams yet;
772 if we allowed, some headers would not get backed up and decoder init
773 would fail, making that logical stream unusable */
774 for ( int i=0; i< p_sys->i_streams; i++ )
776 if ( p_sys->pp_stream[i]->b_initializing )
777 return VLC_EGENERIC;
780 p_stream = Ogg_GetSelectedStream( p_demux );
781 if ( !p_stream )
783 msg_Err( p_demux, "No selected seekable stream found" );
784 return VLC_EGENERIC;
787 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
789 f = va_arg( args, double );
790 acc = va_arg( args, int );
791 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
793 Ogg_PreparePostSeek( p_sys );
794 return Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
797 assert( p_sys->i_length > 0 );
798 i64 = vlc_tick_from_sec( f * p_sys->i_length );
799 Ogg_PreparePostSeek( p_sys );
800 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, VLC_TICK_0 + i64 ) >= 0 )
802 if( acc )
803 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
804 VLC_TICK_0 + i64 );
805 return VLC_SUCCESS;
808 return VLC_EGENERIC;
810 case DEMUX_GET_LENGTH:
811 if ( p_sys->i_length < 0 )
812 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
813 1, i_query, args );
814 *va_arg( args, vlc_tick_t * ) = vlc_tick_from_sec(p_sys->i_length);
815 return VLC_SUCCESS;
817 case DEMUX_GET_TITLE_INFO:
819 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
820 int *pi_int = va_arg( args, int* );
821 int *pi_title_offset = va_arg( args, int* );
822 int *pi_seekpoint_offset = va_arg( args, int* );
824 if( p_sys->i_seekpoints > 0 )
826 *pi_int = 1;
827 *ppp_title = malloc( sizeof( input_title_t* ) );
828 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
829 for( int i = 0; i < p_sys->i_seekpoints; i++ )
831 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
832 if ( likely( p_seekpoint_copy ) )
833 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
835 *pi_title_offset = 0;
836 *pi_seekpoint_offset = 0;
837 return VLC_SUCCESS;
839 return VLC_EGENERIC;
841 case DEMUX_SET_TITLE:
843 const int i_title = va_arg( args, int );
844 if( i_title > 1 )
845 return VLC_EGENERIC;
846 return VLC_SUCCESS;
848 case DEMUX_SET_SEEKPOINT:
850 const int i_seekpoint = va_arg( args, int );
851 if( i_seekpoint > p_sys->i_seekpoints )
852 return VLC_EGENERIC;
854 for ( int i=0; i< p_sys->i_streams; i++ )
856 if ( p_sys->pp_stream[i]->b_initializing )
857 return VLC_EGENERIC;
860 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
862 p_stream = Ogg_GetSelectedStream( p_demux );
863 if ( !p_stream )
865 msg_Err( p_demux, "No selected seekable stream found" );
866 return VLC_EGENERIC;
869 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
870 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TICK_0 + i64, b ) )
872 Ogg_PreparePostSeek( p_sys );
873 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
874 VLC_TICK_0 + i64 );
875 p_sys->updates |= INPUT_UPDATE_SEEKPOINT;
876 p_sys->cur_seekpoint = i_seekpoint;
877 return VLC_SUCCESS;
879 else
880 return VLC_EGENERIC;
882 case DEMUX_TEST_AND_CLEAR_FLAGS:
884 unsigned *restrict flags = va_arg( args, unsigned * );
885 *flags &= p_sys->updates;
886 p_sys->updates &= ~*flags;
887 return VLC_SUCCESS;
889 case DEMUX_GET_TITLE:
890 *va_arg( args, int * ) = 0;
891 return VLC_SUCCESS;
892 case DEMUX_GET_SEEKPOINT:
893 *va_arg( args, int * ) = p_sys->cur_seekpoint;
894 return VLC_SUCCESS;
896 default:
897 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
898 1, i_query, args );
902 /****************************************************************************
903 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
904 ****************************************************************************
905 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
906 * are at the end of stream.
907 ****************************************************************************/
908 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
910 demux_sys_t *p_ogg = p_demux->p_sys ;
911 int i_read = 0;
912 char *p_buffer;
914 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
916 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
918 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
919 if( i_read <= 0 )
920 return VLC_EGENERIC;
922 ogg_sync_wrote( &p_ogg->oy, i_read );
925 return VLC_SUCCESS;
928 static void Ogg_SetNextFrame( demux_t *p_demux, logical_stream_t *p_stream,
929 ogg_packet *p_oggpacket )
931 VLC_UNUSED(p_demux);
932 ogg_int64_t i_granule = p_oggpacket->granulepos;
934 if( Ogg_GranuleIsValid( p_stream, i_granule ) )
936 vlc_tick_t i_endtime = Ogg_GranuleToTime( p_stream, i_granule, false, false );
937 assert( !p_stream->b_contiguous || i_endtime != VLC_TICK_INVALID );
938 if( i_endtime != VLC_TICK_INVALID )
940 date_Set( &p_stream->dts, i_endtime );
941 return;
945 /* Do Interpolation if can't compute directly from granule */
946 if( date_Get( &p_stream->dts ) != VLC_TICK_INVALID )
948 if( p_stream->fmt.i_cat == VIDEO_ES )
950 date_Increment( &p_stream->dts, 1 );
952 else if( p_stream->fmt.i_cat == AUDIO_ES )
954 int64_t i_samples = 0;
955 switch( p_stream->fmt.i_codec )
957 case VLC_CODEC_OPUS:
958 i_samples = Ogg_OpusPacketDuration( p_oggpacket );
959 break;
960 case VLC_CODEC_SPEEX:
961 i_samples = p_stream->special.speex.i_framesize *
962 p_stream->special.speex.i_framesperpacket;
963 break;
964 #ifdef HAVE_LIBVORBIS
965 case VLC_CODEC_VORBIS:
966 if( p_stream->special.vorbis.p_info &&
967 VORBIS_HEADERS_VALID(p_stream) )
969 long i_blocksize = vorbis_packet_blocksize(
970 p_stream->special.vorbis.p_info, p_oggpacket );
971 /* duration in samples per channel */
972 if ( p_stream->special.vorbis.i_prev_blocksize )
973 i_samples = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
974 else
975 i_samples = i_blocksize / 2;
976 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
978 break;
979 #endif
980 default:
981 if( p_stream->fmt.i_bitrate )
983 i_samples = 8 * p_oggpacket->bytes * p_stream->dts.i_divider_num;
984 i_samples /= p_stream->fmt.i_bitrate / p_stream->dts.i_divider_den;
986 break;
988 if( i_samples == 0 )
989 p_stream->b_interpolation_failed = true;
990 else
991 date_Increment( &p_stream->dts, i_samples );
996 static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_stream )
998 vlc_tick_t i_enddts = VLC_TICK_INVALID;
1000 #ifdef HAVE_LIBVORBIS
1001 long i_prev_blocksize = 0;
1002 #else
1003 VLC_UNUSED(p_demux);
1004 #endif
1005 // PASS 1, set number of samples
1006 unsigned i_total_samples = 0;
1007 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
1009 if( p_block->i_dts != VLC_TICK_INVALID )
1011 i_enddts = p_block->i_dts;
1012 break;
1015 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1016 continue;
1018 ogg_packet dumb_packet;
1019 dumb_packet.bytes = p_block->i_buffer;
1020 dumb_packet.packet = p_block->p_buffer;
1022 switch( p_stream->fmt.i_codec )
1024 case VLC_CODEC_SPEEX:
1025 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
1026 p_stream->special.speex.i_framesperpacket;
1027 break;
1028 case VLC_CODEC_OPUS:
1029 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
1030 break;
1031 #ifdef HAVE_LIBVORBIS
1032 case VLC_CODEC_VORBIS:
1034 if( !VORBIS_HEADERS_VALID(p_stream) )
1036 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
1037 break;
1039 long i_blocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info,
1040 &dumb_packet );
1041 if ( i_prev_blocksize )
1042 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
1043 else
1044 p_block->i_nb_samples = i_blocksize / 2;
1045 i_prev_blocksize = i_blocksize;
1046 break;
1048 #endif
1049 default:
1050 if( p_stream->fmt.i_cat == VIDEO_ES )
1051 p_block->i_nb_samples = 1;
1052 break;
1054 i_total_samples += p_block->i_nb_samples;
1057 // PASS 2
1058 if( i_enddts != VLC_TICK_INVALID )
1060 date_t d = p_stream->dts;
1061 date_Set( &d, i_enddts );
1062 i_enddts = date_Decrement( &d, i_total_samples );
1063 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
1065 if( p_block->i_dts != VLC_TICK_INVALID )
1066 break;
1067 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1068 continue;
1069 p_block->i_dts = date_Get( &d );
1070 date_Increment( &d, p_block->i_nb_samples );
1072 } /* else can't do anything, no timestamped blocks in stream */
1074 return i_enddts;
1077 static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream, block_t *p_block )
1079 demux_sys_t *p_sys = p_demux->p_sys;
1080 VLC_UNUSED(p_sys);
1082 if( p_block == NULL )
1084 assert( p_block != NULL );
1085 return;
1088 block_ChainLastAppend( &p_stream->queue.pp_append, p_block );
1090 if( p_stream->i_pcr == VLC_TICK_INVALID && p_block->i_dts != VLC_TICK_INVALID )
1092 /* fixup queue */
1093 p_stream->i_pcr = Ogg_FixupOutputQueue( p_demux, p_stream );
1096 DemuxDebug( msg_Dbg( p_demux, "%4.4s block queued > dts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1097 (char*)&p_stream->fmt.i_codec, p_block->i_dts, p_stream->i_pcr, p_sys->i_pcr ); )
1100 static void Ogg_SendQueuedBlock( demux_t *p_demux, logical_stream_t *p_stream )
1102 demux_sys_t *p_sys = p_demux->p_sys;
1104 if( Ogg_HasQueuedBlocks( p_stream ) )
1106 block_t *p_queued = p_stream->queue.p_blocks;
1107 p_stream->queue.p_blocks = p_queued->p_next;
1108 p_queued->p_next = NULL;
1110 if( p_queued->i_dts == VLC_TICK_INVALID )
1111 p_queued->i_dts = p_queued->i_pts;
1113 if( p_queued->i_flags & BLOCK_FLAG_HEADER )
1115 if( p_sys->i_nzpcr_offset > 0 || /* Don't send metadata from chained streams */
1116 p_stream->fmt.i_extra > 0 ) /* Don't send metadata if configured by extradata */
1118 block_Release( p_queued );
1119 goto end;
1121 p_queued->i_flags &= ~BLOCK_FLAG_HEADER;
1124 unsigned i_toskip = 0;
1125 if( p_stream->i_skip_frames > 0 )
1127 if( p_sys->i_nzpcr_offset > 0 )
1129 /* not preskip handling on chained streams */
1130 p_stream->i_skip_frames = 0;
1132 else
1134 i_toskip = __MIN( p_stream->i_skip_frames, p_queued->i_nb_samples );
1135 p_stream->i_skip_frames -= i_toskip;
1136 p_queued->i_nb_samples -= i_toskip;
1137 if( p_queued->i_nb_samples == 0 )
1138 p_queued->i_flags |= BLOCK_FLAG_PREROLL;
1142 p_queued->i_flags |= p_stream->i_next_block_flags;
1143 p_stream->i_next_block_flags = 0;
1144 p_stream->i_pcr = p_queued->i_dts;
1146 DemuxDebug( msg_Dbg( p_demux, "%4.4s block sent > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64
1147 " samples (%d/%d)",
1148 (char*)&p_stream->fmt.i_codec, p_queued->i_dts,
1149 p_queued->i_pts, p_stream->i_pcr, p_sys->i_pcr,
1150 p_queued->i_nb_samples, i_toskip ); );
1152 assert( p_sys->i_pcr != VLC_TICK_INVALID );
1154 if( p_stream->p_es )
1155 es_out_Send( p_demux->out, p_stream->p_es, p_queued );
1156 else
1157 block_Release( p_queued );
1160 end:
1161 if( p_stream->queue.p_blocks == NULL )
1162 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
1165 static bool Ogg_IsHeaderPacket( const logical_stream_t *p_stream,
1166 const ogg_packet *p_oggpacket )
1168 if ( p_stream->b_oggds )
1170 return p_oggpacket->bytes > 0 &&
1171 (p_oggpacket->packet[0] & PACKET_TYPE_HEADER);
1173 else return ( p_oggpacket->granulepos == 0 && p_stream->i_first_frame_index > 0 );
1176 /****************************************************************************
1177 * Ogg_DecodePacket: Decode an Ogg packet.
1178 ****************************************************************************/
1179 static void Ogg_DecodePacket( demux_t *p_demux,
1180 logical_stream_t *p_stream,
1181 ogg_packet *p_oggpacket )
1183 demux_sys_t *p_sys = p_demux->p_sys;
1184 block_t *p_block;
1185 bool b_selected;
1186 long i_header_len = 0;
1188 if( p_oggpacket->bytes >= 7 &&
1189 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1191 /* it's an Annodex packet -- skip it (do nothing) */
1192 return;
1194 else if( p_oggpacket->bytes >= 7 &&
1195 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1197 /* it's an AnxData packet -- skip it (do nothing) */
1198 return;
1200 else if( p_oggpacket->bytes >= 8 &&
1201 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1203 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1204 return;
1206 else if( p_oggpacket->bytes >= 6 &&
1207 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1209 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1210 return;
1212 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1213 p_oggpacket->bytes >= 7 &&
1214 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1216 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1217 return;
1220 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1221 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1223 /* Check the ES is selected */
1224 if ( !p_stream->p_es )
1225 b_selected = true;
1226 else
1227 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1228 p_stream->p_es, &b_selected );
1230 if( p_stream->b_force_backup )
1232 bool b_xiph;
1233 p_stream->i_packets_backup++;
1234 switch( p_stream->fmt.i_codec )
1236 case VLC_CODEC_VORBIS:
1237 #ifdef HAVE_LIBVORBIS
1238 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1239 #endif
1240 /* fallthrough */
1241 case VLC_CODEC_THEORA:
1242 if( p_stream->i_packets_backup == 3 )
1243 p_stream->b_force_backup = false;
1244 b_xiph = true;
1245 break;
1247 case VLC_CODEC_DAALA:
1248 if( p_stream->i_packets_backup == 3 )
1249 p_stream->b_force_backup = false;
1250 b_xiph = true;
1251 break;
1253 case VLC_CODEC_SPEEX:
1254 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1255 p_stream->b_force_backup = false;
1256 b_xiph = true;
1257 break;
1259 case VLC_CODEC_OPUS:
1260 if( p_stream->i_packets_backup == 2 )
1261 p_stream->b_force_backup = false;
1262 b_xiph = true;
1263 break;
1265 case VLC_CODEC_FLAC:
1266 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1268 p_stream->b_force_backup = false;
1270 if( p_stream->special.flac.b_old )
1272 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1274 else if( p_stream->i_packets_backup == 1 )
1276 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1278 p_oggpacket->packet += 9;
1279 p_oggpacket->bytes -= 9;
1282 b_xiph = false;
1283 break;
1285 case VLC_CODEC_KATE:
1286 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1287 p_stream->b_force_backup = false;
1288 b_xiph = true;
1289 break;
1291 default:
1292 p_stream->b_force_backup = false;
1293 b_xiph = false;
1294 break;
1297 /* Backup the ogg packet (likely an header packet) */
1298 if( !b_xiph )
1300 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1301 if( p_realloc )
1303 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1304 p_stream->i_headers += p_oggpacket->bytes;
1305 p_stream->p_headers = p_realloc;
1307 else
1309 free( p_stream->p_headers );
1310 p_stream->i_headers = 0;
1311 p_stream->p_headers = NULL;
1314 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1315 p_oggpacket->bytes, p_oggpacket->packet ) )
1317 p_stream->i_headers = 0;
1318 p_stream->p_headers = NULL;
1320 if( p_stream->i_headers > 0 )
1322 if( !p_stream->b_force_backup )
1324 /* Last header received, commit changes */
1325 free( p_stream->fmt.p_extra );
1327 p_stream->fmt.i_extra = p_stream->i_headers;
1328 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1329 if( p_stream->fmt.p_extra )
1330 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1331 p_stream->i_headers );
1332 else
1333 p_stream->fmt.i_extra = 0;
1335 if( p_stream->i_headers > 0 )
1336 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1337 p_stream->p_headers, p_stream->i_headers );
1339 /* we're not at BOS anymore for this logical stream */
1340 p_stream->b_initializing = false;
1344 b_selected = false; /* Discard the header packet */
1346 else
1348 p_stream->b_initializing = false;
1351 vlc_tick_t i_dts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, false );
1352 vlc_tick_t i_expected_dts = p_stream->b_interpolation_failed ? VLC_TICK_INVALID :
1353 date_Get( &p_stream->dts ); /* Interpolated or previous end time */
1354 if( i_dts == VLC_TICK_INVALID )
1355 i_dts = i_expected_dts;
1356 else
1357 date_Set( &p_stream->dts, i_dts );
1359 /* Write end granule as next start, or do interpolation */
1360 bool b_header = Ogg_IsHeaderPacket( p_stream, p_oggpacket );
1361 if( !b_header )
1362 Ogg_SetNextFrame( p_demux, p_stream, p_oggpacket );
1364 if( !b_selected )
1366 /* This stream isn't currently selected so we don't need to decode it,
1367 * but we did need to store its pcr as it might be selected later on */
1368 if( !b_header && !p_stream->b_initializing )
1370 vlc_tick_t i_pcr = date_Get( &p_stream->dts );
1371 if( i_pcr != VLC_TICK_INVALID )
1372 p_stream->i_pcr = p_sys->i_nzpcr_offset + i_pcr;
1374 return;
1377 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) )
1378 return;
1380 /* Set effective timestamp */
1381 if( i_dts != VLC_TICK_INVALID )
1382 p_block->i_dts = p_sys->i_nzpcr_offset + i_dts;
1384 /* Vorbis and Opus can trim the end of a stream using granule positions. */
1385 if( p_oggpacket->e_o_s )
1387 vlc_tick_t i_endtime = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, false, false );
1388 if( i_endtime != VLC_TICK_INVALID && i_expected_dts != VLC_TICK_INVALID )
1390 p_block->i_length = i_endtime - i_expected_dts;
1391 p_block->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
1395 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS ) /* also required for trimming */
1396 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1398 DemuxDebug( msg_Dbg(p_demux, "%4.4s block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1399 (char *) &p_stream->fmt.i_codec, p_oggpacket->granulepos,
1400 p_block->i_dts, p_stream->i_skip_frames); )
1402 /* may need to preroll after a seek or in case of preskip */
1404 /* Conditional block fixes */
1405 if ( p_stream->fmt.i_cat == VIDEO_ES )
1407 if( Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1408 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1410 if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1412 if( p_oggpacket->granulepos > 0 )
1413 p_block->i_pts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, true );
1415 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1417 p_block->i_pts = p_block->i_dts;
1420 else if( p_stream->fmt.i_cat == AUDIO_ES )
1422 if( p_stream->b_interpolation_failed && p_oggpacket->granulepos < 0 )
1423 p_block->i_pts = VLC_TICK_INVALID;
1424 else
1425 p_block->i_pts = p_block->i_dts;
1427 else if( p_stream->fmt.i_cat == SPU_ES )
1429 p_block->i_length = 0;
1430 p_block->i_pts = p_block->i_dts;
1433 p_stream->b_interpolation_failed = false;
1435 if( p_stream->b_oggds )
1437 if( p_oggpacket->bytes <= 0 )
1439 msg_Dbg( p_demux, "discarding 0 sized packet" );
1440 block_Release( p_block );
1441 return;
1443 /* We remove the header from the packet */
1444 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1445 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1447 if( i_header_len >= p_oggpacket->bytes )
1449 msg_Dbg( p_demux, "discarding invalid packet" );
1450 block_Release( p_block );
1451 return;
1454 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1456 /* But with subtitles we need to retrieve the duration first */
1457 int i, lenbytes = 0;
1459 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1461 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1463 lenbytes = lenbytes << 8;
1464 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1467 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1468 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1469 p_oggpacket->packet[i_header_len + 1] != 0 &&
1470 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1471 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1473 p_block->i_length = (vlc_tick_t)lenbytes * 1000;
1477 i_header_len++;
1478 if( p_block->i_buffer >= (unsigned int)i_header_len )
1479 p_block->i_buffer -= i_header_len;
1480 else
1481 p_block->i_buffer = 0;
1484 if( b_header )
1485 p_block->i_flags |= BLOCK_FLAG_HEADER;
1487 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1488 p_oggpacket->bytes - i_header_len );
1490 Ogg_QueueBlocks( p_demux, p_stream, p_block );
1493 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1495 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1498 /****************************************************************************
1499 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1500 * stream and fill p_ogg.
1501 *****************************************************************************
1502 * The initial page of a logical stream is marked as a 'bos' page.
1503 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1504 * together and all of the initial pages must appear before any data pages.
1506 * On success this function returns VLC_SUCCESS.
1507 ****************************************************************************/
1508 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1510 demux_sys_t *p_ogg = p_demux->p_sys;
1511 ogg_packet oggpacket;
1513 p_ogg->i_total_length = stream_Size ( p_demux->s );
1514 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1517 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1520 if( ogg_page_bos( &p_ogg->current_page ) )
1523 /* All is wonderful in our fine fine little world.
1524 * We found the beginning of our first logical stream. */
1525 while( ogg_page_bos( &p_ogg->current_page ) )
1527 logical_stream_t *p_stream = malloc( sizeof(logical_stream_t) );
1528 if( unlikely( !p_stream ) )
1529 return VLC_ENOMEM;
1531 Ogg_LogicalStreamInit( p_stream );
1533 /* Setup the logical stream */
1534 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1535 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1537 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1539 /* Extract the initial header from the first page and verify
1540 * the codec type of this Ogg bitstream */
1541 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1543 /* error. stream version mismatch perhaps */
1544 msg_Err( p_demux, "error reading first page of "
1545 "Ogg bitstream data" );
1546 return VLC_EGENERIC;
1549 if ( ogg_stream_packetpeek( &p_stream->os, &oggpacket ) != 1 )
1551 msg_Err( p_demux, "error in ogg_stream_packetpeek" );
1552 return VLC_EGENERIC;
1555 /* Check for Vorbis header */
1556 if( oggpacket.bytes >= 7 &&
1557 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1559 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1560 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1561 msg_Dbg( p_demux, "found vorbis header" );
1562 else
1564 msg_Dbg( p_demux, "found invalid vorbis header" );
1565 Ogg_LogicalStreamDelete( p_demux, p_stream );
1566 p_stream = NULL;
1567 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1568 p_ogg->i_streams - 1 );
1571 /* Check for Speex header */
1572 else if( oggpacket.bytes >= 5 &&
1573 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1575 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1576 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1577 msg_Dbg( p_demux, "found speex header, channels: %i, "
1578 "rate: %"PRIu32"/%"PRIu32", bitrate: %i, frames: %i group %i",
1579 p_stream->fmt.audio.i_channels,
1580 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1581 p_stream->fmt.i_bitrate,
1582 p_stream->special.speex.i_framesize,
1583 p_stream->special.speex.i_framesperpacket );
1584 else
1586 msg_Dbg( p_demux, "found invalid Speex header" );
1587 Ogg_LogicalStreamDelete( p_demux, p_stream );
1588 p_stream = NULL;
1589 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1590 p_ogg->i_streams - 1 );
1593 /* Check for Opus header */
1594 else if( oggpacket.bytes >= 8 &&
1595 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1597 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1598 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1599 msg_Dbg( p_demux, "found opus header, channels: %i, "
1600 "pre-skip: %i",
1601 p_stream->fmt.audio.i_channels,
1602 (int)p_stream->i_pre_skip);
1603 p_stream->i_skip_frames = p_stream->i_pre_skip;
1605 /* Check for OLD Flac header */
1606 else if( oggpacket.bytes >= 4 &&
1607 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1609 msg_Dbg( p_demux, "found FLAC header" );
1611 /* Grrrr!!!! Did they really have to put all the
1612 * important info in the second header packet!!!
1613 * (STREAMINFO metadata is in the following packet) */
1614 p_stream->b_force_backup = true;
1615 p_stream->i_extra_headers_packets = 1;
1616 p_stream->special.flac.b_old = true;
1617 date_Init( &p_stream->dts, 48000, 1 ); /* better be safe since that's delayed */
1618 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1620 /* Check for Flac header (>= version 1.0.0) */
1621 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1622 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1623 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1625 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1626 oggpacket.packet[8];
1627 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1628 "(%i header packets)",
1629 oggpacket.packet[5], oggpacket.packet[6],
1630 i_packets );
1631 /* STREAMINFO is in current packet, and then
1632 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1633 p_stream->b_force_backup = true;
1634 p_stream->i_extra_headers_packets = i_packets;
1635 p_stream->special.flac.b_old = false;
1637 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1638 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1639 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1641 msg_Dbg( p_demux, "found invalid Flac header" );
1642 Ogg_LogicalStreamDelete( p_demux, p_stream );
1643 p_stream = NULL;
1644 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1645 p_ogg->i_streams - 1 );
1647 p_stream->fmt.b_packetized = false;
1649 /* Check for Theora header */
1650 else if( oggpacket.bytes >= 7 &&
1651 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1653 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1654 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1655 msg_Dbg( p_demux,
1656 "found theora header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1657 p_stream->fmt.i_bitrate,
1658 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1659 else
1661 msg_Dbg( p_demux, "found invalid Theora header" );
1662 Ogg_LogicalStreamDelete( p_demux, p_stream );
1663 p_stream = NULL;
1664 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1665 p_ogg->i_streams - 1 );
1668 /* Check for Daala header */
1669 else if( oggpacket.bytes >= 6 &&
1670 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1672 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1673 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1674 msg_Dbg( p_demux,
1675 "found daala header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1676 p_stream->fmt.i_bitrate,
1677 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1678 else
1680 msg_Dbg( p_demux, "found invalid Daala header" );
1681 Ogg_LogicalStreamDelete( p_demux, p_stream );
1682 p_stream = NULL;
1683 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1684 p_ogg->i_streams - 1 );
1687 /* Check for Dirac header */
1688 else if( ( oggpacket.bytes >= 5 &&
1689 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1690 ( oggpacket.bytes >= 9 &&
1691 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1693 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1694 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1695 msg_Dbg( p_demux, "found dirac header" );
1696 else
1698 msg_Warn( p_demux, "found dirac header isn't decodable" );
1699 Ogg_LogicalStreamDelete( p_demux, p_stream );
1700 p_stream = NULL;
1701 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1702 p_ogg->i_streams - 1 );
1705 /* Check for VP8 header */
1706 else if( oggpacket.bytes >= 26 &&
1707 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1709 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1710 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1711 msg_Dbg( p_demux, "found VP8 header "
1712 "fps: %"PRIu32"/%"PRIu32", width:%i; height:%i",
1713 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1714 p_stream->fmt.video.i_width,
1715 p_stream->fmt.video.i_height );
1716 else
1718 msg_Dbg( p_demux, "invalid VP8 header found");
1719 Ogg_LogicalStreamDelete( p_demux, p_stream );
1720 p_stream = NULL;
1721 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1722 p_ogg->i_streams - 1 );
1725 /* Check for Annodex header */
1726 else if( oggpacket.bytes >= 7 &&
1727 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1729 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1730 /* kill annodex track */
1731 FREENULL( p_stream );
1732 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1733 p_ogg->i_streams - 1 );
1735 /* Check for Annodex header */
1736 else if( oggpacket.bytes >= 7 &&
1737 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1739 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1741 /* Check for Kate header */
1742 else if( oggpacket.bytes >= 8 &&
1743 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1745 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1746 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1747 msg_Dbg( p_demux, "found kate header" );
1748 else
1750 msg_Dbg( p_demux, "invalid kate header found");
1751 Ogg_LogicalStreamDelete( p_demux, p_stream );
1752 p_stream = NULL;
1753 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1754 p_ogg->i_streams - 1 );
1757 /* Check for OggDS */
1758 else if( oggpacket.bytes >= 142 &&
1759 !memcmp( &oggpacket.packet[1],
1760 "Direct Show Samples embedded in Ogg", 35 ))
1762 /* Old header type */
1763 p_stream->b_oggds = true;
1764 p_stream->b_contiguous = false;
1765 /* Check for video header (old format) */
1766 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1767 oggpacket.bytes >= 184 )
1769 es_format_Change( &p_stream->fmt, VIDEO_ES,
1770 VLC_FOURCC( oggpacket.packet[68],
1771 oggpacket.packet[69],
1772 oggpacket.packet[70],
1773 oggpacket.packet[71] ) );
1774 msg_Dbg( p_demux, "found video header of type: %.4s",
1775 (char *)&p_stream->fmt.i_codec );
1777 unsigned num = OGGDS_RESOLUTION;
1778 unsigned den = GetQWLE(oggpacket.packet+164);
1779 vlc_ureduce( &num, &den, num, den > 0 ? den : 1, OGGDS_RESOLUTION );
1780 p_stream->fmt.video.i_frame_rate = num;
1781 p_stream->fmt.video.i_frame_rate_base = den;
1782 date_Init( &p_stream->dts, num, den );
1783 p_stream->fmt.video.i_bits_per_pixel =
1784 GetWLE((oggpacket.packet+182));
1785 if( !p_stream->fmt.video.i_bits_per_pixel )
1786 /* hack, FIXME */
1787 p_stream->fmt.video.i_bits_per_pixel = 24;
1788 p_stream->fmt.video.i_width =
1789 GetDWLE((oggpacket.packet+176));
1790 p_stream->fmt.video.i_height =
1791 GetDWLE((oggpacket.packet+180));
1792 p_stream->fmt.video.i_visible_width =
1793 p_stream->fmt.video.i_width;
1794 p_stream->fmt.video.i_visible_height =
1795 p_stream->fmt.video.i_height;
1797 msg_Dbg( p_demux,
1798 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1799 p_stream->fmt.video.i_frame_rate,
1800 p_stream->fmt.video.i_frame_rate_base,
1801 p_stream->fmt.video.i_width,
1802 p_stream->fmt.video.i_height,
1803 p_stream->fmt.video.i_bits_per_pixel);
1805 if ( !p_stream->fmt.video.i_frame_rate ||
1806 !p_stream->fmt.video.i_frame_rate_base )
1808 Ogg_LogicalStreamDelete( p_demux, p_stream );
1809 p_stream = NULL;
1810 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1811 p_ogg->i_streams - 1 );
1814 /* Check for audio header (old format) */
1815 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1817 int i_extra_size;
1818 unsigned int i_format_tag;
1820 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1822 i_extra_size = GetWLE((oggpacket.packet+140));
1823 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1825 p_stream->fmt.i_extra = i_extra_size;
1826 p_stream->fmt.p_extra = malloc( i_extra_size );
1827 if( p_stream->fmt.p_extra )
1828 memcpy( p_stream->fmt.p_extra,
1829 oggpacket.packet + 142, i_extra_size );
1830 else
1831 p_stream->fmt.i_extra = 0;
1834 i_format_tag = GetWLE((oggpacket.packet+124));
1835 p_stream->fmt.audio.i_channels =
1836 GetWLE((oggpacket.packet+126));
1837 fill_channels_info(&p_stream->fmt.audio);
1838 p_stream->fmt.audio.i_rate =
1839 GetDWLE((oggpacket.packet+128));
1840 p_stream->fmt.i_bitrate =
1841 GetDWLE((oggpacket.packet+132)) * 8;
1842 p_stream->fmt.audio.i_blockalign =
1843 GetWLE((oggpacket.packet+136));
1844 p_stream->fmt.audio.i_bitspersample =
1845 GetWLE((oggpacket.packet+138));
1847 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
1849 wf_tag_to_fourcc( i_format_tag,
1850 &p_stream->fmt.i_codec, 0 );
1852 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1854 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1855 ( i_format_tag >> 8 ) & 0xff,
1856 i_format_tag & 0xff );
1859 msg_Dbg( p_demux, "found audio header of type: %.4s",
1860 (char *)&p_stream->fmt.i_codec );
1861 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1862 "%dbits/sample %dkb/s",
1863 i_format_tag,
1864 p_stream->fmt.audio.i_channels,
1865 p_stream->fmt.audio.i_rate,
1866 p_stream->fmt.audio.i_bitspersample,
1867 p_stream->fmt.i_bitrate / 1024 );
1869 if ( p_stream->fmt.audio.i_rate == 0 )
1871 msg_Dbg( p_demux, "invalid oggds audio header" );
1872 Ogg_LogicalStreamDelete( p_demux, p_stream );
1873 p_stream = NULL;
1874 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1875 p_ogg->i_streams - 1 );
1878 else
1880 msg_Dbg( p_demux, "stream %d has an old header "
1881 "but is of an unknown type", p_ogg->i_streams-1 );
1882 FREENULL( p_stream );
1883 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
1884 p_ogg->i_streams - 1 );
1887 /* Check for OggDS */
1888 else if( oggpacket.bytes >= 44+1 &&
1889 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1891 stream_header_t tmp;
1892 stream_header_t *st = &tmp;
1894 p_stream->b_oggds = true;
1895 p_stream->b_contiguous = false;
1897 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1898 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1899 st->size = GetDWLE( &oggpacket.packet[1+12] );
1900 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1901 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1902 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1903 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1904 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1906 /* Check for video header (new format) */
1907 if( !strncmp( st->streamtype, "video", 5 ) &&
1908 oggpacket.bytes >= 52+1 )
1910 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1911 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1913 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1915 /* We need to get rid of the header packet */
1916 ogg_stream_packetout( &p_stream->os, &oggpacket );
1918 p_stream->fmt.i_codec =
1919 VLC_FOURCC( st->subtype[0], st->subtype[1],
1920 st->subtype[2], st->subtype[3] );
1921 msg_Dbg( p_demux, "found video header of type: %.4s",
1922 (char *)&p_stream->fmt.i_codec );
1924 /* FIXME: no clue where it's from */
1925 if( st->time_unit <= 0 )
1926 st->time_unit = 400000;
1927 unsigned num, den;
1928 vlc_ureduce( &num, &den,
1929 st->samples_per_unit * OGGDS_RESOLUTION,
1930 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1931 OGGDS_RESOLUTION );
1932 date_Init( &p_stream->dts, num, den );
1933 p_stream->fmt.video.i_frame_rate = num;
1934 p_stream->fmt.video.i_frame_rate_base = den;
1935 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1936 p_stream->fmt.video.i_width = st->sh.video.width;
1937 p_stream->fmt.video.i_height = st->sh.video.height;
1938 p_stream->fmt.video.i_visible_width =
1939 p_stream->fmt.video.i_width;
1940 p_stream->fmt.video.i_visible_height =
1941 p_stream->fmt.video.i_height;
1943 msg_Dbg( p_demux,
1944 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1945 p_stream->fmt.video.i_frame_rate,
1946 p_stream->fmt.video.i_frame_rate_base,
1947 p_stream->fmt.video.i_width,
1948 p_stream->fmt.video.i_height,
1949 p_stream->fmt.video.i_bits_per_pixel );
1951 /* Check for audio header (new format) */
1952 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1953 oggpacket.bytes >= 56+1 )
1955 char p_buffer[5];
1956 int i_extra_size;
1957 int i_format_tag;
1959 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1960 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1961 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1963 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1965 /* We need to get rid of the header packet */
1966 ogg_stream_packetout( &p_stream->os, &oggpacket );
1968 i_extra_size = st->size - 56;
1970 if( i_extra_size > 0 &&
1971 i_extra_size < oggpacket.bytes - 1 - 56 )
1973 p_stream->fmt.i_extra = i_extra_size;
1974 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1975 if( p_stream->fmt.p_extra )
1976 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1977 p_stream->fmt.i_extra );
1978 else
1979 p_stream->fmt.i_extra = 0;
1982 memcpy( p_buffer, st->subtype, 4 );
1983 p_buffer[4] = '\0';
1984 i_format_tag = strtol(p_buffer,NULL,16);
1985 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1986 fill_channels_info(&p_stream->fmt.audio);
1988 unsigned num,den;
1989 vlc_ureduce( &num, &den,
1990 st->samples_per_unit * OGGDS_RESOLUTION,
1991 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1992 OGGDS_RESOLUTION );
1993 date_Init( &p_stream->dts, num, den );
1994 p_stream->fmt.audio.i_rate = num / den;
1995 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1996 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1997 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1999 wf_tag_to_fourcc( i_format_tag,
2000 &p_stream->fmt.i_codec, 0 );
2002 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
2004 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
2005 ( i_format_tag >> 8 ) & 0xff,
2006 i_format_tag & 0xff );
2009 msg_Dbg( p_demux, "found audio header of type: %.4s",
2010 (char *)&p_stream->fmt.i_codec );
2011 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2012 "%dbits/sample %dkb/s",
2013 i_format_tag,
2014 p_stream->fmt.audio.i_channels,
2015 p_stream->fmt.audio.i_rate,
2016 p_stream->fmt.audio.i_bitspersample,
2017 p_stream->fmt.i_bitrate / 1024 );
2018 if ( p_stream->fmt.audio.i_rate == 0 )
2020 msg_Dbg( p_demux, "invalid oggds audio header" );
2021 Ogg_LogicalStreamDelete( p_demux, p_stream );
2022 p_stream = NULL;
2023 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
2024 p_ogg->i_streams - 1 );
2027 /* Check for text (subtitles) header */
2028 else if( !strncmp(st->streamtype, "text", 4) )
2030 /* We need to get rid of the header packet */
2031 ogg_stream_packetout( &p_stream->os, &oggpacket );
2033 msg_Dbg( p_demux, "found text subtitle header" );
2034 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2035 date_Init( &p_stream->dts, 1000, 1 ); /* granulepos is in millisec */
2037 else
2039 msg_Dbg( p_demux, "stream %d has a header marker "
2040 "but is of an unknown type", p_ogg->i_streams-1 );
2041 FREENULL( p_stream );
2042 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
2043 p_ogg->i_streams - 1 );
2046 else if( oggpacket.bytes >= 8 &&
2047 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2050 /* Skeleton */
2051 msg_Dbg( p_demux, "stream %d is a skeleton",
2052 p_ogg->i_streams-1 );
2053 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2055 /* Check for OggSpots header */
2056 else if( oggpacket.bytes >= 8 &&
2057 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2059 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2060 msg_Dbg( p_demux,
2061 "found OggSpots header, time resolution: %u/%u",
2062 p_stream->fmt.video.i_frame_rate,
2063 p_stream->fmt.video.i_frame_rate_base );
2064 else
2066 msg_Err( p_demux, "found invalid OggSpots header" );
2067 Ogg_LogicalStreamDelete( p_demux, p_stream );
2068 p_stream = NULL;
2069 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
2070 p_ogg->i_streams - 1 );
2073 else
2075 Ogg_LogicalStreamDelete( p_demux, p_stream );
2076 p_stream = NULL;
2077 TAB_ERASE( p_ogg->i_streams, p_ogg->pp_stream,
2078 p_ogg->i_streams - 1 );
2079 msg_Dbg( p_demux, "stream %d is of unknown type",
2080 p_ogg->i_streams );
2083 /* we'll need to get all headers */
2084 if ( p_stream )
2085 p_stream->b_initializing &= p_stream->b_force_backup;
2087 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2088 return VLC_EGENERIC;
2091 /* This is the first data page, which means we are now finished
2092 * with the initial pages. We just need to store it in the relevant
2093 * bitstream. */
2094 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2096 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2097 &p_ogg->current_page ) == 0 )
2099 p_ogg->b_page_waiting = true;
2100 break;
2104 return VLC_SUCCESS;
2108 return VLC_EGENERIC;
2111 /****************************************************************************
2112 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2113 ****************************************************************************/
2114 static void Ogg_CreateES( demux_t *p_demux, bool stable_id )
2116 demux_sys_t *p_ogg = p_demux->p_sys;
2117 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2118 int i_stream;
2120 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2122 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2124 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2126 /* Better be safe than sorry when possible with ogm */
2127 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2128 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2129 p_stream->fmt.b_packetized = false;
2131 /* Try first to reuse an old ES */
2132 if( p_old_stream &&
2133 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2134 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec &&
2135 p_old_stream->p_es != NULL && p_stream->p_es != NULL )
2137 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2139 p_stream->p_es = p_old_stream->p_es;
2140 p_stream->b_finished = false;
2141 p_stream->b_reinit = false;
2142 p_stream->b_initializing = false;
2143 p_stream->i_pre_skip = 0;
2144 es_format_Clean( &p_stream->fmt_old );
2145 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2146 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2148 p_old_stream->p_es = NULL;
2149 p_old_stream = NULL;
2150 if ( b_resetdecoder )
2152 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2153 p_stream->p_es, &p_stream->fmt );
2156 else
2158 if( stable_id )
2160 /* IDs are stable when ES tracks are created from the Open
2161 * function. Don't specify ids when tracks are added
2162 * midstream */
2163 p_stream->fmt.i_id = i_stream;
2165 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2170 if( p_ogg->p_old_stream )
2172 if( p_ogg->p_old_stream->p_es )
2173 msg_Dbg( p_demux, "old stream not reused" );
2174 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2175 p_ogg->p_old_stream = NULL;
2177 p_ogg->b_es_created = true;
2180 /****************************************************************************
2181 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2182 * Elementary streams.
2183 ****************************************************************************/
2184 static int Ogg_BeginningOfStream( demux_t *p_demux )
2186 demux_sys_t *p_ogg = p_demux->p_sys ;
2187 int i_stream;
2189 /* Find the logical streams embedded in the physical stream and
2190 * initialize our p_ogg structure. */
2191 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2193 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2194 return VLC_EGENERIC;
2197 p_ogg->i_bitrate = 0;
2199 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2201 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2203 p_stream->p_es = NULL;
2205 /* initialise kframe index */
2206 p_stream->idx=NULL;
2208 if ( p_stream->fmt.i_bitrate == 0 &&
2209 ( p_stream->fmt.i_cat == VIDEO_ES ||
2210 p_stream->fmt.i_cat == AUDIO_ES ) )
2211 p_ogg->b_partial_bitrate = true;
2212 else
2213 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2215 p_stream->i_pcr = VLC_TICK_INVALID;
2216 p_stream->b_reinit = false;
2219 /* get total frame count for video stream; we will need this for seeking */
2220 p_ogg->i_total_frames = 0;
2222 return VLC_SUCCESS;
2225 /****************************************************************************
2226 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2227 ****************************************************************************/
2228 static void Ogg_EndOfStream( demux_t *p_demux )
2230 demux_sys_t *p_ogg = p_demux->p_sys ;
2231 int i_stream;
2233 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2234 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2235 free( p_ogg->pp_stream );
2237 /* Reinit p_ogg */
2238 p_ogg->i_bitrate = 0;
2239 p_ogg->i_streams = 0;
2240 p_ogg->pp_stream = NULL;
2241 p_ogg->skeleton.major = 0;
2242 p_ogg->skeleton.minor = 0;
2243 p_ogg->b_preparsing_done = false;
2244 p_ogg->b_es_created = false;
2246 /* */
2247 if( p_ogg->p_meta )
2248 vlc_meta_Delete( p_ogg->p_meta );
2249 p_ogg->p_meta = NULL;
2251 for(int i=0; i<p_ogg->i_attachments; i++)
2252 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2253 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2255 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2257 if ( p_ogg->pp_seekpoints[i] )
2258 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2260 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2263 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2265 #ifdef HAVE_LIBVORBIS
2266 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2268 if( p_stream->special.vorbis.p_info )
2269 vorbis_info_clear( p_stream->special.vorbis.p_info );
2270 FREENULL( p_stream->special.vorbis.p_info );
2271 if( p_stream->special.vorbis.p_comment )
2272 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2273 FREENULL( p_stream->special.vorbis.p_comment );
2274 p_stream->special.vorbis.i_headers_flags = 0;
2276 #else
2277 VLC_UNUSED( p_stream );
2278 #endif
2281 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream )
2283 memset( p_stream, 0, sizeof(logical_stream_t) );
2284 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
2285 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
2286 p_stream->i_pcr = VLC_TICK_INVALID;
2287 p_stream->i_first_frame_index = 1;
2288 date_Set( &p_stream->dts, VLC_TICK_INVALID );
2289 p_stream->b_initializing = true;
2290 p_stream->b_contiguous = true; /* default */
2291 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
2295 * This function delete and release all data associated to a logical_stream_t
2297 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2299 demux_sys_t *p_sys = p_demux->p_sys;
2301 if( p_stream->p_es )
2302 es_out_Del( p_demux->out, p_stream->p_es );
2304 ogg_stream_clear( &p_stream->os );
2305 free( p_stream->p_headers );
2307 Ogg_CleanSpecificData( p_stream );
2309 es_format_Clean( &p_stream->fmt_old );
2310 es_format_Clean( &p_stream->fmt );
2312 if ( p_stream->idx != NULL)
2314 oggseek_index_entries_free( p_stream->idx );
2317 Ogg_FreeSkeleton( p_stream->p_skel );
2318 p_stream->p_skel = NULL;
2319 if( p_sys->p_skelstream == p_stream )
2320 p_sys->p_skelstream = NULL;
2322 /* Shouldn't happen */
2323 block_ChainRelease( p_stream->queue.p_blocks );
2325 free( p_stream );
2328 * This function check if a we need to reset a decoder in case we are
2329 * reusing an old ES
2331 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2333 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2334 const void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2335 unsigned i_new_count;
2337 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2338 i_new_count = 0;
2340 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2341 const void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2342 unsigned i_old_count;
2344 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2345 i_old_count = 0;
2347 bool b_match = i_new_count == i_old_count;
2348 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2350 /* Ignore vorbis comment */
2351 if( i == 1 )
2352 continue;
2353 if( pi_new_size[i] != pi_old_size[i] ||
2354 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2355 b_match = false;
2358 return b_match;
2361 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2362 const es_format_t *p_old )
2364 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2365 const void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2366 unsigned i_new_count;
2368 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2369 i_new_count = 0;
2371 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2372 const void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2373 unsigned i_old_count;
2375 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2376 i_old_count = 0;
2377 bool b_match = false;
2378 if( i_new_count == i_old_count && i_new_count > 0 )
2380 static const unsigned char default_map[2] = { 0, 1 };
2381 const unsigned char *p_old_head;
2382 unsigned char *p_new_head;
2383 const unsigned char *p_old_map;
2384 const unsigned char *p_new_map;
2385 int i_old_channel_count;
2386 int i_new_channel_count;
2387 int i_old_stream_count;
2388 int i_new_stream_count;
2389 int i_old_coupled_count;
2390 int i_new_coupled_count;
2391 p_old_head = pp_old_data[0];
2392 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2393 p_old_map = default_map;
2394 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2396 i_old_channel_count = p_old_head[9];
2397 switch( p_old_head[18] )
2399 case 0:
2400 i_old_stream_count = 1;
2401 i_old_coupled_count = i_old_channel_count - 1;
2402 break;
2403 case 1:
2404 if( pi_old_size[0] >= 21U + i_old_channel_count )
2406 i_old_stream_count = p_old_head[19];
2407 i_old_coupled_count = p_old_head[20];
2408 p_old_map = p_old_head + 21;
2410 break;
2413 p_new_head = (unsigned char *)pp_new_data[0];
2414 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2415 p_new_map = default_map;
2416 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2418 i_new_channel_count = p_new_head[9];
2419 switch( p_new_head[18] )
2421 case 0:
2422 i_new_stream_count = 1;
2423 i_new_coupled_count = i_new_channel_count - 1;
2424 break;
2425 case 1:
2426 if( pi_new_size[0] >= 21U + i_new_channel_count )
2428 i_new_stream_count = p_new_head[19];
2429 i_new_coupled_count = p_new_head[20];
2430 p_new_map = p_new_head+21;
2432 break;
2435 b_match = i_old_channel_count == i_new_channel_count &&
2436 i_old_stream_count == i_new_stream_count &&
2437 i_old_coupled_count == i_new_coupled_count &&
2438 memcmp(p_old_map, p_new_map,
2439 i_new_channel_count*sizeof(*p_new_map)) == 0;
2442 return b_match;
2445 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2447 bool b_compatible = false;
2448 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2449 return true;
2451 /* Only Vorbis and Opus are supported. */
2452 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2453 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2454 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2455 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2456 else if( p_stream->fmt.i_codec == VLC_CODEC_FLAC )
2457 b_compatible = !p_stream->fmt.b_packetized;
2459 if( !b_compatible )
2460 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2462 return !b_compatible;
2465 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2466 const void *p_headers, unsigned i_headers )
2468 demux_sys_t *p_ogg = p_demux->p_sys;
2469 int i_cover_score = 0;
2470 int i_cover_idx = 0;
2471 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2472 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2473 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2475 pf_replay_gain[i] = 0;
2476 pf_replay_peak[i] = 0;
2478 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2479 &p_ogg->i_attachments, &p_ogg->attachments,
2480 &i_cover_score, &i_cover_idx,
2481 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2482 &pf_replay_gain, &pf_replay_peak );
2483 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2485 char psz_url[128];
2486 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2487 p_ogg->attachments[i_cover_idx]->psz_name );
2488 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2491 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2493 if ( pf_replay_gain[i] != 0 )
2495 p_fmt->audio_replay_gain.pb_gain[i] = true;
2496 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2497 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2499 if ( pf_replay_peak[i] != 0 )
2501 p_fmt->audio_replay_gain.pb_peak[i] = true;
2502 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2503 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2507 if( p_ogg->i_seekpoints > 1 )
2509 p_ogg->updates |= INPUT_UPDATE_TITLE_LIST;
2513 static inline uint32_t GetDW24BE( const uint8_t *p )
2515 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2516 #ifdef WORDS_BIGENDIAN
2517 i = vlc_bswap32(i);
2518 #endif
2519 return i;
2522 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2523 const uint8_t *p_headers, unsigned i_headers )
2525 /* Skip Streaminfo 42 bytes / 1st page */
2526 if(i_headers <= 46)
2527 return;
2528 p_headers += 42; i_headers -= 42;
2529 /* Block Header 1 + 3 bytes */
2530 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2531 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2533 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2537 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2538 const void *p_headers, unsigned i_headers, unsigned i_skip )
2540 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2541 const void *pp_data[XIPH_MAX_HEADER_COUNT];
2542 unsigned i_count;
2544 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2545 return;
2546 /* TODO how to handle multiple comments properly ? */
2547 if( i_count >= 2 && pi_size[1] > i_skip )
2549 Ogg_ExtractComments( p_demux, p_fmt,
2550 (const uint8_t *)pp_data[1] + i_skip,
2551 pi_size[1] - i_skip );
2555 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2557 demux_sys_t *p_ogg = p_demux->p_sys;
2559 switch( p_fmt->i_codec )
2561 /* 3 headers with the 2° one being the comments */
2562 case VLC_CODEC_VORBIS:
2563 case VLC_CODEC_THEORA:
2564 case VLC_CODEC_DAALA:
2565 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2566 break;
2567 case VLC_CODEC_OPUS:
2568 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2569 break;
2570 case VLC_CODEC_SPEEX:
2571 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2572 break;
2573 case VLC_CODEC_VP8:
2574 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2575 break;
2576 /* N headers with the 2° one being the comments */
2577 case VLC_CODEC_KATE:
2578 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2579 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2580 break;
2582 /* TODO */
2583 case VLC_CODEC_FLAC:
2584 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2585 break;
2587 /* No meta data */
2588 case VLC_CODEC_DIRAC:
2589 default:
2590 break;
2592 if( p_ogg->p_meta )
2593 p_ogg->updates |= INPUT_UPDATE_META;
2596 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2597 ogg_packet *p_oggpacket )
2599 bs_t bitstream;
2600 unsigned int i_fps_numerator;
2601 unsigned int i_fps_denominator;
2602 int i_keyframe_frequency_force;
2603 int i_major;
2604 int i_minor;
2605 int i_subminor;
2606 int i_version;
2608 /* Signal that we want to keep a backup of the theora
2609 * stream headers. They will be used when switching between
2610 * audio streams. */
2611 p_stream->b_force_backup = true;
2613 /* Cheat and get additionnal info ;) */
2614 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2615 bs_skip( &bitstream, 56 );
2617 i_major = bs_read( &bitstream, 8 ); /* major version num */
2618 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2619 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2621 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2622 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2623 bs_read( &bitstream, 24 ); /* frame width */
2624 bs_read( &bitstream, 24 ); /* frame height */
2625 bs_read( &bitstream, 8 ); /* x offset */
2626 bs_read( &bitstream, 8 ); /* y offset */
2628 i_fps_numerator = bs_read( &bitstream, 32 );
2629 i_fps_denominator = bs_read( &bitstream, 32 );
2630 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2631 bs_read( &bitstream, 24 ); /* aspect_numerator */
2632 bs_read( &bitstream, 24 ); /* aspect_denominator */
2634 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2635 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2637 bs_read( &bitstream, 8 ); /* colorspace */
2638 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2639 bs_read( &bitstream, 6 ); /* quality */
2641 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2643 /* granule_shift = i_log( frequency_force -1 ) */
2644 p_stream->i_granule_shift = 0;
2645 i_keyframe_frequency_force--;
2646 while( i_keyframe_frequency_force )
2648 p_stream->i_granule_shift++;
2649 i_keyframe_frequency_force >>= 1;
2652 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2653 p_stream->i_first_frame_index = (i_version >= 3002001) ? 1 : 0;
2654 if ( !i_fps_denominator || !i_fps_numerator )
2655 return false;
2656 date_Init( &p_stream->dts, i_fps_numerator, i_fps_denominator );
2658 return true;
2661 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2662 ogg_packet *p_oggpacket )
2664 oggpack_buffer opb;
2665 uint32_t i_timebase_numerator;
2666 uint32_t i_timebase_denominator;
2667 int keyframe_granule_shift;
2668 unsigned int i_keyframe_frequency_force;
2669 uint8_t i_major;
2670 uint8_t i_minor;
2671 uint8_t i_subminor;
2672 int i_version;
2674 /* Signal that we want to keep a backup of the daala
2675 * stream headers. They will be used when switching between
2676 * audio streams. */
2677 p_stream->b_force_backup = true;
2679 /* Cheat and get additionnal info ;) */
2680 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2681 oggpack_adv( &opb, 48 );
2683 i_major = oggpack_read( &opb, 8 ); /* major version num */
2684 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2685 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2687 oggpack_adv( &opb, 32 ); /* width */
2688 oggpack_adv( &opb, 32 ); /* height */
2690 oggpack_adv( &opb, 32 ); /* aspect numerator */
2691 oggpack_adv( &opb, 32 ); /* aspect denominator */
2692 i_timebase_numerator = oggpack_read( &opb, 32 );
2694 i_timebase_denominator = oggpack_read( &opb, 32 );
2695 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2697 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2698 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2700 oggpack_adv( &opb, 32 ); /* frame duration */
2702 keyframe_granule_shift = oggpack_read( &opb, 8 );
2703 keyframe_granule_shift = __MIN(keyframe_granule_shift, 31);
2704 i_keyframe_frequency_force = 1u << keyframe_granule_shift;
2706 /* granule_shift = i_log( frequency_force -1 ) */
2707 p_stream->i_granule_shift = 0;
2708 i_keyframe_frequency_force--;
2709 while( i_keyframe_frequency_force )
2711 p_stream->i_granule_shift++;
2712 i_keyframe_frequency_force >>= 1;
2715 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2716 VLC_UNUSED(i_version);
2717 p_stream->i_first_frame_index = 0;
2718 if ( !i_timebase_numerator || !i_timebase_denominator )
2719 return false;
2720 date_Init( &p_stream->dts, i_timebase_numerator, i_timebase_denominator );
2722 return true;
2725 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2726 ogg_packet *p_oggpacket )
2728 oggpack_buffer opb;
2730 /* Signal that we want to keep a backup of the vorbis
2731 * stream headers. They will be used when switching between
2732 * audio streams. */
2733 p_stream->b_force_backup = true;
2735 /* Cheat and get additionnal info ;) */
2736 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2737 oggpack_adv( &opb, 88 );
2738 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2739 fill_channels_info(&p_stream->fmt.audio);
2740 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2741 if( p_stream->fmt.audio.i_rate == 0 )
2742 return false;
2743 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2745 oggpack_adv( &opb, 32 );
2746 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2747 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2748 return true;
2750 #ifdef HAVE_LIBVORBIS
2751 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2752 ogg_packet *p_oggpacket, int i_number )
2754 switch( i_number )
2756 case VORBIS_HEADER_IDENTIFICATION:
2757 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2758 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2759 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2761 FREENULL( p_stream->special.vorbis.p_info );
2762 FREENULL( p_stream->special.vorbis.p_comment );
2763 break;
2765 vorbis_info_init( p_stream->special.vorbis.p_info );
2766 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2767 /* fallthrough */
2769 case VORBIS_HEADER_COMMENT:
2770 case VORBIS_HEADER_SETUP:
2771 if ( !p_stream->special.vorbis.p_info ||
2772 vorbis_synthesis_headerin(
2773 p_stream->special.vorbis.p_info,
2774 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2775 break;
2777 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2778 /* fallthrough */
2780 default:
2781 break;
2784 #endif
2786 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2787 ogg_packet *p_oggpacket )
2789 oggpack_buffer opb;
2791 /* Signal that we want to keep a backup of the speex
2792 * stream headers. They will be used when switching between
2793 * audio streams. */
2794 p_stream->b_force_backup = true;
2796 /* Cheat and get additionnal info ;) */
2797 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2798 oggpack_adv( &opb, 224 );
2799 oggpack_adv( &opb, 32 ); /* speex_version_id */
2800 oggpack_adv( &opb, 32 ); /* header_size */
2801 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2802 if ( !p_stream->fmt.audio.i_rate )
2803 return false;
2804 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2805 oggpack_adv( &opb, 32 ); /* mode */
2806 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2807 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2808 fill_channels_info(&p_stream->fmt.audio);
2809 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2810 p_stream->special.speex.i_framesize =
2811 oggpack_read( &opb, 32 ); /* frame_size */
2812 oggpack_adv( &opb, 32 ); /* vbr */
2813 p_stream->special.speex.i_framesperpacket =
2814 oggpack_read( &opb, 32 ); /* frames_per_packet */
2815 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2816 return true;
2819 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2820 ogg_packet *p_oggpacket )
2822 oggpack_buffer opb;
2824 /* Signal that we want to keep a backup of the opus
2825 * stream headers. They will be used when switching between
2826 * audio streams. */
2827 p_stream->b_force_backup = true;
2829 /* All OggOpus streams are timestamped at 48kHz and
2830 * can be played at 48kHz. */
2831 p_stream->fmt.audio.i_rate = 48000;
2832 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2833 p_stream->fmt.i_bitrate = 0;
2835 /* Cheat and get additional info ;) */
2836 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2837 oggpack_adv( &opb, 64 );
2838 oggpack_adv( &opb, 8 ); /* version_id */
2839 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2840 fill_channels_info(&p_stream->fmt.audio);
2841 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2842 /* For Opus, trash the first 80 ms of decoded output as
2843 well, to avoid blowing out speakers if we get unlucky.
2844 Opus predicts content from prior frames, which can go
2845 badly if we seek right where the stream goes from very
2846 quiet to very loud. It will converge after a bit. */
2847 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2850 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2851 ogg_packet *p_oggpacket )
2853 /* Parse the STREAMINFO metadata */
2854 bs_t s;
2856 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2858 bs_read( &s, 1 );
2859 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2861 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2862 return false;
2865 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2867 bs_skip( &s, 80 );
2868 p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2869 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2870 fill_channels_info(&p_stream->fmt.audio);
2872 msg_Dbg( p_demux, "FLAC header, channels: %"PRIu8", rate: %u",
2873 p_stream->fmt.audio.i_channels, p_stream->fmt.audio.i_rate );
2874 if ( p_stream->fmt.audio.i_rate == 0 )
2875 return false;
2876 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2878 else
2880 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2883 /* Fake this as the last metadata block */
2884 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2885 return true;
2888 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2889 ogg_packet *p_oggpacket )
2891 oggpack_buffer opb;
2892 uint32_t gnum;
2893 uint32_t gden;
2894 int n;
2895 char *psz_desc;
2897 /* Signal that we want to keep a backup of the kate
2898 * stream headers. They will be used when switching between
2899 * kate streams. */
2900 p_stream->b_force_backup = true;
2902 /* Cheat and get additionnal info ;) */
2903 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2904 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2905 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2906 oggpack_adv( &opb, 3*8 );
2907 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2908 oggpack_adv( &opb, 8*8 ); /* reserved */
2909 gnum = oggpack_read( &opb, 32 );
2910 gden = oggpack_read( &opb, 32 );
2911 gden = __MAX( gden, 1 );
2912 if ( !gnum || !gden )
2913 return false;
2914 date_Init( &p_stream->dts, gnum, gden );
2916 p_stream->fmt.psz_language = malloc(16);
2917 if( p_stream->fmt.psz_language )
2919 for( n = 0; n < 16; n++ )
2920 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2921 p_stream->fmt.psz_language[15] = 0; /* just in case */
2923 else
2925 for( n = 0; n < 16; n++ )
2926 oggpack_read(&opb,8);
2928 p_stream->fmt.psz_description = malloc(16);
2929 if( p_stream->fmt.psz_description )
2931 for( n = 0; n < 16; n++ )
2932 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2933 p_stream->fmt.psz_description[15] = 0; /* just in case */
2935 /* Now find a localized user readable description for this category */
2936 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2937 if( psz_desc )
2939 free( p_stream->fmt.psz_description );
2940 p_stream->fmt.psz_description = psz_desc;
2943 else
2945 for( n = 0; n < 16; n++ )
2946 oggpack_read(&opb,8);
2949 return true;
2952 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2953 ogg_packet *p_oggpacket )
2955 switch( p_oggpacket->packet[5] )
2957 /* STREAMINFO */
2958 case 0x01:
2959 /* Mapping version */
2960 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2961 return false;
2962 p_stream->i_granule_shift = 32;
2963 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2964 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2965 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2966 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2967 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2968 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2969 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2970 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2971 if ( !p_stream->fmt.video.i_frame_rate || !p_stream->fmt.video.i_frame_rate_base )
2972 return false;
2973 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
2974 p_stream->fmt.video.i_frame_rate_base );
2975 return true;
2976 /* METADATA */
2977 case 0x02:
2978 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2979 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2980 return true;
2981 default:
2982 return false;
2986 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2987 bool *b_force_backup )
2989 if( p_stream->fmt.i_cat != UNKNOWN_ES )
2990 return;
2992 if( !strncmp(psz_value, "audio/x-wav", 11) )
2994 /* n.b. WAVs are unsupported right now */
2995 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2996 free( p_stream->fmt.psz_description );
2997 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2999 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
3000 !strncmp(psz_value, "audio/vorbis", 12) )
3002 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
3004 *b_force_backup = true;
3006 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
3007 !strncmp(psz_value, "audio/speex", 11) )
3009 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
3011 *b_force_backup = true;
3013 else if( !strncmp(psz_value, "audio/flac", 10) )
3015 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
3017 *b_force_backup = true;
3019 else if( !strncmp(psz_value, "video/x-theora", 14) ||
3020 !strncmp(psz_value, "video/theora", 12) )
3022 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
3024 *b_force_backup = true;
3026 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3027 !strncmp(psz_value, "video/daala", 11) )
3029 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
3031 *b_force_backup = true;
3033 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3035 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
3037 *b_force_backup = true;
3039 else if( !strncmp(psz_value, "video/mpeg", 10) )
3041 /* n.b. MPEG streams are unsupported right now */
3042 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3044 else if( !strncmp(psz_value, "application/kate", 16) )
3046 /* ??? */
3047 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3048 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3050 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3052 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3056 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3057 logical_stream_t *p_stream,
3058 ogg_packet *p_oggpacket )
3060 if( p_oggpacket->bytes >= 28 &&
3061 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3063 oggpack_buffer opb;
3065 uint16_t major_version;
3066 uint16_t minor_version;
3067 uint64_t timebase_numerator;
3068 uint64_t timebase_denominator;
3070 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3072 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3073 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3074 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3075 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3076 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3077 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3079 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3080 "Timebase %"PRId64" / %"PRId64,
3081 major_version, minor_version,
3082 timebase_numerator, timebase_denominator );
3084 else if( p_oggpacket->bytes >= 42 &&
3085 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3087 uint64_t granule_rate_numerator;
3088 uint64_t granule_rate_denominator;
3089 char content_type_string[1024];
3091 /* Read in Annodex header fields */
3093 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3094 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3095 p_stream->i_secondary_header_packets =
3096 GetDWLE( &p_oggpacket->packet[24] );
3098 /* we are guaranteed that the first header field will be
3099 * the content-type (by the Annodex standard) */
3100 content_type_string[0] = '\0';
3101 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3103 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3104 p_oggpacket->bytes - 1 );
3105 if( p && p[0] == '\r' && p[1] == '\n' )
3106 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3107 content_type_string );
3110 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3111 granule_rate_numerator, granule_rate_denominator,
3112 p_stream->i_secondary_header_packets, content_type_string );
3114 if( granule_rate_numerator && granule_rate_denominator )
3115 date_Init( &p_stream->dts, granule_rate_numerator, granule_rate_denominator );
3117 /* What type of file do we have?
3118 * strcmp is safe to use here because we've extracted
3119 * content_type_string from the stream manually */
3120 Ogg_ApplyContentType( p_stream, content_type_string,
3121 &p_stream->b_force_backup );
3125 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3126 ogg_packet *p_oggpacket )
3128 demux_sys_t *p_sys = p_demux->p_sys;
3129 if( p_oggpacket->bytes < 12 )
3130 return;
3132 p_sys->p_skelstream = p_stream;
3133 /* There can be only 1 skeleton for streams */
3134 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3135 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3136 if ( asprintf( & p_stream->fmt.psz_description,
3137 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3138 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3139 p_stream->fmt.psz_description = NULL;
3142 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3144 demux_sys_t *p_sys = p_demux->p_sys;
3146 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3148 /* Find the matching stream for this skeleton data */
3149 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3150 logical_stream_t *p_target_stream = NULL;
3151 for ( int i=0; i< p_sys->i_streams; i++ )
3153 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3155 p_target_stream = p_sys->pp_stream[i];
3156 break;
3159 if ( !p_target_stream ) return;
3161 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3162 if ( !p_skel )
3164 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3165 if ( !p_skel ) return;
3166 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3167 p_skel->p_index = NULL;
3168 p_target_stream->p_skel = p_skel;
3171 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3172 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3173 const unsigned char *p = p_messages;
3174 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3176 if ( *p == 0x0D && *(p+1) == 0x0A )
3178 char *psz_message = strndup( (const char *) p_messages,
3179 p - p_messages );
3180 if ( psz_message )
3182 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3183 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3185 if ( p < p_boundary - 1 ) p_messages = p + 2;
3187 p++;
3192 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3193 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3194 unsigned const char *p_end,
3195 uint64_t *pi_value )
3197 int i_shift = 0;
3198 int64_t i_read = 0;
3199 *pi_value = 0;
3201 while ( p_begin < p_end )
3203 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3204 *pi_value = *pi_value | ( i_read << i_shift );
3205 i_shift += 7;
3206 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3209 *pi_value = GetQWLE( pi_value );
3210 return p_begin;
3213 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3215 demux_sys_t *p_sys = p_demux->p_sys;
3217 if( p_sys->skeleton.major < 4
3218 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3219 ) return;
3221 /* Find the matching stream for this skeleton data */
3222 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3223 logical_stream_t *p_stream = NULL;
3224 for ( int i=0; i< p_sys->i_streams; i++ )
3226 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3228 p_stream = p_sys->pp_stream[i];
3229 break;
3232 if ( !p_stream || !p_stream->p_skel ) return;
3233 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3234 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3235 if ( !i_keypoints ) return;
3237 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3238 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3239 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3240 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3241 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3242 uint64_t i_offset = 0;
3243 uint64_t i_time = 0;
3244 uint64_t i_keypoints_found = 0;
3246 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3248 uint64_t i_val;
3249 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3250 i_offset += i_val;
3251 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3252 i_time += i_val * p_stream->p_skel->i_indexstampden;
3253 i_keypoints_found++;
3256 if ( i_keypoints_found != i_keypoints )
3258 msg_Warn( p_demux, "Invalid Index: missing entries" );
3259 return;
3262 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3263 if ( !p_stream->p_skel->p_index ) return;
3264 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3265 p_oggpacket->bytes - 42 );
3266 p_stream->p_skel->i_index = i_keypoints_found;
3267 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3270 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3272 if ( !p_skel ) return;
3273 for ( int i=0; i< p_skel->i_messages; i++ )
3274 free( p_skel->ppsz_messages[i] );
3275 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3276 free( p_skel->p_index );
3277 free( p_skel );
3280 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3282 if ( !p_stream->p_skel ) return;
3283 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3285 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3286 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3288 free( p_stream->fmt.psz_description );
3289 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3291 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3293 bool b_foo;
3294 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo );
3299 /* Return true if there's a skeleton exact match */
3300 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, vlc_tick_t i_time,
3301 int64_t *pi_lower, int64_t *pi_upper )
3303 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index ||
3304 i_time == VLC_TICK_INVALID )
3305 return false;
3307 i_time -= VLC_TICK_0;
3309 /* Validate range */
3310 if ( i_time < p_stream->p_skel->i_indexfirstnum
3311 * p_stream->p_skel->i_indexstampden ||
3312 i_time > p_stream->p_skel->i_indexlastnum
3313 * p_stream->p_skel->i_indexstampden ) return false;
3315 /* Then Lookup its index */
3316 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3317 struct
3319 int64_t i_pos;
3320 vlc_tick_t i_time;
3321 } current = { 0, 0 }, prev = { -1, -1 };
3323 uint64_t i_keypoints_found = 0;
3325 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3326 && i_keypoints_found < p_stream->p_skel->i_index )
3328 uint64_t i_val;
3329 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3330 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3331 current.i_pos += i_val;
3332 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3333 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3334 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3335 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3337 i_keypoints_found++;
3339 if ( i_time <= current.i_time )
3341 *pi_lower = prev.i_pos;
3342 *pi_upper = current.i_pos;
3343 return ( i_time == current.i_time );
3345 prev = current;
3347 return false;
3350 static uint32_t dirac_uint( bs_t *p_bs )
3352 uint32_t u_count = 0, u_value = 0;
3354 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3356 u_count++;
3357 u_value <<= 1;
3358 u_value |= bs_read( p_bs, 1 );
3361 return (1<<u_count) - 1 + u_value;
3364 static int dirac_bool( bs_t *p_bs )
3366 return bs_read( p_bs, 1 );
3369 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3370 ogg_packet *p_oggpacket )
3372 p_stream->special.dirac.b_old = (p_oggpacket->packet[0] == 'K');
3374 static const struct {
3375 uint32_t u_n /* numerator */, u_d /* denominator */;
3376 } p_dirac_frate_tbl[] = { /* table 10.3 */
3377 {1,1}, /* this first value is never used */
3378 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3379 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3381 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3383 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3384 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3386 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3388 bs_t bs;
3390 /* Backing up stream headers is not required -- seqhdrs are repeated
3391 * thoughout the stream at suitable decoding start points */
3392 p_stream->b_force_backup = false;
3394 /* read in useful bits from sequence header */
3395 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3396 bs_skip( &bs, 13*8); /* parse_info_header */
3397 dirac_uint( &bs ); /* major_version */
3398 dirac_uint( &bs ); /* minor_version */
3399 dirac_uint( &bs ); /* profile */
3400 dirac_uint( &bs ); /* level */
3402 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3403 if( u_video_format >= u_dirac_vidfmt_frate )
3405 /* don't know how to parse this ogg dirac stream */
3406 return false;
3409 if( dirac_bool( &bs ) )
3411 dirac_uint( &bs ); /* frame_width */
3412 dirac_uint( &bs ); /* frame_height */
3415 if( dirac_bool( &bs ) )
3417 dirac_uint( &bs ); /* chroma_format */
3420 if( dirac_bool( &bs ) )
3422 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3424 else
3425 p_stream->special.dirac.b_interlaced = false;
3427 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3428 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3429 u_d = __MAX( u_d, 1 );
3430 if( dirac_bool( &bs ) )
3432 uint32_t u_frame_rate_index = dirac_uint( &bs );
3433 if( u_frame_rate_index >= u_dirac_frate_tbl )
3435 /* something is wrong with this stream */
3436 return false;
3438 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3439 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3440 if( u_frame_rate_index == 0 )
3442 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3443 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3447 if( !u_n || !u_d )
3448 return false;
3451 * NB, OggDirac granulepos values are in units of 2*picturerate
3452 * When picture_coding_mode = 0 (progressive),
3453 * pt increments by two for each picture in display order.
3454 * When picture_coding_mode = 1 (interlace),
3455 * pt increments by one for each field in display order. */
3456 date_Init( &p_stream->dts, 2 * u_n, u_d );
3458 return true;
3461 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3462 ogg_packet *p_oggpacket )
3464 uint64_t i_granulerate_numerator;
3465 uint64_t i_granulerate_denominator;
3466 int i_major;
3467 int i_minor;
3469 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3471 /* Signal that we want to keep a backup of the OggSpots
3472 * stream headers. They will be used when switching between
3473 * audio streams. */
3474 p_stream->b_force_backup = true;
3476 /* Cheat and get additionnal info ;) */
3477 if ( p_oggpacket->bytes != 52 )
3479 /* The OggSpots header is always 52 bytes */
3480 return false;
3483 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3484 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3485 if ( i_major != 0 || i_minor != 1 )
3487 return false;
3490 /* Granule rate */
3491 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3492 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3493 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3495 return false;
3498 /* The OggSpots spec contained an error and there are implementations out
3499 * there that used the wrong value. So we detect that case and switch
3500 * numerator and denominator in that case */
3501 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3503 i_granulerate_numerator = 30;
3504 i_granulerate_denominator = 1;
3507 if ( !i_granulerate_numerator || !i_granulerate_denominator )
3508 return false;
3510 /* Normalize granulerate */
3511 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3512 &p_stream->fmt.video.i_frame_rate_base,
3513 i_granulerate_numerator, i_granulerate_denominator, 0);
3515 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
3516 p_stream->fmt.video.i_frame_rate_base );
3518 p_stream->i_granule_shift = p_oggpacket->packet[28];
3520 return true;