qt: add device preferences for mmdevice
[vlc.git] / modules / demux / ogg.c
blob284c0c39a304e1cb6e328358612bc97c4643a80b
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;
923 return VLC_SUCCESS;
925 return VLC_EGENERIC;
927 case DEMUX_SET_TITLE:
929 const int i_title = va_arg( args, int );
930 if( i_title > 1 )
931 return VLC_EGENERIC;
932 return VLC_SUCCESS;
934 case DEMUX_SET_SEEKPOINT:
936 const int i_seekpoint = va_arg( args, int );
937 if( i_seekpoint > p_sys->i_seekpoints )
938 return VLC_EGENERIC;
940 for ( int i=0; i< p_sys->i_streams; i++ )
942 if ( p_sys->pp_stream[i]->b_initializing )
943 return VLC_EGENERIC;
946 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
948 p_stream = Ogg_GetSelectedStream( p_demux );
949 if ( !p_stream )
951 msg_Err( p_demux, "No selected seekable stream found" );
952 return VLC_EGENERIC;
955 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
956 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
958 Ogg_ResetStreamsHelper( p_sys );
959 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
960 VLC_TS_0 + i64 );
961 p_sys->updates |= INPUT_UPDATE_SEEKPOINT;
962 p_sys->cur_seekpoint = i_seekpoint;
963 return VLC_SUCCESS;
965 else
966 return VLC_EGENERIC;
968 case DEMUX_TEST_AND_CLEAR_FLAGS:
970 unsigned *restrict flags = va_arg( args, unsigned * );
971 *flags &= p_sys->updates;
972 p_sys->updates &= ~*flags;
973 return VLC_SUCCESS;
975 case DEMUX_GET_TITLE:
976 *va_arg( args, int * ) = 0;
977 return VLC_SUCCESS;
978 case DEMUX_GET_SEEKPOINT:
979 *va_arg( args, int * ) = p_sys->cur_seekpoint;
980 return VLC_SUCCESS;
982 default:
983 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
984 1, i_query, args );
988 /****************************************************************************
989 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
990 ****************************************************************************
991 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
992 * are at the end of stream.
993 ****************************************************************************/
994 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
996 demux_sys_t *p_ogg = p_demux->p_sys ;
997 int i_read = 0;
998 char *p_buffer;
1000 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
1002 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
1004 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
1005 if( i_read <= 0 )
1006 return VLC_EGENERIC;
1008 ogg_sync_wrote( &p_ogg->oy, i_read );
1011 return VLC_SUCCESS;
1014 /****************************************************************************
1015 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
1016 * current stream.
1017 ****************************************************************************/
1018 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
1019 ogg_packet *p_oggpacket )
1021 demux_sys_t *p_ogg = p_demux->p_sys;
1022 p_stream->i_end_trim = 0;
1024 /* Convert the granulepos into a pcr */
1025 if ( p_oggpacket->granulepos == 0 )
1027 /* We're in headers, and we haven't parsed 1st data packet yet */
1028 // p_stream->i_pcr = VLC_TS_UNKNOWN;
1030 else if( p_oggpacket->granulepos > 0 )
1032 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
1033 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
1034 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
1035 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1036 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
1037 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1038 p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
1039 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
1041 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1042 p_oggpacket->granulepos, true );
1043 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1045 else if ( p_stream->i_previous_granulepos > 0 )
1047 ogg_int64_t sample = p_stream->i_previous_granulepos;
1049 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
1051 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
1052 if( duration > 0 )
1054 ogg_int64_t end_sample = p_oggpacket->granulepos;
1055 if( end_sample < ( sample + duration ) )
1056 p_stream->i_end_trim = sample + duration - end_sample;
1060 if (sample >= p_stream->i_pre_skip)
1061 sample -= p_stream->i_pre_skip;
1062 else
1063 sample = 0;
1065 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1066 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1070 else if ( p_oggpacket->granulepos == -1 )
1072 unsigned i_duration;
1073 /* no granulepos available, try to interpolate the pcr.
1074 * If we can't then don't touch the old value. */
1075 if( p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES )
1077 if( p_stream->i_previous_granulepos > 0 )
1079 p_stream->i_pcr = VLC_TS_0 + p_stream->i_previous_granulepos * CLOCK_FREQ / p_stream->f_rate;
1080 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1082 /* First frame in ogm can be -1 (0 0 -1 2 3 -1 5 ...) */
1083 else if( p_stream->i_previous_granulepos == 0 )
1085 p_stream->i_pcr = VLC_TS_0 + p_ogg->i_nzpcr_offset;
1087 else
1089 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1092 #ifdef HAVE_LIBVORBIS
1093 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1094 p_stream->special.vorbis.p_info &&
1095 VORBIS_HEADERS_VALID(p_stream) &&
1096 p_stream->i_previous_granulepos > 0 )
1098 long i_blocksize = vorbis_packet_blocksize(
1099 p_stream->special.vorbis.p_info, p_oggpacket );
1100 if ( p_stream->special.vorbis.i_prev_blocksize )
1101 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1102 else
1103 i_duration = i_blocksize / 2;
1104 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1105 /* duration in samples per channel */
1106 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1107 p_stream->i_pcr = p_stream->i_previous_granulepos *
1108 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1109 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1111 #endif
1112 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1113 p_stream->i_previous_granulepos > 0 )
1115 i_duration = p_stream->special.speex.i_framesize *
1116 p_stream->special.speex.i_framesperpacket;
1117 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1118 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1119 p_stream->i_previous_granulepos, false );
1120 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1122 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1123 p_stream->i_previous_granulepos > 0 &&
1124 ( i_duration =
1125 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1127 ogg_int64_t sample;
1128 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1129 sample = p_stream->i_previous_granulepos;
1130 if (sample >= p_stream->i_pre_skip)
1131 sample -= p_stream->i_pre_skip;
1132 else
1133 sample = 0;
1135 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1136 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1138 else if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_UNKNOWN )
1140 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1142 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1144 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1145 p_stream->fmt.i_bitrate / 8 );
1149 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1152 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1153 block_t *p_block )
1155 demux_sys_t *p_ogg = p_demux->p_sys;
1156 if ( (!p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN) &&
1157 p_ogg->i_nzpcr_offset == 0 /* Not on chained streams */ )
1159 if ( !p_block ) return;
1160 if ( p_stream->prepcr.pp_blocks )
1162 assert( p_stream->prepcr.i_size );
1163 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1165 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1166 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1167 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1169 else
1171 /* Because ES creation is delayed for preparsing */
1172 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1173 if ( p_stream->p_preparse_block )
1175 block_t *temp = p_stream->p_preparse_block;
1176 while ( temp )
1178 if ( temp && i_firstpts < VLC_TS_0 )
1179 i_firstpts = temp->i_pts;
1181 block_t *tosend = temp;
1182 temp = temp->p_next;
1183 tosend->p_next = NULL;
1185 if( tosend->i_pts < VLC_TS_0 )
1187 /* Don't send metadata from chained streams */
1188 block_Release( tosend );
1189 continue;
1191 else if( tosend->i_dts < VLC_TS_0 )
1193 tosend->i_dts = tosend->i_pts;
1196 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1197 tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1198 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1200 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1202 p_ogg->i_pcr = i_firstpts;
1203 if( likely( !p_ogg->b_slave ) )
1204 es_out_SetPCR( p_demux->out, p_ogg->i_pcr );
1207 p_stream->p_preparse_block = NULL;
1210 if ( p_block )
1212 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1213 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1214 if ( p_stream->p_es )
1215 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1216 else
1217 block_Release( p_block );
1222 /****************************************************************************
1223 * Ogg_DecodePacket: Decode an Ogg packet.
1224 ****************************************************************************/
1225 static void Ogg_DecodePacket( demux_t *p_demux,
1226 logical_stream_t *p_stream,
1227 ogg_packet *p_oggpacket )
1229 demux_sys_t *p_sys = p_demux->p_sys;
1230 block_t *p_block;
1231 bool b_selected;
1232 int i_header_len = 0;
1234 if( p_oggpacket->bytes >= 7 &&
1235 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1237 /* it's an Annodex packet -- skip it (do nothing) */
1238 return;
1240 else if( p_oggpacket->bytes >= 7 &&
1241 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1243 /* it's an AnxData packet -- skip it (do nothing) */
1244 return;
1246 else if( p_oggpacket->bytes >= 8 &&
1247 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1249 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1250 return;
1252 else if( p_oggpacket->bytes >= 6 &&
1253 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1255 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1256 return;
1258 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1259 p_oggpacket->bytes >= 7 &&
1260 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1262 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1263 return;
1266 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1267 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1269 /* Check the ES is selected */
1270 if ( !p_stream->p_es )
1271 b_selected = true;
1272 else
1273 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1274 p_stream->p_es, &b_selected );
1276 if( p_stream->b_force_backup )
1278 bool b_xiph;
1279 p_stream->i_packets_backup++;
1280 switch( p_stream->fmt.i_codec )
1282 case VLC_CODEC_VORBIS:
1283 #ifdef HAVE_LIBVORBIS
1284 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1285 #endif
1286 /* fallthrough */
1287 case VLC_CODEC_THEORA:
1288 if( p_stream->i_packets_backup == 3 )
1289 p_stream->b_force_backup = false;
1290 b_xiph = true;
1291 break;
1293 case VLC_CODEC_DAALA:
1294 if( p_stream->i_packets_backup == 3 )
1295 p_stream->b_force_backup = false;
1296 b_xiph = true;
1297 break;
1299 case VLC_CODEC_SPEEX:
1300 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1301 p_stream->b_force_backup = false;
1302 b_xiph = true;
1303 break;
1305 case VLC_CODEC_OPUS:
1306 if( p_stream->i_packets_backup == 2 )
1307 p_stream->b_force_backup = false;
1308 b_xiph = true;
1309 break;
1311 case VLC_CODEC_FLAC:
1312 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1314 p_stream->b_force_backup = false;
1316 if( p_stream->special.flac.b_old )
1318 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1320 else if( p_stream->i_packets_backup == 1 )
1322 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1324 p_oggpacket->packet += 9;
1325 p_oggpacket->bytes -= 9;
1328 b_xiph = false;
1329 break;
1331 case VLC_CODEC_KATE:
1332 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1333 p_stream->b_force_backup = false;
1334 b_xiph = true;
1335 break;
1337 default:
1338 p_stream->b_force_backup = false;
1339 b_xiph = false;
1340 break;
1343 /* Backup the ogg packet (likely an header packet) */
1344 if( !b_xiph )
1346 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1347 if( p_realloc )
1349 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1350 p_stream->i_headers += p_oggpacket->bytes;
1351 p_stream->p_headers = p_realloc;
1353 else
1355 free( p_stream->p_headers );
1356 p_stream->i_headers = 0;
1357 p_stream->p_headers = NULL;
1360 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1361 p_oggpacket->bytes, p_oggpacket->packet ) )
1363 p_stream->i_headers = 0;
1364 p_stream->p_headers = NULL;
1366 if( p_stream->i_headers > 0 )
1368 if( !p_stream->b_force_backup )
1370 /* Last header received, commit changes */
1371 free( p_stream->fmt.p_extra );
1373 p_stream->fmt.i_extra = p_stream->i_headers;
1374 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1375 if( p_stream->fmt.p_extra )
1376 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1377 p_stream->i_headers );
1378 else
1379 p_stream->fmt.i_extra = 0;
1381 if( p_stream->i_headers > 0 )
1382 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1383 p_stream->p_headers, p_stream->i_headers );
1385 /* we're not at BOS anymore for this logical stream */
1386 p_stream->b_initializing = false;
1390 b_selected = false; /* Discard the header packet */
1392 else
1394 p_stream->b_initializing = false;
1397 /* Convert the granulepos into the next pcr */
1398 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1400 if( !b_selected )
1402 /* This stream isn't currently selected so we don't need to decode it,
1403 * but we did need to store its pcr as it might be selected later on */
1404 return;
1407 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1409 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1410 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1412 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1413 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1415 /* may need to preroll after a seek or in case of preskip */
1416 if ( p_stream->i_skip_frames > 0 )
1418 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1420 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1422 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1423 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1424 p_stream->i_skip_frames -= p_block->i_nb_samples;
1425 p_block->i_nb_samples = 0;
1427 else
1429 p_block->i_nb_samples -= p_stream->i_skip_frames;
1430 p_stream->i_skip_frames = 0;
1433 else
1435 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1436 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1437 p_stream->i_skip_frames--;
1441 /* Conditional block fixes */
1442 if ( p_stream->fmt.i_cat == VIDEO_ES )
1444 if( Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1445 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1447 if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1449 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1450 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1451 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1452 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1453 /* granulepos for dirac is possibly broken, this value should be ignored */
1454 if( 0 >= p_oggpacket->granulepos )
1456 p_block->i_pts = VLC_TS_INVALID;
1457 p_block->i_dts = p_stream->i_pcr;
1460 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1462 p_block->i_pts =
1463 p_block->i_dts = p_stream->i_pcr;
1465 else
1467 p_block->i_pts = VLC_TS_INVALID;
1468 p_block->i_dts = p_stream->i_pcr;
1471 else if( p_stream->fmt.i_cat == AUDIO_ES )
1473 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1474 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1475 p_stream->fmt.b_packetized )
1477 /* Handle OggFlac spec violation (multiple frame/packet
1478 * by turning on packetizer */
1479 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1480 p_stream->fmt.b_packetized = false;
1481 es_out_Del( p_demux->out, p_stream->p_es );
1482 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1484 else if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1486 /* FIXME: the biggest hack I've ever done */
1487 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1488 p_block->i_pts, p_block->i_dts );
1489 msleep(10000);
1492 /* Blatant abuse of the i_length field. */
1493 p_block->i_length = p_stream->i_end_trim;
1494 p_block->i_pts = p_block->i_dts = p_stream->i_pcr;
1496 else if( p_stream->fmt.i_cat == SPU_ES )
1498 p_block->i_length = 0;
1499 p_block->i_pts = p_block->i_dts = p_stream->i_pcr;
1502 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1503 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1504 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1505 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1506 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1507 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1508 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1509 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1510 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1511 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1512 p_stream->fmt.i_codec != VLC_CODEC_KATE &&
1513 p_stream->fmt.i_codec != VLC_CODEC_OGGSPOTS )
1515 if( p_oggpacket->bytes <= 0 )
1517 msg_Dbg( p_demux, "discarding 0 sized packet" );
1518 block_Release( p_block );
1519 return;
1521 /* We remove the header from the packet */
1522 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1523 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1525 if( i_header_len >= p_oggpacket->bytes )
1527 msg_Dbg( p_demux, "discarding invalid packet" );
1528 block_Release( p_block );
1529 return;
1532 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1534 /* But with subtitles we need to retrieve the duration first */
1535 int i, lenbytes = 0;
1537 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1539 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1541 lenbytes = lenbytes << 8;
1542 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1545 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1546 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1547 p_oggpacket->packet[i_header_len + 1] != 0 &&
1548 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1549 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1551 p_block->i_length = (mtime_t)lenbytes * 1000;
1555 i_header_len++;
1556 if( p_block->i_buffer >= (unsigned int)i_header_len )
1557 p_block->i_buffer -= i_header_len;
1558 else
1559 p_block->i_buffer = 0;
1562 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1563 p_oggpacket->bytes - i_header_len );
1565 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1568 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1570 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1573 /****************************************************************************
1574 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1575 * stream and fill p_ogg.
1576 *****************************************************************************
1577 * The initial page of a logical stream is marked as a 'bos' page.
1578 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1579 * together and all of the initial pages must appear before any data pages.
1581 * On success this function returns VLC_SUCCESS.
1582 ****************************************************************************/
1583 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1585 demux_sys_t *p_ogg = p_demux->p_sys ;
1586 ogg_packet oggpacket;
1588 p_ogg->i_total_length = stream_Size ( p_demux->s );
1589 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1592 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1595 if( ogg_page_bos( &p_ogg->current_page ) )
1598 /* All is wonderful in our fine fine little world.
1599 * We found the beginning of our first logical stream. */
1600 while( ogg_page_bos( &p_ogg->current_page ) )
1602 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1603 if( unlikely( !p_stream ) )
1604 return VLC_ENOMEM;
1606 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1608 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
1609 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
1610 p_stream->b_initializing = true;
1612 /* Setup the logical stream */
1613 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1614 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1616 /* Extract the initial header from the first page and verify
1617 * the codec type of this Ogg bitstream */
1618 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1620 /* error. stream version mismatch perhaps */
1621 msg_Err( p_demux, "error reading first page of "
1622 "Ogg bitstream data" );
1623 return VLC_EGENERIC;
1626 /* FIXME: check return value */
1627 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1629 /* Check for Vorbis header */
1630 if( oggpacket.bytes >= 7 &&
1631 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1633 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1634 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1635 msg_Dbg( p_demux, "found vorbis header" );
1636 else
1638 msg_Dbg( p_demux, "found invalid vorbis header" );
1639 Ogg_LogicalStreamDelete( p_demux, p_stream );
1640 p_stream = NULL;
1641 p_ogg->i_streams--;
1644 /* Check for Speex header */
1645 else if( oggpacket.bytes >= 5 &&
1646 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1648 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1649 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1650 msg_Dbg( p_demux, "found speex header, channels: %i, "
1651 "rate: %i, bitrate: %i, frames: %i group %i",
1652 p_stream->fmt.audio.i_channels,
1653 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1654 p_stream->special.speex.i_framesize,
1655 p_stream->special.speex.i_framesperpacket );
1656 else
1658 msg_Dbg( p_demux, "found invalid Speex header" );
1659 Ogg_LogicalStreamDelete( p_demux, p_stream );
1660 p_stream = NULL;
1661 p_ogg->i_streams--;
1664 /* Check for Opus header */
1665 else if( oggpacket.bytes >= 8 &&
1666 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1668 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1669 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1670 msg_Dbg( p_demux, "found opus header, channels: %i, "
1671 "pre-skip: %i",
1672 p_stream->fmt.audio.i_channels,
1673 (int)p_stream->i_pre_skip);
1674 p_stream->i_skip_frames = p_stream->i_pre_skip;
1676 /* Check for OLD Flac header */
1677 else if( oggpacket.bytes >= 4 &&
1678 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1680 msg_Dbg( p_demux, "found FLAC header" );
1682 /* Grrrr!!!! Did they really have to put all the
1683 * important info in the second header packet!!!
1684 * (STREAMINFO metadata is in the following packet) */
1685 p_stream->b_force_backup = true;
1686 p_stream->i_extra_headers_packets = 1;
1687 p_stream->special.flac.b_old = true;
1688 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1690 /* Check for Flac header (>= version 1.0.0) */
1691 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1692 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1693 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1695 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1696 oggpacket.packet[8];
1697 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1698 "(%i header packets)",
1699 oggpacket.packet[5], oggpacket.packet[6],
1700 i_packets );
1701 /* STREAMINFO is in current packet, and then
1702 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1703 p_stream->b_force_backup = true;
1704 p_stream->i_extra_headers_packets = i_packets;
1705 p_stream->special.flac.b_old = false;
1707 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1708 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1709 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1711 msg_Dbg( p_demux, "found invalid Flac header" );
1712 Ogg_LogicalStreamDelete( p_demux, p_stream );
1713 p_stream = NULL;
1714 p_ogg->i_streams--;
1717 /* Check for Theora header */
1718 else if( oggpacket.bytes >= 7 &&
1719 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1721 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1722 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1723 msg_Dbg( p_demux,
1724 "found theora header, bitrate: %i, rate: %f",
1725 p_stream->fmt.i_bitrate, p_stream->f_rate );
1726 else
1728 msg_Dbg( p_demux, "found invalid Theora header" );
1729 Ogg_LogicalStreamDelete( p_demux, p_stream );
1730 p_stream = NULL;
1731 p_ogg->i_streams--;
1734 /* Check for Daala header */
1735 else if( oggpacket.bytes >= 6 &&
1736 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1738 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1739 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1740 msg_Dbg( p_demux,
1741 "found daala header, bitrate: %i, rate: %f",
1742 p_stream->fmt.i_bitrate, p_stream->f_rate );
1743 else
1745 msg_Dbg( p_demux, "found invalid Daala header" );
1746 Ogg_LogicalStreamDelete( p_demux, p_stream );
1747 p_stream = NULL;
1748 p_ogg->i_streams--;
1751 /* Check for Dirac header */
1752 else if( ( oggpacket.bytes >= 5 &&
1753 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1754 ( oggpacket.bytes >= 9 &&
1755 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1757 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1758 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1759 msg_Dbg( p_demux, "found dirac header" );
1760 else
1762 msg_Warn( p_demux, "found dirac header isn't decodable" );
1763 Ogg_LogicalStreamDelete( p_demux, p_stream );
1764 p_stream = NULL;
1765 p_ogg->i_streams--;
1768 /* Check for Tarkin header */
1769 else if( oggpacket.bytes >= 7 &&
1770 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1772 oggpack_buffer opb;
1774 msg_Dbg( p_demux, "found tarkin header" );
1775 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_TARKIN );
1777 /* Cheat and get additionnal info ;) */
1778 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1779 oggpack_adv( &opb, 88 );
1780 oggpack_adv( &opb, 104 );
1781 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1782 p_stream->f_rate = 2; /* FIXME */
1783 msg_Dbg( p_demux,
1784 "found tarkin header, bitrate: %i, rate: %f",
1785 p_stream->fmt.i_bitrate, p_stream->f_rate );
1787 /* Check for VP8 header */
1788 else if( oggpacket.bytes >= 26 &&
1789 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1791 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1792 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1793 msg_Dbg( p_demux, "found VP8 header "
1794 "fps: %f, width:%i; height:%i",
1795 p_stream->f_rate,
1796 p_stream->fmt.video.i_width,
1797 p_stream->fmt.video.i_height );
1798 else
1800 msg_Dbg( p_demux, "invalid VP8 header found");
1801 Ogg_LogicalStreamDelete( p_demux, p_stream );
1802 p_stream = NULL;
1803 p_ogg->i_streams--;
1806 /* Check for Annodex header */
1807 else if( oggpacket.bytes >= 7 &&
1808 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1810 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1811 /* kill annodex track */
1812 FREENULL( p_stream );
1813 p_ogg->i_streams--;
1815 /* Check for Annodex header */
1816 else if( oggpacket.bytes >= 7 &&
1817 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1819 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1821 /* Check for Kate header */
1822 else if( oggpacket.bytes >= 8 &&
1823 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1825 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1826 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1827 msg_Dbg( p_demux, "found kate header" );
1828 else
1830 msg_Dbg( p_demux, "invalid kate header found");
1831 Ogg_LogicalStreamDelete( p_demux, p_stream );
1832 p_stream = NULL;
1833 p_ogg->i_streams--;
1836 /* Check for OggDS */
1837 else if( oggpacket.bytes >= 142 &&
1838 !memcmp( &oggpacket.packet[1],
1839 "Direct Show Samples embedded in Ogg", 35 ))
1841 /* Old header type */
1842 p_stream->b_oggds = true;
1843 /* Check for video header (old format) */
1844 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1845 oggpacket.bytes >= 184 )
1847 es_format_Change( &p_stream->fmt, VIDEO_ES,
1848 VLC_FOURCC( oggpacket.packet[68],
1849 oggpacket.packet[69],
1850 oggpacket.packet[70],
1851 oggpacket.packet[71] ) );
1852 msg_Dbg( p_demux, "found video header of type: %.4s",
1853 (char *)&p_stream->fmt.i_codec );
1855 p_stream->fmt.video.i_frame_rate = 10000000;
1856 p_stream->fmt.video.i_frame_rate_base =
1857 GetQWLE((oggpacket.packet+164));
1858 p_stream->fmt.video.i_frame_rate_base =
1859 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1860 p_stream->f_rate = 10000000.0 /
1861 p_stream->fmt.video.i_frame_rate_base;
1862 p_stream->fmt.video.i_bits_per_pixel =
1863 GetWLE((oggpacket.packet+182));
1864 if( !p_stream->fmt.video.i_bits_per_pixel )
1865 /* hack, FIXME */
1866 p_stream->fmt.video.i_bits_per_pixel = 24;
1867 p_stream->fmt.video.i_width =
1868 GetDWLE((oggpacket.packet+176));
1869 p_stream->fmt.video.i_height =
1870 GetDWLE((oggpacket.packet+180));
1871 p_stream->fmt.video.i_visible_width =
1872 p_stream->fmt.video.i_width;
1873 p_stream->fmt.video.i_visible_height =
1874 p_stream->fmt.video.i_height;
1876 msg_Dbg( p_demux,
1877 "fps: %f, width:%i; height:%i, bitcount:%i",
1878 p_stream->f_rate,
1879 p_stream->fmt.video.i_width,
1880 p_stream->fmt.video.i_height,
1881 p_stream->fmt.video.i_bits_per_pixel);
1884 /* Check for audio header (old format) */
1885 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1887 int i_extra_size;
1888 unsigned int i_format_tag;
1890 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1892 i_extra_size = GetWLE((oggpacket.packet+140));
1893 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1895 p_stream->fmt.i_extra = i_extra_size;
1896 p_stream->fmt.p_extra = malloc( i_extra_size );
1897 if( p_stream->fmt.p_extra )
1898 memcpy( p_stream->fmt.p_extra,
1899 oggpacket.packet + 142, i_extra_size );
1900 else
1901 p_stream->fmt.i_extra = 0;
1904 i_format_tag = GetWLE((oggpacket.packet+124));
1905 p_stream->fmt.audio.i_channels =
1906 GetWLE((oggpacket.packet+126));
1907 fill_channels_info(&p_stream->fmt.audio);
1908 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1909 GetDWLE((oggpacket.packet+128));
1910 p_stream->fmt.i_bitrate =
1911 GetDWLE((oggpacket.packet+132)) * 8;
1912 p_stream->fmt.audio.i_blockalign =
1913 GetWLE((oggpacket.packet+136));
1914 p_stream->fmt.audio.i_bitspersample =
1915 GetWLE((oggpacket.packet+138));
1917 wf_tag_to_fourcc( i_format_tag,
1918 &p_stream->fmt.i_codec, 0 );
1920 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1922 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1923 ( i_format_tag >> 8 ) & 0xff,
1924 i_format_tag & 0xff );
1927 msg_Dbg( p_demux, "found audio header of type: %.4s",
1928 (char *)&p_stream->fmt.i_codec );
1929 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1930 "%dbits/sample %dkb/s",
1931 i_format_tag,
1932 p_stream->fmt.audio.i_channels,
1933 p_stream->fmt.audio.i_rate,
1934 p_stream->fmt.audio.i_bitspersample,
1935 p_stream->fmt.i_bitrate / 1024 );
1936 if ( p_stream->f_rate == 0 )
1938 msg_Dbg( p_demux, "invalid oggds audio header" );
1939 Ogg_LogicalStreamDelete( p_demux, p_stream );
1940 p_stream = NULL;
1941 p_ogg->i_streams--;
1944 else
1946 msg_Dbg( p_demux, "stream %d has an old header "
1947 "but is of an unknown type", p_ogg->i_streams-1 );
1948 FREENULL( p_stream );
1949 p_ogg->i_streams--;
1952 /* Check for OggDS */
1953 else if( oggpacket.bytes >= 44+1 &&
1954 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1956 stream_header_t tmp;
1957 stream_header_t *st = &tmp;
1959 p_stream->b_oggds = true;
1961 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1962 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1963 st->size = GetDWLE( &oggpacket.packet[1+12] );
1964 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1965 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1966 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1967 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1968 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1970 /* Check for video header (new format) */
1971 if( !strncmp( st->streamtype, "video", 5 ) &&
1972 oggpacket.bytes >= 52+1 )
1974 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1975 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1977 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1979 /* We need to get rid of the header packet */
1980 ogg_stream_packetout( &p_stream->os, &oggpacket );
1982 p_stream->fmt.i_codec =
1983 VLC_FOURCC( st->subtype[0], st->subtype[1],
1984 st->subtype[2], st->subtype[3] );
1985 msg_Dbg( p_demux, "found video header of type: %.4s",
1986 (char *)&p_stream->fmt.i_codec );
1988 p_stream->fmt.video.i_frame_rate = 10000000;
1989 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1990 if( st->time_unit <= 0 )
1991 st->time_unit = 400000;
1992 p_stream->f_rate = 10000000.0 / st->time_unit;
1993 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1994 p_stream->fmt.video.i_width = st->sh.video.width;
1995 p_stream->fmt.video.i_height = st->sh.video.height;
1996 p_stream->fmt.video.i_visible_width =
1997 p_stream->fmt.video.i_width;
1998 p_stream->fmt.video.i_visible_height =
1999 p_stream->fmt.video.i_height;
2001 msg_Dbg( p_demux,
2002 "fps: %f, width:%i; height:%i, bitcount:%i",
2003 p_stream->f_rate,
2004 p_stream->fmt.video.i_width,
2005 p_stream->fmt.video.i_height,
2006 p_stream->fmt.video.i_bits_per_pixel );
2008 /* Check for audio header (new format) */
2009 else if( !strncmp( st->streamtype, "audio", 5 ) &&
2010 oggpacket.bytes >= 56+1 )
2012 char p_buffer[5];
2013 int i_extra_size;
2014 int i_format_tag;
2016 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
2017 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
2018 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
2020 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
2022 /* We need to get rid of the header packet */
2023 ogg_stream_packetout( &p_stream->os, &oggpacket );
2025 i_extra_size = st->size - 56;
2027 if( i_extra_size > 0 &&
2028 i_extra_size < oggpacket.bytes - 1 - 56 )
2030 p_stream->fmt.i_extra = i_extra_size;
2031 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
2032 if( p_stream->fmt.p_extra )
2033 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
2034 p_stream->fmt.i_extra );
2035 else
2036 p_stream->fmt.i_extra = 0;
2039 memcpy( p_buffer, st->subtype, 4 );
2040 p_buffer[4] = '\0';
2041 i_format_tag = strtol(p_buffer,NULL,16);
2042 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
2043 fill_channels_info(&p_stream->fmt.audio);
2044 if( st->time_unit <= 0 )
2045 st->time_unit = 10000000;
2046 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
2047 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
2048 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
2049 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
2051 wf_tag_to_fourcc( i_format_tag,
2052 &p_stream->fmt.i_codec, 0 );
2054 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
2056 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
2057 ( i_format_tag >> 8 ) & 0xff,
2058 i_format_tag & 0xff );
2061 msg_Dbg( p_demux, "found audio header of type: %.4s",
2062 (char *)&p_stream->fmt.i_codec );
2063 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2064 "%dbits/sample %dkb/s",
2065 i_format_tag,
2066 p_stream->fmt.audio.i_channels,
2067 p_stream->fmt.audio.i_rate,
2068 p_stream->fmt.audio.i_bitspersample,
2069 p_stream->fmt.i_bitrate / 1024 );
2070 if ( p_stream->f_rate == 0 )
2072 msg_Dbg( p_demux, "invalid oggds audio header" );
2073 Ogg_LogicalStreamDelete( p_demux, p_stream );
2074 p_stream = NULL;
2075 p_ogg->i_streams--;
2078 /* Check for text (subtitles) header */
2079 else if( !strncmp(st->streamtype, "text", 4) )
2081 /* We need to get rid of the header packet */
2082 ogg_stream_packetout( &p_stream->os, &oggpacket );
2084 msg_Dbg( p_demux, "found text subtitle header" );
2085 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2086 p_stream->f_rate = 1000; /* granulepos is in millisec */
2088 else
2090 msg_Dbg( p_demux, "stream %d has a header marker "
2091 "but is of an unknown type", p_ogg->i_streams-1 );
2092 FREENULL( p_stream );
2093 p_ogg->i_streams--;
2096 else if( oggpacket.bytes >= 8 &&
2097 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2100 /* Skeleton */
2101 msg_Dbg( p_demux, "stream %d is a skeleton",
2102 p_ogg->i_streams-1 );
2103 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2105 /* Check for OggSpots header */
2106 else if( oggpacket.bytes >= 8 &&
2107 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2109 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2110 msg_Dbg( p_demux,
2111 "found OggSpots header, time resolution: %f",
2112 p_stream->f_rate );
2113 else
2115 msg_Err( p_demux, "found invalid OggSpots header" );
2116 Ogg_LogicalStreamDelete( p_demux, p_stream );
2117 p_stream = NULL;
2118 p_ogg->i_streams--;
2121 else
2123 msg_Dbg( p_demux, "stream %d is of unknown type",
2124 p_ogg->i_streams-1 );
2127 /* we'll need to get all headers */
2128 if ( p_stream )
2129 p_stream->b_initializing &= p_stream->b_force_backup;
2131 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2132 return VLC_EGENERIC;
2135 /* This is the first data page, which means we are now finished
2136 * with the initial pages. We just need to store it in the relevant
2137 * bitstream. */
2138 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2140 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2141 &p_ogg->current_page ) == 0 )
2143 p_ogg->b_page_waiting = true;
2144 break;
2148 return VLC_SUCCESS;
2152 return VLC_EGENERIC;
2155 /****************************************************************************
2156 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2157 ****************************************************************************/
2158 static void Ogg_CreateES( demux_t *p_demux )
2160 demux_sys_t *p_ogg = p_demux->p_sys;
2161 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2162 int i_stream;
2164 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2166 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2168 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2170 /* Better be safe than sorry when possible with ogm */
2171 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2172 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2173 p_stream->fmt.b_packetized = false;
2175 /* Try first to reuse an old ES */
2176 if( p_old_stream &&
2177 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2178 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2180 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2182 p_stream->p_es = p_old_stream->p_es;
2183 p_stream->b_finished = false;
2184 p_stream->b_reinit = false;
2185 p_stream->b_initializing = false;
2186 p_stream->i_pre_skip = 0;
2187 es_format_Clean( &p_stream->fmt_old );
2188 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2189 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2191 p_old_stream->p_es = NULL;
2192 p_old_stream = NULL;
2193 if ( b_resetdecoder )
2195 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2196 p_stream->p_es, &p_stream->fmt );
2199 else
2201 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2204 // TODO: something to do here ?
2205 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2207 /* Set the CMML stream active */
2208 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2213 if( p_ogg->p_old_stream )
2215 if( p_ogg->p_old_stream->p_es )
2216 msg_Dbg( p_demux, "old stream not reused" );
2217 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2218 p_ogg->p_old_stream = NULL;
2220 p_ogg->b_es_created = true;
2223 /****************************************************************************
2224 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2225 * Elementary streams.
2226 ****************************************************************************/
2227 static int Ogg_BeginningOfStream( demux_t *p_demux )
2229 demux_sys_t *p_ogg = p_demux->p_sys ;
2230 int i_stream;
2232 /* Find the logical streams embedded in the physical stream and
2233 * initialize our p_ogg structure. */
2234 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2236 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2237 return VLC_EGENERIC;
2240 p_ogg->i_bitrate = 0;
2242 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2244 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2246 p_stream->p_es = NULL;
2248 /* initialise kframe index */
2249 p_stream->idx=NULL;
2251 if ( p_stream->fmt.i_bitrate == 0 &&
2252 ( p_stream->fmt.i_cat == VIDEO_ES ||
2253 p_stream->fmt.i_cat == AUDIO_ES ) )
2254 p_ogg->b_partial_bitrate = true;
2255 else
2256 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2258 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2259 p_stream->i_previous_granulepos = -1;
2260 p_stream->b_reinit = false;
2263 /* get total frame count for video stream; we will need this for seeking */
2264 p_ogg->i_total_frames = 0;
2266 return VLC_SUCCESS;
2269 /****************************************************************************
2270 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2271 ****************************************************************************/
2272 static void Ogg_EndOfStream( demux_t *p_demux )
2274 demux_sys_t *p_ogg = p_demux->p_sys ;
2275 int i_stream;
2277 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2278 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2279 free( p_ogg->pp_stream );
2281 /* Reinit p_ogg */
2282 p_ogg->i_bitrate = 0;
2283 p_ogg->i_streams = 0;
2284 p_ogg->pp_stream = NULL;
2285 p_ogg->skeleton.major = 0;
2286 p_ogg->skeleton.minor = 0;
2287 p_ogg->b_preparsing_done = false;
2288 p_ogg->b_es_created = false;
2290 /* */
2291 if( p_ogg->p_meta )
2292 vlc_meta_Delete( p_ogg->p_meta );
2293 p_ogg->p_meta = NULL;
2295 for(int i=0; i<p_ogg->i_attachments; i++)
2296 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2297 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2299 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2301 if ( p_ogg->pp_seekpoints[i] )
2302 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2304 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2307 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2309 #ifdef HAVE_LIBVORBIS
2310 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2312 if( p_stream->special.vorbis.p_info )
2313 vorbis_info_clear( p_stream->special.vorbis.p_info );
2314 FREENULL( p_stream->special.vorbis.p_info );
2315 if( p_stream->special.vorbis.p_comment )
2316 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2317 FREENULL( p_stream->special.vorbis.p_comment );
2318 p_stream->special.vorbis.i_headers_flags = 0;
2320 #else
2321 VLC_UNUSED( p_stream );
2322 #endif
2326 * This function delete and release all data associated to a logical_stream_t
2328 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2330 demux_sys_t *p_sys = p_demux->p_sys;
2332 if( p_stream->p_es )
2333 es_out_Del( p_demux->out, p_stream->p_es );
2335 ogg_stream_clear( &p_stream->os );
2336 free( p_stream->p_headers );
2338 Ogg_CleanSpecificData( p_stream );
2340 es_format_Clean( &p_stream->fmt_old );
2341 es_format_Clean( &p_stream->fmt );
2343 if ( p_stream->idx != NULL)
2345 oggseek_index_entries_free( p_stream->idx );
2348 Ogg_FreeSkeleton( p_stream->p_skel );
2349 p_stream->p_skel = NULL;
2350 if( p_sys->p_skelstream == p_stream )
2351 p_sys->p_skelstream = NULL;
2353 /* Shouldn't happen */
2354 if ( unlikely( p_stream->p_preparse_block ) )
2356 block_ChainRelease( p_stream->p_preparse_block );
2357 p_stream->p_preparse_block = NULL;
2359 free( p_stream->prepcr.pp_blocks );
2361 free( p_stream );
2364 * This function check if a we need to reset a decoder in case we are
2365 * reusing an old ES
2367 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2369 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2370 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2371 unsigned i_new_count;
2372 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2373 i_new_count = 0;
2375 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2376 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2377 unsigned i_old_count;
2378 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2379 i_old_count = 0;
2381 bool b_match = i_new_count == i_old_count;
2382 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2384 /* Ignore vorbis comment */
2385 if( i == 1 )
2386 continue;
2387 if( pi_new_size[i] != pi_old_size[i] ||
2388 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2389 b_match = false;
2392 return b_match;
2395 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2396 const es_format_t *p_old )
2398 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2399 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2400 unsigned i_new_count;
2401 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2402 i_new_count = 0;
2403 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2404 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2405 unsigned i_old_count;
2406 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2407 i_old_count = 0;
2408 bool b_match = false;
2409 if( i_new_count == i_old_count && i_new_count > 0 )
2411 static const unsigned char default_map[2] = { 0, 1 };
2412 unsigned char *p_old_head;
2413 unsigned char *p_new_head;
2414 const unsigned char *p_old_map;
2415 const unsigned char *p_new_map;
2416 int i_old_channel_count;
2417 int i_new_channel_count;
2418 int i_old_stream_count;
2419 int i_new_stream_count;
2420 int i_old_coupled_count;
2421 int i_new_coupled_count;
2422 p_old_head = (unsigned char *)pp_old_data[0];
2423 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2424 p_old_map = default_map;
2425 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2427 i_old_channel_count = p_old_head[9];
2428 switch( p_old_head[18] )
2430 case 0:
2431 i_old_stream_count = 1;
2432 i_old_coupled_count = i_old_channel_count - 1;
2433 break;
2434 case 1:
2435 if( pi_old_size[0] >= 21U + i_old_channel_count )
2437 i_old_stream_count = p_old_head[19];
2438 i_old_coupled_count = p_old_head[20];
2439 p_old_map = p_old_head + 21;
2441 break;
2444 p_new_head = (unsigned char *)pp_new_data[0];
2445 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2446 p_new_map = default_map;
2447 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2449 i_new_channel_count = p_new_head[9];
2450 switch( p_new_head[18] )
2452 case 0:
2453 i_new_stream_count = 1;
2454 i_new_coupled_count = i_new_channel_count - 1;
2455 break;
2456 case 1:
2457 if( pi_new_size[0] >= 21U + i_new_channel_count )
2459 i_new_stream_count = p_new_head[19];
2460 i_new_coupled_count = p_new_head[20];
2461 p_new_map = p_new_head+21;
2463 break;
2466 b_match = i_old_channel_count == i_new_channel_count &&
2467 i_old_stream_count == i_new_stream_count &&
2468 i_old_coupled_count == i_new_coupled_count &&
2469 memcmp(p_old_map, p_new_map,
2470 i_new_channel_count*sizeof(*p_new_map)) == 0;
2473 return b_match;
2476 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2478 bool b_compatible = false;
2479 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2480 return true;
2482 /* Only Vorbis and Opus are supported. */
2483 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2484 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2485 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2486 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2488 if( !b_compatible )
2489 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2491 return !b_compatible;
2494 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2495 const void *p_headers, unsigned i_headers )
2497 demux_sys_t *p_ogg = p_demux->p_sys;
2498 int i_cover_score = 0;
2499 int i_cover_idx = 0;
2500 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2501 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2502 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2504 pf_replay_gain[i] = 0;
2505 pf_replay_peak[i] = 0;
2507 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2508 &p_ogg->i_attachments, &p_ogg->attachments,
2509 &i_cover_score, &i_cover_idx,
2510 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2511 &pf_replay_gain, &pf_replay_peak );
2512 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2514 char psz_url[128];
2515 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2516 p_ogg->attachments[i_cover_idx]->psz_name );
2517 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2520 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2522 if ( pf_replay_gain[i] != 0 )
2524 p_fmt->audio_replay_gain.pb_gain[i] = true;
2525 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2526 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2528 if ( pf_replay_peak[i] != 0 )
2530 p_fmt->audio_replay_gain.pb_peak[i] = true;
2531 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2532 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2536 if( p_ogg->i_seekpoints > 1 )
2538 p_ogg->updates |= INPUT_UPDATE_TITLE_LIST;
2542 static inline uint32_t GetDW24BE( const uint8_t *p )
2544 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2545 #ifdef WORDS_BIGENDIAN
2546 i = bswap32(i);
2547 #endif
2548 return i;
2551 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2552 const uint8_t *p_headers, unsigned i_headers )
2554 /* Skip Streaminfo 42 bytes / 1st page */
2555 if(i_headers <= 46)
2556 return;
2557 p_headers += 42; i_headers -= 42;
2558 /* Block Header 1 + 3 bytes */
2559 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2560 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2562 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2566 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2567 const void *p_headers, unsigned i_headers, unsigned i_skip )
2569 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2570 void *pp_data[XIPH_MAX_HEADER_COUNT];
2571 unsigned i_count;
2573 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2574 return;
2575 /* TODO how to handle multiple comments properly ? */
2576 if( i_count >= 2 && pi_size[1] > i_skip )
2578 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2582 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2584 demux_sys_t *p_ogg = p_demux->p_sys;
2586 switch( p_fmt->i_codec )
2588 /* 3 headers with the 2° one being the comments */
2589 case VLC_CODEC_VORBIS:
2590 case VLC_CODEC_THEORA:
2591 case VLC_CODEC_DAALA:
2592 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2593 break;
2594 case VLC_CODEC_OPUS:
2595 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2596 break;
2597 case VLC_CODEC_SPEEX:
2598 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2599 break;
2600 case VLC_CODEC_VP8:
2601 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2602 break;
2603 /* N headers with the 2° one being the comments */
2604 case VLC_CODEC_KATE:
2605 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2606 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2607 break;
2609 /* TODO */
2610 case VLC_CODEC_FLAC:
2611 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2612 break;
2614 /* No meta data */
2615 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2616 case VLC_CODEC_DIRAC:
2617 default:
2618 break;
2620 if( p_ogg->p_meta )
2621 p_ogg->updates |= INPUT_UPDATE_META;
2624 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2625 ogg_packet *p_oggpacket )
2627 bs_t bitstream;
2628 unsigned int i_fps_numerator;
2629 unsigned int i_fps_denominator;
2630 int i_keyframe_frequency_force;
2631 int i_major;
2632 int i_minor;
2633 int i_subminor;
2634 int i_version;
2636 /* Signal that we want to keep a backup of the theora
2637 * stream headers. They will be used when switching between
2638 * audio streams. */
2639 p_stream->b_force_backup = true;
2641 /* Cheat and get additionnal info ;) */
2642 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2643 bs_skip( &bitstream, 56 );
2645 i_major = bs_read( &bitstream, 8 ); /* major version num */
2646 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2647 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2649 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2650 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2651 bs_read( &bitstream, 24 ); /* frame width */
2652 bs_read( &bitstream, 24 ); /* frame height */
2653 bs_read( &bitstream, 8 ); /* x offset */
2654 bs_read( &bitstream, 8 ); /* y offset */
2656 i_fps_numerator = bs_read( &bitstream, 32 );
2657 i_fps_denominator = bs_read( &bitstream, 32 );
2658 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2659 bs_read( &bitstream, 24 ); /* aspect_numerator */
2660 bs_read( &bitstream, 24 ); /* aspect_denominator */
2662 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2663 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2665 bs_read( &bitstream, 8 ); /* colorspace */
2666 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2667 bs_read( &bitstream, 6 ); /* quality */
2669 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2671 /* granule_shift = i_log( frequency_force -1 ) */
2672 p_stream->i_granule_shift = 0;
2673 i_keyframe_frequency_force--;
2674 while( i_keyframe_frequency_force )
2676 p_stream->i_granule_shift++;
2677 i_keyframe_frequency_force >>= 1;
2680 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2681 p_stream->i_keyframe_offset = 0;
2682 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2683 if ( p_stream->f_rate == 0 ) return false;
2685 if ( i_version >= 3002001 )
2687 p_stream->i_keyframe_offset = 1;
2689 return true;
2692 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2693 ogg_packet *p_oggpacket )
2695 oggpack_buffer opb;
2696 uint32_t i_timebase_numerator;
2697 uint32_t i_timebase_denominator;
2698 int i_keyframe_frequency_force;
2699 uint8_t i_major;
2700 uint8_t i_minor;
2701 uint8_t i_subminor;
2702 int i_version;
2704 /* Signal that we want to keep a backup of the daala
2705 * stream headers. They will be used when switching between
2706 * audio streams. */
2707 p_stream->b_force_backup = true;
2709 /* Cheat and get additionnal info ;) */
2710 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2711 oggpack_adv( &opb, 48 );
2713 i_major = oggpack_read( &opb, 8 ); /* major version num */
2714 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2715 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2717 oggpack_adv( &opb, 32 ); /* width */
2718 oggpack_adv( &opb, 32 ); /* height */
2720 oggpack_adv( &opb, 32 ); /* aspect numerator */
2721 oggpack_adv( &opb, 32 ); /* aspect denominator */
2722 i_timebase_numerator = oggpack_read( &opb, 32 );
2724 i_timebase_denominator = oggpack_read( &opb, 32 );
2725 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2727 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2728 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2730 oggpack_adv( &opb, 32 ); /* frame duration */
2732 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2734 /* granule_shift = i_log( frequency_force -1 ) */
2735 p_stream->i_granule_shift = 0;
2736 i_keyframe_frequency_force--;
2737 while( i_keyframe_frequency_force )
2739 p_stream->i_granule_shift++;
2740 i_keyframe_frequency_force >>= 1;
2743 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2744 VLC_UNUSED(i_version);
2745 p_stream->i_keyframe_offset = 0;
2746 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2747 if ( p_stream->f_rate == 0 ) return false;
2749 return true;
2752 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2753 ogg_packet *p_oggpacket )
2755 oggpack_buffer opb;
2757 /* Signal that we want to keep a backup of the vorbis
2758 * stream headers. They will be used when switching between
2759 * audio streams. */
2760 p_stream->b_force_backup = true;
2762 /* Cheat and get additionnal info ;) */
2763 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2764 oggpack_adv( &opb, 88 );
2765 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2766 fill_channels_info(&p_stream->fmt.audio);
2767 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2768 oggpack_read( &opb, 32 );
2769 oggpack_adv( &opb, 32 );
2770 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2771 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2772 if ( p_stream->f_rate == 0 ) return false;
2773 return true;
2775 #ifdef HAVE_LIBVORBIS
2776 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2777 ogg_packet *p_oggpacket, int i_number )
2779 switch( i_number )
2781 case VORBIS_HEADER_IDENTIFICATION:
2782 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2783 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2784 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2786 FREENULL( p_stream->special.vorbis.p_info );
2787 FREENULL( p_stream->special.vorbis.p_comment );
2788 break;
2790 vorbis_info_init( p_stream->special.vorbis.p_info );
2791 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2792 /* fallthrough */
2794 case VORBIS_HEADER_COMMENT:
2795 case VORBIS_HEADER_SETUP:
2796 if ( !p_stream->special.vorbis.p_info ||
2797 vorbis_synthesis_headerin(
2798 p_stream->special.vorbis.p_info,
2799 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2800 break;
2802 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2803 /* fallthrough */
2805 default:
2806 break;
2809 #endif
2811 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2812 ogg_packet *p_oggpacket )
2814 oggpack_buffer opb;
2816 /* Signal that we want to keep a backup of the speex
2817 * stream headers. They will be used when switching between
2818 * audio streams. */
2819 p_stream->b_force_backup = true;
2821 /* Cheat and get additionnal info ;) */
2822 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2823 oggpack_adv( &opb, 224 );
2824 oggpack_adv( &opb, 32 ); /* speex_version_id */
2825 oggpack_adv( &opb, 32 ); /* header_size */
2826 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2827 if ( p_stream->f_rate == 0 ) return false;
2828 oggpack_adv( &opb, 32 ); /* mode */
2829 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2830 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2831 fill_channels_info(&p_stream->fmt.audio);
2832 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2833 p_stream->special.speex.i_framesize =
2834 oggpack_read( &opb, 32 ); /* frame_size */
2835 oggpack_adv( &opb, 32 ); /* vbr */
2836 p_stream->special.speex.i_framesperpacket =
2837 oggpack_read( &opb, 32 ); /* frames_per_packet */
2838 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2839 return true;
2842 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2843 ogg_packet *p_oggpacket )
2845 oggpack_buffer opb;
2847 /* Signal that we want to keep a backup of the opus
2848 * stream headers. They will be used when switching between
2849 * audio streams. */
2850 p_stream->b_force_backup = true;
2852 /* All OggOpus streams are timestamped at 48kHz and
2853 * can be played at 48kHz. */
2854 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2855 p_stream->fmt.i_bitrate = 0;
2857 /* Cheat and get additional info ;) */
2858 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2859 oggpack_adv( &opb, 64 );
2860 oggpack_adv( &opb, 8 ); /* version_id */
2861 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2862 fill_channels_info(&p_stream->fmt.audio);
2863 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2864 /* For Opus, trash the first 80 ms of decoded output as
2865 well, to avoid blowing out speakers if we get unlucky.
2866 Opus predicts content from prior frames, which can go
2867 badly if we seek right where the stream goes from very
2868 quiet to very loud. It will converge after a bit. */
2869 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2872 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2873 ogg_packet *p_oggpacket )
2875 /* Parse the STREAMINFO metadata */
2876 bs_t s;
2878 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2880 bs_read( &s, 1 );
2881 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2883 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2884 return false;
2887 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2889 bs_skip( &s, 80 );
2890 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2891 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2892 fill_channels_info(&p_stream->fmt.audio);
2894 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2895 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2896 if ( p_stream->f_rate == 0 ) return false;
2898 else
2900 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2903 /* Fake this as the last metadata block */
2904 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2905 return true;
2908 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2909 ogg_packet *p_oggpacket )
2911 oggpack_buffer opb;
2912 uint32_t gnum;
2913 uint32_t gden;
2914 int n;
2915 char *psz_desc;
2917 /* Signal that we want to keep a backup of the kate
2918 * stream headers. They will be used when switching between
2919 * kate streams. */
2920 p_stream->b_force_backup = true;
2922 /* Cheat and get additionnal info ;) */
2923 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2924 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2925 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2926 oggpack_adv( &opb, 3*8 );
2927 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2928 oggpack_adv( &opb, 8*8 ); /* reserved */
2929 gnum = oggpack_read( &opb, 32 );
2930 gden = oggpack_read( &opb, 32 );
2931 gden = __MAX( gden, 1 );
2932 p_stream->f_rate = (double)gnum/gden;
2933 if ( p_stream->f_rate == 0 ) return false;
2935 p_stream->fmt.psz_language = malloc(16);
2936 if( p_stream->fmt.psz_language )
2938 for( n = 0; n < 16; n++ )
2939 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2940 p_stream->fmt.psz_language[15] = 0; /* just in case */
2942 else
2944 for( n = 0; n < 16; n++ )
2945 oggpack_read(&opb,8);
2947 p_stream->fmt.psz_description = malloc(16);
2948 if( p_stream->fmt.psz_description )
2950 for( n = 0; n < 16; n++ )
2951 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2952 p_stream->fmt.psz_description[15] = 0; /* just in case */
2954 /* Now find a localized user readable description for this category */
2955 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2956 if( psz_desc )
2958 free( p_stream->fmt.psz_description );
2959 p_stream->fmt.psz_description = psz_desc;
2962 else
2964 for( n = 0; n < 16; n++ )
2965 oggpack_read(&opb,8);
2968 return true;
2971 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2972 ogg_packet *p_oggpacket )
2974 switch( p_oggpacket->packet[5] )
2976 /* STREAMINFO */
2977 case 0x01:
2978 /* Mapping version */
2979 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2980 return false;
2981 p_stream->i_granule_shift = 32;
2982 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2983 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2984 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2985 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2986 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2987 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2988 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2989 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2990 p_stream->fmt.video.i_frame_rate_base =
2991 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2992 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2993 if ( p_stream->f_rate == 0 ) return false;
2994 return true;
2995 /* METADATA */
2996 case 0x02:
2997 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2998 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2999 return true;
3000 default:
3001 return false;
3005 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
3006 bool *b_force_backup, bool *b_packet_out )
3008 if( p_stream->fmt.i_cat != UNKNOWN_ES )
3009 return;
3011 if( !strncmp(psz_value, "audio/x-wav", 11) )
3013 /* n.b. WAVs are unsupported right now */
3014 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3015 free( p_stream->fmt.psz_description );
3016 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
3018 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
3019 !strncmp(psz_value, "audio/vorbis", 12) )
3021 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
3023 *b_force_backup = true;
3025 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
3026 !strncmp(psz_value, "audio/speex", 11) )
3028 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
3030 *b_force_backup = true;
3032 else if( !strncmp(psz_value, "audio/flac", 10) )
3034 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
3036 *b_force_backup = true;
3038 else if( !strncmp(psz_value, "video/x-theora", 14) ||
3039 !strncmp(psz_value, "video/theora", 12) )
3041 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
3043 *b_force_backup = true;
3045 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3046 !strncmp(psz_value, "video/daala", 11) )
3048 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
3050 *b_force_backup = true;
3052 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3054 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
3056 *b_force_backup = true;
3058 else if( !strncmp(psz_value, "video/mpeg", 10) )
3060 /* n.b. MPEG streams are unsupported right now */
3061 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3063 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
3064 !strncmp(psz_value, "text/cmml", 9) )
3066 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_CMML );
3067 *b_packet_out = true;
3069 else if( !strncmp(psz_value, "application/kate", 16) )
3071 /* ??? */
3072 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3073 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3075 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3077 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3081 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3082 logical_stream_t *p_stream,
3083 ogg_packet *p_oggpacket )
3085 if( p_oggpacket->bytes >= 28 &&
3086 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3088 oggpack_buffer opb;
3090 uint16_t major_version;
3091 uint16_t minor_version;
3092 uint64_t timebase_numerator;
3093 uint64_t timebase_denominator;
3095 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3097 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3098 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3099 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3100 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3101 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3102 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3104 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3105 "Timebase %"PRId64" / %"PRId64,
3106 major_version, minor_version,
3107 timebase_numerator, timebase_denominator );
3109 else if( p_oggpacket->bytes >= 42 &&
3110 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3112 uint64_t granule_rate_numerator;
3113 uint64_t granule_rate_denominator;
3114 char content_type_string[1024];
3116 /* Read in Annodex header fields */
3118 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3119 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3120 p_stream->i_secondary_header_packets =
3121 GetDWLE( &p_oggpacket->packet[24] );
3123 /* we are guaranteed that the first header field will be
3124 * the content-type (by the Annodex standard) */
3125 content_type_string[0] = '\0';
3126 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3128 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3129 p_oggpacket->bytes - 1 );
3130 if( p && p[0] == '\r' && p[1] == '\n' )
3131 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3132 content_type_string );
3135 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3136 granule_rate_numerator, granule_rate_denominator,
3137 p_stream->i_secondary_header_packets, content_type_string );
3139 p_stream->f_rate = (float) granule_rate_numerator /
3140 (float) granule_rate_denominator;
3142 /* What type of file do we have?
3143 * strcmp is safe to use here because we've extracted
3144 * content_type_string from the stream manually */
3145 bool b_dopacketout = false;
3146 Ogg_ApplyContentType( p_stream, content_type_string,
3147 &p_stream->b_force_backup, &b_dopacketout );
3148 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3152 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3153 ogg_packet *p_oggpacket )
3155 demux_sys_t *p_sys = p_demux->p_sys;
3157 p_sys->p_skelstream = p_stream;
3158 /* There can be only 1 skeleton for streams */
3159 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3160 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3161 if ( asprintf( & p_stream->fmt.psz_description,
3162 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3163 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3164 p_stream->fmt.psz_description = NULL;
3167 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3169 demux_sys_t *p_sys = p_demux->p_sys;
3171 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3173 /* Find the matching stream for this skeleton data */
3174 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3175 logical_stream_t *p_target_stream = NULL;
3176 for ( int i=0; i< p_sys->i_streams; i++ )
3178 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3180 p_target_stream = p_sys->pp_stream[i];
3181 break;
3184 if ( !p_target_stream ) return;
3186 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3187 if ( !p_skel )
3189 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3190 if ( !p_skel ) return;
3191 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3192 p_skel->p_index = NULL;
3193 p_target_stream->p_skel = p_skel;
3196 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3197 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3198 const unsigned char *p = p_messages;
3199 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3201 if ( *p == 0x0D && *(p+1) == 0x0A )
3203 char *psz_message = strndup( (const char *) p_messages,
3204 p - p_messages );
3205 if ( psz_message )
3207 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3208 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3210 if ( p < p_boundary - 1 ) p_messages = p + 2;
3212 p++;
3217 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3218 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3219 unsigned const char *p_end,
3220 uint64_t *pi_value )
3222 int i_shift = 0;
3223 int64_t i_read = 0;
3224 *pi_value = 0;
3226 while ( p_begin < p_end )
3228 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3229 *pi_value = *pi_value | ( i_read << i_shift );
3230 i_shift += 7;
3231 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3234 *pi_value = GetQWLE( pi_value );
3235 return p_begin;
3238 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3240 demux_sys_t *p_sys = p_demux->p_sys;
3242 if( p_sys->skeleton.major < 4
3243 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3244 ) return;
3246 /* Find the matching stream for this skeleton data */
3247 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3248 logical_stream_t *p_stream = NULL;
3249 for ( int i=0; i< p_sys->i_streams; i++ )
3251 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3253 p_stream = p_sys->pp_stream[i];
3254 break;
3257 if ( !p_stream || !p_stream->p_skel ) return;
3258 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3259 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3260 if ( !i_keypoints ) return;
3262 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3263 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3264 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3265 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3266 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3267 uint64_t i_offset = 0;
3268 uint64_t i_time = 0;
3269 uint64_t i_keypoints_found = 0;
3271 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3273 uint64_t i_val;
3274 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3275 i_offset += i_val;
3276 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3277 i_time += i_val * p_stream->p_skel->i_indexstampden;
3278 i_keypoints_found++;
3281 if ( i_keypoints_found != i_keypoints )
3283 msg_Warn( p_demux, "Invalid Index: missing entries" );
3284 return;
3287 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3288 if ( !p_stream->p_skel->p_index ) return;
3289 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3290 p_oggpacket->bytes - 42 );
3291 p_stream->p_skel->i_index = i_keypoints_found;
3292 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3295 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3297 if ( !p_skel ) return;
3298 for ( int i=0; i< p_skel->i_messages; i++ )
3299 free( p_skel->ppsz_messages[i] );
3300 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3301 free( p_skel->p_index );
3302 free( p_skel );
3305 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3307 if ( !p_stream->p_skel ) return;
3308 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3310 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3311 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3313 free( p_stream->fmt.psz_description );
3314 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3316 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3318 bool b_foo;
3319 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3324 /* Return true if there's a skeleton exact match */
3325 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3326 int64_t *pi_lower, int64_t *pi_upper )
3328 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3329 return false;
3331 /* Validate range */
3332 if ( i_time < p_stream->p_skel->i_indexfirstnum
3333 * p_stream->p_skel->i_indexstampden ||
3334 i_time > p_stream->p_skel->i_indexlastnum
3335 * p_stream->p_skel->i_indexstampden ) return false;
3337 /* Then Lookup its index */
3338 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3339 struct
3341 int64_t i_pos;
3342 int64_t i_time;
3343 } current = { 0, 0 }, prev = { -1, -1 };
3345 uint64_t i_keypoints_found = 0;
3347 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3348 && i_keypoints_found < p_stream->p_skel->i_index )
3350 uint64_t i_val;
3351 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3352 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3353 current.i_pos += i_val;
3354 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3355 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3356 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3357 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3359 i_keypoints_found++;
3361 if ( i_time <= current.i_time )
3363 *pi_lower = prev.i_pos;
3364 *pi_upper = current.i_pos;
3365 return ( i_time == current.i_time );
3367 prev = current;
3369 return false;
3372 static uint32_t dirac_uint( bs_t *p_bs )
3374 uint32_t u_count = 0, u_value = 0;
3376 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3378 u_count++;
3379 u_value <<= 1;
3380 u_value |= bs_read( p_bs, 1 );
3383 return (1<<u_count) - 1 + u_value;
3386 static int dirac_bool( bs_t *p_bs )
3388 return bs_read( p_bs, 1 );
3391 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3392 ogg_packet *p_oggpacket )
3394 static const struct {
3395 uint32_t u_n /* numerator */, u_d /* denominator */;
3396 } p_dirac_frate_tbl[] = { /* table 10.3 */
3397 {1,1}, /* this first value is never used */
3398 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3399 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3401 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3403 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3404 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3406 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3408 bs_t bs;
3410 p_stream->i_granule_shift = 22; /* not 32 */
3412 /* Backing up stream headers is not required -- seqhdrs are repeated
3413 * thoughout the stream at suitable decoding start points */
3414 p_stream->b_force_backup = false;
3416 /* read in useful bits from sequence header */
3417 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3418 bs_skip( &bs, 13*8); /* parse_info_header */
3419 dirac_uint( &bs ); /* major_version */
3420 dirac_uint( &bs ); /* minor_version */
3421 dirac_uint( &bs ); /* profile */
3422 dirac_uint( &bs ); /* level */
3424 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3425 if( u_video_format >= u_dirac_vidfmt_frate )
3427 /* don't know how to parse this ogg dirac stream */
3428 return false;
3431 if( dirac_bool( &bs ) )
3433 dirac_uint( &bs ); /* frame_width */
3434 dirac_uint( &bs ); /* frame_height */
3437 if( dirac_bool( &bs ) )
3439 dirac_uint( &bs ); /* chroma_format */
3442 if( dirac_bool( &bs ) )
3444 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3446 else
3447 p_stream->special.dirac.b_interlaced = false;
3449 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3450 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3451 u_d = __MAX( u_d, 1 );
3452 if( dirac_bool( &bs ) )
3454 uint32_t u_frame_rate_index = dirac_uint( &bs );
3455 if( u_frame_rate_index >= u_dirac_frate_tbl )
3457 /* something is wrong with this stream */
3458 return false;
3460 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3461 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3462 if( u_frame_rate_index == 0 )
3464 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3465 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3468 p_stream->f_rate = (float) u_n / u_d;
3469 if ( p_stream->f_rate == 0 ) return false;
3471 return true;
3474 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3475 ogg_packet *p_oggpacket )
3477 uint64_t i_granulerate_numerator;
3478 uint64_t i_granulerate_denominator;
3479 int i_major;
3480 int i_minor;
3482 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3484 /* Signal that we want to keep a backup of the OggSpots
3485 * stream headers. They will be used when switching between
3486 * audio streams. */
3487 p_stream->b_force_backup = true;
3489 /* Cheat and get additionnal info ;) */
3490 if ( p_oggpacket->bytes != 52 )
3492 /* The OggSpots header is always 52 bytes */
3493 return false;
3496 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3497 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3498 if ( i_major != 0 || i_minor != 1 )
3500 return false;
3503 /* Granule rate */
3504 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3505 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3506 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3508 return false;
3511 /* The OggSpots spec contained an error and there are implementations out
3512 * there that used the wrong value. So we detect that case and switch
3513 * numerator and denominator in that case */
3514 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3516 i_granulerate_numerator = 30;
3517 i_granulerate_denominator = 1;
3520 p_stream->f_rate = ((double)i_granulerate_numerator) / i_granulerate_denominator;
3521 if ( p_stream->f_rate == 0 )
3523 return false;
3526 /* Normalize granulerate */
3527 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3528 &p_stream->fmt.video.i_frame_rate_base,
3529 i_granulerate_numerator, i_granulerate_denominator, 0);
3531 p_stream->i_granule_shift = p_oggpacket->packet[28];
3533 return true;