demux: libavi: force chunk type check
[vlc.git] / modules / demux / ogg.c
blobb9844a2c195a3a7d27c7eab685affb79922b56eb
1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_demux.h>
36 #include <vlc_meta.h>
37 #include <vlc_input.h>
39 #include <ogg/ogg.h>
41 #include <vlc_codecs.h>
42 #include <vlc_bits.h>
43 #include "xiph.h"
44 #include "xiph_metadata.h"
45 #include "ogg.h"
46 #include "oggseek.h"
47 #include "opus.h"
49 /*****************************************************************************
50 * Module descriptor
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close( vlc_object_t * );
55 vlc_module_begin ()
56 set_shortname ( "OGG" )
57 set_description( N_("OGG demuxer" ) )
58 set_category( CAT_INPUT )
59 set_subcategory( SUBCAT_INPUT_DEMUX )
60 set_capability( "demux", 50 )
61 set_callbacks( Open, Close )
62 add_shortcut( "ogg" )
63 vlc_module_end ()
66 /*****************************************************************************
67 * Definitions of structures and functions used by this plugins
68 *****************************************************************************/
70 /* OggDS headers for the new header format (used in ogm files) */
71 typedef struct
73 ogg_int32_t width;
74 ogg_int32_t height;
75 } stream_header_video_t;
77 typedef struct
79 ogg_int16_t channels;
80 ogg_int16_t padding;
81 ogg_int16_t blockalign;
82 ogg_int32_t avgbytespersec;
83 } stream_header_audio_t;
85 typedef struct
87 char streamtype[8];
88 char subtype[4];
90 ogg_int32_t size; /* size of the structure */
92 ogg_int64_t time_unit; /* in reference time */
93 ogg_int64_t samples_per_unit;
94 ogg_int32_t default_len; /* in media time */
96 ogg_int32_t buffersize;
97 ogg_int16_t bits_per_sample;
98 ogg_int16_t padding;
100 union
102 /* Video specific */
103 stream_header_video_t video;
104 /* Audio specific */
105 stream_header_audio_t audio;
106 } sh;
107 } stream_header_t;
109 #define VORBIS_HEADER_IDENTIFICATION 1
110 #define VORBIS_HEADER_COMMENT 2
111 #define VORBIS_HEADER_SETUP 3
112 #define VORBIS_HEADER_TO_FLAG(i) (1 << (i - 1))
113 #define VORBIS_HEADERS_VALID(p_stream) \
114 ((p_stream->special.vorbis.i_headers_flags & 0x07) == 0x07) // 0b111
116 /*****************************************************************************
117 * Local prototypes
118 *****************************************************************************/
119 static int Demux ( demux_t * );
120 static int Control( demux_t *, int, va_list );
122 /* Bitstream manipulation */
123 static int Ogg_ReadPage ( demux_t *, ogg_page * );
124 static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * );
125 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
126 static unsigned Ogg_OpusPacketDuration( ogg_packet * );
127 static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * );
129 static void Ogg_CreateES( demux_t *p_demux );
130 static int Ogg_BeginningOfStream( demux_t *p_demux );
131 static int Ogg_FindLogicalStreams( demux_t *p_demux );
132 static void Ogg_EndOfStream( demux_t *p_demux );
134 /* */
135 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
136 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
137 static void Ogg_ResetStream( logical_stream_t *p_stream );
139 /* */
140 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
142 /* Logical bitstream headers */
143 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
144 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
145 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
146 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
147 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
148 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
149 static bool Ogg_ReadFlacStreamInfo( demux_t *, logical_stream_t *, ogg_packet * );
150 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
151 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
152 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
153 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
154 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *, ogg_packet * );
156 /* Skeleton */
157 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
158 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
159 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
160 static void Ogg_ApplySkeleton( logical_stream_t * );
162 /* Special decoding */
163 static void Ogg_CleanSpecificData( logical_stream_t * );
164 #ifdef HAVE_LIBVORBIS
165 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
166 #endif
168 static void fill_channels_info(audio_format_t *audio)
170 static const int pi_channels_map[9] =
173 AOUT_CHAN_CENTER,
174 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
175 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
176 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
177 | AOUT_CHAN_REARRIGHT,
178 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
179 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
180 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
181 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
182 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
183 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
184 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
185 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
186 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
187 | AOUT_CHAN_LFE,
190 unsigned chans = audio->i_channels;
191 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
192 audio->i_physical_channels = pi_channels_map[chans];
195 /* Special TS value: don't send or derive any pts/pcr from it.
196 Represents TS state prior first known valid timestamp */
197 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
199 /*****************************************************************************
200 * Open: initializes ogg demux structures
201 *****************************************************************************/
202 static int Open( vlc_object_t * p_this )
204 demux_t *p_demux = (demux_t *)p_this;
205 demux_sys_t *p_sys;
206 const uint8_t *p_peek;
208 /* Check if we are dealing with an ogg stream */
209 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
210 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
212 char *psz_mime = stream_ContentType( p_demux->s );
213 if( !psz_mime )
215 return VLC_EGENERIC;
217 else if ( strcmp( psz_mime, "application/ogg" ) &&
218 strcmp( psz_mime, "video/ogg" ) &&
219 strcmp( psz_mime, "audio/ogg" ) )
221 free( psz_mime );
222 return VLC_EGENERIC;
224 free( psz_mime );
227 /* */
228 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
229 if( !p_sys )
230 return VLC_ENOMEM;
232 p_sys->i_length = -1;
233 p_sys->b_preparsing_done = false;
235 vlc_stream_Control( p_demux->s, STREAM_GET_PTS_DELAY,
236 &p_sys->i_access_delay );
238 /* Set exported functions */
239 p_demux->pf_demux = Demux;
240 p_demux->pf_control = Control;
242 /* Initialize the Ogg physical bitstream parser */
243 ogg_sync_init( &p_sys->oy );
245 /* */
246 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
249 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
251 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
252 Ogg_CreateES( p_demux );
254 return VLC_SUCCESS;
257 /*****************************************************************************
258 * Close: frees unused data
259 *****************************************************************************/
260 static void Close( vlc_object_t *p_this )
262 demux_t *p_demux = (demux_t *)p_this;
263 demux_sys_t *p_sys = p_demux->p_sys ;
265 /* Cleanup the bitstream parser */
266 ogg_sync_clear( &p_sys->oy );
268 Ogg_EndOfStream( p_demux );
270 if( p_sys->p_old_stream )
271 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
273 free( p_sys );
276 /*****************************************************************************
277 * Demux: reads and demuxes data packets
278 *****************************************************************************
279 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
280 *****************************************************************************/
281 static int Demux( demux_t * p_demux )
283 demux_sys_t *p_sys = p_demux->p_sys;
284 ogg_packet oggpacket;
285 int i_stream;
286 bool b_skipping = false;
287 bool b_canseek;
289 int i_active_streams = p_sys->i_streams;
290 for ( int i=0; i < p_sys->i_streams; i++ )
292 if ( p_sys->pp_stream[i]->b_finished )
293 i_active_streams--;
296 if ( i_active_streams == 0 )
298 if ( p_sys->i_streams ) /* All finished */
300 msg_Dbg( p_demux, "end of a group of logical streams" );
302 mtime_t i_lastpcr = VLC_TS_INVALID;
303 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
305 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
306 if( p_stream->i_pcr > i_lastpcr )
307 i_lastpcr = p_stream->i_pcr;
310 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
311 * only 1 ES is supported (common case for ogg web radio) */
312 if( p_sys->i_streams == 1 )
314 p_sys->p_old_stream = p_sys->pp_stream[0];
315 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
318 Ogg_EndOfStream( p_demux );
319 p_sys->b_chained_boundary = true;
321 if( i_lastpcr > VLC_TS_INVALID )
323 p_sys->i_nzpcr_offset = i_lastpcr - VLC_TS_0;
324 if( likely( !p_sys->b_slave ) )
325 es_out_SetPCR( p_demux->out, i_lastpcr );
327 p_sys->i_pcr = VLC_TS_INVALID;
330 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
331 return VLC_DEMUXER_EOF;
333 msg_Dbg( p_demux, "beginning of a group of logical streams" );
335 if ( !p_sys->b_chained_boundary )
337 /* Find the real duration */
338 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
339 if ( b_canseek )
340 Oggseek_ProbeEnd( p_demux );
342 else
344 p_sys->b_chained_boundary = false;
348 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
349 Ogg_CreateES( p_demux );
352 * The first data page of a physical stream is stored in the relevant logical stream
353 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
354 * stream it belongs to if we haven't processed this first page yet. If we do, we
355 * will only process that first page whenever we find the second page for this stream.
356 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
357 * the second page will arrive real quick, this is not fine for Kate, whose second
358 * data page will typically arrive much later.
359 * This means it is now possible to seek right at the start of a stream where the last
360 * logical stream is Kate, without having to wait for the second data page to unblock
361 * the first one, which is the one that triggers the 'no more headers to backup' code.
362 * And, as we all know, seeking without having backed up all headers is bad, since the
363 * codec will fail to initialize if it's missing its headers.
365 if( !p_sys->b_page_waiting)
368 * Demux an ogg page from the stream
370 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
371 return VLC_DEMUXER_EOF; /* EOF */
372 /* Test for End of Stream */
373 if( ogg_page_eos( &p_sys->current_page ) )
375 /* If we delayed restarting encoders/SET_ES_FMT for more
376 * skeleton provided configuration */
377 if ( p_sys->p_skelstream )
379 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
381 msg_Dbg( p_demux, "End of Skeleton" );
382 p_sys->b_preparsing_done = true;
383 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
385 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
386 Ogg_ApplySkeleton( p_stream );
391 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
393 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
395 p_sys->pp_stream[i_stream]->b_finished = true;
396 break;
402 b_skipping = false;
403 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
405 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
408 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
410 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
412 /* if we've just pulled page, look for the right logical stream */
413 if( !p_sys->b_page_waiting )
415 if( p_sys->i_streams == 1 &&
416 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
418 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
419 Ogg_ResetStream( p_stream );
420 if( p_stream->i_pcr > VLC_TS_INVALID )
421 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TS_0;
422 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
425 /* Does fail if serialno differs */
426 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
428 continue;
432 /* clear the finished flag if pages after eos (ex: after a seek) */
433 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
434 p_stream->b_finished = false;
436 DemuxDebug(
437 if ( p_stream->fmt.i_cat == VIDEO_ES )
438 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
439 ogg_page_pageno( &p_sys->current_page ),
440 ogg_page_granulepos( &p_sys->current_page ),
441 ogg_page_packets( &p_sys->current_page ),
442 ogg_page_continued(&p_sys->current_page),
443 p_sys->current_page.body_len )
446 const int i_page_packets = ogg_page_packets( &p_sys->current_page );
447 bool b_doprepcr = false;
449 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
451 // PASS 0
452 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
453 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
454 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
455 p_stream->fmt.i_cat == VIDEO_ES )
457 assert( p_stream->prepcr.pp_blocks == NULL );
458 b_doprepcr = true;
462 int i_real_page_packets = 0;
463 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
465 i_real_page_packets++;
466 int i_max_packets = __MAX(i_page_packets, i_real_page_packets);
467 if ( b_doprepcr && p_stream->prepcr.i_size < i_max_packets )
469 /* always double alloc for performance */
470 i_max_packets = __MAX( i_max_packets << 1, 255 );
471 /* alloc or realloc */
472 block_t **pp_realloc = realloc( p_stream->prepcr.pp_blocks,
473 sizeof(block_t *) * i_max_packets );
474 if ( !pp_realloc )
476 /* drop it then */
477 continue;
479 p_stream->prepcr.i_size = i_max_packets;
480 p_stream->prepcr.pp_blocks = pp_realloc;
483 /* Read info from any secondary header packets, if there are any */
484 if( p_stream->i_secondary_header_packets > 0 )
486 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
487 oggpacket.bytes >= 7 &&
488 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
490 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
491 p_stream->i_secondary_header_packets = 0;
493 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
494 oggpacket.bytes >= 6 &&
495 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
497 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
498 p_stream->i_secondary_header_packets = 0;
500 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
501 oggpacket.bytes >= 7 &&
502 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
504 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
505 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
506 p_stream->i_secondary_header_packets = 0;
508 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
510 p_stream->i_secondary_header_packets = 0;
513 /* update start of data pointer */
514 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
517 /* If any streams have i_skip_frames, only decode (pre-roll)
518 * for those streams, but don't skip headers */
519 if ( b_skipping && p_stream->i_skip_frames == 0
520 && p_stream->i_secondary_header_packets ) continue;
522 if( p_stream->b_reinit )
524 p_stream->b_reinit = false;
525 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
527 p_stream->i_skip_frames = p_stream->i_pre_skip;
531 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
534 if ( p_stream->prepcr.pp_blocks )
536 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
537 p_stream->i_previous_pcr = pagestamp;
538 #ifdef HAVE_LIBVORBIS
539 int i_prev_blocksize = 0;
540 #endif
541 // PASS 1
542 for( int i=0; i<p_stream->prepcr.i_used; i++ )
544 block_t *p_block = p_stream->prepcr.pp_blocks[i];
545 ogg_packet dumb_packet;
546 dumb_packet.bytes = p_block->i_buffer;
547 dumb_packet.packet = p_block->p_buffer;
549 switch( p_stream->fmt.i_codec )
551 case VLC_CODEC_SPEEX:
552 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
553 p_stream->special.speex.i_framesperpacket;
554 break;
555 case VLC_CODEC_OPUS:
556 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
557 break;
558 #ifdef HAVE_LIBVORBIS
559 case VLC_CODEC_VORBIS:
561 if( !VORBIS_HEADERS_VALID(p_stream) )
563 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
564 break;
566 long i_blocksize = vorbis_packet_blocksize(
567 p_stream->special.vorbis.p_info, &dumb_packet );
568 if ( i_prev_blocksize )
569 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
570 else
571 p_block->i_nb_samples = i_blocksize / 2;
572 i_prev_blocksize = i_blocksize;
574 #endif
578 // PASS 2
579 bool b_fixed = false;
580 for( int i=p_stream->prepcr.i_used - 1; i>=0; i-- )
582 block_t *p_block = p_stream->prepcr.pp_blocks[i];
583 switch( p_stream->fmt.i_codec )
585 case VLC_CODEC_SPEEX:
586 case VLC_CODEC_OPUS:
587 case VLC_CODEC_VORBIS:
588 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
589 if ( pagestamp < 0 )
591 p_block->i_pts = VLC_TS_INVALID;
592 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
593 p_block->i_flags |= BLOCK_FLAG_PREROLL;
595 else
596 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
597 b_fixed = true;
598 break;
599 default:
600 if ( p_stream->fmt.i_cat == VIDEO_ES )
602 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
603 if( pagestamp < 0 )
604 pagestamp = 0;
605 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
606 b_fixed = true;
611 if ( b_fixed )
613 pagestamp = p_stream->i_previous_pcr; /* as set above */
614 if ( pagestamp < 0 ) pagestamp = 0;
615 p_stream->i_pcr = VLC_TS_0 + pagestamp;
616 p_stream->i_pcr += p_sys->i_nzpcr_offset;
617 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
620 FREENULL(p_stream->prepcr.pp_blocks);
621 p_stream->prepcr.i_used = 0;
623 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
627 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
628 ogg_page_granulepos( &p_sys->current_page ), false );
629 if ( i_pagestamp > -1 )
631 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
632 p_stream->i_pcr += p_sys->i_nzpcr_offset;
635 if( !p_sys->b_page_waiting )
636 break;
639 /* if a page was waiting, it's now processed */
640 p_sys->b_page_waiting = false;
642 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
643 p_sys->b_preparsing_done = false;
644 else
645 p_sys->b_preparsing_done = true;
647 /* We will consider the lowest PCR among tracks, because the audio core badly
648 * handles PCR rewind (mute)
650 mtime_t i_pcr_candidate = VLC_TS_INVALID;
651 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
653 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
655 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
657 /* We have 1 or more streams needing more than 1 page for preparsing */
658 p_sys->b_preparsing_done = false;
661 if( p_stream->fmt.i_cat == SPU_ES )
662 continue;
663 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
664 continue;
665 if( p_stream->i_pcr < VLC_TS_0 )
666 continue;
667 if ( p_stream->b_finished || p_stream->b_initializing )
668 continue;
669 if ( p_stream->p_preparse_block )
670 continue;
671 if( i_pcr_candidate < VLC_TS_0
672 || p_stream->i_pcr <= i_pcr_candidate )
674 i_pcr_candidate = p_stream->i_pcr;
678 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
680 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
682 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
683 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
685 p_sys->i_pcr_jitter = i_pcr_jitter;
686 if ( p_sys->i_access_delay < i_pcr_jitter )
687 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
688 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
692 if( ! b_skipping && p_sys->b_preparsing_done )
694 p_sys->i_pcr = i_pcr_candidate;
695 if( likely( !p_sys->b_slave ) )
696 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
700 return VLC_DEMUXER_SUCCESS;
703 static void Ogg_ResetStream( logical_stream_t *p_stream )
705 #ifdef HAVE_LIBVORBIS
706 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
708 p_stream->special.vorbis.i_prev_blocksize = 0;
710 #endif
711 /* we'll trash all the data until we find the next pcr */
712 p_stream->b_reinit = true;
713 p_stream->i_pcr = VLC_TS_UNKNOWN;
714 p_stream->i_previous_granulepos = -1;
715 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
716 ogg_stream_reset( &p_stream->os );
717 FREENULL( p_stream->prepcr.pp_blocks );
718 p_stream->prepcr.i_size = 0;
719 p_stream->prepcr.i_used = 0;
722 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
724 for( int i = 0; i < p_sys->i_streams; i++ )
725 Ogg_ResetStream( p_sys->pp_stream[i] );
727 ogg_sync_reset( &p_sys->oy );
728 p_sys->i_pcr = VLC_TS_UNKNOWN;
731 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
733 demux_sys_t *p_sys = p_demux->p_sys;
734 logical_stream_t *p_stream = NULL;
735 for( int i=0; i<p_sys->i_streams; i++ )
737 logical_stream_t *p_candidate = p_sys->pp_stream[i];
738 if ( !p_candidate->p_es ) continue;
740 bool b_selected = false;
741 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
742 p_candidate->p_es, &b_selected );
743 if ( !b_selected ) continue;
745 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
747 p_stream = p_candidate;
748 continue; /* Try to find video anyway */
751 if ( p_candidate->fmt.i_cat == VIDEO_ES )
753 p_stream = p_candidate;
754 break;
757 return p_stream;
760 /*****************************************************************************
761 * Control:
762 *****************************************************************************/
763 static int Control( demux_t *p_demux, int i_query, va_list args )
765 demux_sys_t *p_sys = p_demux->p_sys;
766 vlc_meta_t *p_meta;
767 int64_t *pi64, i64;
768 double *pf, f;
769 bool *pb_bool, b, acc;
771 switch( i_query )
773 case DEMUX_CAN_SEEK:
774 return vlc_stream_vaControl( p_demux->s, i_query, args );
776 case DEMUX_GET_META:
777 p_meta = va_arg( args, vlc_meta_t * );
778 if( p_sys->p_meta )
779 vlc_meta_Merge( p_meta, p_sys->p_meta );
780 return VLC_SUCCESS;
782 case DEMUX_HAS_UNSUPPORTED_META:
783 pb_bool = va_arg( args, bool* );
784 *pb_bool = true;
785 return VLC_SUCCESS;
787 case DEMUX_SET_NEXT_DEMUX_TIME:
788 p_sys->b_slave = true;
789 return VLC_EGENERIC;
791 case DEMUX_GET_TIME:
792 if( p_sys->i_pcr > VLC_TS_INVALID || p_sys->b_slave )
794 pi64 = va_arg( args, int64_t * );
795 *pi64 = p_sys->i_pcr;
796 return VLC_SUCCESS;
798 return VLC_EGENERIC;
800 case DEMUX_SET_TIME:
801 i64 = va_arg( args, int64_t );
802 acc = va_arg( args, int );
803 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
804 if ( !p_stream )
806 msg_Err( p_demux, "No selected seekable stream found" );
807 return VLC_EGENERIC;
809 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
810 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
812 Ogg_ResetStreamsHelper( p_sys );
813 if( acc )
814 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
815 VLC_TS_0 + i64 );
816 return VLC_SUCCESS;
818 else
819 return VLC_EGENERIC;
821 case DEMUX_GET_ATTACHMENTS:
823 input_attachment_t ***ppp_attach =
824 va_arg( args, input_attachment_t *** );
825 int *pi_int = va_arg( args, int * );
827 if( p_sys->i_attachments <= 0 )
828 return VLC_EGENERIC;
830 *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
831 if (!**ppp_attach)
832 return VLC_ENOMEM;
833 *pi_int = p_sys->i_attachments;
834 for( int i = 0; i < p_sys->i_attachments; i++ )
835 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
836 return VLC_SUCCESS;
839 case DEMUX_GET_POSITION:
840 pf = va_arg( args, double * );
841 if( p_sys->i_length > 0 && p_sys->i_pcr > VLC_TS_INVALID )
843 *pf = (double) p_sys->i_pcr /
844 (double) ( p_sys->i_length * (mtime_t)1000000 );
846 else if( stream_Size( p_demux->s ) > 0 )
848 i64 = vlc_stream_Tell( p_demux->s );
849 *pf = (double) i64 / stream_Size( p_demux->s );
851 else *pf = 0.0;
852 return VLC_SUCCESS;
854 case DEMUX_SET_POSITION:
855 /* forbid seeking if we haven't initialized all logical bitstreams yet;
856 if we allowed, some headers would not get backed up and decoder init
857 would fail, making that logical stream unusable */
858 for ( int i=0; i< p_sys->i_streams; i++ )
860 if ( p_sys->pp_stream[i]->b_initializing )
861 return VLC_EGENERIC;
864 p_stream = Ogg_GetSelectedStream( p_demux );
865 if ( !p_stream )
867 msg_Err( p_demux, "No selected seekable stream found" );
868 return VLC_EGENERIC;
871 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
873 f = va_arg( args, double );
874 acc = va_arg( args, int );
875 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
877 Ogg_ResetStreamsHelper( p_sys );
878 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
879 return VLC_SUCCESS;
882 assert( p_sys->i_length > 0 );
883 i64 = CLOCK_FREQ * p_sys->i_length * f;
884 Ogg_ResetStreamsHelper( p_sys );
885 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
887 if( acc )
888 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
889 VLC_TS_0 + i64 );
890 return VLC_SUCCESS;
893 return VLC_EGENERIC;
895 case DEMUX_GET_LENGTH:
896 if ( p_sys->i_length < 0 )
897 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
898 1, i_query, args );
899 pi64 = va_arg( args, int64_t * );
900 *pi64 = p_sys->i_length * 1000000;
901 return VLC_SUCCESS;
903 case DEMUX_GET_TITLE_INFO:
905 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
906 int *pi_int = va_arg( args, int* );
907 int *pi_title_offset = va_arg( args, int* );
908 int *pi_seekpoint_offset = va_arg( args, int* );
910 if( p_sys->i_seekpoints > 0 )
912 *pi_int = 1;
913 *ppp_title = malloc( sizeof( input_title_t* ) );
914 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
915 for( int i = 0; i < p_sys->i_seekpoints; i++ )
917 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
918 if ( likely( p_seekpoint_copy ) )
919 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
921 *pi_title_offset = 0;
922 *pi_seekpoint_offset = 0;
924 return VLC_SUCCESS;
926 case DEMUX_SET_TITLE:
928 const int i_title = va_arg( args, int );
929 if( i_title > 1 )
930 return VLC_EGENERIC;
931 return VLC_SUCCESS;
933 case DEMUX_SET_SEEKPOINT:
935 const int i_seekpoint = va_arg( args, int );
936 if( i_seekpoint > p_sys->i_seekpoints )
937 return VLC_EGENERIC;
939 for ( int i=0; i< p_sys->i_streams; i++ )
941 if ( p_sys->pp_stream[i]->b_initializing )
942 return VLC_EGENERIC;
945 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
947 p_stream = Ogg_GetSelectedStream( p_demux );
948 if ( !p_stream )
950 msg_Err( p_demux, "No selected seekable stream found" );
951 return VLC_EGENERIC;
954 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
955 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
957 Ogg_ResetStreamsHelper( p_sys );
958 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
959 VLC_TS_0 + i64 );
960 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
961 p_demux->info.i_seekpoint = i_seekpoint;
962 return VLC_SUCCESS;
964 else
965 return VLC_EGENERIC;
968 default:
969 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
970 1, i_query, args );
974 /****************************************************************************
975 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
976 ****************************************************************************
977 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
978 * are at the end of stream.
979 ****************************************************************************/
980 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
982 demux_sys_t *p_ogg = p_demux->p_sys ;
983 int i_read = 0;
984 char *p_buffer;
986 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
988 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
990 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
991 if( i_read <= 0 )
992 return VLC_EGENERIC;
994 ogg_sync_wrote( &p_ogg->oy, i_read );
997 return VLC_SUCCESS;
1000 /****************************************************************************
1001 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
1002 * current stream.
1003 ****************************************************************************/
1004 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
1005 ogg_packet *p_oggpacket )
1007 demux_sys_t *p_ogg = p_demux->p_sys;
1008 p_stream->i_end_trim = 0;
1010 /* Convert the granulepos into a pcr */
1011 if ( p_oggpacket->granulepos == 0 )
1013 /* We're in headers, and we haven't parsed 1st data packet yet */
1014 // p_stream->i_pcr = VLC_TS_UNKNOWN;
1016 else if( p_oggpacket->granulepos > 0 )
1018 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
1019 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
1020 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
1021 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1022 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
1023 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1024 p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
1025 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
1027 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1028 p_oggpacket->granulepos, true );
1029 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1031 else if ( p_stream->i_previous_granulepos > 0 )
1033 ogg_int64_t sample = p_stream->i_previous_granulepos;
1035 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
1037 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
1038 if( duration > 0 )
1040 ogg_int64_t end_sample = p_oggpacket->granulepos;
1041 if( end_sample < ( sample + duration ) )
1042 p_stream->i_end_trim = sample + duration - end_sample;
1046 if (sample >= p_stream->i_pre_skip)
1047 sample -= p_stream->i_pre_skip;
1048 else
1049 sample = 0;
1051 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1052 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1056 else if ( p_oggpacket->granulepos == -1 )
1058 unsigned i_duration;
1059 /* no granulepos available, try to interpolate the pcr.
1060 * If we can't then don't touch the old value. */
1061 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
1063 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1065 #ifdef HAVE_LIBVORBIS
1066 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1067 p_stream->special.vorbis.p_info &&
1068 VORBIS_HEADERS_VALID(p_stream) &&
1069 p_stream->i_previous_granulepos > 0 )
1071 long i_blocksize = vorbis_packet_blocksize(
1072 p_stream->special.vorbis.p_info, p_oggpacket );
1073 if ( p_stream->special.vorbis.i_prev_blocksize )
1074 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1075 else
1076 i_duration = i_blocksize / 2;
1077 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1078 /* duration in samples per channel */
1079 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1080 p_stream->i_pcr = p_stream->i_previous_granulepos *
1081 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1082 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1084 #endif
1085 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1086 p_stream->i_previous_granulepos > 0 )
1088 i_duration = p_stream->special.speex.i_framesize *
1089 p_stream->special.speex.i_framesperpacket;
1090 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1091 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1092 p_stream->i_previous_granulepos, false );
1093 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1095 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1096 p_stream->i_previous_granulepos > 0 &&
1097 ( i_duration =
1098 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1100 ogg_int64_t sample;
1101 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1102 sample = p_stream->i_previous_granulepos;
1103 if (sample >= p_stream->i_pre_skip)
1104 sample -= p_stream->i_pre_skip;
1105 else
1106 sample = 0;
1108 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1109 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1111 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1113 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1114 p_stream->fmt.i_bitrate / 8 );
1118 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1121 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1122 block_t *p_block )
1124 demux_sys_t *p_ogg = p_demux->p_sys;
1125 if ( (!p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN) &&
1126 p_ogg->i_nzpcr_offset == 0 /* Not on chained streams */ )
1128 if ( !p_block ) return;
1129 if ( p_stream->prepcr.pp_blocks )
1131 assert( p_stream->prepcr.i_size );
1132 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1134 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1135 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1136 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1138 else
1140 /* Because ES creation is delayed for preparsing */
1141 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1142 if ( p_stream->p_preparse_block )
1144 block_t *temp = p_stream->p_preparse_block;
1145 while ( temp )
1147 if ( temp && i_firstpts < VLC_TS_0 )
1148 i_firstpts = temp->i_pts;
1150 block_t *tosend = temp;
1151 temp = temp->p_next;
1152 tosend->p_next = NULL;
1154 if( tosend->i_pts < VLC_TS_0 )
1156 /* Don't send metadata from chained streams */
1157 block_Release( tosend );
1158 continue;
1160 else if( tosend->i_dts < VLC_TS_0 )
1162 tosend->i_dts = tosend->i_pts;
1165 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1166 tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1167 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1169 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1171 p_ogg->i_pcr = i_firstpts;
1172 if( likely( !p_ogg->b_slave ) )
1173 es_out_SetPCR( p_demux->out, p_ogg->i_pcr );
1176 p_stream->p_preparse_block = NULL;
1179 if ( p_block )
1181 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1182 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1183 if ( p_stream->p_es )
1184 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1185 else
1186 block_Release( p_block );
1191 /****************************************************************************
1192 * Ogg_DecodePacket: Decode an Ogg packet.
1193 ****************************************************************************/
1194 static void Ogg_DecodePacket( demux_t *p_demux,
1195 logical_stream_t *p_stream,
1196 ogg_packet *p_oggpacket )
1198 block_t *p_block;
1199 bool b_selected;
1200 int i_header_len = 0;
1202 if( p_oggpacket->bytes >= 7 &&
1203 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1205 /* it's an Annodex packet -- skip it (do nothing) */
1206 return;
1208 else if( p_oggpacket->bytes >= 7 &&
1209 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1211 /* it's an AnxData packet -- skip it (do nothing) */
1212 return;
1214 else if( p_oggpacket->bytes >= 8 &&
1215 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1217 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1218 return;
1220 else if( p_oggpacket->bytes >= 6 &&
1221 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1223 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1224 return;
1226 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1227 p_oggpacket->bytes >= 7 &&
1228 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1230 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1231 return;
1234 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1235 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1237 /* Check the ES is selected */
1238 if ( !p_stream->p_es )
1239 b_selected = true;
1240 else
1241 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1242 p_stream->p_es, &b_selected );
1244 if( p_stream->b_force_backup )
1246 bool b_xiph;
1247 p_stream->i_packets_backup++;
1248 switch( p_stream->fmt.i_codec )
1250 case VLC_CODEC_VORBIS:
1251 #ifdef HAVE_LIBVORBIS
1252 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1253 #endif
1254 /* fallthrough */
1255 case VLC_CODEC_THEORA:
1256 if( p_stream->i_packets_backup == 3 )
1257 p_stream->b_force_backup = false;
1258 b_xiph = true;
1259 break;
1261 case VLC_CODEC_DAALA:
1262 if( p_stream->i_packets_backup == 3 )
1263 p_stream->b_force_backup = false;
1264 b_xiph = true;
1265 break;
1267 case VLC_CODEC_SPEEX:
1268 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1269 p_stream->b_force_backup = false;
1270 b_xiph = true;
1271 break;
1273 case VLC_CODEC_OPUS:
1274 if( p_stream->i_packets_backup == 2 )
1275 p_stream->b_force_backup = false;
1276 b_xiph = true;
1277 break;
1279 case VLC_CODEC_FLAC:
1280 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1282 p_stream->b_force_backup = false;
1284 if( p_stream->special.flac.b_old )
1286 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1288 else if( p_stream->i_packets_backup == 1 )
1290 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1292 p_oggpacket->packet += 9;
1293 p_oggpacket->bytes -= 9;
1296 b_xiph = false;
1297 break;
1299 case VLC_CODEC_KATE:
1300 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1301 p_stream->b_force_backup = false;
1302 b_xiph = true;
1303 break;
1305 default:
1306 p_stream->b_force_backup = false;
1307 b_xiph = false;
1308 break;
1311 /* Backup the ogg packet (likely an header packet) */
1312 if( !b_xiph )
1314 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1315 if( p_realloc )
1317 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1318 p_stream->i_headers += p_oggpacket->bytes;
1319 p_stream->p_headers = p_realloc;
1321 else
1323 free( p_stream->p_headers );
1324 p_stream->i_headers = 0;
1325 p_stream->p_headers = NULL;
1328 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1329 p_oggpacket->bytes, p_oggpacket->packet ) )
1331 p_stream->i_headers = 0;
1332 p_stream->p_headers = NULL;
1334 if( p_stream->i_headers > 0 )
1336 if( !p_stream->b_force_backup )
1338 /* Last header received, commit changes */
1339 free( p_stream->fmt.p_extra );
1341 p_stream->fmt.i_extra = p_stream->i_headers;
1342 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1343 if( p_stream->fmt.p_extra )
1344 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1345 p_stream->i_headers );
1346 else
1347 p_stream->fmt.i_extra = 0;
1349 if( p_stream->i_headers > 0 )
1350 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1351 p_stream->p_headers, p_stream->i_headers );
1353 /* we're not at BOS anymore for this logical stream */
1354 p_stream->b_initializing = false;
1358 b_selected = false; /* Discard the header packet */
1360 else
1362 p_stream->b_initializing = false;
1365 /* Convert the granulepos into the next pcr */
1366 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1368 if( !b_selected )
1370 /* This stream isn't currently selected so we don't need to decode it,
1371 * but we did need to store its pcr as it might be selected later on */
1372 return;
1375 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1376 p_block->i_pts = p_stream->i_pcr;
1378 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1379 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1381 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1382 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1384 /* may need to preroll after a seek or in case of preskip */
1385 if ( p_stream->i_skip_frames > 0 )
1387 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1389 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1391 if( p_demux->p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1392 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1393 p_stream->i_skip_frames -= p_block->i_nb_samples;
1394 p_block->i_nb_samples = 0;
1396 else
1398 p_block->i_nb_samples -= p_stream->i_skip_frames;
1399 p_stream->i_skip_frames = 0;
1402 else
1404 if( p_demux->p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1405 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1406 p_stream->i_skip_frames--;
1410 /* Conditional block fixes */
1411 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1412 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1414 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1416 else if( p_stream->fmt.i_cat == AUDIO_ES )
1418 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1419 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1420 p_stream->fmt.b_packetized )
1422 /* Handle OggFlac spec violation (multiple frame/packet
1423 * by turning on packetizer */
1424 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1425 p_stream->fmt.b_packetized = false;
1426 es_out_Del( p_demux->out, p_stream->p_es );
1427 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1430 /* Blatant abuse of the i_length field. */
1431 p_block->i_length = p_stream->i_end_trim;
1433 else if( p_stream->fmt.i_cat == SPU_ES )
1435 p_block->i_length = 0;
1437 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1439 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1440 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1441 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1442 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1443 /* granulepos for dirac is possibly broken, this value should be ignored */
1444 if( 0 >= p_oggpacket->granulepos )
1446 p_block->i_pts = VLC_TS_INVALID;
1447 p_block->i_dts = p_stream->i_pcr;
1451 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1452 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1453 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1454 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1455 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1456 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1457 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1458 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1459 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1460 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1461 p_stream->fmt.i_codec != VLC_CODEC_KATE &&
1462 p_stream->fmt.i_codec != VLC_CODEC_OGGSPOTS )
1464 if( p_oggpacket->bytes <= 0 )
1466 msg_Dbg( p_demux, "discarding 0 sized packet" );
1467 block_Release( p_block );
1468 return;
1470 /* We remove the header from the packet */
1471 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1472 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1474 if( i_header_len >= p_oggpacket->bytes )
1476 msg_Dbg( p_demux, "discarding invalid packet" );
1477 block_Release( p_block );
1478 return;
1481 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1483 /* But with subtitles we need to retrieve the duration first */
1484 int i, lenbytes = 0;
1486 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1488 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1490 lenbytes = lenbytes << 8;
1491 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1494 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1495 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1496 p_oggpacket->packet[i_header_len + 1] != 0 &&
1497 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1498 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1500 p_block->i_length = (mtime_t)lenbytes * 1000;
1504 i_header_len++;
1505 if( p_block->i_buffer >= (unsigned int)i_header_len )
1506 p_block->i_buffer -= i_header_len;
1507 else
1508 p_block->i_buffer = 0;
1512 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1514 /* FIXME: the biggest hack I've ever done */
1515 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1516 p_block->i_pts, p_block->i_dts );
1517 msleep(10000);
1520 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1521 p_oggpacket->bytes - i_header_len );
1523 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1526 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1528 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1531 /****************************************************************************
1532 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1533 * stream and fill p_ogg.
1534 *****************************************************************************
1535 * The initial page of a logical stream is marked as a 'bos' page.
1536 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1537 * together and all of the initial pages must appear before any data pages.
1539 * On success this function returns VLC_SUCCESS.
1540 ****************************************************************************/
1541 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1543 demux_sys_t *p_ogg = p_demux->p_sys ;
1544 ogg_packet oggpacket;
1546 p_ogg->i_total_length = stream_Size ( p_demux->s );
1547 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1550 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1553 if( ogg_page_bos( &p_ogg->current_page ) )
1556 /* All is wonderful in our fine fine little world.
1557 * We found the beginning of our first logical stream. */
1558 while( ogg_page_bos( &p_ogg->current_page ) )
1560 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1561 if( unlikely( !p_stream ) )
1562 return VLC_ENOMEM;
1564 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1566 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
1567 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
1568 p_stream->b_initializing = true;
1570 /* Setup the logical stream */
1571 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1572 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1574 /* Extract the initial header from the first page and verify
1575 * the codec type of this Ogg bitstream */
1576 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1578 /* error. stream version mismatch perhaps */
1579 msg_Err( p_demux, "error reading first page of "
1580 "Ogg bitstream data" );
1581 return VLC_EGENERIC;
1584 /* FIXME: check return value */
1585 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1587 /* Check for Vorbis header */
1588 if( oggpacket.bytes >= 7 &&
1589 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1591 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1592 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1593 msg_Dbg( p_demux, "found vorbis header" );
1594 else
1596 msg_Dbg( p_demux, "found invalid vorbis header" );
1597 Ogg_LogicalStreamDelete( p_demux, p_stream );
1598 p_stream = NULL;
1599 p_ogg->i_streams--;
1602 /* Check for Speex header */
1603 else if( oggpacket.bytes >= 5 &&
1604 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1606 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1607 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1608 msg_Dbg( p_demux, "found speex header, channels: %i, "
1609 "rate: %i, bitrate: %i, frames: %i group %i",
1610 p_stream->fmt.audio.i_channels,
1611 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1612 p_stream->special.speex.i_framesize,
1613 p_stream->special.speex.i_framesperpacket );
1614 else
1616 msg_Dbg( p_demux, "found invalid Speex header" );
1617 Ogg_LogicalStreamDelete( p_demux, p_stream );
1618 p_stream = NULL;
1619 p_ogg->i_streams--;
1622 /* Check for Opus header */
1623 else if( oggpacket.bytes >= 8 &&
1624 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1626 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1627 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1628 msg_Dbg( p_demux, "found opus header, channels: %i, "
1629 "pre-skip: %i",
1630 p_stream->fmt.audio.i_channels,
1631 (int)p_stream->i_pre_skip);
1632 p_stream->i_skip_frames = p_stream->i_pre_skip;
1634 /* Check for OLD Flac header */
1635 else if( oggpacket.bytes >= 4 &&
1636 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1638 msg_Dbg( p_demux, "found FLAC header" );
1640 /* Grrrr!!!! Did they really have to put all the
1641 * important info in the second header packet!!!
1642 * (STREAMINFO metadata is in the following packet) */
1643 p_stream->b_force_backup = true;
1644 p_stream->i_extra_headers_packets = 1;
1645 p_stream->special.flac.b_old = true;
1646 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1648 /* Check for Flac header (>= version 1.0.0) */
1649 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1650 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1651 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1653 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1654 oggpacket.packet[8];
1655 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1656 "(%i header packets)",
1657 oggpacket.packet[5], oggpacket.packet[6],
1658 i_packets );
1659 /* STREAMINFO is in current packet, and then
1660 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1661 p_stream->b_force_backup = true;
1662 p_stream->i_extra_headers_packets = i_packets;
1663 p_stream->special.flac.b_old = false;
1665 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1666 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1667 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1669 msg_Dbg( p_demux, "found invalid Flac header" );
1670 Ogg_LogicalStreamDelete( p_demux, p_stream );
1671 p_stream = NULL;
1672 p_ogg->i_streams--;
1675 /* Check for Theora header */
1676 else if( oggpacket.bytes >= 7 &&
1677 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1679 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1680 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1681 msg_Dbg( p_demux,
1682 "found theora header, bitrate: %i, rate: %f",
1683 p_stream->fmt.i_bitrate, p_stream->f_rate );
1684 else
1686 msg_Dbg( p_demux, "found invalid Theora header" );
1687 Ogg_LogicalStreamDelete( p_demux, p_stream );
1688 p_stream = NULL;
1689 p_ogg->i_streams--;
1692 /* Check for Daala header */
1693 else if( oggpacket.bytes >= 6 &&
1694 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1696 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1697 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1698 msg_Dbg( p_demux,
1699 "found daala header, bitrate: %i, rate: %f",
1700 p_stream->fmt.i_bitrate, p_stream->f_rate );
1701 else
1703 msg_Dbg( p_demux, "found invalid Daala header" );
1704 Ogg_LogicalStreamDelete( p_demux, p_stream );
1705 p_stream = NULL;
1706 p_ogg->i_streams--;
1709 /* Check for Dirac header */
1710 else if( ( oggpacket.bytes >= 5 &&
1711 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1712 ( oggpacket.bytes >= 9 &&
1713 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1715 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1716 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1717 msg_Dbg( p_demux, "found dirac header" );
1718 else
1720 msg_Warn( p_demux, "found dirac header isn't decodable" );
1721 Ogg_LogicalStreamDelete( p_demux, p_stream );
1722 p_stream = NULL;
1723 p_ogg->i_streams--;
1726 /* Check for Tarkin header */
1727 else if( oggpacket.bytes >= 7 &&
1728 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1730 oggpack_buffer opb;
1732 msg_Dbg( p_demux, "found tarkin header" );
1733 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_TARKIN );
1735 /* Cheat and get additionnal info ;) */
1736 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1737 oggpack_adv( &opb, 88 );
1738 oggpack_adv( &opb, 104 );
1739 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1740 p_stream->f_rate = 2; /* FIXME */
1741 msg_Dbg( p_demux,
1742 "found tarkin header, bitrate: %i, rate: %f",
1743 p_stream->fmt.i_bitrate, p_stream->f_rate );
1745 /* Check for VP8 header */
1746 else if( oggpacket.bytes >= 26 &&
1747 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1749 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1750 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1751 msg_Dbg( p_demux, "found VP8 header "
1752 "fps: %f, width:%i; height:%i",
1753 p_stream->f_rate,
1754 p_stream->fmt.video.i_width,
1755 p_stream->fmt.video.i_height );
1756 else
1758 msg_Dbg( p_demux, "invalid VP8 header found");
1759 Ogg_LogicalStreamDelete( p_demux, p_stream );
1760 p_stream = NULL;
1761 p_ogg->i_streams--;
1764 /* Check for Annodex header */
1765 else if( oggpacket.bytes >= 7 &&
1766 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1768 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1769 /* kill annodex track */
1770 FREENULL( p_stream );
1771 p_ogg->i_streams--;
1773 /* Check for Annodex header */
1774 else if( oggpacket.bytes >= 7 &&
1775 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1777 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1779 /* Check for Kate header */
1780 else if( oggpacket.bytes >= 8 &&
1781 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1783 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1784 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1785 msg_Dbg( p_demux, "found kate header" );
1786 else
1788 msg_Dbg( p_demux, "invalid kate header found");
1789 Ogg_LogicalStreamDelete( p_demux, p_stream );
1790 p_stream = NULL;
1791 p_ogg->i_streams--;
1794 /* Check for OggDS */
1795 else if( oggpacket.bytes >= 142 &&
1796 !memcmp( &oggpacket.packet[1],
1797 "Direct Show Samples embedded in Ogg", 35 ))
1799 /* Old header type */
1800 p_stream->b_oggds = true;
1801 /* Check for video header (old format) */
1802 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1803 oggpacket.bytes >= 184 )
1805 es_format_Change( &p_stream->fmt, VIDEO_ES,
1806 VLC_FOURCC( oggpacket.packet[68],
1807 oggpacket.packet[69],
1808 oggpacket.packet[70],
1809 oggpacket.packet[71] ) );
1810 msg_Dbg( p_demux, "found video header of type: %.4s",
1811 (char *)&p_stream->fmt.i_codec );
1813 p_stream->fmt.video.i_frame_rate = 10000000;
1814 p_stream->fmt.video.i_frame_rate_base =
1815 GetQWLE((oggpacket.packet+164));
1816 p_stream->fmt.video.i_frame_rate_base =
1817 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1818 p_stream->f_rate = 10000000.0 /
1819 p_stream->fmt.video.i_frame_rate_base;
1820 p_stream->fmt.video.i_bits_per_pixel =
1821 GetWLE((oggpacket.packet+182));
1822 if( !p_stream->fmt.video.i_bits_per_pixel )
1823 /* hack, FIXME */
1824 p_stream->fmt.video.i_bits_per_pixel = 24;
1825 p_stream->fmt.video.i_width =
1826 GetDWLE((oggpacket.packet+176));
1827 p_stream->fmt.video.i_height =
1828 GetDWLE((oggpacket.packet+180));
1829 p_stream->fmt.video.i_visible_width =
1830 p_stream->fmt.video.i_width;
1831 p_stream->fmt.video.i_visible_height =
1832 p_stream->fmt.video.i_height;
1834 msg_Dbg( p_demux,
1835 "fps: %f, width:%i; height:%i, bitcount:%i",
1836 p_stream->f_rate,
1837 p_stream->fmt.video.i_width,
1838 p_stream->fmt.video.i_height,
1839 p_stream->fmt.video.i_bits_per_pixel);
1842 /* Check for audio header (old format) */
1843 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1845 int i_extra_size;
1846 unsigned int i_format_tag;
1848 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1850 i_extra_size = GetWLE((oggpacket.packet+140));
1851 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1853 p_stream->fmt.i_extra = i_extra_size;
1854 p_stream->fmt.p_extra = malloc( i_extra_size );
1855 if( p_stream->fmt.p_extra )
1856 memcpy( p_stream->fmt.p_extra,
1857 oggpacket.packet + 142, i_extra_size );
1858 else
1859 p_stream->fmt.i_extra = 0;
1862 i_format_tag = GetWLE((oggpacket.packet+124));
1863 p_stream->fmt.audio.i_channels =
1864 GetWLE((oggpacket.packet+126));
1865 fill_channels_info(&p_stream->fmt.audio);
1866 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1867 GetDWLE((oggpacket.packet+128));
1868 p_stream->fmt.i_bitrate =
1869 GetDWLE((oggpacket.packet+132)) * 8;
1870 p_stream->fmt.audio.i_blockalign =
1871 GetWLE((oggpacket.packet+136));
1872 p_stream->fmt.audio.i_bitspersample =
1873 GetWLE((oggpacket.packet+138));
1875 wf_tag_to_fourcc( i_format_tag,
1876 &p_stream->fmt.i_codec, 0 );
1878 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1880 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1881 ( i_format_tag >> 8 ) & 0xff,
1882 i_format_tag & 0xff );
1885 msg_Dbg( p_demux, "found audio header of type: %.4s",
1886 (char *)&p_stream->fmt.i_codec );
1887 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1888 "%dbits/sample %dkb/s",
1889 i_format_tag,
1890 p_stream->fmt.audio.i_channels,
1891 p_stream->fmt.audio.i_rate,
1892 p_stream->fmt.audio.i_bitspersample,
1893 p_stream->fmt.i_bitrate / 1024 );
1894 if ( p_stream->f_rate == 0 )
1896 msg_Dbg( p_demux, "invalid oggds audio header" );
1897 Ogg_LogicalStreamDelete( p_demux, p_stream );
1898 p_stream = NULL;
1899 p_ogg->i_streams--;
1902 else
1904 msg_Dbg( p_demux, "stream %d has an old header "
1905 "but is of an unknown type", p_ogg->i_streams-1 );
1906 FREENULL( p_stream );
1907 p_ogg->i_streams--;
1910 /* Check for OggDS */
1911 else if( oggpacket.bytes >= 44+1 &&
1912 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1914 stream_header_t tmp;
1915 stream_header_t *st = &tmp;
1917 p_stream->b_oggds = true;
1919 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1920 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1921 st->size = GetDWLE( &oggpacket.packet[1+12] );
1922 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1923 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1924 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1925 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1926 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1928 /* Check for video header (new format) */
1929 if( !strncmp( st->streamtype, "video", 5 ) &&
1930 oggpacket.bytes >= 52+1 )
1932 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1933 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1935 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1937 /* We need to get rid of the header packet */
1938 ogg_stream_packetout( &p_stream->os, &oggpacket );
1940 p_stream->fmt.i_codec =
1941 VLC_FOURCC( st->subtype[0], st->subtype[1],
1942 st->subtype[2], st->subtype[3] );
1943 msg_Dbg( p_demux, "found video header of type: %.4s",
1944 (char *)&p_stream->fmt.i_codec );
1946 p_stream->fmt.video.i_frame_rate = 10000000;
1947 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1948 if( st->time_unit <= 0 )
1949 st->time_unit = 400000;
1950 p_stream->f_rate = 10000000.0 / st->time_unit;
1951 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1952 p_stream->fmt.video.i_width = st->sh.video.width;
1953 p_stream->fmt.video.i_height = st->sh.video.height;
1954 p_stream->fmt.video.i_visible_width =
1955 p_stream->fmt.video.i_width;
1956 p_stream->fmt.video.i_visible_height =
1957 p_stream->fmt.video.i_height;
1959 msg_Dbg( p_demux,
1960 "fps: %f, width:%i; height:%i, bitcount:%i",
1961 p_stream->f_rate,
1962 p_stream->fmt.video.i_width,
1963 p_stream->fmt.video.i_height,
1964 p_stream->fmt.video.i_bits_per_pixel );
1966 /* Check for audio header (new format) */
1967 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1968 oggpacket.bytes >= 56+1 )
1970 char p_buffer[5];
1971 int i_extra_size;
1972 int i_format_tag;
1974 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1975 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1976 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1978 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1980 /* We need to get rid of the header packet */
1981 ogg_stream_packetout( &p_stream->os, &oggpacket );
1983 i_extra_size = st->size - 56;
1985 if( i_extra_size > 0 &&
1986 i_extra_size < oggpacket.bytes - 1 - 56 )
1988 p_stream->fmt.i_extra = i_extra_size;
1989 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1990 if( p_stream->fmt.p_extra )
1991 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1992 p_stream->fmt.i_extra );
1993 else
1994 p_stream->fmt.i_extra = 0;
1997 memcpy( p_buffer, st->subtype, 4 );
1998 p_buffer[4] = '\0';
1999 i_format_tag = strtol(p_buffer,NULL,16);
2000 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
2001 fill_channels_info(&p_stream->fmt.audio);
2002 if( st->time_unit <= 0 )
2003 st->time_unit = 10000000;
2004 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
2005 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
2006 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
2007 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
2009 wf_tag_to_fourcc( i_format_tag,
2010 &p_stream->fmt.i_codec, 0 );
2012 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
2014 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
2015 ( i_format_tag >> 8 ) & 0xff,
2016 i_format_tag & 0xff );
2019 msg_Dbg( p_demux, "found audio header of type: %.4s",
2020 (char *)&p_stream->fmt.i_codec );
2021 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2022 "%dbits/sample %dkb/s",
2023 i_format_tag,
2024 p_stream->fmt.audio.i_channels,
2025 p_stream->fmt.audio.i_rate,
2026 p_stream->fmt.audio.i_bitspersample,
2027 p_stream->fmt.i_bitrate / 1024 );
2028 if ( p_stream->f_rate == 0 )
2030 msg_Dbg( p_demux, "invalid oggds audio header" );
2031 Ogg_LogicalStreamDelete( p_demux, p_stream );
2032 p_stream = NULL;
2033 p_ogg->i_streams--;
2036 /* Check for text (subtitles) header */
2037 else if( !strncmp(st->streamtype, "text", 4) )
2039 /* We need to get rid of the header packet */
2040 ogg_stream_packetout( &p_stream->os, &oggpacket );
2042 msg_Dbg( p_demux, "found text subtitle header" );
2043 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2044 p_stream->f_rate = 1000; /* granulepos is in millisec */
2046 else
2048 msg_Dbg( p_demux, "stream %d has a header marker "
2049 "but is of an unknown type", p_ogg->i_streams-1 );
2050 FREENULL( p_stream );
2051 p_ogg->i_streams--;
2054 else if( oggpacket.bytes >= 8 &&
2055 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2058 /* Skeleton */
2059 msg_Dbg( p_demux, "stream %d is a skeleton",
2060 p_ogg->i_streams-1 );
2061 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2063 /* Check for OggSpots header */
2064 else if( oggpacket.bytes >= 8 &&
2065 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2067 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2068 msg_Dbg( p_demux,
2069 "found OggSpots header, time resolution: %f",
2070 p_stream->f_rate );
2071 else
2073 msg_Err( p_demux, "found invalid OggSpots header" );
2074 Ogg_LogicalStreamDelete( p_demux, p_stream );
2075 p_stream = NULL;
2076 p_ogg->i_streams--;
2079 else
2081 msg_Dbg( p_demux, "stream %d is of unknown type",
2082 p_ogg->i_streams-1 );
2085 /* we'll need to get all headers */
2086 if ( p_stream )
2087 p_stream->b_initializing &= p_stream->b_force_backup;
2089 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2090 return VLC_EGENERIC;
2093 /* This is the first data page, which means we are now finished
2094 * with the initial pages. We just need to store it in the relevant
2095 * bitstream. */
2096 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2098 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2099 &p_ogg->current_page ) == 0 )
2101 p_ogg->b_page_waiting = true;
2102 break;
2106 return VLC_SUCCESS;
2110 return VLC_EGENERIC;
2113 /****************************************************************************
2114 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2115 ****************************************************************************/
2116 static void Ogg_CreateES( demux_t *p_demux )
2118 demux_sys_t *p_ogg = p_demux->p_sys;
2119 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2120 int i_stream;
2122 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2124 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2126 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2128 /* Better be safe than sorry when possible with ogm */
2129 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2130 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2131 p_stream->fmt.b_packetized = false;
2133 /* Try first to reuse an old ES */
2134 if( p_old_stream &&
2135 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2136 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2138 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2140 p_stream->p_es = p_old_stream->p_es;
2141 p_stream->b_finished = false;
2142 p_stream->b_reinit = false;
2143 p_stream->b_initializing = false;
2144 p_stream->i_pre_skip = 0;
2145 es_format_Clean( &p_stream->fmt_old );
2146 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2147 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2149 p_old_stream->p_es = NULL;
2150 p_old_stream = NULL;
2151 if ( b_resetdecoder )
2153 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2154 p_stream->p_es, &p_stream->fmt );
2157 else
2159 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2162 // TODO: something to do here ?
2163 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2165 /* Set the CMML stream active */
2166 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2171 if( p_ogg->p_old_stream )
2173 if( p_ogg->p_old_stream->p_es )
2174 msg_Dbg( p_demux, "old stream not reused" );
2175 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2176 p_ogg->p_old_stream = NULL;
2178 p_ogg->b_es_created = true;
2181 /****************************************************************************
2182 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2183 * Elementary streams.
2184 ****************************************************************************/
2185 static int Ogg_BeginningOfStream( demux_t *p_demux )
2187 demux_sys_t *p_ogg = p_demux->p_sys ;
2188 int i_stream;
2190 /* Find the logical streams embedded in the physical stream and
2191 * initialize our p_ogg structure. */
2192 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2194 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2195 return VLC_EGENERIC;
2198 p_ogg->i_bitrate = 0;
2200 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2202 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2204 p_stream->p_es = NULL;
2206 /* initialise kframe index */
2207 p_stream->idx=NULL;
2209 if ( p_stream->fmt.i_bitrate == 0 &&
2210 ( p_stream->fmt.i_cat == VIDEO_ES ||
2211 p_stream->fmt.i_cat == AUDIO_ES ) )
2212 p_ogg->b_partial_bitrate = true;
2213 else
2214 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2216 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2217 p_stream->i_previous_granulepos = -1;
2218 p_stream->b_reinit = false;
2221 /* get total frame count for video stream; we will need this for seeking */
2222 p_ogg->i_total_frames = 0;
2224 return VLC_SUCCESS;
2227 /****************************************************************************
2228 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2229 ****************************************************************************/
2230 static void Ogg_EndOfStream( demux_t *p_demux )
2232 demux_sys_t *p_ogg = p_demux->p_sys ;
2233 int i_stream;
2235 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2236 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2237 free( p_ogg->pp_stream );
2239 /* Reinit p_ogg */
2240 p_ogg->i_bitrate = 0;
2241 p_ogg->i_streams = 0;
2242 p_ogg->pp_stream = NULL;
2243 p_ogg->skeleton.major = 0;
2244 p_ogg->skeleton.minor = 0;
2245 p_ogg->b_preparsing_done = false;
2246 p_ogg->b_es_created = false;
2248 /* */
2249 if( p_ogg->p_meta )
2250 vlc_meta_Delete( p_ogg->p_meta );
2251 p_ogg->p_meta = NULL;
2253 for(int i=0; i<p_ogg->i_attachments; i++)
2254 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2255 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2257 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2259 if ( p_ogg->pp_seekpoints[i] )
2260 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2262 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2265 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2267 #ifdef HAVE_LIBVORBIS
2268 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2270 if( p_stream->special.vorbis.p_info )
2271 vorbis_info_clear( p_stream->special.vorbis.p_info );
2272 FREENULL( p_stream->special.vorbis.p_info );
2273 if( p_stream->special.vorbis.p_comment )
2274 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2275 FREENULL( p_stream->special.vorbis.p_comment );
2276 p_stream->special.vorbis.i_headers_flags = 0;
2278 #else
2279 VLC_UNUSED( p_stream );
2280 #endif
2284 * This function delete and release all data associated to a logical_stream_t
2286 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2288 if( p_stream->p_es )
2289 es_out_Del( p_demux->out, p_stream->p_es );
2291 ogg_stream_clear( &p_stream->os );
2292 free( p_stream->p_headers );
2294 Ogg_CleanSpecificData( p_stream );
2296 es_format_Clean( &p_stream->fmt_old );
2297 es_format_Clean( &p_stream->fmt );
2299 if ( p_stream->idx != NULL)
2301 oggseek_index_entries_free( p_stream->idx );
2304 Ogg_FreeSkeleton( p_stream->p_skel );
2305 p_stream->p_skel = NULL;
2306 if ( p_demux->p_sys->p_skelstream == p_stream )
2307 p_demux->p_sys->p_skelstream = NULL;
2309 /* Shouldn't happen */
2310 if ( unlikely( p_stream->p_preparse_block ) )
2312 block_ChainRelease( p_stream->p_preparse_block );
2313 p_stream->p_preparse_block = NULL;
2315 free( p_stream->prepcr.pp_blocks );
2317 free( p_stream );
2320 * This function check if a we need to reset a decoder in case we are
2321 * reusing an old ES
2323 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2325 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2326 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2327 unsigned i_new_count;
2328 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2329 i_new_count = 0;
2331 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2332 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2333 unsigned i_old_count;
2334 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2335 i_old_count = 0;
2337 bool b_match = i_new_count == i_old_count;
2338 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2340 /* Ignore vorbis comment */
2341 if( i == 1 )
2342 continue;
2343 if( pi_new_size[i] != pi_old_size[i] ||
2344 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2345 b_match = false;
2348 return b_match;
2351 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2352 const es_format_t *p_old )
2354 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2355 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2356 unsigned i_new_count;
2357 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2358 i_new_count = 0;
2359 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2360 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2361 unsigned i_old_count;
2362 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2363 i_old_count = 0;
2364 bool b_match = false;
2365 if( i_new_count == i_old_count && i_new_count > 0 )
2367 static const unsigned char default_map[2] = { 0, 1 };
2368 unsigned char *p_old_head;
2369 unsigned char *p_new_head;
2370 const unsigned char *p_old_map;
2371 const unsigned char *p_new_map;
2372 int i_old_channel_count;
2373 int i_new_channel_count;
2374 int i_old_stream_count;
2375 int i_new_stream_count;
2376 int i_old_coupled_count;
2377 int i_new_coupled_count;
2378 p_old_head = (unsigned char *)pp_old_data[0];
2379 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2380 p_old_map = default_map;
2381 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2383 i_old_channel_count = p_old_head[9];
2384 switch( p_old_head[18] )
2386 case 0:
2387 i_old_stream_count = 1;
2388 i_old_coupled_count = i_old_channel_count - 1;
2389 break;
2390 case 1:
2391 if( pi_old_size[0] >= 21U + i_old_channel_count )
2393 i_old_stream_count = p_old_head[19];
2394 i_old_coupled_count = p_old_head[20];
2395 p_old_map = p_old_head + 21;
2397 break;
2400 p_new_head = (unsigned char *)pp_new_data[0];
2401 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2402 p_new_map = default_map;
2403 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2405 i_new_channel_count = p_new_head[9];
2406 switch( p_new_head[18] )
2408 case 0:
2409 i_new_stream_count = 1;
2410 i_new_coupled_count = i_new_channel_count - 1;
2411 break;
2412 case 1:
2413 if( pi_new_size[0] >= 21U + i_new_channel_count )
2415 i_new_stream_count = p_new_head[19];
2416 i_new_coupled_count = p_new_head[20];
2417 p_new_map = p_new_head+21;
2419 break;
2422 b_match = i_old_channel_count == i_new_channel_count &&
2423 i_old_stream_count == i_new_stream_count &&
2424 i_old_coupled_count == i_new_coupled_count &&
2425 memcmp(p_old_map, p_new_map,
2426 i_new_channel_count*sizeof(*p_new_map)) == 0;
2429 return b_match;
2432 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2434 bool b_compatible = false;
2435 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2436 return true;
2438 /* Only Vorbis and Opus are supported. */
2439 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2440 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2441 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2442 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2444 if( !b_compatible )
2445 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2447 return !b_compatible;
2450 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2451 const void *p_headers, unsigned i_headers )
2453 demux_sys_t *p_ogg = p_demux->p_sys;
2454 int i_cover_score = 0;
2455 int i_cover_idx = 0;
2456 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2457 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2458 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2460 pf_replay_gain[i] = 0;
2461 pf_replay_peak[i] = 0;
2463 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2464 &p_ogg->i_attachments, &p_ogg->attachments,
2465 &i_cover_score, &i_cover_idx,
2466 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2467 &pf_replay_gain, &pf_replay_peak );
2468 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2470 char psz_url[128];
2471 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2472 p_ogg->attachments[i_cover_idx]->psz_name );
2473 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2476 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2478 if ( pf_replay_gain[i] != 0 )
2480 p_fmt->audio_replay_gain.pb_gain[i] = true;
2481 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2482 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2484 if ( pf_replay_peak[i] != 0 )
2486 p_fmt->audio_replay_gain.pb_peak[i] = true;
2487 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2488 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2492 if( p_ogg->i_seekpoints > 1 )
2494 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2498 static inline uint32_t GetDW24BE( const uint8_t *p )
2500 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2501 #ifdef WORDS_BIGENDIAN
2502 i = bswap32(i);
2503 #endif
2504 return i;
2507 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2508 const uint8_t *p_headers, unsigned i_headers )
2510 /* Skip Streaminfo 42 bytes / 1st page */
2511 if(i_headers <= 46)
2512 return;
2513 p_headers += 42; i_headers -= 42;
2514 /* Block Header 1 + 3 bytes */
2515 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2516 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2518 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2522 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2523 const void *p_headers, unsigned i_headers, unsigned i_skip )
2525 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2526 void *pp_data[XIPH_MAX_HEADER_COUNT];
2527 unsigned i_count;
2529 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2530 return;
2531 /* TODO how to handle multiple comments properly ? */
2532 if( i_count >= 2 && pi_size[1] > i_skip )
2534 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2538 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2540 demux_sys_t *p_ogg = p_demux->p_sys;
2542 switch( p_fmt->i_codec )
2544 /* 3 headers with the 2° one being the comments */
2545 case VLC_CODEC_VORBIS:
2546 case VLC_CODEC_THEORA:
2547 case VLC_CODEC_DAALA:
2548 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2549 break;
2550 case VLC_CODEC_OPUS:
2551 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2552 break;
2553 case VLC_CODEC_SPEEX:
2554 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2555 break;
2556 case VLC_CODEC_VP8:
2557 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2558 break;
2559 /* N headers with the 2° one being the comments */
2560 case VLC_CODEC_KATE:
2561 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2562 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2563 break;
2565 /* TODO */
2566 case VLC_CODEC_FLAC:
2567 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2568 break;
2570 /* No meta data */
2571 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2572 case VLC_CODEC_DIRAC:
2573 default:
2574 break;
2576 if( p_ogg->p_meta )
2577 p_demux->info.i_update |= INPUT_UPDATE_META;
2580 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2581 ogg_packet *p_oggpacket )
2583 bs_t bitstream;
2584 unsigned int i_fps_numerator;
2585 unsigned int i_fps_denominator;
2586 int i_keyframe_frequency_force;
2587 int i_major;
2588 int i_minor;
2589 int i_subminor;
2590 int i_version;
2592 /* Signal that we want to keep a backup of the theora
2593 * stream headers. They will be used when switching between
2594 * audio streams. */
2595 p_stream->b_force_backup = true;
2597 /* Cheat and get additionnal info ;) */
2598 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2599 bs_skip( &bitstream, 56 );
2601 i_major = bs_read( &bitstream, 8 ); /* major version num */
2602 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2603 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2605 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2606 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2607 bs_read( &bitstream, 24 ); /* frame width */
2608 bs_read( &bitstream, 24 ); /* frame height */
2609 bs_read( &bitstream, 8 ); /* x offset */
2610 bs_read( &bitstream, 8 ); /* y offset */
2612 i_fps_numerator = bs_read( &bitstream, 32 );
2613 i_fps_denominator = bs_read( &bitstream, 32 );
2614 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2615 bs_read( &bitstream, 24 ); /* aspect_numerator */
2616 bs_read( &bitstream, 24 ); /* aspect_denominator */
2618 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2619 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2621 bs_read( &bitstream, 8 ); /* colorspace */
2622 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2623 bs_read( &bitstream, 6 ); /* quality */
2625 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2627 /* granule_shift = i_log( frequency_force -1 ) */
2628 p_stream->i_granule_shift = 0;
2629 i_keyframe_frequency_force--;
2630 while( i_keyframe_frequency_force )
2632 p_stream->i_granule_shift++;
2633 i_keyframe_frequency_force >>= 1;
2636 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2637 p_stream->i_keyframe_offset = 0;
2638 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2639 if ( p_stream->f_rate == 0 ) return false;
2641 if ( i_version >= 3002001 )
2643 p_stream->i_keyframe_offset = 1;
2645 return true;
2648 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2649 ogg_packet *p_oggpacket )
2651 oggpack_buffer opb;
2652 uint32_t i_timebase_numerator;
2653 uint32_t i_timebase_denominator;
2654 int i_keyframe_frequency_force;
2655 uint8_t i_major;
2656 uint8_t i_minor;
2657 uint8_t i_subminor;
2658 int i_version;
2660 /* Signal that we want to keep a backup of the daala
2661 * stream headers. They will be used when switching between
2662 * audio streams. */
2663 p_stream->b_force_backup = true;
2665 /* Cheat and get additionnal info ;) */
2666 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2667 oggpack_adv( &opb, 48 );
2669 i_major = oggpack_read( &opb, 8 ); /* major version num */
2670 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2671 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2673 oggpack_adv( &opb, 32 ); /* width */
2674 oggpack_adv( &opb, 32 ); /* height */
2676 oggpack_adv( &opb, 32 ); /* aspect numerator */
2677 oggpack_adv( &opb, 32 ); /* aspect denominator */
2678 i_timebase_numerator = oggpack_read( &opb, 32 );
2680 i_timebase_denominator = oggpack_read( &opb, 32 );
2681 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2683 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2684 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2686 oggpack_adv( &opb, 32 ); /* frame duration */
2688 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2690 /* granule_shift = i_log( frequency_force -1 ) */
2691 p_stream->i_granule_shift = 0;
2692 i_keyframe_frequency_force--;
2693 while( i_keyframe_frequency_force )
2695 p_stream->i_granule_shift++;
2696 i_keyframe_frequency_force >>= 1;
2699 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2700 VLC_UNUSED(i_version);
2701 p_stream->i_keyframe_offset = 0;
2702 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2703 if ( p_stream->f_rate == 0 ) return false;
2705 return true;
2708 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2709 ogg_packet *p_oggpacket )
2711 oggpack_buffer opb;
2713 /* Signal that we want to keep a backup of the vorbis
2714 * stream headers. They will be used when switching between
2715 * audio streams. */
2716 p_stream->b_force_backup = true;
2718 /* Cheat and get additionnal info ;) */
2719 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2720 oggpack_adv( &opb, 88 );
2721 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2722 fill_channels_info(&p_stream->fmt.audio);
2723 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2724 oggpack_read( &opb, 32 );
2725 oggpack_adv( &opb, 32 );
2726 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2727 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2728 if ( p_stream->f_rate == 0 ) return false;
2729 return true;
2731 #ifdef HAVE_LIBVORBIS
2732 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2733 ogg_packet *p_oggpacket, int i_number )
2735 switch( i_number )
2737 case VORBIS_HEADER_IDENTIFICATION:
2738 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2739 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2740 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2742 FREENULL( p_stream->special.vorbis.p_info );
2743 FREENULL( p_stream->special.vorbis.p_comment );
2744 break;
2746 vorbis_info_init( p_stream->special.vorbis.p_info );
2747 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2748 /* fallthrough */
2750 case VORBIS_HEADER_COMMENT:
2751 case VORBIS_HEADER_SETUP:
2752 if ( !p_stream->special.vorbis.p_info ||
2753 vorbis_synthesis_headerin(
2754 p_stream->special.vorbis.p_info,
2755 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2756 break;
2758 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2759 /* fallthrough */
2761 default:
2762 break;
2765 #endif
2767 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2768 ogg_packet *p_oggpacket )
2770 oggpack_buffer opb;
2772 /* Signal that we want to keep a backup of the speex
2773 * stream headers. They will be used when switching between
2774 * audio streams. */
2775 p_stream->b_force_backup = true;
2777 /* Cheat and get additionnal info ;) */
2778 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2779 oggpack_adv( &opb, 224 );
2780 oggpack_adv( &opb, 32 ); /* speex_version_id */
2781 oggpack_adv( &opb, 32 ); /* header_size */
2782 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2783 if ( p_stream->f_rate == 0 ) return false;
2784 oggpack_adv( &opb, 32 ); /* mode */
2785 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2786 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2787 fill_channels_info(&p_stream->fmt.audio);
2788 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2789 p_stream->special.speex.i_framesize =
2790 oggpack_read( &opb, 32 ); /* frame_size */
2791 oggpack_adv( &opb, 32 ); /* vbr */
2792 p_stream->special.speex.i_framesperpacket =
2793 oggpack_read( &opb, 32 ); /* frames_per_packet */
2794 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2795 return true;
2798 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2799 ogg_packet *p_oggpacket )
2801 oggpack_buffer opb;
2803 /* Signal that we want to keep a backup of the opus
2804 * stream headers. They will be used when switching between
2805 * audio streams. */
2806 p_stream->b_force_backup = true;
2808 /* All OggOpus streams are timestamped at 48kHz and
2809 * can be played at 48kHz. */
2810 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2811 p_stream->fmt.i_bitrate = 0;
2813 /* Cheat and get additional info ;) */
2814 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2815 oggpack_adv( &opb, 64 );
2816 oggpack_adv( &opb, 8 ); /* version_id */
2817 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2818 fill_channels_info(&p_stream->fmt.audio);
2819 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2820 /* For Opus, trash the first 80 ms of decoded output as
2821 well, to avoid blowing out speakers if we get unlucky.
2822 Opus predicts content from prior frames, which can go
2823 badly if we seek right where the stream goes from very
2824 quiet to very loud. It will converge after a bit. */
2825 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2828 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2829 ogg_packet *p_oggpacket )
2831 /* Parse the STREAMINFO metadata */
2832 bs_t s;
2834 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2836 bs_read( &s, 1 );
2837 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2839 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2840 return false;
2843 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2845 bs_skip( &s, 80 );
2846 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2847 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2848 fill_channels_info(&p_stream->fmt.audio);
2850 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2851 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2852 if ( p_stream->f_rate == 0 ) return false;
2854 else
2856 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2859 /* Fake this as the last metadata block */
2860 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2861 return true;
2864 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2865 ogg_packet *p_oggpacket )
2867 oggpack_buffer opb;
2868 uint32_t gnum;
2869 uint32_t gden;
2870 int n;
2871 char *psz_desc;
2873 /* Signal that we want to keep a backup of the kate
2874 * stream headers. They will be used when switching between
2875 * kate streams. */
2876 p_stream->b_force_backup = true;
2878 /* Cheat and get additionnal info ;) */
2879 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2880 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2881 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2882 oggpack_adv( &opb, 3*8 );
2883 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2884 oggpack_adv( &opb, 8*8 ); /* reserved */
2885 gnum = oggpack_read( &opb, 32 );
2886 gden = oggpack_read( &opb, 32 );
2887 gden = __MAX( gden, 1 );
2888 p_stream->f_rate = (double)gnum/gden;
2889 if ( p_stream->f_rate == 0 ) return false;
2891 p_stream->fmt.psz_language = malloc(16);
2892 if( p_stream->fmt.psz_language )
2894 for( n = 0; n < 16; n++ )
2895 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2896 p_stream->fmt.psz_language[15] = 0; /* just in case */
2898 else
2900 for( n = 0; n < 16; n++ )
2901 oggpack_read(&opb,8);
2903 p_stream->fmt.psz_description = malloc(16);
2904 if( p_stream->fmt.psz_description )
2906 for( n = 0; n < 16; n++ )
2907 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2908 p_stream->fmt.psz_description[15] = 0; /* just in case */
2910 /* Now find a localized user readable description for this category */
2911 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2912 if( psz_desc )
2914 free( p_stream->fmt.psz_description );
2915 p_stream->fmt.psz_description = psz_desc;
2918 else
2920 for( n = 0; n < 16; n++ )
2921 oggpack_read(&opb,8);
2924 return true;
2927 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2928 ogg_packet *p_oggpacket )
2930 switch( p_oggpacket->packet[5] )
2932 /* STREAMINFO */
2933 case 0x01:
2934 /* Mapping version */
2935 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2936 return false;
2937 p_stream->i_granule_shift = 32;
2938 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2939 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2940 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2941 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2942 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2943 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2944 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2945 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2946 p_stream->fmt.video.i_frame_rate_base =
2947 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2948 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2949 if ( p_stream->f_rate == 0 ) return false;
2950 return true;
2951 /* METADATA */
2952 case 0x02:
2953 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2954 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2955 return true;
2956 default:
2957 return false;
2961 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2962 bool *b_force_backup, bool *b_packet_out )
2964 if( p_stream->fmt.i_cat != UNKNOWN_ES )
2965 return;
2967 if( !strncmp(psz_value, "audio/x-wav", 11) )
2969 /* n.b. WAVs are unsupported right now */
2970 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2971 free( p_stream->fmt.psz_description );
2972 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2974 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2975 !strncmp(psz_value, "audio/vorbis", 12) )
2977 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
2979 *b_force_backup = true;
2981 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2982 !strncmp(psz_value, "audio/speex", 11) )
2984 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
2986 *b_force_backup = true;
2988 else if( !strncmp(psz_value, "audio/flac", 10) )
2990 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
2992 *b_force_backup = true;
2994 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2995 !strncmp(psz_value, "video/theora", 12) )
2997 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
2999 *b_force_backup = true;
3001 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3002 !strncmp(psz_value, "video/daala", 11) )
3004 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
3006 *b_force_backup = true;
3008 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3010 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
3012 *b_force_backup = true;
3014 else if( !strncmp(psz_value, "video/mpeg", 10) )
3016 /* n.b. MPEG streams are unsupported right now */
3017 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3019 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
3020 !strncmp(psz_value, "text/cmml", 9) )
3022 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_CMML );
3023 *b_packet_out = true;
3025 else if( !strncmp(psz_value, "application/kate", 16) )
3027 /* ??? */
3028 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3029 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3031 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3033 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3037 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3038 logical_stream_t *p_stream,
3039 ogg_packet *p_oggpacket )
3041 if( p_oggpacket->bytes >= 28 &&
3042 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3044 oggpack_buffer opb;
3046 uint16_t major_version;
3047 uint16_t minor_version;
3048 uint64_t timebase_numerator;
3049 uint64_t timebase_denominator;
3051 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3053 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3054 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3055 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3056 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3057 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3058 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3060 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3061 "Timebase %"PRId64" / %"PRId64,
3062 major_version, minor_version,
3063 timebase_numerator, timebase_denominator );
3065 else if( p_oggpacket->bytes >= 42 &&
3066 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3068 uint64_t granule_rate_numerator;
3069 uint64_t granule_rate_denominator;
3070 char content_type_string[1024];
3072 /* Read in Annodex header fields */
3074 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3075 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3076 p_stream->i_secondary_header_packets =
3077 GetDWLE( &p_oggpacket->packet[24] );
3079 /* we are guaranteed that the first header field will be
3080 * the content-type (by the Annodex standard) */
3081 content_type_string[0] = '\0';
3082 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3084 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3085 p_oggpacket->bytes - 1 );
3086 if( p && p[0] == '\r' && p[1] == '\n' )
3087 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3088 content_type_string );
3091 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3092 granule_rate_numerator, granule_rate_denominator,
3093 p_stream->i_secondary_header_packets, content_type_string );
3095 p_stream->f_rate = (float) granule_rate_numerator /
3096 (float) granule_rate_denominator;
3098 /* What type of file do we have?
3099 * strcmp is safe to use here because we've extracted
3100 * content_type_string from the stream manually */
3101 bool b_dopacketout = false;
3102 Ogg_ApplyContentType( p_stream, content_type_string,
3103 &p_stream->b_force_backup, &b_dopacketout );
3104 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3108 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3109 ogg_packet *p_oggpacket )
3111 p_demux->p_sys->p_skelstream = p_stream;
3112 /* There can be only 1 skeleton for streams */
3113 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3114 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3115 if ( asprintf( & p_stream->fmt.psz_description,
3116 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3117 p_demux->p_sys->skeleton.major,
3118 p_demux->p_sys->skeleton.minor ) < 0 )
3119 p_stream->fmt.psz_description = NULL;
3122 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3124 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3126 /* Find the matching stream for this skeleton data */
3127 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3128 logical_stream_t *p_target_stream = NULL;
3129 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3131 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3133 p_target_stream = p_demux->p_sys->pp_stream[i];
3134 break;
3137 if ( !p_target_stream ) return;
3139 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3140 if ( !p_skel )
3142 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3143 if ( !p_skel ) return;
3144 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3145 p_skel->p_index = NULL;
3146 p_target_stream->p_skel = p_skel;
3149 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3150 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3151 const unsigned char *p = p_messages;
3152 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3154 if ( *p == 0x0D && *(p+1) == 0x0A )
3156 char *psz_message = strndup( (const char *) p_messages,
3157 p - p_messages );
3158 if ( psz_message )
3160 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3161 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3163 if ( p < p_boundary - 1 ) p_messages = p + 2;
3165 p++;
3170 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3171 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3172 unsigned const char *p_end,
3173 uint64_t *pi_value )
3175 int i_shift = 0;
3176 int64_t i_read = 0;
3177 *pi_value = 0;
3179 while ( p_begin < p_end )
3181 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3182 *pi_value = *pi_value | ( i_read << i_shift );
3183 i_shift += 7;
3184 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3187 *pi_value = GetQWLE( pi_value );
3188 return p_begin;
3191 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3193 if ( p_demux->p_sys->skeleton.major < 4
3194 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3195 ) return;
3197 /* Find the matching stream for this skeleton data */
3198 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3199 logical_stream_t *p_stream = NULL;
3200 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3202 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3204 p_stream = p_demux->p_sys->pp_stream[i];
3205 break;
3208 if ( !p_stream || !p_stream->p_skel ) return;
3209 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3210 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3211 if ( !i_keypoints ) return;
3213 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3214 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3215 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3216 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3217 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3218 uint64_t i_offset = 0;
3219 uint64_t i_time = 0;
3220 uint64_t i_keypoints_found = 0;
3222 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3224 uint64_t i_val;
3225 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3226 i_offset += i_val;
3227 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3228 i_time += i_val * p_stream->p_skel->i_indexstampden;
3229 i_keypoints_found++;
3232 if ( i_keypoints_found != i_keypoints )
3234 msg_Warn( p_demux, "Invalid Index: missing entries" );
3235 return;
3238 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3239 if ( !p_stream->p_skel->p_index ) return;
3240 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3241 p_oggpacket->bytes - 42 );
3242 p_stream->p_skel->i_index = i_keypoints_found;
3243 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3246 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3248 if ( !p_skel ) return;
3249 for ( int i=0; i< p_skel->i_messages; i++ )
3250 free( p_skel->ppsz_messages[i] );
3251 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3252 free( p_skel->p_index );
3253 free( p_skel );
3256 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3258 if ( !p_stream->p_skel ) return;
3259 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3261 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3262 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3264 free( p_stream->fmt.psz_description );
3265 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3267 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3269 bool b_foo;
3270 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3275 /* Return true if there's a skeleton exact match */
3276 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3277 int64_t *pi_lower, int64_t *pi_upper )
3279 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3280 return false;
3282 /* Validate range */
3283 if ( i_time < p_stream->p_skel->i_indexfirstnum
3284 * p_stream->p_skel->i_indexstampden ||
3285 i_time > p_stream->p_skel->i_indexlastnum
3286 * p_stream->p_skel->i_indexstampden ) return false;
3288 /* Then Lookup its index */
3289 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3290 struct
3292 int64_t i_pos;
3293 int64_t i_time;
3294 } current = { 0, 0 }, prev = { -1, -1 };
3296 uint64_t i_keypoints_found = 0;
3298 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3299 && i_keypoints_found < p_stream->p_skel->i_index )
3301 uint64_t i_val;
3302 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3303 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3304 current.i_pos += i_val;
3305 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3306 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3307 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3308 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3310 i_keypoints_found++;
3312 if ( i_time <= current.i_time )
3314 *pi_lower = prev.i_pos;
3315 *pi_upper = current.i_pos;
3316 return ( i_time == current.i_time );
3318 prev = current;
3320 return false;
3323 static uint32_t dirac_uint( bs_t *p_bs )
3325 uint32_t u_count = 0, u_value = 0;
3327 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3329 u_count++;
3330 u_value <<= 1;
3331 u_value |= bs_read( p_bs, 1 );
3334 return (1<<u_count) - 1 + u_value;
3337 static int dirac_bool( bs_t *p_bs )
3339 return bs_read( p_bs, 1 );
3342 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3343 ogg_packet *p_oggpacket )
3345 static const struct {
3346 uint32_t u_n /* numerator */, u_d /* denominator */;
3347 } p_dirac_frate_tbl[] = { /* table 10.3 */
3348 {1,1}, /* this first value is never used */
3349 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3350 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3352 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3354 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3355 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3357 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3359 bs_t bs;
3361 p_stream->i_granule_shift = 22; /* not 32 */
3363 /* Backing up stream headers is not required -- seqhdrs are repeated
3364 * thoughout the stream at suitable decoding start points */
3365 p_stream->b_force_backup = false;
3367 /* read in useful bits from sequence header */
3368 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3369 bs_skip( &bs, 13*8); /* parse_info_header */
3370 dirac_uint( &bs ); /* major_version */
3371 dirac_uint( &bs ); /* minor_version */
3372 dirac_uint( &bs ); /* profile */
3373 dirac_uint( &bs ); /* level */
3375 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3376 if( u_video_format >= u_dirac_vidfmt_frate )
3378 /* don't know how to parse this ogg dirac stream */
3379 return false;
3382 if( dirac_bool( &bs ) )
3384 dirac_uint( &bs ); /* frame_width */
3385 dirac_uint( &bs ); /* frame_height */
3388 if( dirac_bool( &bs ) )
3390 dirac_uint( &bs ); /* chroma_format */
3393 if( dirac_bool( &bs ) )
3395 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3397 else
3398 p_stream->special.dirac.b_interlaced = false;
3400 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3401 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3402 u_d = __MAX( u_d, 1 );
3403 if( dirac_bool( &bs ) )
3405 uint32_t u_frame_rate_index = dirac_uint( &bs );
3406 if( u_frame_rate_index >= u_dirac_frate_tbl )
3408 /* something is wrong with this stream */
3409 return false;
3411 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3412 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3413 if( u_frame_rate_index == 0 )
3415 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3416 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3419 p_stream->f_rate = (float) u_n / u_d;
3420 if ( p_stream->f_rate == 0 ) return false;
3422 return true;
3425 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3426 ogg_packet *p_oggpacket )
3428 uint64_t i_granulerate_numerator;
3429 uint64_t i_granulerate_denominator;
3430 int i_major;
3431 int i_minor;
3433 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3435 /* Signal that we want to keep a backup of the OggSpots
3436 * stream headers. They will be used when switching between
3437 * audio streams. */
3438 p_stream->b_force_backup = true;
3440 /* Cheat and get additionnal info ;) */
3441 if ( p_oggpacket->bytes != 52 )
3443 /* The OggSpots header is always 52 bytes */
3444 return false;
3447 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3448 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3449 if ( i_major != 0 || i_minor != 1 )
3451 return false;
3454 /* Granule rate */
3455 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3456 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3457 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3459 return false;
3462 /* The OggSpots spec contained an error and there are implementations out
3463 * there that used the wrong value. So we detect that case and switch
3464 * numerator and denominator in that case */
3465 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3467 i_granulerate_numerator = 30;
3468 i_granulerate_denominator = 1;
3471 p_stream->f_rate = ((double)i_granulerate_numerator) / i_granulerate_denominator;
3472 if ( p_stream->f_rate == 0 )
3474 return false;
3477 /* Normalize granulerate */
3478 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3479 &p_stream->fmt.video.i_frame_rate_base,
3480 i_granulerate_numerator, i_granulerate_denominator, 0);
3482 p_stream->i_granule_shift = p_oggpacket->packet[28];
3484 return true;