contrib:d3d9: add defines necessary to handle different deinterlacing algorithms
[vlc.git] / modules / demux / ogg.c
blobcfc3813fa8743150fead611118c9481bc813c1d0
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 =
193 audio->i_original_channels = pi_channels_map[chans];
196 /* Special TS value: don't send or derive any pts/pcr from it.
197 Represents TS state prior first known valid timestamp */
198 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
200 /*****************************************************************************
201 * Open: initializes ogg demux structures
202 *****************************************************************************/
203 static int Open( vlc_object_t * p_this )
205 demux_t *p_demux = (demux_t *)p_this;
206 demux_sys_t *p_sys;
207 const uint8_t *p_peek;
209 /* Check if we are dealing with an ogg stream */
210 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
211 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
213 char *psz_mime = stream_ContentType( p_demux->s );
214 if( !psz_mime )
216 return VLC_EGENERIC;
218 else if ( strcmp( psz_mime, "application/ogg" ) &&
219 strcmp( psz_mime, "video/ogg" ) &&
220 strcmp( psz_mime, "audio/ogg" ) )
222 free( psz_mime );
223 return VLC_EGENERIC;
225 free( psz_mime );
228 /* */
229 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
230 if( !p_sys )
231 return VLC_ENOMEM;
233 p_sys->i_length = -1;
234 p_sys->b_preparsing_done = false;
236 vlc_stream_Control( p_demux->s, STREAM_GET_PTS_DELAY,
237 &p_sys->i_access_delay );
239 /* Set exported functions */
240 p_demux->pf_demux = Demux;
241 p_demux->pf_control = Control;
243 /* Initialize the Ogg physical bitstream parser */
244 ogg_sync_init( &p_sys->oy );
246 /* */
247 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
250 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
252 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
253 Ogg_CreateES( p_demux );
255 return VLC_SUCCESS;
258 /*****************************************************************************
259 * Close: frees unused data
260 *****************************************************************************/
261 static void Close( vlc_object_t *p_this )
263 demux_t *p_demux = (demux_t *)p_this;
264 demux_sys_t *p_sys = p_demux->p_sys ;
266 /* Cleanup the bitstream parser */
267 ogg_sync_clear( &p_sys->oy );
269 Ogg_EndOfStream( p_demux );
271 if( p_sys->p_old_stream )
272 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
274 free( p_sys );
277 /*****************************************************************************
278 * Demux: reads and demuxes data packets
279 *****************************************************************************
280 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
281 *****************************************************************************/
282 static int Demux( demux_t * p_demux )
284 demux_sys_t *p_sys = p_demux->p_sys;
285 ogg_packet oggpacket;
286 int i_stream;
287 bool b_skipping = false;
288 bool b_canseek;
290 int i_active_streams = p_sys->i_streams;
291 for ( int i=0; i < p_sys->i_streams; i++ )
293 if ( p_sys->pp_stream[i]->b_finished )
294 i_active_streams--;
297 if ( i_active_streams == 0 )
299 if ( p_sys->i_streams ) /* All finished */
301 msg_Dbg( p_demux, "end of a group of logical streams" );
303 mtime_t i_lastpcr = VLC_TS_INVALID;
304 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
306 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
307 if( p_stream->i_pcr > i_lastpcr )
308 i_lastpcr = p_stream->i_pcr;
311 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
312 * only 1 ES is supported (common case for ogg web radio) */
313 if( p_sys->i_streams == 1 )
315 p_sys->p_old_stream = p_sys->pp_stream[0];
316 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
319 Ogg_EndOfStream( p_demux );
320 p_sys->b_chained_boundary = true;
322 if( i_lastpcr > VLC_TS_INVALID )
324 p_sys->i_nzpcr_offset = i_lastpcr - VLC_TS_0;
325 es_out_Control( p_demux->out, ES_OUT_SET_PCR, 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 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
505 p_stream->i_secondary_header_packets = 0;
507 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
509 p_stream->i_secondary_header_packets = 0;
512 /* update start of data pointer */
513 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
516 /* If any streams have i_skip_frames, only decode (pre-roll)
517 * for those streams, but don't skip headers */
518 if ( b_skipping && p_stream->i_skip_frames == 0
519 && p_stream->i_secondary_header_packets ) continue;
521 if( p_stream->b_reinit )
523 p_stream->b_reinit = false;
524 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
526 p_stream->i_skip_frames = p_stream->i_pre_skip;
530 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
533 if ( p_stream->prepcr.pp_blocks )
535 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
536 p_stream->i_previous_pcr = pagestamp;
537 #ifdef HAVE_LIBVORBIS
538 int i_prev_blocksize = 0;
539 #endif
540 // PASS 1
541 for( int i=0; i<p_stream->prepcr.i_used; i++ )
543 block_t *p_block = p_stream->prepcr.pp_blocks[i];
544 ogg_packet dumb_packet;
545 dumb_packet.bytes = p_block->i_buffer;
546 dumb_packet.packet = p_block->p_buffer;
548 switch( p_stream->fmt.i_codec )
550 case VLC_CODEC_SPEEX:
551 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
552 p_stream->special.speex.i_framesperpacket;
553 break;
554 case VLC_CODEC_OPUS:
555 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
556 break;
557 #ifdef HAVE_LIBVORBIS
558 case VLC_CODEC_VORBIS:
560 if( !VORBIS_HEADERS_VALID(p_stream) )
562 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
563 break;
565 long i_blocksize = vorbis_packet_blocksize(
566 p_stream->special.vorbis.p_info, &dumb_packet );
567 if ( i_prev_blocksize )
568 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
569 else
570 p_block->i_nb_samples = i_blocksize / 2;
571 i_prev_blocksize = i_blocksize;
573 #endif
577 // PASS 2
578 bool b_fixed = false;
579 for( int i=p_stream->prepcr.i_used - 1; i>=0; i-- )
581 block_t *p_block = p_stream->prepcr.pp_blocks[i];
582 switch( p_stream->fmt.i_codec )
584 case VLC_CODEC_SPEEX:
585 case VLC_CODEC_OPUS:
586 case VLC_CODEC_VORBIS:
587 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
588 if ( pagestamp < 0 )
590 p_block->i_pts = VLC_TS_INVALID;
591 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
592 p_block->i_flags |= BLOCK_FLAG_PREROLL;
594 else
595 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
596 b_fixed = true;
597 break;
598 default:
599 if ( p_stream->fmt.i_cat == VIDEO_ES )
601 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
602 if( pagestamp < 0 )
603 pagestamp = 0;
604 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
605 b_fixed = true;
610 if ( b_fixed )
612 pagestamp = p_stream->i_previous_pcr; /* as set above */
613 if ( pagestamp < 0 ) pagestamp = 0;
614 p_stream->i_pcr = VLC_TS_0 + pagestamp;
615 p_stream->i_pcr += p_sys->i_nzpcr_offset;
616 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
619 FREENULL(p_stream->prepcr.pp_blocks);
620 p_stream->prepcr.i_used = 0;
622 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
626 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
627 ogg_page_granulepos( &p_sys->current_page ), false );
628 if ( i_pagestamp > -1 )
630 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
631 p_stream->i_pcr += p_sys->i_nzpcr_offset;
634 if( !p_sys->b_page_waiting )
635 break;
638 /* if a page was waiting, it's now processed */
639 p_sys->b_page_waiting = false;
641 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
642 p_sys->b_preparsing_done = false;
643 else
644 p_sys->b_preparsing_done = true;
646 /* We will consider the lowest PCR among tracks, because the audio core badly
647 * handles PCR rewind (mute)
649 mtime_t i_pcr_candidate = VLC_TS_INVALID;
650 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
652 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
654 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
656 /* We have 1 or more streams needing more than 1 page for preparsing */
657 p_sys->b_preparsing_done = false;
660 if( p_stream->fmt.i_cat == SPU_ES )
661 continue;
662 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
663 continue;
664 if( p_stream->i_pcr < VLC_TS_0 )
665 continue;
666 if ( p_stream->b_finished || p_stream->b_initializing )
667 continue;
668 if ( p_stream->p_preparse_block )
669 continue;
670 if( i_pcr_candidate < VLC_TS_0
671 || p_stream->i_pcr <= i_pcr_candidate )
673 i_pcr_candidate = p_stream->i_pcr;
677 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
679 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
681 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
682 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
684 p_sys->i_pcr_jitter = i_pcr_jitter;
685 if ( p_sys->i_access_delay < i_pcr_jitter )
686 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
687 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
691 if( ! b_skipping && p_sys->b_preparsing_done )
693 p_sys->i_pcr = i_pcr_candidate;
694 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
698 return VLC_DEMUXER_SUCCESS;
701 static void Ogg_ResetStream( logical_stream_t *p_stream )
703 #ifdef HAVE_LIBVORBIS
704 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
706 p_stream->special.vorbis.i_prev_blocksize = 0;
708 #endif
709 /* we'll trash all the data until we find the next pcr */
710 p_stream->b_reinit = true;
711 p_stream->i_pcr = VLC_TS_UNKNOWN;
712 p_stream->i_previous_granulepos = -1;
713 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
714 ogg_stream_reset( &p_stream->os );
715 FREENULL( p_stream->prepcr.pp_blocks );
716 p_stream->prepcr.i_size = 0;
717 p_stream->prepcr.i_used = 0;
720 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
722 for( int i = 0; i < p_sys->i_streams; i++ )
723 Ogg_ResetStream( p_sys->pp_stream[i] );
725 ogg_sync_reset( &p_sys->oy );
726 p_sys->i_pcr = VLC_TS_UNKNOWN;
729 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
731 demux_sys_t *p_sys = p_demux->p_sys;
732 logical_stream_t *p_stream = NULL;
733 for( int i=0; i<p_sys->i_streams; i++ )
735 logical_stream_t *p_candidate = p_sys->pp_stream[i];
736 if ( !p_candidate->p_es ) continue;
738 bool b_selected = false;
739 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
740 p_candidate->p_es, &b_selected );
741 if ( !b_selected ) continue;
743 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
745 p_stream = p_candidate;
746 continue; /* Try to find video anyway */
749 if ( p_candidate->fmt.i_cat == VIDEO_ES )
751 p_stream = p_candidate;
752 break;
755 return p_stream;
758 /*****************************************************************************
759 * Control:
760 *****************************************************************************/
761 static int Control( demux_t *p_demux, int i_query, va_list args )
763 demux_sys_t *p_sys = p_demux->p_sys;
764 vlc_meta_t *p_meta;
765 int64_t *pi64, i64;
766 double *pf, f;
767 bool *pb_bool, b;
769 switch( i_query )
771 case DEMUX_CAN_SEEK:
772 return vlc_stream_vaControl( p_demux->s, i_query, args );
774 case DEMUX_GET_META:
775 p_meta = va_arg( args, vlc_meta_t * );
776 if( p_sys->p_meta )
777 vlc_meta_Merge( p_meta, p_sys->p_meta );
778 return VLC_SUCCESS;
780 case DEMUX_HAS_UNSUPPORTED_META:
781 pb_bool = va_arg( args, bool* );
782 *pb_bool = true;
783 return VLC_SUCCESS;
785 case DEMUX_GET_TIME:
786 if( p_sys->i_pcr > VLC_TS_INVALID )
788 pi64 = va_arg( args, int64_t * );
789 *pi64 = p_sys->i_pcr;
790 return VLC_SUCCESS;
792 return VLC_EGENERIC;
794 case DEMUX_SET_TIME:
795 i64 = va_arg( args, int64_t );
796 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
797 if ( !p_stream )
799 msg_Err( p_demux, "No selected seekable stream found" );
800 return VLC_EGENERIC;
802 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
803 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
805 Ogg_ResetStreamsHelper( p_sys );
806 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
807 VLC_TS_0 + i64 );
808 return VLC_SUCCESS;
810 else
811 return VLC_EGENERIC;
813 case DEMUX_GET_ATTACHMENTS:
815 input_attachment_t ***ppp_attach =
816 va_arg( args, input_attachment_t *** );
817 int *pi_int = va_arg( args, int * );
819 if( p_sys->i_attachments <= 0 )
820 return VLC_EGENERIC;
822 *pi_int = p_sys->i_attachments;
823 *ppp_attach = xmalloc( sizeof(input_attachment_t*) * p_sys->i_attachments );
824 for( int i = 0; i < p_sys->i_attachments; i++ )
825 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
826 return VLC_SUCCESS;
829 case DEMUX_GET_POSITION:
830 pf = va_arg( args, double * );
831 if( p_sys->i_length > 0 && p_sys->i_pcr > VLC_TS_INVALID )
833 *pf = (double) p_sys->i_pcr /
834 (double) ( p_sys->i_length * (mtime_t)1000000 );
836 else if( stream_Size( p_demux->s ) > 0 )
838 i64 = vlc_stream_Tell( p_demux->s );
839 *pf = (double) i64 / stream_Size( p_demux->s );
841 else *pf = 0.0;
842 return VLC_SUCCESS;
844 case DEMUX_SET_POSITION:
845 /* forbid seeking if we haven't initialized all logical bitstreams yet;
846 if we allowed, some headers would not get backed up and decoder init
847 would fail, making that logical stream unusable */
848 for ( int i=0; i< p_sys->i_streams; i++ )
850 if ( p_sys->pp_stream[i]->b_initializing )
851 return VLC_EGENERIC;
854 p_stream = Ogg_GetSelectedStream( p_demux );
855 if ( !p_stream )
857 msg_Err( p_demux, "No selected seekable stream found" );
858 return VLC_EGENERIC;
861 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
863 f = va_arg( args, double );
864 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
866 Ogg_ResetStreamsHelper( p_sys );
867 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
868 return VLC_SUCCESS;
871 assert( p_sys->i_length > 0 );
872 i64 = CLOCK_FREQ * p_sys->i_length * f;
873 Ogg_ResetStreamsHelper( p_sys );
874 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
876 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
877 VLC_TS_0 + i64 );
878 return VLC_SUCCESS;
881 return VLC_EGENERIC;
883 case DEMUX_GET_LENGTH:
884 if ( p_sys->i_length < 0 )
885 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
886 1, i_query, args );
887 pi64 = va_arg( args, int64_t * );
888 *pi64 = p_sys->i_length * 1000000;
889 return VLC_SUCCESS;
891 case DEMUX_GET_TITLE_INFO:
893 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
894 int *pi_int = va_arg( args, int* );
895 int *pi_title_offset = va_arg( args, int* );
896 int *pi_seekpoint_offset = va_arg( args, int* );
898 if( p_sys->i_seekpoints > 0 )
900 *pi_int = 1;
901 *ppp_title = malloc( sizeof( input_title_t* ) );
902 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
903 for( int i = 0; i < p_sys->i_seekpoints; i++ )
905 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
906 if ( likely( p_seekpoint_copy ) )
907 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
909 *pi_title_offset = 0;
910 *pi_seekpoint_offset = 0;
912 return VLC_SUCCESS;
914 case DEMUX_SET_TITLE:
916 const int i_title = va_arg( args, int );
917 if( i_title > 1 )
918 return VLC_EGENERIC;
919 return VLC_SUCCESS;
921 case DEMUX_SET_SEEKPOINT:
923 const int i_seekpoint = va_arg( args, int );
924 if( i_seekpoint > p_sys->i_seekpoints )
925 return VLC_EGENERIC;
927 for ( int i=0; i< p_sys->i_streams; i++ )
929 if ( p_sys->pp_stream[i]->b_initializing )
930 return VLC_EGENERIC;
933 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
935 p_stream = Ogg_GetSelectedStream( p_demux );
936 if ( !p_stream )
938 msg_Err( p_demux, "No selected seekable stream found" );
939 return VLC_EGENERIC;
942 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
943 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
945 Ogg_ResetStreamsHelper( p_sys );
946 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
947 VLC_TS_0 + i64 );
948 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
949 p_demux->info.i_seekpoint = i_seekpoint;
950 return VLC_SUCCESS;
952 else
953 return VLC_EGENERIC;
956 default:
957 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
958 1, i_query, args );
962 /****************************************************************************
963 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
964 ****************************************************************************
965 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
966 * are at the end of stream.
967 ****************************************************************************/
968 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
970 demux_sys_t *p_ogg = p_demux->p_sys ;
971 int i_read = 0;
972 char *p_buffer;
974 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
976 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
978 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
979 if( i_read <= 0 )
980 return VLC_EGENERIC;
982 ogg_sync_wrote( &p_ogg->oy, i_read );
985 return VLC_SUCCESS;
988 /****************************************************************************
989 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
990 * current stream.
991 ****************************************************************************/
992 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
993 ogg_packet *p_oggpacket )
995 demux_sys_t *p_ogg = p_demux->p_sys;
996 p_stream->i_end_trim = 0;
998 /* Convert the granulepos into a pcr */
999 if ( p_oggpacket->granulepos == 0 )
1001 /* We're in headers, and we haven't parsed 1st data packet yet */
1002 // p_stream->i_pcr = VLC_TS_UNKNOWN;
1004 else if( p_oggpacket->granulepos > 0 )
1006 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
1007 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
1008 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
1009 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1010 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
1011 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1012 p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
1013 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
1015 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1016 p_oggpacket->granulepos, true );
1017 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1019 else if ( p_stream->i_previous_granulepos > 0 )
1021 ogg_int64_t sample = p_stream->i_previous_granulepos;
1023 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
1025 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
1026 if( duration > 0 )
1028 ogg_int64_t end_sample = p_oggpacket->granulepos;
1029 if( end_sample < ( sample + duration ) )
1030 p_stream->i_end_trim = sample + duration - end_sample;
1034 if (sample >= p_stream->i_pre_skip)
1035 sample -= p_stream->i_pre_skip;
1036 else
1037 sample = 0;
1039 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1040 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1044 else if ( p_oggpacket->granulepos == -1 )
1046 unsigned i_duration;
1047 /* no granulepos available, try to interpolate the pcr.
1048 * If we can't then don't touch the old value. */
1049 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
1051 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1053 #ifdef HAVE_LIBVORBIS
1054 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1055 p_stream->special.vorbis.p_info &&
1056 VORBIS_HEADERS_VALID(p_stream) &&
1057 p_stream->i_previous_granulepos > 0 )
1059 long i_blocksize = vorbis_packet_blocksize(
1060 p_stream->special.vorbis.p_info, p_oggpacket );
1061 if ( p_stream->special.vorbis.i_prev_blocksize )
1062 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1063 else
1064 i_duration = i_blocksize / 2;
1065 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1066 /* duration in samples per channel */
1067 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1068 p_stream->i_pcr = p_stream->i_previous_granulepos *
1069 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1070 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1072 #endif
1073 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1074 p_stream->i_previous_granulepos > 0 )
1076 i_duration = p_stream->special.speex.i_framesize *
1077 p_stream->special.speex.i_framesperpacket;
1078 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1079 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1080 p_stream->i_previous_granulepos, false );
1081 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1083 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1084 p_stream->i_previous_granulepos > 0 &&
1085 ( i_duration =
1086 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1088 ogg_int64_t sample;
1089 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1090 sample = p_stream->i_previous_granulepos;
1091 if (sample >= p_stream->i_pre_skip)
1092 sample -= p_stream->i_pre_skip;
1093 else
1094 sample = 0;
1096 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1097 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1099 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1101 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1102 p_stream->fmt.i_bitrate / 8 );
1106 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1109 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1110 block_t *p_block )
1112 demux_sys_t *p_ogg = p_demux->p_sys;
1113 if ( (!p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN) &&
1114 p_ogg->i_nzpcr_offset == 0 /* Not on chained streams */ )
1116 if ( !p_block ) return;
1117 if ( p_stream->prepcr.pp_blocks )
1119 assert( p_stream->prepcr.i_size );
1120 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1122 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1123 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1124 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1126 else
1128 /* Because ES creation is delayed for preparsing */
1129 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1130 if ( p_stream->p_preparse_block )
1132 block_t *temp = p_stream->p_preparse_block;
1133 while ( temp )
1135 if ( temp && i_firstpts < VLC_TS_0 )
1136 i_firstpts = temp->i_pts;
1138 block_t *tosend = temp;
1139 temp = temp->p_next;
1140 tosend->p_next = NULL;
1142 if( tosend->i_pts < VLC_TS_0 )
1144 /* Don't send metadata from chained streams */
1145 block_Release( tosend );
1146 continue;
1148 else if( tosend->i_dts < VLC_TS_0 )
1150 tosend->i_dts = tosend->i_pts;
1153 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1154 tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1155 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1157 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1159 p_ogg->i_pcr = i_firstpts;
1160 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_ogg->i_pcr );
1163 p_stream->p_preparse_block = NULL;
1166 if ( p_block )
1168 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1169 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1170 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1175 /****************************************************************************
1176 * Ogg_DecodePacket: Decode an Ogg packet.
1177 ****************************************************************************/
1178 static void Ogg_DecodePacket( demux_t *p_demux,
1179 logical_stream_t *p_stream,
1180 ogg_packet *p_oggpacket )
1182 block_t *p_block;
1183 bool b_selected;
1184 int i_header_len = 0;
1186 if( p_oggpacket->bytes >= 7 &&
1187 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1189 /* it's an Annodex packet -- skip it (do nothing) */
1190 return;
1192 else if( p_oggpacket->bytes >= 7 &&
1193 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1195 /* it's an AnxData packet -- skip it (do nothing) */
1196 return;
1198 else if( p_oggpacket->bytes >= 8 &&
1199 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1201 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1202 return;
1204 else if( p_oggpacket->bytes >= 6 &&
1205 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1207 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1208 return;
1210 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1211 p_oggpacket->bytes >= 7 &&
1212 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1214 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1215 return;
1218 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1219 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1221 /* Check the ES is selected */
1222 if ( !p_stream->p_es )
1223 b_selected = true;
1224 else
1225 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1226 p_stream->p_es, &b_selected );
1228 if( p_stream->b_force_backup )
1230 bool b_xiph;
1231 p_stream->i_packets_backup++;
1232 switch( p_stream->fmt.i_codec )
1234 case VLC_CODEC_VORBIS:
1235 #ifdef HAVE_LIBVORBIS
1236 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1237 #endif
1238 //ft
1239 case VLC_CODEC_THEORA:
1240 if( p_stream->i_packets_backup == 3 )
1241 p_stream->b_force_backup = false;
1242 b_xiph = true;
1243 break;
1245 case VLC_CODEC_DAALA:
1246 if( p_stream->i_packets_backup == 3 )
1247 p_stream->b_force_backup = false;
1248 b_xiph = true;
1249 break;
1251 case VLC_CODEC_SPEEX:
1252 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1253 p_stream->b_force_backup = false;
1254 b_xiph = true;
1255 break;
1257 case VLC_CODEC_OPUS:
1258 if( p_stream->i_packets_backup == 2 )
1259 p_stream->b_force_backup = false;
1260 b_xiph = true;
1261 break;
1263 case VLC_CODEC_FLAC:
1264 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1266 p_stream->b_force_backup = false;
1268 if( p_stream->special.flac.b_old )
1270 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1272 else if( p_stream->i_packets_backup == 1 )
1274 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1276 p_oggpacket->packet += 9;
1277 p_oggpacket->bytes -= 9;
1280 b_xiph = false;
1281 break;
1283 case VLC_CODEC_KATE:
1284 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1285 p_stream->b_force_backup = false;
1286 b_xiph = true;
1287 break;
1289 default:
1290 p_stream->b_force_backup = false;
1291 b_xiph = false;
1292 break;
1295 /* Backup the ogg packet (likely an header packet) */
1296 if( !b_xiph )
1298 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1299 if( p_realloc )
1301 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1302 p_stream->i_headers += p_oggpacket->bytes;
1303 p_stream->p_headers = p_realloc;
1305 else
1307 free( p_stream->p_headers );
1308 p_stream->i_headers = 0;
1309 p_stream->p_headers = NULL;
1312 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1313 p_oggpacket->bytes, p_oggpacket->packet ) )
1315 p_stream->i_headers = 0;
1316 p_stream->p_headers = NULL;
1318 if( p_stream->i_headers > 0 )
1320 if( !p_stream->b_force_backup )
1322 /* Last header received, commit changes */
1323 free( p_stream->fmt.p_extra );
1325 p_stream->fmt.i_extra = p_stream->i_headers;
1326 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1327 if( p_stream->fmt.p_extra )
1328 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1329 p_stream->i_headers );
1330 else
1331 p_stream->fmt.i_extra = 0;
1333 if( p_stream->i_headers > 0 )
1334 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1335 p_stream->p_headers, p_stream->i_headers );
1337 /* we're not at BOS anymore for this logical stream */
1338 p_stream->b_initializing = false;
1342 b_selected = false; /* Discard the header packet */
1344 else
1346 p_stream->b_initializing = false;
1349 /* Convert the granulepos into the next pcr */
1350 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1352 if( !b_selected )
1354 /* This stream isn't currently selected so we don't need to decode it,
1355 * but we did need to store its pcr as it might be selected later on */
1356 return;
1359 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1360 p_block->i_pts = p_stream->i_pcr;
1362 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1363 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1365 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1366 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1368 /* may need to preroll after a seek or in case of preskip */
1369 if ( p_stream->i_skip_frames > 0 )
1371 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1373 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1375 if( p_demux->p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1376 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1377 p_stream->i_skip_frames -= p_block->i_nb_samples;
1378 p_block->i_nb_samples = 0;
1380 else
1382 p_block->i_nb_samples -= p_stream->i_skip_frames;
1383 p_stream->i_skip_frames = 0;
1386 else
1388 if( p_demux->p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1389 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1390 p_stream->i_skip_frames--;
1394 /* Conditional block fixes */
1395 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1396 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1398 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1400 else if( p_stream->fmt.i_cat == AUDIO_ES )
1402 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1403 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1404 p_stream->fmt.b_packetized )
1406 /* Handle OggFlac spec violation (multiple frame/packet
1407 * by turning on packetizer */
1408 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1409 p_stream->fmt.b_packetized = false;
1410 es_out_Del( p_demux->out, p_stream->p_es );
1411 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1414 /* Blatant abuse of the i_length field. */
1415 p_block->i_length = p_stream->i_end_trim;
1417 else if( p_stream->fmt.i_cat == SPU_ES )
1419 p_block->i_length = 0;
1421 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1423 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1424 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1425 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1426 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1427 /* granulepos for dirac is possibly broken, this value should be ignored */
1428 if( 0 >= p_oggpacket->granulepos )
1430 p_block->i_pts = VLC_TS_INVALID;
1431 p_block->i_dts = p_stream->i_pcr;
1435 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1436 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1437 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1438 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1439 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1440 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1441 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1442 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1443 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1444 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1445 p_stream->fmt.i_codec != VLC_CODEC_KATE &&
1446 p_stream->fmt.i_codec != VLC_CODEC_OGGSPOTS )
1448 if( p_oggpacket->bytes <= 0 )
1450 msg_Dbg( p_demux, "discarding 0 sized packet" );
1451 block_Release( p_block );
1452 return;
1454 /* We remove the header from the packet */
1455 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1456 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1458 if( i_header_len >= p_oggpacket->bytes )
1460 msg_Dbg( p_demux, "discarding invalid packet" );
1461 block_Release( p_block );
1462 return;
1465 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1467 /* But with subtitles we need to retrieve the duration first */
1468 int i, lenbytes = 0;
1470 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1472 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1474 lenbytes = lenbytes << 8;
1475 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1478 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1479 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1480 p_oggpacket->packet[i_header_len + 1] != 0 &&
1481 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1482 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1484 p_block->i_length = (mtime_t)lenbytes * 1000;
1488 i_header_len++;
1489 if( p_block->i_buffer >= (unsigned int)i_header_len )
1490 p_block->i_buffer -= i_header_len;
1491 else
1492 p_block->i_buffer = 0;
1496 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1498 /* FIXME: the biggest hack I've ever done */
1499 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1500 p_block->i_pts, p_block->i_dts );
1501 msleep(10000);
1504 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1505 p_oggpacket->bytes - i_header_len );
1507 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1510 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1512 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1515 /****************************************************************************
1516 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1517 * stream and fill p_ogg.
1518 *****************************************************************************
1519 * The initial page of a logical stream is marked as a 'bos' page.
1520 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1521 * together and all of the initial pages must appear before any data pages.
1523 * On success this function returns VLC_SUCCESS.
1524 ****************************************************************************/
1525 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1527 demux_sys_t *p_ogg = p_demux->p_sys ;
1528 ogg_packet oggpacket;
1530 p_ogg->i_total_length = stream_Size ( p_demux->s );
1531 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1534 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1537 if( ogg_page_bos( &p_ogg->current_page ) )
1540 /* All is wonderful in our fine fine little world.
1541 * We found the beginning of our first logical stream. */
1542 while( ogg_page_bos( &p_ogg->current_page ) )
1544 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1545 if( unlikely( !p_stream ) )
1546 return VLC_ENOMEM;
1548 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1550 es_format_Init( &p_stream->fmt, 0, 0 );
1551 es_format_Init( &p_stream->fmt_old, 0, 0 );
1552 p_stream->b_initializing = true;
1554 /* Setup the logical stream */
1555 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1556 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1558 /* Extract the initial header from the first page and verify
1559 * the codec type of this Ogg bitstream */
1560 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1562 /* error. stream version mismatch perhaps */
1563 msg_Err( p_demux, "error reading first page of "
1564 "Ogg bitstream data" );
1565 return VLC_EGENERIC;
1568 /* FIXME: check return value */
1569 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1571 /* Check for Vorbis header */
1572 if( oggpacket.bytes >= 7 &&
1573 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1575 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1576 msg_Dbg( p_demux, "found vorbis header" );
1577 else
1579 msg_Dbg( p_demux, "found invalid vorbis header" );
1580 Ogg_LogicalStreamDelete( p_demux, p_stream );
1581 p_stream = NULL;
1582 p_ogg->i_streams--;
1585 /* Check for Speex header */
1586 else if( oggpacket.bytes >= 5 &&
1587 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1589 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1590 msg_Dbg( p_demux, "found speex header, channels: %i, "
1591 "rate: %i, bitrate: %i, frames: %i group %i",
1592 p_stream->fmt.audio.i_channels,
1593 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1594 p_stream->special.speex.i_framesize,
1595 p_stream->special.speex.i_framesperpacket );
1596 else
1598 msg_Dbg( p_demux, "found invalid Speex header" );
1599 Ogg_LogicalStreamDelete( p_demux, p_stream );
1600 p_stream = NULL;
1601 p_ogg->i_streams--;
1604 /* Check for Opus header */
1605 else if( oggpacket.bytes >= 8 &&
1606 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1608 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1609 msg_Dbg( p_demux, "found opus header, channels: %i, "
1610 "pre-skip: %i",
1611 p_stream->fmt.audio.i_channels,
1612 (int)p_stream->i_pre_skip);
1613 p_stream->i_skip_frames = p_stream->i_pre_skip;
1615 /* Check for OLD Flac header */
1616 else if( oggpacket.bytes >= 4 &&
1617 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1619 msg_Dbg( p_demux, "found FLAC header" );
1621 /* Grrrr!!!! Did they really have to put all the
1622 * important info in the second header packet!!!
1623 * (STREAMINFO metadata is in the following packet) */
1624 p_stream->b_force_backup = true;
1625 p_stream->i_extra_headers_packets = 1;
1626 p_stream->special.flac.b_old = true;
1627 p_stream->fmt.i_cat = AUDIO_ES;
1628 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1630 /* Check for Flac header (>= version 1.0.0) */
1631 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1632 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1633 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1635 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1636 oggpacket.packet[8];
1637 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1638 "(%i header packets)",
1639 oggpacket.packet[5], oggpacket.packet[6],
1640 i_packets );
1641 /* STREAMINFO is in current packet, and then
1642 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1643 p_stream->b_force_backup = true;
1644 p_stream->i_extra_headers_packets = i_packets;
1645 p_stream->special.flac.b_old = false;
1647 p_stream->fmt.i_cat = AUDIO_ES;
1648 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
1649 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1650 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1652 msg_Dbg( p_demux, "found invalid Flac header" );
1653 Ogg_LogicalStreamDelete( p_demux, p_stream );
1654 p_stream = NULL;
1655 p_ogg->i_streams--;
1658 /* Check for Theora header */
1659 else if( oggpacket.bytes >= 7 &&
1660 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1662 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1663 msg_Dbg( p_demux,
1664 "found theora header, bitrate: %i, rate: %f",
1665 p_stream->fmt.i_bitrate, p_stream->f_rate );
1666 else
1668 msg_Dbg( p_demux, "found invalid Theora header" );
1669 Ogg_LogicalStreamDelete( p_demux, p_stream );
1670 p_stream = NULL;
1671 p_ogg->i_streams--;
1674 /* Check for Daala header */
1675 else if( oggpacket.bytes >= 6 &&
1676 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1678 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1679 msg_Dbg( p_demux,
1680 "found daala header, bitrate: %i, rate: %f",
1681 p_stream->fmt.i_bitrate, p_stream->f_rate );
1682 else
1684 msg_Dbg( p_demux, "found invalid Daala header" );
1685 Ogg_LogicalStreamDelete( p_demux, p_stream );
1686 p_stream = NULL;
1687 p_ogg->i_streams--;
1690 /* Check for Dirac header */
1691 else if( ( oggpacket.bytes >= 5 &&
1692 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1693 ( oggpacket.bytes >= 9 &&
1694 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1696 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1697 msg_Dbg( p_demux, "found dirac header" );
1698 else
1700 msg_Warn( p_demux, "found dirac header isn't decodable" );
1701 Ogg_LogicalStreamDelete( p_demux, p_stream );
1702 p_stream = NULL;
1703 p_ogg->i_streams--;
1706 /* Check for Tarkin header */
1707 else if( oggpacket.bytes >= 7 &&
1708 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1710 oggpack_buffer opb;
1712 msg_Dbg( p_demux, "found tarkin header" );
1713 p_stream->fmt.i_cat = VIDEO_ES;
1714 p_stream->fmt.i_codec = VLC_CODEC_TARKIN;
1716 /* Cheat and get additionnal info ;) */
1717 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1718 oggpack_adv( &opb, 88 );
1719 oggpack_adv( &opb, 104 );
1720 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1721 p_stream->f_rate = 2; /* FIXME */
1722 msg_Dbg( p_demux,
1723 "found tarkin header, bitrate: %i, rate: %f",
1724 p_stream->fmt.i_bitrate, p_stream->f_rate );
1726 /* Check for VP8 header */
1727 else if( oggpacket.bytes >= 26 &&
1728 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1730 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1731 msg_Dbg( p_demux, "found VP8 header "
1732 "fps: %f, width:%i; height:%i",
1733 p_stream->f_rate,
1734 p_stream->fmt.video.i_width,
1735 p_stream->fmt.video.i_height );
1736 else
1738 msg_Dbg( p_demux, "invalid VP8 header found");
1739 Ogg_LogicalStreamDelete( p_demux, p_stream );
1740 p_stream = NULL;
1741 p_ogg->i_streams--;
1744 /* Check for Annodex header */
1745 else if( oggpacket.bytes >= 7 &&
1746 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1748 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1749 /* kill annodex track */
1750 FREENULL( p_stream );
1751 p_ogg->i_streams--;
1753 /* Check for Annodex header */
1754 else if( oggpacket.bytes >= 7 &&
1755 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1757 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1759 /* Check for Kate header */
1760 else if( oggpacket.bytes >= 8 &&
1761 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1763 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1764 msg_Dbg( p_demux, "found kate header" );
1765 else
1767 msg_Dbg( p_demux, "invalid kate header found");
1768 Ogg_LogicalStreamDelete( p_demux, p_stream );
1769 p_stream = NULL;
1770 p_ogg->i_streams--;
1773 /* Check for OggDS */
1774 else if( oggpacket.bytes >= 142 &&
1775 !memcmp( &oggpacket.packet[1],
1776 "Direct Show Samples embedded in Ogg", 35 ))
1778 /* Old header type */
1779 p_stream->b_oggds = true;
1780 /* Check for video header (old format) */
1781 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1782 oggpacket.bytes >= 184 )
1784 p_stream->fmt.i_cat = VIDEO_ES;
1785 p_stream->fmt.i_codec =
1786 VLC_FOURCC( oggpacket.packet[68],
1787 oggpacket.packet[69],
1788 oggpacket.packet[70],
1789 oggpacket.packet[71] );
1790 msg_Dbg( p_demux, "found video header of type: %.4s",
1791 (char *)&p_stream->fmt.i_codec );
1793 p_stream->fmt.video.i_frame_rate = 10000000;
1794 p_stream->fmt.video.i_frame_rate_base =
1795 GetQWLE((oggpacket.packet+164));
1796 p_stream->fmt.video.i_frame_rate_base =
1797 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1798 p_stream->f_rate = 10000000.0 /
1799 p_stream->fmt.video.i_frame_rate_base;
1800 p_stream->fmt.video.i_bits_per_pixel =
1801 GetWLE((oggpacket.packet+182));
1802 if( !p_stream->fmt.video.i_bits_per_pixel )
1803 /* hack, FIXME */
1804 p_stream->fmt.video.i_bits_per_pixel = 24;
1805 p_stream->fmt.video.i_width =
1806 GetDWLE((oggpacket.packet+176));
1807 p_stream->fmt.video.i_height =
1808 GetDWLE((oggpacket.packet+180));
1809 p_stream->fmt.video.i_visible_width =
1810 p_stream->fmt.video.i_width;
1811 p_stream->fmt.video.i_visible_height =
1812 p_stream->fmt.video.i_height;
1814 msg_Dbg( p_demux,
1815 "fps: %f, width:%i; height:%i, bitcount:%i",
1816 p_stream->f_rate,
1817 p_stream->fmt.video.i_width,
1818 p_stream->fmt.video.i_height,
1819 p_stream->fmt.video.i_bits_per_pixel);
1822 /* Check for audio header (old format) */
1823 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1825 int i_extra_size;
1826 unsigned int i_format_tag;
1828 p_stream->fmt.i_cat = AUDIO_ES;
1830 i_extra_size = GetWLE((oggpacket.packet+140));
1831 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1833 p_stream->fmt.i_extra = i_extra_size;
1834 p_stream->fmt.p_extra = malloc( i_extra_size );
1835 if( p_stream->fmt.p_extra )
1836 memcpy( p_stream->fmt.p_extra,
1837 oggpacket.packet + 142, i_extra_size );
1838 else
1839 p_stream->fmt.i_extra = 0;
1842 i_format_tag = GetWLE((oggpacket.packet+124));
1843 p_stream->fmt.audio.i_channels =
1844 GetWLE((oggpacket.packet+126));
1845 fill_channels_info(&p_stream->fmt.audio);
1846 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1847 GetDWLE((oggpacket.packet+128));
1848 p_stream->fmt.i_bitrate =
1849 GetDWLE((oggpacket.packet+132)) * 8;
1850 p_stream->fmt.audio.i_blockalign =
1851 GetWLE((oggpacket.packet+136));
1852 p_stream->fmt.audio.i_bitspersample =
1853 GetWLE((oggpacket.packet+138));
1855 wf_tag_to_fourcc( i_format_tag,
1856 &p_stream->fmt.i_codec, 0 );
1858 if( p_stream->fmt.i_codec ==
1859 VLC_FOURCC('u','n','d','f') )
1861 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1862 ( i_format_tag >> 8 ) & 0xff,
1863 i_format_tag & 0xff );
1866 msg_Dbg( p_demux, "found audio header of type: %.4s",
1867 (char *)&p_stream->fmt.i_codec );
1868 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1869 "%dbits/sample %dkb/s",
1870 i_format_tag,
1871 p_stream->fmt.audio.i_channels,
1872 p_stream->fmt.audio.i_rate,
1873 p_stream->fmt.audio.i_bitspersample,
1874 p_stream->fmt.i_bitrate / 1024 );
1875 if ( p_stream->f_rate == 0 )
1877 msg_Dbg( p_demux, "invalid oggds audio header" );
1878 Ogg_LogicalStreamDelete( p_demux, p_stream );
1879 p_stream = NULL;
1880 p_ogg->i_streams--;
1883 else
1885 msg_Dbg( p_demux, "stream %d has an old header "
1886 "but is of an unknown type", p_ogg->i_streams-1 );
1887 FREENULL( p_stream );
1888 p_ogg->i_streams--;
1891 /* Check for OggDS */
1892 else if( oggpacket.bytes >= 44+1 &&
1893 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1895 stream_header_t tmp;
1896 stream_header_t *st = &tmp;
1898 p_stream->b_oggds = true;
1900 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1901 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1902 st->size = GetDWLE( &oggpacket.packet[1+12] );
1903 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1904 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1905 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1906 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1907 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1909 /* Check for video header (new format) */
1910 if( !strncmp( st->streamtype, "video", 5 ) &&
1911 oggpacket.bytes >= 52+1 )
1913 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1914 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1916 p_stream->fmt.i_cat = VIDEO_ES;
1918 /* We need to get rid of the header packet */
1919 ogg_stream_packetout( &p_stream->os, &oggpacket );
1921 p_stream->fmt.i_codec =
1922 VLC_FOURCC( st->subtype[0], st->subtype[1],
1923 st->subtype[2], st->subtype[3] );
1924 msg_Dbg( p_demux, "found video header of type: %.4s",
1925 (char *)&p_stream->fmt.i_codec );
1927 p_stream->fmt.video.i_frame_rate = 10000000;
1928 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1929 if( st->time_unit <= 0 )
1930 st->time_unit = 400000;
1931 p_stream->f_rate = 10000000.0 / st->time_unit;
1932 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1933 p_stream->fmt.video.i_width = st->sh.video.width;
1934 p_stream->fmt.video.i_height = st->sh.video.height;
1935 p_stream->fmt.video.i_visible_width =
1936 p_stream->fmt.video.i_width;
1937 p_stream->fmt.video.i_visible_height =
1938 p_stream->fmt.video.i_height;
1940 msg_Dbg( p_demux,
1941 "fps: %f, width:%i; height:%i, bitcount:%i",
1942 p_stream->f_rate,
1943 p_stream->fmt.video.i_width,
1944 p_stream->fmt.video.i_height,
1945 p_stream->fmt.video.i_bits_per_pixel );
1947 /* Check for audio header (new format) */
1948 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1949 oggpacket.bytes >= 56+1 )
1951 char p_buffer[5];
1952 int i_extra_size;
1953 int i_format_tag;
1955 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1956 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1957 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1959 p_stream->fmt.i_cat = AUDIO_ES;
1961 /* We need to get rid of the header packet */
1962 ogg_stream_packetout( &p_stream->os, &oggpacket );
1964 i_extra_size = st->size - 56;
1966 if( i_extra_size > 0 &&
1967 i_extra_size < oggpacket.bytes - 1 - 56 )
1969 p_stream->fmt.i_extra = i_extra_size;
1970 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1971 if( p_stream->fmt.p_extra )
1972 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1973 p_stream->fmt.i_extra );
1974 else
1975 p_stream->fmt.i_extra = 0;
1978 memcpy( p_buffer, st->subtype, 4 );
1979 p_buffer[4] = '\0';
1980 i_format_tag = strtol(p_buffer,NULL,16);
1981 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1982 fill_channels_info(&p_stream->fmt.audio);
1983 if( st->time_unit <= 0 )
1984 st->time_unit = 10000000;
1985 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
1986 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1987 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1988 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1990 wf_tag_to_fourcc( i_format_tag,
1991 &p_stream->fmt.i_codec, 0 );
1993 if( p_stream->fmt.i_codec ==
1994 VLC_FOURCC('u','n','d','f') )
1996 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1997 ( i_format_tag >> 8 ) & 0xff,
1998 i_format_tag & 0xff );
2001 msg_Dbg( p_demux, "found audio header of type: %.4s",
2002 (char *)&p_stream->fmt.i_codec );
2003 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2004 "%dbits/sample %dkb/s",
2005 i_format_tag,
2006 p_stream->fmt.audio.i_channels,
2007 p_stream->fmt.audio.i_rate,
2008 p_stream->fmt.audio.i_bitspersample,
2009 p_stream->fmt.i_bitrate / 1024 );
2010 if ( p_stream->f_rate == 0 )
2012 msg_Dbg( p_demux, "invalid oggds audio header" );
2013 Ogg_LogicalStreamDelete( p_demux, p_stream );
2014 p_stream = NULL;
2015 p_ogg->i_streams--;
2018 /* Check for text (subtitles) header */
2019 else if( !strncmp(st->streamtype, "text", 4) )
2021 /* We need to get rid of the header packet */
2022 ogg_stream_packetout( &p_stream->os, &oggpacket );
2024 msg_Dbg( p_demux, "found text subtitle header" );
2025 p_stream->fmt.i_cat = SPU_ES;
2026 p_stream->fmt.i_codec = VLC_CODEC_SUBT;
2027 p_stream->f_rate = 1000; /* granulepos is in millisec */
2029 else
2031 msg_Dbg( p_demux, "stream %d has a header marker "
2032 "but is of an unknown type", p_ogg->i_streams-1 );
2033 FREENULL( p_stream );
2034 p_ogg->i_streams--;
2037 else if( oggpacket.bytes >= 8 &&
2038 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2041 /* Skeleton */
2042 msg_Dbg( p_demux, "stream %d is a skeleton",
2043 p_ogg->i_streams-1 );
2044 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2046 /* Check for OggSpots header */
2047 else if( oggpacket.bytes >= 8 &&
2048 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2050 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2051 msg_Dbg( p_demux,
2052 "found OggSpots header, time resolution: %f",
2053 p_stream->f_rate );
2054 else
2056 msg_Err( p_demux, "found invalid OggSpots header" );
2057 Ogg_LogicalStreamDelete( p_demux, p_stream );
2058 p_stream = NULL;
2059 p_ogg->i_streams--;
2062 else
2064 msg_Dbg( p_demux, "stream %d is of unknown type",
2065 p_ogg->i_streams-1 );
2068 /* we'll need to get all headers */
2069 if ( p_stream )
2070 p_stream->b_initializing &= p_stream->b_force_backup;
2072 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2073 return VLC_EGENERIC;
2076 /* This is the first data page, which means we are now finished
2077 * with the initial pages. We just need to store it in the relevant
2078 * bitstream. */
2079 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2081 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2082 &p_ogg->current_page ) == 0 )
2084 p_ogg->b_page_waiting = true;
2085 break;
2089 return VLC_SUCCESS;
2093 return VLC_EGENERIC;
2096 /****************************************************************************
2097 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2098 ****************************************************************************/
2099 static void Ogg_CreateES( demux_t *p_demux )
2101 demux_sys_t *p_ogg = p_demux->p_sys;
2102 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2103 int i_stream;
2105 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2107 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2109 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2111 /* Better be safe than sorry when possible with ogm */
2112 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2113 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2114 p_stream->fmt.b_packetized = false;
2116 /* Try first to reuse an old ES */
2117 if( p_old_stream &&
2118 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2119 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2121 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2123 p_stream->p_es = p_old_stream->p_es;
2124 p_stream->b_finished = false;
2125 p_stream->b_reinit = false;
2126 p_stream->b_initializing = false;
2127 p_stream->i_pre_skip = 0;
2128 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2129 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2131 p_old_stream->p_es = NULL;
2132 p_old_stream = NULL;
2133 if ( b_resetdecoder )
2135 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2136 p_stream->p_es, &p_stream->fmt );
2139 else
2141 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2144 // TODO: something to do here ?
2145 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2147 /* Set the CMML stream active */
2148 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2153 if( p_ogg->p_old_stream )
2155 if( p_ogg->p_old_stream->p_es )
2156 msg_Dbg( p_demux, "old stream not reused" );
2157 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2158 p_ogg->p_old_stream = NULL;
2160 p_ogg->b_es_created = true;
2163 /****************************************************************************
2164 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2165 * Elementary streams.
2166 ****************************************************************************/
2167 static int Ogg_BeginningOfStream( demux_t *p_demux )
2169 demux_sys_t *p_ogg = p_demux->p_sys ;
2170 int i_stream;
2172 /* Find the logical streams embedded in the physical stream and
2173 * initialize our p_ogg structure. */
2174 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2176 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2177 return VLC_EGENERIC;
2180 p_ogg->i_bitrate = 0;
2182 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2184 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2186 p_stream->p_es = NULL;
2188 /* initialise kframe index */
2189 p_stream->idx=NULL;
2191 if ( p_stream->fmt.i_bitrate == 0 &&
2192 ( p_stream->fmt.i_cat == VIDEO_ES ||
2193 p_stream->fmt.i_cat == AUDIO_ES ) )
2194 p_ogg->b_partial_bitrate = true;
2195 else
2196 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2198 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2199 p_stream->i_previous_granulepos = -1;
2200 p_stream->b_reinit = false;
2203 /* get total frame count for video stream; we will need this for seeking */
2204 p_ogg->i_total_frames = 0;
2206 return VLC_SUCCESS;
2209 /****************************************************************************
2210 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2211 ****************************************************************************/
2212 static void Ogg_EndOfStream( demux_t *p_demux )
2214 demux_sys_t *p_ogg = p_demux->p_sys ;
2215 int i_stream;
2217 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2218 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2219 free( p_ogg->pp_stream );
2221 /* Reinit p_ogg */
2222 p_ogg->i_bitrate = 0;
2223 p_ogg->i_streams = 0;
2224 p_ogg->pp_stream = NULL;
2225 p_ogg->skeleton.major = 0;
2226 p_ogg->skeleton.minor = 0;
2227 p_ogg->b_preparsing_done = false;
2228 p_ogg->b_es_created = false;
2230 /* */
2231 if( p_ogg->p_meta )
2232 vlc_meta_Delete( p_ogg->p_meta );
2233 p_ogg->p_meta = NULL;
2235 for(int i=0; i<p_ogg->i_attachments; i++)
2236 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2237 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2239 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2241 if ( p_ogg->pp_seekpoints[i] )
2242 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2244 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2247 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2249 #ifdef HAVE_LIBVORBIS
2250 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2252 if( p_stream->special.vorbis.p_info )
2253 vorbis_info_clear( p_stream->special.vorbis.p_info );
2254 FREENULL( p_stream->special.vorbis.p_info );
2255 if( p_stream->special.vorbis.p_comment )
2256 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2257 FREENULL( p_stream->special.vorbis.p_comment );
2258 p_stream->special.vorbis.i_headers_flags = 0;
2260 #else
2261 VLC_UNUSED( p_stream );
2262 #endif
2266 * This function delete and release all data associated to a logical_stream_t
2268 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2270 if( p_stream->p_es )
2271 es_out_Del( p_demux->out, p_stream->p_es );
2273 ogg_stream_clear( &p_stream->os );
2274 free( p_stream->p_headers );
2276 Ogg_CleanSpecificData( p_stream );
2278 es_format_Clean( &p_stream->fmt_old );
2279 es_format_Clean( &p_stream->fmt );
2281 if ( p_stream->idx != NULL)
2283 oggseek_index_entries_free( p_stream->idx );
2286 Ogg_FreeSkeleton( p_stream->p_skel );
2287 p_stream->p_skel = NULL;
2288 if ( p_demux->p_sys->p_skelstream == p_stream )
2289 p_demux->p_sys->p_skelstream = NULL;
2291 /* Shouldn't happen */
2292 if ( unlikely( p_stream->p_preparse_block ) )
2294 block_ChainRelease( p_stream->p_preparse_block );
2295 p_stream->p_preparse_block = NULL;
2297 free( p_stream->prepcr.pp_blocks );
2299 free( p_stream );
2302 * This function check if a we need to reset a decoder in case we are
2303 * reusing an old ES
2305 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2307 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2308 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2309 unsigned i_new_count;
2310 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2311 i_new_count = 0;
2313 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2314 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2315 unsigned i_old_count;
2316 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2317 i_old_count = 0;
2319 bool b_match = i_new_count == i_old_count;
2320 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2322 /* Ignore vorbis comment */
2323 if( i == 1 )
2324 continue;
2325 if( pi_new_size[i] != pi_old_size[i] ||
2326 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2327 b_match = false;
2330 return b_match;
2333 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2334 const es_format_t *p_old )
2336 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2337 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2338 unsigned i_new_count;
2339 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2340 i_new_count = 0;
2341 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2342 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2343 unsigned i_old_count;
2344 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2345 i_old_count = 0;
2346 bool b_match = false;
2347 if( i_new_count == i_old_count && i_new_count > 0 )
2349 static const unsigned char default_map[2] = { 0, 1 };
2350 unsigned char *p_old_head;
2351 unsigned char *p_new_head;
2352 const unsigned char *p_old_map;
2353 const unsigned char *p_new_map;
2354 int i_old_channel_count;
2355 int i_new_channel_count;
2356 int i_old_stream_count;
2357 int i_new_stream_count;
2358 int i_old_coupled_count;
2359 int i_new_coupled_count;
2360 p_old_head = (unsigned char *)pp_old_data[0];
2361 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2362 p_old_map = default_map;
2363 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2365 i_old_channel_count = p_old_head[9];
2366 switch( p_old_head[18] )
2368 case 0:
2369 i_old_stream_count = 1;
2370 i_old_coupled_count = i_old_channel_count - 1;
2371 break;
2372 case 1:
2373 if( pi_old_size[0] >= 21U + i_old_channel_count )
2375 i_old_stream_count = p_old_head[19];
2376 i_old_coupled_count = p_old_head[20];
2377 p_old_map = p_old_head + 21;
2379 break;
2382 p_new_head = (unsigned char *)pp_new_data[0];
2383 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2384 p_new_map = default_map;
2385 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2387 i_new_channel_count = p_new_head[9];
2388 switch( p_new_head[18] )
2390 case 0:
2391 i_new_stream_count = 1;
2392 i_new_coupled_count = i_new_channel_count - 1;
2393 break;
2394 case 1:
2395 if( pi_new_size[0] >= 21U + i_new_channel_count )
2397 i_new_stream_count = p_new_head[19];
2398 i_new_coupled_count = p_new_head[20];
2399 p_new_map = p_new_head+21;
2401 break;
2404 b_match = i_old_channel_count == i_new_channel_count &&
2405 i_old_stream_count == i_new_stream_count &&
2406 i_old_coupled_count == i_new_coupled_count &&
2407 memcmp(p_old_map, p_new_map,
2408 i_new_channel_count*sizeof(*p_new_map)) == 0;
2411 return b_match;
2414 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2416 bool b_compatible = false;
2417 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2418 return true;
2420 /* Only Vorbis and Opus are supported. */
2421 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2422 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2423 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2424 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2426 if( !b_compatible )
2427 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2429 return !b_compatible;
2432 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2433 const void *p_headers, unsigned i_headers )
2435 demux_sys_t *p_ogg = p_demux->p_sys;
2436 int i_cover_score = 0;
2437 int i_cover_idx = 0;
2438 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2439 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2440 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2442 pf_replay_gain[i] = 0;
2443 pf_replay_peak[i] = 0;
2445 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2446 &p_ogg->i_attachments, &p_ogg->attachments,
2447 &i_cover_score, &i_cover_idx,
2448 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2449 &pf_replay_gain, &pf_replay_peak );
2450 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2452 char psz_url[128];
2453 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2454 p_ogg->attachments[i_cover_idx]->psz_name );
2455 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2458 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2460 if ( pf_replay_gain[i] != 0 )
2462 p_fmt->audio_replay_gain.pb_gain[i] = true;
2463 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2464 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2466 if ( pf_replay_peak[i] != 0 )
2468 p_fmt->audio_replay_gain.pb_peak[i] = true;
2469 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2470 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2474 if( p_ogg->i_seekpoints > 1 )
2476 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2480 static inline uint32_t GetDW24BE( const uint8_t *p )
2482 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2483 #ifdef WORDS_BIGENDIAN
2484 i = bswap32(i);
2485 #endif
2486 return i;
2489 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2490 const uint8_t *p_headers, unsigned i_headers )
2492 /* Skip Streaminfo 42 bytes / 1st page */
2493 if(i_headers <= 46)
2494 return;
2495 p_headers += 42; i_headers -= 42;
2496 /* Block Header 1 + 3 bytes */
2497 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2498 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2500 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2504 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2505 const void *p_headers, unsigned i_headers, unsigned i_skip )
2507 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2508 void *pp_data[XIPH_MAX_HEADER_COUNT];
2509 unsigned i_count;
2511 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2512 return;
2513 /* TODO how to handle multiple comments properly ? */
2514 if( i_count >= 2 && pi_size[1] > i_skip )
2516 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2520 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2522 demux_sys_t *p_ogg = p_demux->p_sys;
2524 switch( p_fmt->i_codec )
2526 /* 3 headers with the 2° one being the comments */
2527 case VLC_CODEC_VORBIS:
2528 case VLC_CODEC_THEORA:
2529 case VLC_CODEC_DAALA:
2530 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2531 break;
2532 case VLC_CODEC_OPUS:
2533 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2534 break;
2535 case VLC_CODEC_SPEEX:
2536 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2537 break;
2538 case VLC_CODEC_VP8:
2539 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2540 break;
2541 /* N headers with the 2° one being the comments */
2542 case VLC_CODEC_KATE:
2543 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2544 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2545 break;
2547 /* TODO */
2548 case VLC_CODEC_FLAC:
2549 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2550 break;
2552 /* No meta data */
2553 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2554 case VLC_CODEC_DIRAC:
2555 default:
2556 break;
2558 if( p_ogg->p_meta )
2559 p_demux->info.i_update |= INPUT_UPDATE_META;
2562 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2563 ogg_packet *p_oggpacket )
2565 bs_t bitstream;
2566 unsigned int i_fps_numerator;
2567 unsigned int i_fps_denominator;
2568 int i_keyframe_frequency_force;
2569 int i_major;
2570 int i_minor;
2571 int i_subminor;
2572 int i_version;
2574 p_stream->fmt.i_cat = VIDEO_ES;
2575 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
2577 /* Signal that we want to keep a backup of the theora
2578 * stream headers. They will be used when switching between
2579 * audio streams. */
2580 p_stream->b_force_backup = true;
2582 /* Cheat and get additionnal info ;) */
2583 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2584 bs_skip( &bitstream, 56 );
2586 i_major = bs_read( &bitstream, 8 ); /* major version num */
2587 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2588 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2590 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2591 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2592 bs_read( &bitstream, 24 ); /* frame width */
2593 bs_read( &bitstream, 24 ); /* frame height */
2594 bs_read( &bitstream, 8 ); /* x offset */
2595 bs_read( &bitstream, 8 ); /* y offset */
2597 i_fps_numerator = bs_read( &bitstream, 32 );
2598 i_fps_denominator = bs_read( &bitstream, 32 );
2599 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2600 bs_read( &bitstream, 24 ); /* aspect_numerator */
2601 bs_read( &bitstream, 24 ); /* aspect_denominator */
2603 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2604 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2606 bs_read( &bitstream, 8 ); /* colorspace */
2607 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2608 bs_read( &bitstream, 6 ); /* quality */
2610 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2612 /* granule_shift = i_log( frequency_force -1 ) */
2613 p_stream->i_granule_shift = 0;
2614 i_keyframe_frequency_force--;
2615 while( i_keyframe_frequency_force )
2617 p_stream->i_granule_shift++;
2618 i_keyframe_frequency_force >>= 1;
2621 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2622 p_stream->i_keyframe_offset = 0;
2623 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2624 if ( p_stream->f_rate == 0 ) return false;
2626 if ( i_version >= 3002001 )
2628 p_stream->i_keyframe_offset = 1;
2630 return true;
2633 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2634 ogg_packet *p_oggpacket )
2636 oggpack_buffer opb;
2637 uint32_t i_timebase_numerator;
2638 uint32_t i_timebase_denominator;
2639 int i_keyframe_frequency_force;
2640 uint8_t i_major;
2641 uint8_t i_minor;
2642 uint8_t i_subminor;
2643 int i_version;
2645 p_stream->fmt.i_cat = VIDEO_ES;
2646 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
2648 /* Signal that we want to keep a backup of the daala
2649 * stream headers. They will be used when switching between
2650 * audio streams. */
2651 p_stream->b_force_backup = true;
2653 /* Cheat and get additionnal info ;) */
2654 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2655 oggpack_adv( &opb, 48 );
2657 i_major = oggpack_read( &opb, 8 ); /* major version num */
2658 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2659 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2661 oggpack_adv( &opb, 32 ); /* width */
2662 oggpack_adv( &opb, 32 ); /* height */
2664 oggpack_adv( &opb, 32 ); /* aspect numerator */
2665 oggpack_adv( &opb, 32 ); /* aspect denominator */
2666 i_timebase_numerator = oggpack_read( &opb, 32 );
2668 i_timebase_denominator = oggpack_read( &opb, 32 );
2669 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2671 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2672 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2674 oggpack_adv( &opb, 32 ); /* frame duration */
2676 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2678 /* granule_shift = i_log( frequency_force -1 ) */
2679 p_stream->i_granule_shift = 0;
2680 i_keyframe_frequency_force--;
2681 while( i_keyframe_frequency_force )
2683 p_stream->i_granule_shift++;
2684 i_keyframe_frequency_force >>= 1;
2687 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2688 VLC_UNUSED(i_version);
2689 p_stream->i_keyframe_offset = 0;
2690 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2691 if ( p_stream->f_rate == 0 ) return false;
2693 return true;
2696 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2697 ogg_packet *p_oggpacket )
2699 oggpack_buffer opb;
2701 p_stream->fmt.i_cat = AUDIO_ES;
2702 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2704 /* Signal that we want to keep a backup of the vorbis
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, 88 );
2712 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2713 fill_channels_info(&p_stream->fmt.audio);
2714 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2715 oggpack_read( &opb, 32 );
2716 oggpack_adv( &opb, 32 );
2717 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2718 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2719 if ( p_stream->f_rate == 0 ) return false;
2720 return true;
2722 #ifdef HAVE_LIBVORBIS
2723 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2724 ogg_packet *p_oggpacket, int i_number )
2726 switch( i_number )
2728 case VORBIS_HEADER_IDENTIFICATION:
2729 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2730 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2731 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2733 FREENULL( p_stream->special.vorbis.p_info );
2734 FREENULL( p_stream->special.vorbis.p_comment );
2735 break;
2737 vorbis_info_init( p_stream->special.vorbis.p_info );
2738 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2739 // ft
2741 case VORBIS_HEADER_COMMENT:
2742 case VORBIS_HEADER_SETUP:
2743 if ( !p_stream->special.vorbis.p_info ||
2744 vorbis_synthesis_headerin(
2745 p_stream->special.vorbis.p_info,
2746 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2747 break;
2749 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2750 // ft
2752 default:
2753 break;
2756 #endif
2758 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2759 ogg_packet *p_oggpacket )
2761 oggpack_buffer opb;
2763 p_stream->fmt.i_cat = AUDIO_ES;
2764 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2766 /* Signal that we want to keep a backup of the speex
2767 * stream headers. They will be used when switching between
2768 * audio streams. */
2769 p_stream->b_force_backup = true;
2771 /* Cheat and get additionnal info ;) */
2772 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2773 oggpack_adv( &opb, 224 );
2774 oggpack_adv( &opb, 32 ); /* speex_version_id */
2775 oggpack_adv( &opb, 32 ); /* header_size */
2776 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2777 if ( p_stream->f_rate == 0 ) return false;
2778 oggpack_adv( &opb, 32 ); /* mode */
2779 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2780 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2781 fill_channels_info(&p_stream->fmt.audio);
2782 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2783 p_stream->special.speex.i_framesize =
2784 oggpack_read( &opb, 32 ); /* frame_size */
2785 oggpack_adv( &opb, 32 ); /* vbr */
2786 p_stream->special.speex.i_framesperpacket =
2787 oggpack_read( &opb, 32 ); /* frames_per_packet */
2788 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2789 return true;
2792 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2793 ogg_packet *p_oggpacket )
2795 oggpack_buffer opb;
2797 p_stream->fmt.i_cat = AUDIO_ES;
2798 p_stream->fmt.i_codec = VLC_CODEC_OPUS;
2800 /* Signal that we want to keep a backup of the opus
2801 * stream headers. They will be used when switching between
2802 * audio streams. */
2803 p_stream->b_force_backup = true;
2805 /* All OggOpus streams are timestamped at 48kHz and
2806 * can be played at 48kHz. */
2807 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2808 p_stream->fmt.i_bitrate = 0;
2810 /* Cheat and get additional info ;) */
2811 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2812 oggpack_adv( &opb, 64 );
2813 oggpack_adv( &opb, 8 ); /* version_id */
2814 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2815 fill_channels_info(&p_stream->fmt.audio);
2816 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2817 /* For Opus, trash the first 80 ms of decoded output as
2818 well, to avoid blowing out speakers if we get unlucky.
2819 Opus predicts content from prior frames, which can go
2820 badly if we seek right where the stream goes from very
2821 quiet to very loud. It will converge after a bit. */
2822 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2825 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2826 ogg_packet *p_oggpacket )
2828 /* Parse the STREAMINFO metadata */
2829 bs_t s;
2831 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2833 bs_read( &s, 1 );
2834 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2836 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2837 return false;
2840 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2842 bs_skip( &s, 80 );
2843 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2844 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2845 fill_channels_info(&p_stream->fmt.audio);
2847 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2848 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2849 if ( p_stream->f_rate == 0 ) return false;
2851 else
2853 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2856 /* Fake this as the last metadata block */
2857 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2858 return true;
2861 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2862 ogg_packet *p_oggpacket )
2864 oggpack_buffer opb;
2865 uint32_t gnum;
2866 uint32_t gden;
2867 int n;
2868 char *psz_desc;
2870 p_stream->fmt.i_cat = SPU_ES;
2871 p_stream->fmt.i_codec = VLC_CODEC_KATE;
2873 /* Signal that we want to keep a backup of the kate
2874 * stream headers. They will be used when switching between
2875 * kate streams. */
2876 p_stream->b_force_backup = true;
2878 /* Cheat and get additionnal info ;) */
2879 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2880 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2881 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2882 oggpack_adv( &opb, 3*8 );
2883 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2884 oggpack_adv( &opb, 8*8 ); /* reserved */
2885 gnum = oggpack_read( &opb, 32 );
2886 gden = oggpack_read( &opb, 32 );
2887 gden = __MAX( gden, 1 );
2888 p_stream->f_rate = (double)gnum/gden;
2889 if ( p_stream->f_rate == 0 ) return false;
2891 p_stream->fmt.psz_language = malloc(16);
2892 if( p_stream->fmt.psz_language )
2894 for( n = 0; n < 16; n++ )
2895 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2896 p_stream->fmt.psz_language[15] = 0; /* just in case */
2898 else
2900 for( n = 0; n < 16; n++ )
2901 oggpack_read(&opb,8);
2903 p_stream->fmt.psz_description = malloc(16);
2904 if( p_stream->fmt.psz_description )
2906 for( n = 0; n < 16; n++ )
2907 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2908 p_stream->fmt.psz_description[15] = 0; /* just in case */
2910 /* Now find a localized user readable description for this category */
2911 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2912 if( psz_desc )
2914 free( p_stream->fmt.psz_description );
2915 p_stream->fmt.psz_description = psz_desc;
2918 else
2920 for( n = 0; n < 16; n++ )
2921 oggpack_read(&opb,8);
2924 return true;
2927 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2928 ogg_packet *p_oggpacket )
2930 switch( p_oggpacket->packet[5] )
2932 /* STREAMINFO */
2933 case 0x01:
2934 /* Mapping version */
2935 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2936 return false;
2937 p_stream->fmt.i_cat = VIDEO_ES;
2938 p_stream->fmt.i_codec = VLC_CODEC_VP8;
2939 p_stream->i_granule_shift = 32;
2940 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2941 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2942 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2943 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2944 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2945 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2946 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2947 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2948 p_stream->fmt.video.i_frame_rate_base =
2949 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2950 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2951 if ( p_stream->f_rate == 0 ) return false;
2952 return true;
2953 /* METADATA */
2954 case 0x02:
2955 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2956 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2957 return true;
2958 default:
2959 return false;
2963 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2964 bool *b_force_backup, bool *b_packet_out )
2966 if( !strncmp(psz_value, "audio/x-wav", 11) )
2968 /* n.b. WAVs are unsupported right now */
2969 p_stream->fmt.i_cat = UNKNOWN_ES;
2970 free( p_stream->fmt.psz_description );
2971 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2973 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2974 !strncmp(psz_value, "audio/vorbis", 12) )
2976 p_stream->fmt.i_cat = AUDIO_ES;
2977 p_stream->fmt.i_codec = VLC_CODEC_VORBIS;
2979 *b_force_backup = true;
2981 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2982 !strncmp(psz_value, "audio/speex", 11) )
2984 p_stream->fmt.i_cat = AUDIO_ES;
2985 p_stream->fmt.i_codec = VLC_CODEC_SPEEX;
2987 *b_force_backup = true;
2989 else if( !strncmp(psz_value, "audio/flac", 10) )
2991 p_stream->fmt.i_cat = AUDIO_ES;
2992 p_stream->fmt.i_codec = VLC_CODEC_FLAC;
2994 *b_force_backup = true;
2996 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2997 !strncmp(psz_value, "video/theora", 12) )
2999 p_stream->fmt.i_cat = VIDEO_ES;
3000 p_stream->fmt.i_codec = VLC_CODEC_THEORA;
3002 *b_force_backup = true;
3004 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3005 !strncmp(psz_value, "video/daala", 11) )
3007 p_stream->fmt.i_cat = VIDEO_ES;
3008 p_stream->fmt.i_codec = VLC_CODEC_DAALA;
3010 *b_force_backup = true;
3012 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3014 p_stream->fmt.i_cat = VIDEO_ES;
3015 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
3017 *b_force_backup = true;
3019 else if( !strncmp(psz_value, "video/mpeg", 10) )
3021 /* n.b. MPEG streams are unsupported right now */
3022 p_stream->fmt.i_cat = VIDEO_ES;
3023 p_stream->fmt.i_codec = VLC_CODEC_MPGV;
3025 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
3026 !strncmp(psz_value, "text/cmml", 9) )
3028 p_stream->fmt.i_cat = SPU_ES;
3029 p_stream->fmt.i_codec = VLC_CODEC_CMML;
3030 *b_packet_out = true;
3032 else if( !strncmp(psz_value, "application/kate", 16) )
3034 /* ??? */
3035 p_stream->fmt.i_cat = UNKNOWN_ES;
3036 free( p_stream->fmt.psz_description );
3037 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3039 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3041 p_stream->fmt.i_cat = VIDEO_ES;
3042 p_stream->fmt.i_codec = VLC_CODEC_VP8;
3046 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3047 logical_stream_t *p_stream,
3048 ogg_packet *p_oggpacket )
3050 if( p_oggpacket->bytes >= 28 &&
3051 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3053 oggpack_buffer opb;
3055 uint16_t major_version;
3056 uint16_t minor_version;
3057 uint64_t timebase_numerator;
3058 uint64_t timebase_denominator;
3060 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3062 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3063 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3064 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3065 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3066 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3067 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3069 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3070 "Timebase %"PRId64" / %"PRId64,
3071 major_version, minor_version,
3072 timebase_numerator, timebase_denominator );
3074 else if( p_oggpacket->bytes >= 42 &&
3075 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3077 uint64_t granule_rate_numerator;
3078 uint64_t granule_rate_denominator;
3079 char content_type_string[1024];
3081 /* Read in Annodex header fields */
3083 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3084 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3085 p_stream->i_secondary_header_packets =
3086 GetDWLE( &p_oggpacket->packet[24] );
3088 /* we are guaranteed that the first header field will be
3089 * the content-type (by the Annodex standard) */
3090 content_type_string[0] = '\0';
3091 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3093 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3094 p_oggpacket->bytes - 1 );
3095 if( p && p[0] == '\r' && p[1] == '\n' )
3096 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3097 content_type_string );
3100 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3101 granule_rate_numerator, granule_rate_denominator,
3102 p_stream->i_secondary_header_packets, content_type_string );
3104 p_stream->f_rate = (float) granule_rate_numerator /
3105 (float) granule_rate_denominator;
3107 /* What type of file do we have?
3108 * strcmp is safe to use here because we've extracted
3109 * content_type_string from the stream manually */
3110 bool b_dopacketout = false;
3111 Ogg_ApplyContentType( p_stream, content_type_string,
3112 &p_stream->b_force_backup, &b_dopacketout );
3113 if ( b_dopacketout ) ogg_stream_packetout( &p_stream->os, p_oggpacket );
3117 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3118 ogg_packet *p_oggpacket )
3120 p_demux->p_sys->p_skelstream = p_stream;
3121 /* There can be only 1 skeleton for streams */
3122 p_demux->p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3123 p_demux->p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3124 if ( asprintf( & p_stream->fmt.psz_description,
3125 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3126 p_demux->p_sys->skeleton.major,
3127 p_demux->p_sys->skeleton.minor ) < 0 )
3128 p_stream->fmt.psz_description = NULL;
3131 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3133 if ( p_demux->p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3135 /* Find the matching stream for this skeleton data */
3136 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3137 logical_stream_t *p_target_stream = NULL;
3138 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3140 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3142 p_target_stream = p_demux->p_sys->pp_stream[i];
3143 break;
3146 if ( !p_target_stream ) return;
3148 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3149 if ( !p_skel )
3151 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3152 if ( !p_skel ) return;
3153 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3154 p_skel->p_index = NULL;
3155 p_target_stream->p_skel = p_skel;
3158 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3159 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3160 const unsigned char *p = p_messages;
3161 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3163 if ( *p == 0x0D && *(p+1) == 0x0A )
3165 char *psz_message = strndup( (const char *) p_messages,
3166 p - p_messages );
3167 if ( psz_message )
3169 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3170 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3172 if ( p < p_boundary - 1 ) p_messages = p + 2;
3174 p++;
3179 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3180 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3181 unsigned const char *p_end,
3182 uint64_t *pi_value )
3184 int i_shift = 0;
3185 int64_t i_read = 0;
3186 *pi_value = 0;
3188 while ( p_begin < p_end )
3190 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3191 *pi_value = *pi_value | ( i_read << i_shift );
3192 i_shift += 7;
3193 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3196 *pi_value = GetQWLE( pi_value );
3197 return p_begin;
3200 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3202 if ( p_demux->p_sys->skeleton.major < 4
3203 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3204 ) return;
3206 /* Find the matching stream for this skeleton data */
3207 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3208 logical_stream_t *p_stream = NULL;
3209 for ( int i=0; i< p_demux->p_sys->i_streams; i++ )
3211 if ( p_demux->p_sys->pp_stream[i]->i_serial_no == i_serialno )
3213 p_stream = p_demux->p_sys->pp_stream[i];
3214 break;
3217 if ( !p_stream || !p_stream->p_skel ) return;
3218 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3219 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3220 if ( !i_keypoints ) return;
3222 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3223 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3224 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3225 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3226 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3227 uint64_t i_offset = 0;
3228 uint64_t i_time = 0;
3229 uint64_t i_keypoints_found = 0;
3231 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3233 uint64_t i_val;
3234 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3235 i_offset += i_val;
3236 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3237 i_time += i_val * p_stream->p_skel->i_indexstampden;
3238 i_keypoints_found++;
3241 if ( i_keypoints_found != i_keypoints )
3243 msg_Warn( p_demux, "Invalid Index: missing entries" );
3244 return;
3247 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3248 if ( !p_stream->p_skel->p_index ) return;
3249 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3250 p_oggpacket->bytes - 42 );
3251 p_stream->p_skel->i_index = i_keypoints_found;
3252 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3255 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3257 if ( !p_skel ) return;
3258 for ( int i=0; i< p_skel->i_messages; i++ )
3259 free( p_skel->ppsz_messages[i] );
3260 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3261 free( p_skel->p_index );
3262 free( p_skel );
3265 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3267 if ( !p_stream->p_skel ) return;
3268 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3270 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3271 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3273 free( p_stream->fmt.psz_description );
3274 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3276 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3278 bool b_foo;
3279 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3284 /* Return true if there's a skeleton exact match */
3285 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3286 int64_t *pi_lower, int64_t *pi_upper )
3288 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3289 return false;
3291 /* Validate range */
3292 if ( i_time < p_stream->p_skel->i_indexfirstnum
3293 * p_stream->p_skel->i_indexstampden ||
3294 i_time > p_stream->p_skel->i_indexlastnum
3295 * p_stream->p_skel->i_indexstampden ) return false;
3297 /* Then Lookup its index */
3298 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3299 struct
3301 int64_t i_pos;
3302 int64_t i_time;
3303 } current = { 0, 0 }, prev = { -1, -1 };
3305 uint64_t i_keypoints_found = 0;
3307 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3308 && i_keypoints_found < p_stream->p_skel->i_index )
3310 uint64_t i_val;
3311 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3312 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3313 current.i_pos += i_val;
3314 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3315 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3316 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3317 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3319 i_keypoints_found++;
3321 if ( i_time <= current.i_time )
3323 *pi_lower = prev.i_pos;
3324 *pi_upper = current.i_pos;
3325 return ( i_time == current.i_time );
3327 prev = current;
3329 return false;
3332 static uint32_t dirac_uint( bs_t *p_bs )
3334 uint32_t u_count = 0, u_value = 0;
3336 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3338 u_count++;
3339 u_value <<= 1;
3340 u_value |= bs_read( p_bs, 1 );
3343 return (1<<u_count) - 1 + u_value;
3346 static int dirac_bool( bs_t *p_bs )
3348 return bs_read( p_bs, 1 );
3351 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3352 ogg_packet *p_oggpacket )
3354 static const struct {
3355 uint32_t u_n /* numerator */, u_d /* denominator */;
3356 } p_dirac_frate_tbl[] = { /* table 10.3 */
3357 {1,1}, /* this first value is never used */
3358 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3359 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3361 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3363 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3364 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3366 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3368 bs_t bs;
3370 p_stream->i_granule_shift = 22; /* not 32 */
3372 /* Backing up stream headers is not required -- seqhdrs are repeated
3373 * thoughout the stream at suitable decoding start points */
3374 p_stream->b_force_backup = false;
3376 /* read in useful bits from sequence header */
3377 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3378 bs_skip( &bs, 13*8); /* parse_info_header */
3379 dirac_uint( &bs ); /* major_version */
3380 dirac_uint( &bs ); /* minor_version */
3381 dirac_uint( &bs ); /* profile */
3382 dirac_uint( &bs ); /* level */
3384 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3385 if( u_video_format >= u_dirac_vidfmt_frate )
3387 /* don't know how to parse this ogg dirac stream */
3388 return false;
3391 if( dirac_bool( &bs ) )
3393 dirac_uint( &bs ); /* frame_width */
3394 dirac_uint( &bs ); /* frame_height */
3397 if( dirac_bool( &bs ) )
3399 dirac_uint( &bs ); /* chroma_format */
3402 if( dirac_bool( &bs ) )
3404 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3406 else
3407 p_stream->special.dirac.b_interlaced = false;
3409 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3410 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3411 u_d = __MAX( u_d, 1 );
3412 if( dirac_bool( &bs ) )
3414 uint32_t u_frame_rate_index = dirac_uint( &bs );
3415 if( u_frame_rate_index >= u_dirac_frate_tbl )
3417 /* something is wrong with this stream */
3418 return false;
3420 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3421 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3422 if( u_frame_rate_index == 0 )
3424 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3425 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3428 p_stream->f_rate = (float) u_n / u_d;
3429 if ( p_stream->f_rate == 0 ) return false;
3431 /* probably is an ogg dirac es */
3432 p_stream->fmt.i_cat = VIDEO_ES;
3433 p_stream->fmt.i_codec = VLC_CODEC_DIRAC;
3435 return true;
3438 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3439 ogg_packet *p_oggpacket )
3441 uint64_t i_granulerate_numerator;
3442 uint64_t i_granulerate_denominator;
3443 int i_major;
3444 int i_minor;
3446 p_stream->fmt.i_cat = VIDEO_ES;
3447 p_stream->fmt.i_codec = VLC_CODEC_OGGSPOTS;
3449 /* Signal that we want to keep a backup of the OggSpots
3450 * stream headers. They will be used when switching between
3451 * audio streams. */
3452 p_stream->b_force_backup = true;
3454 /* Cheat and get additionnal info ;) */
3455 if ( p_oggpacket->bytes != 52 )
3457 /* The OggSpots header is always 52 bytes */
3458 return false;
3461 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3462 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3463 if ( i_major != 0 || i_minor != 1 )
3465 return false;
3468 /* Granule rate */
3469 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3470 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3471 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3473 return false;
3476 /* The OggSpots spec contained an error and there are implementations out
3477 * there that used the wrong value. So we detect that case and switch
3478 * numerator and denominator in that case */
3479 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3481 i_granulerate_numerator = 30;
3482 i_granulerate_denominator = 1;
3485 p_stream->f_rate = ((double)i_granulerate_numerator) / i_granulerate_denominator;
3486 if ( p_stream->f_rate == 0 )
3488 return false;
3491 /* Normalize granulerate */
3492 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3493 &p_stream->fmt.video.i_frame_rate_base,
3494 i_granulerate_numerator, i_granulerate_denominator, 0);
3496 p_stream->i_granule_shift = p_oggpacket->packet[28];
3498 return true;