packetizer: hevc: add poc debug
[vlc.git] / modules / demux / ogg.c
blobed658ebcdc7fdd935db8f3d094616b1a0c48d903
1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_demux.h>
36 #include <vlc_meta.h>
37 #include <vlc_input.h>
39 #include <ogg/ogg.h>
41 #include <vlc_codecs.h>
42 #include <vlc_bits.h>
43 #include "xiph.h"
44 #include "xiph_metadata.h"
45 #include "ogg.h"
46 #include "oggseek.h"
47 #include "opus.h"
49 /*****************************************************************************
50 * Module descriptor
51 *****************************************************************************/
52 static int Open ( vlc_object_t * );
53 static void Close( vlc_object_t * );
55 vlc_module_begin ()
56 set_shortname ( "OGG" )
57 set_description( N_("OGG demuxer" ) )
58 set_category( CAT_INPUT )
59 set_subcategory( SUBCAT_INPUT_DEMUX )
60 set_capability( "demux", 50 )
61 set_callbacks( Open, Close )
62 add_shortcut( "ogg" )
63 vlc_module_end ()
66 /*****************************************************************************
67 * Definitions of structures and functions used by this plugins
68 *****************************************************************************/
70 /* OggDS headers for the new header format (used in ogm files) */
71 typedef struct
73 ogg_int32_t width;
74 ogg_int32_t height;
75 } stream_header_video_t;
77 typedef struct
79 ogg_int16_t channels;
80 ogg_int16_t padding;
81 ogg_int16_t blockalign;
82 ogg_int32_t avgbytespersec;
83 } stream_header_audio_t;
85 typedef struct
87 char streamtype[8];
88 char subtype[4];
90 ogg_int32_t size; /* size of the structure */
92 ogg_int64_t time_unit; /* in reference time */
93 ogg_int64_t samples_per_unit;
94 ogg_int32_t default_len; /* in media time */
96 ogg_int32_t buffersize;
97 ogg_int16_t bits_per_sample;
98 ogg_int16_t padding;
100 union
102 /* Video specific */
103 stream_header_video_t video;
104 /* Audio specific */
105 stream_header_audio_t audio;
106 } sh;
107 } stream_header_t;
109 #define VORBIS_HEADER_IDENTIFICATION 1
110 #define VORBIS_HEADER_COMMENT 2
111 #define VORBIS_HEADER_SETUP 3
112 #define VORBIS_HEADER_TO_FLAG(i) (1 << (i - 1))
113 #define VORBIS_HEADERS_VALID(p_stream) \
114 ((p_stream->special.vorbis.i_headers_flags & 0x07) == 0x07) // 0b111
116 /*****************************************************************************
117 * Local prototypes
118 *****************************************************************************/
119 static int Demux ( demux_t * );
120 static int Control( demux_t *, int, va_list );
122 /* Bitstream manipulation */
123 static int Ogg_ReadPage ( demux_t *, ogg_page * );
124 static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * );
125 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
126 static unsigned Ogg_OpusPacketDuration( ogg_packet * );
127 static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * );
129 static void Ogg_CreateES( demux_t *p_demux );
130 static int Ogg_BeginningOfStream( demux_t *p_demux );
131 static int Ogg_FindLogicalStreams( demux_t *p_demux );
132 static void Ogg_EndOfStream( demux_t *p_demux );
134 /* */
135 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
136 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
137 static void Ogg_ResetStream( logical_stream_t *p_stream );
139 /* */
140 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
142 /* Logical bitstream headers */
143 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
144 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
145 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
146 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
147 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
148 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
149 static bool Ogg_ReadFlacStreamInfo( demux_t *, logical_stream_t *, ogg_packet * );
150 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
151 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
152 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
153 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
154 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *, ogg_packet * );
156 /* Skeleton */
157 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
158 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
159 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
160 static void Ogg_ApplySkeleton( logical_stream_t * );
162 /* Special decoding */
163 static void Ogg_CleanSpecificData( logical_stream_t * );
164 #ifdef HAVE_LIBVORBIS
165 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
166 #endif
168 static void fill_channels_info(audio_format_t *audio)
170 static const int pi_channels_map[9] =
173 AOUT_CHAN_CENTER,
174 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
175 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
176 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
177 | AOUT_CHAN_REARRIGHT,
178 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
179 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
180 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
181 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
182 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
183 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
184 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
185 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
186 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
187 | AOUT_CHAN_LFE,
190 unsigned chans = audio->i_channels;
191 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
192 audio->i_physical_channels = pi_channels_map[chans];
195 /* Special TS value: don't send or derive any pts/pcr from it.
196 Represents TS state prior first known valid timestamp */
197 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
199 /*****************************************************************************
200 * Open: initializes ogg demux structures
201 *****************************************************************************/
202 static int Open( vlc_object_t * p_this )
204 demux_t *p_demux = (demux_t *)p_this;
205 demux_sys_t *p_sys;
206 const uint8_t *p_peek;
208 /* Check if we are dealing with an ogg stream */
209 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
210 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
212 char *psz_mime = stream_ContentType( p_demux->s );
213 if( !psz_mime )
215 return VLC_EGENERIC;
217 else if ( strcmp( psz_mime, "application/ogg" ) &&
218 strcmp( psz_mime, "video/ogg" ) &&
219 strcmp( psz_mime, "audio/ogg" ) )
221 free( psz_mime );
222 return VLC_EGENERIC;
224 free( psz_mime );
227 /* */
228 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
229 if( !p_sys )
230 return VLC_ENOMEM;
232 p_sys->i_length = -1;
233 p_sys->b_preparsing_done = false;
235 vlc_stream_Control( p_demux->s, STREAM_GET_PTS_DELAY,
236 &p_sys->i_access_delay );
238 /* Set exported functions */
239 p_demux->pf_demux = Demux;
240 p_demux->pf_control = Control;
242 /* Initialize the Ogg physical bitstream parser */
243 ogg_sync_init( &p_sys->oy );
245 /* */
246 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
249 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
251 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
252 Ogg_CreateES( p_demux );
254 return VLC_SUCCESS;
257 /*****************************************************************************
258 * Close: frees unused data
259 *****************************************************************************/
260 static void Close( vlc_object_t *p_this )
262 demux_t *p_demux = (demux_t *)p_this;
263 demux_sys_t *p_sys = p_demux->p_sys ;
265 /* Cleanup the bitstream parser */
266 ogg_sync_clear( &p_sys->oy );
268 Ogg_EndOfStream( p_demux );
270 if( p_sys->p_old_stream )
271 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
273 free( p_sys );
276 /*****************************************************************************
277 * Demux: reads and demuxes data packets
278 *****************************************************************************
279 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
280 *****************************************************************************/
281 static int Demux( demux_t * p_demux )
283 demux_sys_t *p_sys = p_demux->p_sys;
284 ogg_packet oggpacket;
285 int i_stream;
286 bool b_skipping = false;
287 bool b_canseek;
289 int i_active_streams = p_sys->i_streams;
290 for ( int i=0; i < p_sys->i_streams; i++ )
292 if ( p_sys->pp_stream[i]->b_finished )
293 i_active_streams--;
296 if ( i_active_streams == 0 )
298 if ( p_sys->i_streams ) /* All finished */
300 msg_Dbg( p_demux, "end of a group of logical streams" );
302 mtime_t i_lastpcr = VLC_TS_INVALID;
303 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
305 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
306 if( p_stream->i_pcr > i_lastpcr )
307 i_lastpcr = p_stream->i_pcr;
310 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
311 * only 1 ES is supported (common case for ogg web radio) */
312 if( p_sys->i_streams == 1 )
314 p_sys->p_old_stream = p_sys->pp_stream[0];
315 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
318 Ogg_EndOfStream( p_demux );
319 p_sys->b_chained_boundary = true;
321 if( i_lastpcr > VLC_TS_INVALID )
323 p_sys->i_nzpcr_offset = i_lastpcr - VLC_TS_0;
324 if( likely( !p_sys->b_slave ) )
325 es_out_SetPCR( p_demux->out, i_lastpcr );
327 p_sys->i_pcr = VLC_TS_INVALID;
330 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
331 return VLC_DEMUXER_EOF;
333 msg_Dbg( p_demux, "beginning of a group of logical streams" );
335 if ( !p_sys->b_chained_boundary )
337 /* Find the real duration */
338 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
339 if ( b_canseek )
340 Oggseek_ProbeEnd( p_demux );
342 else
344 p_sys->b_chained_boundary = false;
348 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
349 Ogg_CreateES( p_demux );
352 * The first data page of a physical stream is stored in the relevant logical stream
353 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
354 * stream it belongs to if we haven't processed this first page yet. If we do, we
355 * will only process that first page whenever we find the second page for this stream.
356 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
357 * the second page will arrive real quick, this is not fine for Kate, whose second
358 * data page will typically arrive much later.
359 * This means it is now possible to seek right at the start of a stream where the last
360 * logical stream is Kate, without having to wait for the second data page to unblock
361 * the first one, which is the one that triggers the 'no more headers to backup' code.
362 * And, as we all know, seeking without having backed up all headers is bad, since the
363 * codec will fail to initialize if it's missing its headers.
365 if( !p_sys->b_page_waiting)
368 * Demux an ogg page from the stream
370 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
371 return VLC_DEMUXER_EOF; /* EOF */
372 /* Test for End of Stream */
373 if( ogg_page_eos( &p_sys->current_page ) )
375 /* If we delayed restarting encoders/SET_ES_FMT for more
376 * skeleton provided configuration */
377 if ( p_sys->p_skelstream )
379 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
381 msg_Dbg( p_demux, "End of Skeleton" );
382 p_sys->b_preparsing_done = true;
383 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
385 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
386 Ogg_ApplySkeleton( p_stream );
391 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
393 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
395 p_sys->pp_stream[i_stream]->b_finished = true;
396 break;
402 b_skipping = false;
403 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
405 b_skipping |= p_sys->pp_stream[i_stream]->i_skip_frames;
408 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
410 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
412 /* if we've just pulled page, look for the right logical stream */
413 if( !p_sys->b_page_waiting )
415 if( p_sys->i_streams == 1 &&
416 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
418 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
419 Ogg_ResetStream( p_stream );
420 if( p_stream->i_pcr > VLC_TS_INVALID )
421 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TS_0;
422 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
425 /* Does fail if serialno differs */
426 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
428 continue;
432 /* clear the finished flag if pages after eos (ex: after a seek) */
433 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
434 p_stream->b_finished = false;
436 DemuxDebug(
437 if ( p_stream->fmt.i_cat == VIDEO_ES )
438 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
439 ogg_page_pageno( &p_sys->current_page ),
440 ogg_page_granulepos( &p_sys->current_page ),
441 ogg_page_packets( &p_sys->current_page ),
442 ogg_page_continued(&p_sys->current_page),
443 p_sys->current_page.body_len )
446 const int i_page_packets = ogg_page_packets( &p_sys->current_page );
447 bool b_doprepcr = false;
449 if ( p_stream->i_pcr < VLC_TS_0 && ogg_page_granulepos( &p_sys->current_page ) > 0 )
451 // PASS 0
452 if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
453 p_stream->fmt.i_codec == VLC_CODEC_VORBIS ||
454 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
455 p_stream->fmt.i_cat == VIDEO_ES )
457 assert( p_stream->prepcr.pp_blocks == NULL );
458 b_doprepcr = true;
462 int i_real_page_packets = 0;
463 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
465 i_real_page_packets++;
466 int i_max_packets = __MAX(i_page_packets, i_real_page_packets);
467 if ( b_doprepcr && p_stream->prepcr.i_size < i_max_packets )
469 /* always double alloc for performance */
470 i_max_packets = __MAX( i_max_packets << 1, 255 );
471 /* alloc or realloc */
472 block_t **pp_realloc = realloc( p_stream->prepcr.pp_blocks,
473 sizeof(block_t *) * i_max_packets );
474 if ( !pp_realloc )
476 /* drop it then */
477 continue;
479 p_stream->prepcr.i_size = i_max_packets;
480 p_stream->prepcr.pp_blocks = pp_realloc;
483 /* Read info from any secondary header packets, if there are any */
484 if( p_stream->i_secondary_header_packets > 0 )
486 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
487 oggpacket.bytes >= 7 &&
488 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
490 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
491 p_stream->i_secondary_header_packets = 0;
493 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
494 oggpacket.bytes >= 6 &&
495 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
497 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
498 p_stream->i_secondary_header_packets = 0;
500 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
501 oggpacket.bytes >= 7 &&
502 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
504 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
505 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
506 p_stream->i_secondary_header_packets = 0;
508 else if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
510 p_stream->i_secondary_header_packets = 0;
513 /* update start of data pointer */
514 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
517 /* If any streams have i_skip_frames, only decode (pre-roll)
518 * for those streams, but don't skip headers */
519 if ( b_skipping && p_stream->i_skip_frames == 0
520 && p_stream->i_secondary_header_packets ) continue;
522 if( p_stream->b_reinit )
524 p_stream->b_reinit = false;
525 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
527 p_stream->i_skip_frames = p_stream->i_pre_skip;
531 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
534 if ( p_stream->prepcr.pp_blocks )
536 int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
537 p_stream->i_previous_pcr = pagestamp;
538 #ifdef HAVE_LIBVORBIS
539 int i_prev_blocksize = 0;
540 #endif
541 // PASS 1
542 for( int i=0; i<p_stream->prepcr.i_used; i++ )
544 block_t *p_block = p_stream->prepcr.pp_blocks[i];
545 ogg_packet dumb_packet;
546 dumb_packet.bytes = p_block->i_buffer;
547 dumb_packet.packet = p_block->p_buffer;
549 switch( p_stream->fmt.i_codec )
551 case VLC_CODEC_SPEEX:
552 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
553 p_stream->special.speex.i_framesperpacket;
554 break;
555 case VLC_CODEC_OPUS:
556 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
557 break;
558 #ifdef HAVE_LIBVORBIS
559 case VLC_CODEC_VORBIS:
561 if( !VORBIS_HEADERS_VALID(p_stream) )
563 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
564 break;
566 long i_blocksize = vorbis_packet_blocksize(
567 p_stream->special.vorbis.p_info, &dumb_packet );
568 if ( i_prev_blocksize )
569 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
570 else
571 p_block->i_nb_samples = i_blocksize / 2;
572 i_prev_blocksize = i_blocksize;
574 #endif
578 // PASS 2
579 bool b_fixed = false;
580 for( int i=p_stream->prepcr.i_used - 1; i>=0; i-- )
582 block_t *p_block = p_stream->prepcr.pp_blocks[i];
583 switch( p_stream->fmt.i_codec )
585 case VLC_CODEC_SPEEX:
586 case VLC_CODEC_OPUS:
587 case VLC_CODEC_VORBIS:
588 pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
589 if ( pagestamp < 0 )
591 p_block->i_pts = VLC_TS_INVALID;
592 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
593 p_block->i_flags |= BLOCK_FLAG_PREROLL;
595 else
596 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
597 b_fixed = true;
598 break;
599 default:
600 if ( p_stream->fmt.i_cat == VIDEO_ES )
602 pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
603 if( pagestamp < 0 )
604 pagestamp = 0;
605 p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
606 b_fixed = true;
611 if ( b_fixed )
613 pagestamp = p_stream->i_previous_pcr; /* as set above */
614 if ( pagestamp < 0 ) pagestamp = 0;
615 p_stream->i_pcr = VLC_TS_0 + pagestamp;
616 p_stream->i_pcr += p_sys->i_nzpcr_offset;
617 p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
620 FREENULL(p_stream->prepcr.pp_blocks);
621 p_stream->prepcr.i_used = 0;
623 Ogg_SendOrQueueBlocks( p_demux, p_stream, NULL );
627 int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
628 ogg_page_granulepos( &p_sys->current_page ), false );
629 if ( i_pagestamp > -1 )
631 p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
632 p_stream->i_pcr += p_sys->i_nzpcr_offset;
635 if( !p_sys->b_page_waiting )
636 break;
639 /* if a page was waiting, it's now processed */
640 p_sys->b_page_waiting = false;
642 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
643 p_sys->b_preparsing_done = false;
644 else
645 p_sys->b_preparsing_done = true;
647 /* We will consider the lowest PCR among tracks, because the audio core badly
648 * handles PCR rewind (mute)
650 mtime_t i_pcr_candidate = VLC_TS_INVALID;
651 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
653 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
655 if ( p_sys->b_preparsing_done && p_stream->b_initializing )
657 /* We have 1 or more streams needing more than 1 page for preparsing */
658 p_sys->b_preparsing_done = false;
661 if( p_stream->fmt.i_cat == SPU_ES )
662 continue;
663 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
664 continue;
665 if( p_stream->i_pcr < VLC_TS_0 )
666 continue;
667 if ( p_stream->b_finished || p_stream->b_initializing )
668 continue;
669 if ( p_stream->p_preparse_block )
670 continue;
671 if( i_pcr_candidate < VLC_TS_0
672 || p_stream->i_pcr <= i_pcr_candidate )
674 i_pcr_candidate = p_stream->i_pcr;
678 if ( i_pcr_candidate > VLC_TS_INVALID && p_sys->i_pcr != i_pcr_candidate )
680 if ( p_sys->i_streams == 1 && p_sys->i_access_delay )
682 int64_t i_pcr_jitter = i_pcr_candidate - p_sys->i_pcr;
683 if ( i_pcr_jitter > p_sys->i_pcr_jitter )
685 p_sys->i_pcr_jitter = i_pcr_jitter;
686 if ( p_sys->i_access_delay < i_pcr_jitter )
687 msg_Warn( p_demux, "Consider increasing access caching variable from %"PRId64" to >%"PRId64,
688 p_sys->i_access_delay / 1000, i_pcr_jitter / 1000 );
692 if( ! b_skipping && p_sys->b_preparsing_done )
694 p_sys->i_pcr = i_pcr_candidate;
695 if( likely( !p_sys->b_slave ) )
696 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
700 return VLC_DEMUXER_SUCCESS;
703 static void Ogg_ResetStream( logical_stream_t *p_stream )
705 #ifdef HAVE_LIBVORBIS
706 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
708 p_stream->special.vorbis.i_prev_blocksize = 0;
710 #endif
711 /* we'll trash all the data until we find the next pcr */
712 p_stream->b_reinit = true;
713 p_stream->i_pcr = VLC_TS_UNKNOWN;
714 p_stream->i_previous_granulepos = -1;
715 p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
716 ogg_stream_reset( &p_stream->os );
717 FREENULL( p_stream->prepcr.pp_blocks );
718 p_stream->prepcr.i_size = 0;
719 p_stream->prepcr.i_used = 0;
722 static void Ogg_ResetStreamsHelper( demux_sys_t *p_sys )
724 for( int i = 0; i < p_sys->i_streams; i++ )
725 Ogg_ResetStream( p_sys->pp_stream[i] );
727 ogg_sync_reset( &p_sys->oy );
728 p_sys->i_pcr = VLC_TS_UNKNOWN;
731 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
733 demux_sys_t *p_sys = p_demux->p_sys;
734 logical_stream_t *p_stream = NULL;
735 for( int i=0; i<p_sys->i_streams; i++ )
737 logical_stream_t *p_candidate = p_sys->pp_stream[i];
738 if ( !p_candidate->p_es ) continue;
740 bool b_selected = false;
741 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
742 p_candidate->p_es, &b_selected );
743 if ( !b_selected ) continue;
745 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
747 p_stream = p_candidate;
748 continue; /* Try to find video anyway */
751 if ( p_candidate->fmt.i_cat == VIDEO_ES )
753 p_stream = p_candidate;
754 break;
757 return p_stream;
760 /*****************************************************************************
761 * Control:
762 *****************************************************************************/
763 static int Control( demux_t *p_demux, int i_query, va_list args )
765 demux_sys_t *p_sys = p_demux->p_sys;
766 vlc_meta_t *p_meta;
767 int64_t *pi64, i64;
768 double *pf, f;
769 bool *pb_bool, b, acc;
771 switch( i_query )
773 case DEMUX_CAN_SEEK:
774 return vlc_stream_vaControl( p_demux->s, i_query, args );
776 case DEMUX_GET_META:
777 p_meta = va_arg( args, vlc_meta_t * );
778 if( p_sys->p_meta )
779 vlc_meta_Merge( p_meta, p_sys->p_meta );
780 return VLC_SUCCESS;
782 case DEMUX_HAS_UNSUPPORTED_META:
783 pb_bool = va_arg( args, bool* );
784 *pb_bool = true;
785 return VLC_SUCCESS;
787 case DEMUX_SET_NEXT_DEMUX_TIME:
788 p_sys->b_slave = true;
789 return VLC_EGENERIC;
791 case DEMUX_GET_TIME:
792 if( p_sys->i_pcr > VLC_TS_INVALID || p_sys->b_slave )
794 pi64 = va_arg( args, int64_t * );
795 *pi64 = p_sys->i_pcr;
796 return VLC_SUCCESS;
798 return VLC_EGENERIC;
800 case DEMUX_SET_TIME:
801 i64 = va_arg( args, int64_t );
802 acc = va_arg( args, int );
803 logical_stream_t *p_stream = Ogg_GetSelectedStream( p_demux );
804 if ( !p_stream )
806 msg_Err( p_demux, "No selected seekable stream found" );
807 return VLC_EGENERIC;
809 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
810 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
812 Ogg_ResetStreamsHelper( p_sys );
813 if( acc )
814 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
815 VLC_TS_0 + i64 );
816 return VLC_SUCCESS;
818 else
819 return VLC_EGENERIC;
821 case DEMUX_GET_ATTACHMENTS:
823 input_attachment_t ***ppp_attach =
824 va_arg( args, input_attachment_t *** );
825 int *pi_int = va_arg( args, int * );
827 if( p_sys->i_attachments <= 0 )
828 return VLC_EGENERIC;
830 *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
831 if (!**ppp_attach)
832 return VLC_ENOMEM;
833 *pi_int = p_sys->i_attachments;
834 for( int i = 0; i < p_sys->i_attachments; i++ )
835 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
836 return VLC_SUCCESS;
839 case DEMUX_GET_POSITION:
840 pf = va_arg( args, double * );
841 if( p_sys->i_length > 0 && p_sys->i_pcr > VLC_TS_INVALID )
843 *pf = (double) p_sys->i_pcr /
844 (double) ( p_sys->i_length * (mtime_t)1000000 );
846 else if( stream_Size( p_demux->s ) > 0 )
848 i64 = vlc_stream_Tell( p_demux->s );
849 *pf = (double) i64 / stream_Size( p_demux->s );
851 else *pf = 0.0;
852 return VLC_SUCCESS;
854 case DEMUX_SET_POSITION:
855 /* forbid seeking if we haven't initialized all logical bitstreams yet;
856 if we allowed, some headers would not get backed up and decoder init
857 would fail, making that logical stream unusable */
858 for ( int i=0; i< p_sys->i_streams; i++ )
860 if ( p_sys->pp_stream[i]->b_initializing )
861 return VLC_EGENERIC;
864 p_stream = Ogg_GetSelectedStream( p_demux );
865 if ( !p_stream )
867 msg_Err( p_demux, "No selected seekable stream found" );
868 return VLC_EGENERIC;
871 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
873 f = va_arg( args, double );
874 acc = va_arg( args, int );
875 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
877 Ogg_ResetStreamsHelper( p_sys );
878 Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
879 return VLC_SUCCESS;
882 assert( p_sys->i_length > 0 );
883 i64 = CLOCK_FREQ * p_sys->i_length * f;
884 Ogg_ResetStreamsHelper( p_sys );
885 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
887 if( acc )
888 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
889 VLC_TS_0 + i64 );
890 return VLC_SUCCESS;
893 return VLC_EGENERIC;
895 case DEMUX_GET_LENGTH:
896 if ( p_sys->i_length < 0 )
897 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
898 1, i_query, args );
899 pi64 = va_arg( args, int64_t * );
900 *pi64 = p_sys->i_length * 1000000;
901 return VLC_SUCCESS;
903 case DEMUX_GET_TITLE_INFO:
905 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
906 int *pi_int = va_arg( args, int* );
907 int *pi_title_offset = va_arg( args, int* );
908 int *pi_seekpoint_offset = va_arg( args, int* );
910 if( p_sys->i_seekpoints > 0 )
912 *pi_int = 1;
913 *ppp_title = malloc( sizeof( input_title_t* ) );
914 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
915 for( int i = 0; i < p_sys->i_seekpoints; i++ )
917 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
918 if ( likely( p_seekpoint_copy ) )
919 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
921 *pi_title_offset = 0;
922 *pi_seekpoint_offset = 0;
924 return VLC_SUCCESS;
926 case DEMUX_SET_TITLE:
928 const int i_title = va_arg( args, int );
929 if( i_title > 1 )
930 return VLC_EGENERIC;
931 return VLC_SUCCESS;
933 case DEMUX_SET_SEEKPOINT:
935 const int i_seekpoint = va_arg( args, int );
936 if( i_seekpoint > p_sys->i_seekpoints )
937 return VLC_EGENERIC;
939 for ( int i=0; i< p_sys->i_streams; i++ )
941 if ( p_sys->pp_stream[i]->b_initializing )
942 return VLC_EGENERIC;
945 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
947 p_stream = Ogg_GetSelectedStream( p_demux );
948 if ( !p_stream )
950 msg_Err( p_demux, "No selected seekable stream found" );
951 return VLC_EGENERIC;
954 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
955 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
957 Ogg_ResetStreamsHelper( p_sys );
958 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
959 VLC_TS_0 + i64 );
960 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
961 p_sys->cur_seekpoint = i_seekpoint;
962 return VLC_SUCCESS;
964 else
965 return VLC_EGENERIC;
967 case DEMUX_GET_TITLE:
968 *va_arg( args, int * ) = 0;
969 return VLC_SUCCESS;
970 case DEMUX_GET_SEEKPOINT:
971 *va_arg( args, int * ) = p_sys->cur_seekpoint;
972 return VLC_SUCCESS;
974 default:
975 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
976 1, i_query, args );
980 /****************************************************************************
981 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
982 ****************************************************************************
983 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
984 * are at the end of stream.
985 ****************************************************************************/
986 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
988 demux_sys_t *p_ogg = p_demux->p_sys ;
989 int i_read = 0;
990 char *p_buffer;
992 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
994 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
996 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
997 if( i_read <= 0 )
998 return VLC_EGENERIC;
1000 ogg_sync_wrote( &p_ogg->oy, i_read );
1003 return VLC_SUCCESS;
1006 /****************************************************************************
1007 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
1008 * current stream.
1009 ****************************************************************************/
1010 static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
1011 ogg_packet *p_oggpacket )
1013 demux_sys_t *p_ogg = p_demux->p_sys;
1014 p_stream->i_end_trim = 0;
1016 /* Convert the granulepos into a pcr */
1017 if ( p_oggpacket->granulepos == 0 )
1019 /* We're in headers, and we haven't parsed 1st data packet yet */
1020 // p_stream->i_pcr = VLC_TS_UNKNOWN;
1022 else if( p_oggpacket->granulepos > 0 )
1024 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
1025 p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
1026 p_stream->fmt.i_codec == VLC_CODEC_KATE ||
1027 p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
1028 p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
1029 p_stream->fmt.i_codec == VLC_CODEC_SPEEX ||
1030 p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
1031 (p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
1033 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1034 p_oggpacket->granulepos, true );
1035 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1037 else if ( p_stream->i_previous_granulepos > 0 )
1039 ogg_int64_t sample = p_stream->i_previous_granulepos;
1041 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
1043 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
1044 if( duration > 0 )
1046 ogg_int64_t end_sample = p_oggpacket->granulepos;
1047 if( end_sample < ( sample + duration ) )
1048 p_stream->i_end_trim = sample + duration - end_sample;
1052 if (sample >= p_stream->i_pre_skip)
1053 sample -= p_stream->i_pre_skip;
1054 else
1055 sample = 0;
1057 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1058 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1062 else if ( p_oggpacket->granulepos == -1 )
1064 unsigned i_duration;
1065 /* no granulepos available, try to interpolate the pcr.
1066 * If we can't then don't touch the old value. */
1067 if( p_stream->fmt.i_cat == VIDEO_ES && p_stream->i_pcr > VLC_TS_INVALID )
1069 p_stream->i_pcr += (CLOCK_FREQ / p_stream->f_rate);
1071 #ifdef HAVE_LIBVORBIS
1072 else if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
1073 p_stream->special.vorbis.p_info &&
1074 VORBIS_HEADERS_VALID(p_stream) &&
1075 p_stream->i_previous_granulepos > 0 )
1077 long i_blocksize = vorbis_packet_blocksize(
1078 p_stream->special.vorbis.p_info, p_oggpacket );
1079 if ( p_stream->special.vorbis.i_prev_blocksize )
1080 i_duration = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
1081 else
1082 i_duration = i_blocksize / 2;
1083 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
1084 /* duration in samples per channel */
1085 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1086 p_stream->i_pcr = p_stream->i_previous_granulepos *
1087 CLOCK_FREQ / p_stream->special.vorbis.p_info->rate;
1088 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1090 #endif
1091 else if ( p_stream->fmt.i_codec == VLC_CODEC_SPEEX &&
1092 p_stream->i_previous_granulepos > 0 )
1094 i_duration = p_stream->special.speex.i_framesize *
1095 p_stream->special.speex.i_framesperpacket;
1096 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1097 p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
1098 p_stream->i_previous_granulepos, false );
1099 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1101 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS &&
1102 p_stream->i_previous_granulepos > 0 &&
1103 ( i_duration =
1104 Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 )
1106 ogg_int64_t sample;
1107 p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
1108 sample = p_stream->i_previous_granulepos;
1109 if (sample >= p_stream->i_pre_skip)
1110 sample -= p_stream->i_pre_skip;
1111 else
1112 sample = 0;
1114 p_stream->i_pcr = VLC_TS_0 + sample * CLOCK_FREQ / p_stream->f_rate;
1115 p_stream->i_pcr += p_ogg->i_nzpcr_offset;
1117 else if( p_stream->fmt.i_bitrate && p_stream->i_pcr > VLC_TS_UNKNOWN )
1119 p_stream->i_pcr += ( CLOCK_FREQ * p_oggpacket->bytes /
1120 p_stream->fmt.i_bitrate / 8 );
1124 p_stream->i_previous_granulepos = p_oggpacket->granulepos;
1127 static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
1128 block_t *p_block )
1130 demux_sys_t *p_ogg = p_demux->p_sys;
1131 if ( (!p_stream->p_es || p_stream->prepcr.pp_blocks || p_stream->i_pcr == VLC_TS_UNKNOWN) &&
1132 p_ogg->i_nzpcr_offset == 0 /* Not on chained streams */ )
1134 if ( !p_block ) return;
1135 if ( p_stream->prepcr.pp_blocks )
1137 assert( p_stream->prepcr.i_size );
1138 p_stream->prepcr.pp_blocks[p_stream->prepcr.i_used++] = p_block;
1140 DemuxDebug( msg_Dbg( p_demux, "block prepcr append > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1141 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1142 block_ChainAppend( & p_stream->p_preparse_block, p_block );
1144 else
1146 /* Because ES creation is delayed for preparsing */
1147 mtime_t i_firstpts = VLC_TS_UNKNOWN;
1148 if ( p_stream->p_preparse_block )
1150 block_t *temp = p_stream->p_preparse_block;
1151 while ( temp )
1153 if ( temp && i_firstpts < VLC_TS_0 )
1154 i_firstpts = temp->i_pts;
1156 block_t *tosend = temp;
1157 temp = temp->p_next;
1158 tosend->p_next = NULL;
1160 if( tosend->i_pts < VLC_TS_0 )
1162 /* Don't send metadata from chained streams */
1163 block_Release( tosend );
1164 continue;
1166 else if( tosend->i_dts < VLC_TS_0 )
1168 tosend->i_dts = tosend->i_pts;
1171 DemuxDebug( msg_Dbg( p_demux, "block sent from preparse > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1172 tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
1173 es_out_Send( p_demux->out, p_stream->p_es, tosend );
1175 if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts > VLC_TS_INVALID )
1177 p_ogg->i_pcr = i_firstpts;
1178 if( likely( !p_ogg->b_slave ) )
1179 es_out_SetPCR( p_demux->out, p_ogg->i_pcr );
1182 p_stream->p_preparse_block = NULL;
1185 if ( p_block )
1187 DemuxDebug( msg_Dbg( p_demux, "block sent directly > pts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1188 p_block->i_pts, p_stream->i_pcr, p_ogg->i_pcr ) );
1189 if ( p_stream->p_es )
1190 es_out_Send( p_demux->out, p_stream->p_es, p_block );
1191 else
1192 block_Release( p_block );
1197 /****************************************************************************
1198 * Ogg_DecodePacket: Decode an Ogg packet.
1199 ****************************************************************************/
1200 static void Ogg_DecodePacket( demux_t *p_demux,
1201 logical_stream_t *p_stream,
1202 ogg_packet *p_oggpacket )
1204 demux_sys_t *p_sys = p_demux->p_sys;
1205 block_t *p_block;
1206 bool b_selected;
1207 int i_header_len = 0;
1209 if( p_oggpacket->bytes >= 7 &&
1210 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1212 /* it's an Annodex packet -- skip it (do nothing) */
1213 return;
1215 else if( p_oggpacket->bytes >= 7 &&
1216 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1218 /* it's an AnxData packet -- skip it (do nothing) */
1219 return;
1221 else if( p_oggpacket->bytes >= 8 &&
1222 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1224 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1225 return;
1227 else if( p_oggpacket->bytes >= 6 &&
1228 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1230 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1231 return;
1233 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1234 p_oggpacket->bytes >= 7 &&
1235 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1237 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1238 return;
1241 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1242 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1244 /* Check the ES is selected */
1245 if ( !p_stream->p_es )
1246 b_selected = true;
1247 else
1248 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1249 p_stream->p_es, &b_selected );
1251 if( p_stream->b_force_backup )
1253 bool b_xiph;
1254 p_stream->i_packets_backup++;
1255 switch( p_stream->fmt.i_codec )
1257 case VLC_CODEC_VORBIS:
1258 #ifdef HAVE_LIBVORBIS
1259 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1260 #endif
1261 /* fallthrough */
1262 case VLC_CODEC_THEORA:
1263 if( p_stream->i_packets_backup == 3 )
1264 p_stream->b_force_backup = false;
1265 b_xiph = true;
1266 break;
1268 case VLC_CODEC_DAALA:
1269 if( p_stream->i_packets_backup == 3 )
1270 p_stream->b_force_backup = false;
1271 b_xiph = true;
1272 break;
1274 case VLC_CODEC_SPEEX:
1275 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1276 p_stream->b_force_backup = false;
1277 b_xiph = true;
1278 break;
1280 case VLC_CODEC_OPUS:
1281 if( p_stream->i_packets_backup == 2 )
1282 p_stream->b_force_backup = false;
1283 b_xiph = true;
1284 break;
1286 case VLC_CODEC_FLAC:
1287 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1289 p_stream->b_force_backup = false;
1291 if( p_stream->special.flac.b_old )
1293 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1295 else if( p_stream->i_packets_backup == 1 )
1297 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1299 p_oggpacket->packet += 9;
1300 p_oggpacket->bytes -= 9;
1303 b_xiph = false;
1304 break;
1306 case VLC_CODEC_KATE:
1307 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1308 p_stream->b_force_backup = false;
1309 b_xiph = true;
1310 break;
1312 default:
1313 p_stream->b_force_backup = false;
1314 b_xiph = false;
1315 break;
1318 /* Backup the ogg packet (likely an header packet) */
1319 if( !b_xiph )
1321 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1322 if( p_realloc )
1324 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1325 p_stream->i_headers += p_oggpacket->bytes;
1326 p_stream->p_headers = p_realloc;
1328 else
1330 free( p_stream->p_headers );
1331 p_stream->i_headers = 0;
1332 p_stream->p_headers = NULL;
1335 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1336 p_oggpacket->bytes, p_oggpacket->packet ) )
1338 p_stream->i_headers = 0;
1339 p_stream->p_headers = NULL;
1341 if( p_stream->i_headers > 0 )
1343 if( !p_stream->b_force_backup )
1345 /* Last header received, commit changes */
1346 free( p_stream->fmt.p_extra );
1348 p_stream->fmt.i_extra = p_stream->i_headers;
1349 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1350 if( p_stream->fmt.p_extra )
1351 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1352 p_stream->i_headers );
1353 else
1354 p_stream->fmt.i_extra = 0;
1356 if( p_stream->i_headers > 0 )
1357 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1358 p_stream->p_headers, p_stream->i_headers );
1360 /* we're not at BOS anymore for this logical stream */
1361 p_stream->b_initializing = false;
1365 b_selected = false; /* Discard the header packet */
1367 else
1369 p_stream->b_initializing = false;
1372 /* Convert the granulepos into the next pcr */
1373 Ogg_UpdatePCR( p_demux, p_stream, p_oggpacket );
1375 if( !b_selected )
1377 /* This stream isn't currently selected so we don't need to decode it,
1378 * but we did need to store its pcr as it might be selected later on */
1379 return;
1382 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) ) return;
1383 p_block->i_pts = p_stream->i_pcr;
1385 DemuxDebug( msg_Dbg(p_demux, "block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1386 p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); )
1388 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1389 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1391 /* may need to preroll after a seek or in case of preskip */
1392 if ( p_stream->i_skip_frames > 0 )
1394 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
1396 if( p_stream->i_skip_frames >= p_block->i_nb_samples )
1398 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1399 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1400 p_stream->i_skip_frames -= p_block->i_nb_samples;
1401 p_block->i_nb_samples = 0;
1403 else
1405 p_block->i_nb_samples -= p_stream->i_skip_frames;
1406 p_stream->i_skip_frames = 0;
1409 else
1411 if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
1412 p_block->i_flags |= BLOCK_FLAG_PREROLL;
1413 p_stream->i_skip_frames--;
1417 /* Conditional block fixes */
1418 if ( p_stream->fmt.i_cat == VIDEO_ES &&
1419 Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1421 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1423 else if( p_stream->fmt.i_cat == AUDIO_ES )
1425 if ( p_stream->fmt.i_codec == VLC_CODEC_FLAC &&
1426 p_stream->p_es && 0 >= p_oggpacket->granulepos &&
1427 p_stream->fmt.b_packetized )
1429 /* Handle OggFlac spec violation (multiple frame/packet
1430 * by turning on packetizer */
1431 msg_Warn( p_demux, "Invalid FLAC in ogg detected. Restarting ES with packetizer." );
1432 p_stream->fmt.b_packetized = false;
1433 es_out_Del( p_demux->out, p_stream->p_es );
1434 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
1437 /* Blatant abuse of the i_length field. */
1438 p_block->i_length = p_stream->i_end_trim;
1440 else if( p_stream->fmt.i_cat == SPU_ES )
1442 p_block->i_length = 0;
1444 else if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1446 ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
1447 ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
1448 p_block->i_dts = ( nzdts > VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
1449 p_block->i_pts = ( nzpts > VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
1450 /* granulepos for dirac is possibly broken, this value should be ignored */
1451 if( 0 >= p_oggpacket->granulepos )
1453 p_block->i_pts = VLC_TS_INVALID;
1454 p_block->i_dts = p_stream->i_pcr;
1458 if( p_stream->fmt.i_codec != VLC_CODEC_VORBIS &&
1459 p_stream->fmt.i_codec != VLC_CODEC_SPEEX &&
1460 p_stream->fmt.i_codec != VLC_CODEC_OPUS &&
1461 p_stream->fmt.i_codec != VLC_CODEC_VP8 &&
1462 p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
1463 p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
1464 p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
1465 p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
1466 p_stream->fmt.i_codec != VLC_CODEC_CMML &&
1467 p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
1468 p_stream->fmt.i_codec != VLC_CODEC_KATE &&
1469 p_stream->fmt.i_codec != VLC_CODEC_OGGSPOTS )
1471 if( p_oggpacket->bytes <= 0 )
1473 msg_Dbg( p_demux, "discarding 0 sized packet" );
1474 block_Release( p_block );
1475 return;
1477 /* We remove the header from the packet */
1478 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1479 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1481 if( i_header_len >= p_oggpacket->bytes )
1483 msg_Dbg( p_demux, "discarding invalid packet" );
1484 block_Release( p_block );
1485 return;
1488 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1490 /* But with subtitles we need to retrieve the duration first */
1491 int i, lenbytes = 0;
1493 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1495 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1497 lenbytes = lenbytes << 8;
1498 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1501 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1502 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1503 p_oggpacket->packet[i_header_len + 1] != 0 &&
1504 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1505 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1507 p_block->i_length = (mtime_t)lenbytes * 1000;
1511 i_header_len++;
1512 if( p_block->i_buffer >= (unsigned int)i_header_len )
1513 p_block->i_buffer -= i_header_len;
1514 else
1515 p_block->i_buffer = 0;
1519 if( p_stream->fmt.i_codec == VLC_CODEC_TARKIN )
1521 /* FIXME: the biggest hack I've ever done */
1522 msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,
1523 p_block->i_pts, p_block->i_dts );
1524 msleep(10000);
1527 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1528 p_oggpacket->bytes - i_header_len );
1530 Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block );
1533 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1535 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1538 /****************************************************************************
1539 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1540 * stream and fill p_ogg.
1541 *****************************************************************************
1542 * The initial page of a logical stream is marked as a 'bos' page.
1543 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1544 * together and all of the initial pages must appear before any data pages.
1546 * On success this function returns VLC_SUCCESS.
1547 ****************************************************************************/
1548 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1550 demux_sys_t *p_ogg = p_demux->p_sys ;
1551 ogg_packet oggpacket;
1553 p_ogg->i_total_length = stream_Size ( p_demux->s );
1554 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1557 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1560 if( ogg_page_bos( &p_ogg->current_page ) )
1563 /* All is wonderful in our fine fine little world.
1564 * We found the beginning of our first logical stream. */
1565 while( ogg_page_bos( &p_ogg->current_page ) )
1567 logical_stream_t *p_stream = calloc( 1, sizeof(logical_stream_t) );
1568 if( unlikely( !p_stream ) )
1569 return VLC_ENOMEM;
1571 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1573 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
1574 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
1575 p_stream->b_initializing = true;
1577 /* Setup the logical stream */
1578 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1579 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1581 /* Extract the initial header from the first page and verify
1582 * the codec type of this Ogg bitstream */
1583 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1585 /* error. stream version mismatch perhaps */
1586 msg_Err( p_demux, "error reading first page of "
1587 "Ogg bitstream data" );
1588 return VLC_EGENERIC;
1591 /* FIXME: check return value */
1592 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1594 /* Check for Vorbis header */
1595 if( oggpacket.bytes >= 7 &&
1596 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1598 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1599 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1600 msg_Dbg( p_demux, "found vorbis header" );
1601 else
1603 msg_Dbg( p_demux, "found invalid vorbis header" );
1604 Ogg_LogicalStreamDelete( p_demux, p_stream );
1605 p_stream = NULL;
1606 p_ogg->i_streams--;
1609 /* Check for Speex header */
1610 else if( oggpacket.bytes >= 5 &&
1611 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1613 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1614 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1615 msg_Dbg( p_demux, "found speex header, channels: %i, "
1616 "rate: %i, bitrate: %i, frames: %i group %i",
1617 p_stream->fmt.audio.i_channels,
1618 (int)p_stream->f_rate, p_stream->fmt.i_bitrate,
1619 p_stream->special.speex.i_framesize,
1620 p_stream->special.speex.i_framesperpacket );
1621 else
1623 msg_Dbg( p_demux, "found invalid Speex header" );
1624 Ogg_LogicalStreamDelete( p_demux, p_stream );
1625 p_stream = NULL;
1626 p_ogg->i_streams--;
1629 /* Check for Opus header */
1630 else if( oggpacket.bytes >= 8 &&
1631 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1633 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1634 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1635 msg_Dbg( p_demux, "found opus header, channels: %i, "
1636 "pre-skip: %i",
1637 p_stream->fmt.audio.i_channels,
1638 (int)p_stream->i_pre_skip);
1639 p_stream->i_skip_frames = p_stream->i_pre_skip;
1641 /* Check for OLD Flac header */
1642 else if( oggpacket.bytes >= 4 &&
1643 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1645 msg_Dbg( p_demux, "found FLAC header" );
1647 /* Grrrr!!!! Did they really have to put all the
1648 * important info in the second header packet!!!
1649 * (STREAMINFO metadata is in the following packet) */
1650 p_stream->b_force_backup = true;
1651 p_stream->i_extra_headers_packets = 1;
1652 p_stream->special.flac.b_old = true;
1653 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1655 /* Check for Flac header (>= version 1.0.0) */
1656 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1657 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1658 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1660 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1661 oggpacket.packet[8];
1662 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1663 "(%i header packets)",
1664 oggpacket.packet[5], oggpacket.packet[6],
1665 i_packets );
1666 /* STREAMINFO is in current packet, and then
1667 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1668 p_stream->b_force_backup = true;
1669 p_stream->i_extra_headers_packets = i_packets;
1670 p_stream->special.flac.b_old = false;
1672 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1673 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1674 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1676 msg_Dbg( p_demux, "found invalid Flac header" );
1677 Ogg_LogicalStreamDelete( p_demux, p_stream );
1678 p_stream = NULL;
1679 p_ogg->i_streams--;
1682 /* Check for Theora header */
1683 else if( oggpacket.bytes >= 7 &&
1684 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1686 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1687 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1688 msg_Dbg( p_demux,
1689 "found theora header, bitrate: %i, rate: %f",
1690 p_stream->fmt.i_bitrate, p_stream->f_rate );
1691 else
1693 msg_Dbg( p_demux, "found invalid Theora header" );
1694 Ogg_LogicalStreamDelete( p_demux, p_stream );
1695 p_stream = NULL;
1696 p_ogg->i_streams--;
1699 /* Check for Daala header */
1700 else if( oggpacket.bytes >= 6 &&
1701 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1703 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1704 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1705 msg_Dbg( p_demux,
1706 "found daala header, bitrate: %i, rate: %f",
1707 p_stream->fmt.i_bitrate, p_stream->f_rate );
1708 else
1710 msg_Dbg( p_demux, "found invalid Daala header" );
1711 Ogg_LogicalStreamDelete( p_demux, p_stream );
1712 p_stream = NULL;
1713 p_ogg->i_streams--;
1716 /* Check for Dirac header */
1717 else if( ( oggpacket.bytes >= 5 &&
1718 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1719 ( oggpacket.bytes >= 9 &&
1720 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1722 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1723 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1724 msg_Dbg( p_demux, "found dirac header" );
1725 else
1727 msg_Warn( p_demux, "found dirac header isn't decodable" );
1728 Ogg_LogicalStreamDelete( p_demux, p_stream );
1729 p_stream = NULL;
1730 p_ogg->i_streams--;
1733 /* Check for Tarkin header */
1734 else if( oggpacket.bytes >= 7 &&
1735 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
1737 oggpack_buffer opb;
1739 msg_Dbg( p_demux, "found tarkin header" );
1740 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_TARKIN );
1742 /* Cheat and get additionnal info ;) */
1743 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
1744 oggpack_adv( &opb, 88 );
1745 oggpack_adv( &opb, 104 );
1746 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
1747 p_stream->f_rate = 2; /* FIXME */
1748 msg_Dbg( p_demux,
1749 "found tarkin header, bitrate: %i, rate: %f",
1750 p_stream->fmt.i_bitrate, p_stream->f_rate );
1752 /* Check for VP8 header */
1753 else if( oggpacket.bytes >= 26 &&
1754 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1756 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1757 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1758 msg_Dbg( p_demux, "found VP8 header "
1759 "fps: %f, width:%i; height:%i",
1760 p_stream->f_rate,
1761 p_stream->fmt.video.i_width,
1762 p_stream->fmt.video.i_height );
1763 else
1765 msg_Dbg( p_demux, "invalid VP8 header found");
1766 Ogg_LogicalStreamDelete( p_demux, p_stream );
1767 p_stream = NULL;
1768 p_ogg->i_streams--;
1771 /* Check for Annodex header */
1772 else if( oggpacket.bytes >= 7 &&
1773 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1775 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1776 /* kill annodex track */
1777 FREENULL( p_stream );
1778 p_ogg->i_streams--;
1780 /* Check for Annodex header */
1781 else if( oggpacket.bytes >= 7 &&
1782 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1784 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1786 /* Check for Kate header */
1787 else if( oggpacket.bytes >= 8 &&
1788 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1790 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1791 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1792 msg_Dbg( p_demux, "found kate header" );
1793 else
1795 msg_Dbg( p_demux, "invalid kate header found");
1796 Ogg_LogicalStreamDelete( p_demux, p_stream );
1797 p_stream = NULL;
1798 p_ogg->i_streams--;
1801 /* Check for OggDS */
1802 else if( oggpacket.bytes >= 142 &&
1803 !memcmp( &oggpacket.packet[1],
1804 "Direct Show Samples embedded in Ogg", 35 ))
1806 /* Old header type */
1807 p_stream->b_oggds = true;
1808 /* Check for video header (old format) */
1809 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1810 oggpacket.bytes >= 184 )
1812 es_format_Change( &p_stream->fmt, VIDEO_ES,
1813 VLC_FOURCC( oggpacket.packet[68],
1814 oggpacket.packet[69],
1815 oggpacket.packet[70],
1816 oggpacket.packet[71] ) );
1817 msg_Dbg( p_demux, "found video header of type: %.4s",
1818 (char *)&p_stream->fmt.i_codec );
1820 p_stream->fmt.video.i_frame_rate = 10000000;
1821 p_stream->fmt.video.i_frame_rate_base =
1822 GetQWLE((oggpacket.packet+164));
1823 p_stream->fmt.video.i_frame_rate_base =
1824 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
1825 p_stream->f_rate = 10000000.0 /
1826 p_stream->fmt.video.i_frame_rate_base;
1827 p_stream->fmt.video.i_bits_per_pixel =
1828 GetWLE((oggpacket.packet+182));
1829 if( !p_stream->fmt.video.i_bits_per_pixel )
1830 /* hack, FIXME */
1831 p_stream->fmt.video.i_bits_per_pixel = 24;
1832 p_stream->fmt.video.i_width =
1833 GetDWLE((oggpacket.packet+176));
1834 p_stream->fmt.video.i_height =
1835 GetDWLE((oggpacket.packet+180));
1836 p_stream->fmt.video.i_visible_width =
1837 p_stream->fmt.video.i_width;
1838 p_stream->fmt.video.i_visible_height =
1839 p_stream->fmt.video.i_height;
1841 msg_Dbg( p_demux,
1842 "fps: %f, width:%i; height:%i, bitcount:%i",
1843 p_stream->f_rate,
1844 p_stream->fmt.video.i_width,
1845 p_stream->fmt.video.i_height,
1846 p_stream->fmt.video.i_bits_per_pixel);
1849 /* Check for audio header (old format) */
1850 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1852 int i_extra_size;
1853 unsigned int i_format_tag;
1855 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1857 i_extra_size = GetWLE((oggpacket.packet+140));
1858 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1860 p_stream->fmt.i_extra = i_extra_size;
1861 p_stream->fmt.p_extra = malloc( i_extra_size );
1862 if( p_stream->fmt.p_extra )
1863 memcpy( p_stream->fmt.p_extra,
1864 oggpacket.packet + 142, i_extra_size );
1865 else
1866 p_stream->fmt.i_extra = 0;
1869 i_format_tag = GetWLE((oggpacket.packet+124));
1870 p_stream->fmt.audio.i_channels =
1871 GetWLE((oggpacket.packet+126));
1872 fill_channels_info(&p_stream->fmt.audio);
1873 p_stream->f_rate = p_stream->fmt.audio.i_rate =
1874 GetDWLE((oggpacket.packet+128));
1875 p_stream->fmt.i_bitrate =
1876 GetDWLE((oggpacket.packet+132)) * 8;
1877 p_stream->fmt.audio.i_blockalign =
1878 GetWLE((oggpacket.packet+136));
1879 p_stream->fmt.audio.i_bitspersample =
1880 GetWLE((oggpacket.packet+138));
1882 wf_tag_to_fourcc( i_format_tag,
1883 &p_stream->fmt.i_codec, 0 );
1885 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1887 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1888 ( i_format_tag >> 8 ) & 0xff,
1889 i_format_tag & 0xff );
1892 msg_Dbg( p_demux, "found audio header of type: %.4s",
1893 (char *)&p_stream->fmt.i_codec );
1894 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1895 "%dbits/sample %dkb/s",
1896 i_format_tag,
1897 p_stream->fmt.audio.i_channels,
1898 p_stream->fmt.audio.i_rate,
1899 p_stream->fmt.audio.i_bitspersample,
1900 p_stream->fmt.i_bitrate / 1024 );
1901 if ( p_stream->f_rate == 0 )
1903 msg_Dbg( p_demux, "invalid oggds audio header" );
1904 Ogg_LogicalStreamDelete( p_demux, p_stream );
1905 p_stream = NULL;
1906 p_ogg->i_streams--;
1909 else
1911 msg_Dbg( p_demux, "stream %d has an old header "
1912 "but is of an unknown type", p_ogg->i_streams-1 );
1913 FREENULL( p_stream );
1914 p_ogg->i_streams--;
1917 /* Check for OggDS */
1918 else if( oggpacket.bytes >= 44+1 &&
1919 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1921 stream_header_t tmp;
1922 stream_header_t *st = &tmp;
1924 p_stream->b_oggds = true;
1926 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1927 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1928 st->size = GetDWLE( &oggpacket.packet[1+12] );
1929 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1930 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1931 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1932 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1933 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1935 /* Check for video header (new format) */
1936 if( !strncmp( st->streamtype, "video", 5 ) &&
1937 oggpacket.bytes >= 52+1 )
1939 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1940 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1942 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1944 /* We need to get rid of the header packet */
1945 ogg_stream_packetout( &p_stream->os, &oggpacket );
1947 p_stream->fmt.i_codec =
1948 VLC_FOURCC( st->subtype[0], st->subtype[1],
1949 st->subtype[2], st->subtype[3] );
1950 msg_Dbg( p_demux, "found video header of type: %.4s",
1951 (char *)&p_stream->fmt.i_codec );
1953 p_stream->fmt.video.i_frame_rate = 10000000;
1954 p_stream->fmt.video.i_frame_rate_base = st->time_unit;
1955 if( st->time_unit <= 0 )
1956 st->time_unit = 400000;
1957 p_stream->f_rate = 10000000.0 / st->time_unit;
1958 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1959 p_stream->fmt.video.i_width = st->sh.video.width;
1960 p_stream->fmt.video.i_height = st->sh.video.height;
1961 p_stream->fmt.video.i_visible_width =
1962 p_stream->fmt.video.i_width;
1963 p_stream->fmt.video.i_visible_height =
1964 p_stream->fmt.video.i_height;
1966 msg_Dbg( p_demux,
1967 "fps: %f, width:%i; height:%i, bitcount:%i",
1968 p_stream->f_rate,
1969 p_stream->fmt.video.i_width,
1970 p_stream->fmt.video.i_height,
1971 p_stream->fmt.video.i_bits_per_pixel );
1973 /* Check for audio header (new format) */
1974 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1975 oggpacket.bytes >= 56+1 )
1977 char p_buffer[5];
1978 int i_extra_size;
1979 int i_format_tag;
1981 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1982 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1983 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1985 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1987 /* We need to get rid of the header packet */
1988 ogg_stream_packetout( &p_stream->os, &oggpacket );
1990 i_extra_size = st->size - 56;
1992 if( i_extra_size > 0 &&
1993 i_extra_size < oggpacket.bytes - 1 - 56 )
1995 p_stream->fmt.i_extra = i_extra_size;
1996 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1997 if( p_stream->fmt.p_extra )
1998 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1999 p_stream->fmt.i_extra );
2000 else
2001 p_stream->fmt.i_extra = 0;
2004 memcpy( p_buffer, st->subtype, 4 );
2005 p_buffer[4] = '\0';
2006 i_format_tag = strtol(p_buffer,NULL,16);
2007 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
2008 fill_channels_info(&p_stream->fmt.audio);
2009 if( st->time_unit <= 0 )
2010 st->time_unit = 10000000;
2011 p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
2012 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
2013 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
2014 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
2016 wf_tag_to_fourcc( i_format_tag,
2017 &p_stream->fmt.i_codec, 0 );
2019 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
2021 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
2022 ( i_format_tag >> 8 ) & 0xff,
2023 i_format_tag & 0xff );
2026 msg_Dbg( p_demux, "found audio header of type: %.4s",
2027 (char *)&p_stream->fmt.i_codec );
2028 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
2029 "%dbits/sample %dkb/s",
2030 i_format_tag,
2031 p_stream->fmt.audio.i_channels,
2032 p_stream->fmt.audio.i_rate,
2033 p_stream->fmt.audio.i_bitspersample,
2034 p_stream->fmt.i_bitrate / 1024 );
2035 if ( p_stream->f_rate == 0 )
2037 msg_Dbg( p_demux, "invalid oggds audio header" );
2038 Ogg_LogicalStreamDelete( p_demux, p_stream );
2039 p_stream = NULL;
2040 p_ogg->i_streams--;
2043 /* Check for text (subtitles) header */
2044 else if( !strncmp(st->streamtype, "text", 4) )
2046 /* We need to get rid of the header packet */
2047 ogg_stream_packetout( &p_stream->os, &oggpacket );
2049 msg_Dbg( p_demux, "found text subtitle header" );
2050 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2051 p_stream->f_rate = 1000; /* granulepos is in millisec */
2053 else
2055 msg_Dbg( p_demux, "stream %d has a header marker "
2056 "but is of an unknown type", p_ogg->i_streams-1 );
2057 FREENULL( p_stream );
2058 p_ogg->i_streams--;
2061 else if( oggpacket.bytes >= 8 &&
2062 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2065 /* Skeleton */
2066 msg_Dbg( p_demux, "stream %d is a skeleton",
2067 p_ogg->i_streams-1 );
2068 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2070 /* Check for OggSpots header */
2071 else if( oggpacket.bytes >= 8 &&
2072 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2074 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2075 msg_Dbg( p_demux,
2076 "found OggSpots header, time resolution: %f",
2077 p_stream->f_rate );
2078 else
2080 msg_Err( p_demux, "found invalid OggSpots header" );
2081 Ogg_LogicalStreamDelete( p_demux, p_stream );
2082 p_stream = NULL;
2083 p_ogg->i_streams--;
2086 else
2088 msg_Dbg( p_demux, "stream %d is of unknown type",
2089 p_ogg->i_streams-1 );
2092 /* we'll need to get all headers */
2093 if ( p_stream )
2094 p_stream->b_initializing &= p_stream->b_force_backup;
2096 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2097 return VLC_EGENERIC;
2100 /* This is the first data page, which means we are now finished
2101 * with the initial pages. We just need to store it in the relevant
2102 * bitstream. */
2103 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2105 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2106 &p_ogg->current_page ) == 0 )
2108 p_ogg->b_page_waiting = true;
2109 break;
2113 return VLC_SUCCESS;
2117 return VLC_EGENERIC;
2120 /****************************************************************************
2121 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2122 ****************************************************************************/
2123 static void Ogg_CreateES( demux_t *p_demux )
2125 demux_sys_t *p_ogg = p_demux->p_sys;
2126 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2127 int i_stream;
2129 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2131 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2133 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2135 /* Better be safe than sorry when possible with ogm */
2136 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2137 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2138 p_stream->fmt.b_packetized = false;
2140 /* Try first to reuse an old ES */
2141 if( p_old_stream &&
2142 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2143 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )
2145 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2147 p_stream->p_es = p_old_stream->p_es;
2148 p_stream->b_finished = false;
2149 p_stream->b_reinit = false;
2150 p_stream->b_initializing = false;
2151 p_stream->i_pre_skip = 0;
2152 es_format_Clean( &p_stream->fmt_old );
2153 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2154 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2156 p_old_stream->p_es = NULL;
2157 p_old_stream = NULL;
2158 if ( b_resetdecoder )
2160 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2161 p_stream->p_es, &p_stream->fmt );
2164 else
2166 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2169 // TODO: something to do here ?
2170 if( p_stream->fmt.i_codec == VLC_CODEC_CMML )
2172 /* Set the CMML stream active */
2173 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
2178 if( p_ogg->p_old_stream )
2180 if( p_ogg->p_old_stream->p_es )
2181 msg_Dbg( p_demux, "old stream not reused" );
2182 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2183 p_ogg->p_old_stream = NULL;
2185 p_ogg->b_es_created = true;
2188 /****************************************************************************
2189 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2190 * Elementary streams.
2191 ****************************************************************************/
2192 static int Ogg_BeginningOfStream( demux_t *p_demux )
2194 demux_sys_t *p_ogg = p_demux->p_sys ;
2195 int i_stream;
2197 /* Find the logical streams embedded in the physical stream and
2198 * initialize our p_ogg structure. */
2199 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2201 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2202 return VLC_EGENERIC;
2205 p_ogg->i_bitrate = 0;
2207 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2209 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2211 p_stream->p_es = NULL;
2213 /* initialise kframe index */
2214 p_stream->idx=NULL;
2216 if ( p_stream->fmt.i_bitrate == 0 &&
2217 ( p_stream->fmt.i_cat == VIDEO_ES ||
2218 p_stream->fmt.i_cat == AUDIO_ES ) )
2219 p_ogg->b_partial_bitrate = true;
2220 else
2221 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2223 p_stream->i_pcr = p_stream->i_previous_pcr = VLC_TS_UNKNOWN;
2224 p_stream->i_previous_granulepos = -1;
2225 p_stream->b_reinit = false;
2228 /* get total frame count for video stream; we will need this for seeking */
2229 p_ogg->i_total_frames = 0;
2231 return VLC_SUCCESS;
2234 /****************************************************************************
2235 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2236 ****************************************************************************/
2237 static void Ogg_EndOfStream( demux_t *p_demux )
2239 demux_sys_t *p_ogg = p_demux->p_sys ;
2240 int i_stream;
2242 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2243 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2244 free( p_ogg->pp_stream );
2246 /* Reinit p_ogg */
2247 p_ogg->i_bitrate = 0;
2248 p_ogg->i_streams = 0;
2249 p_ogg->pp_stream = NULL;
2250 p_ogg->skeleton.major = 0;
2251 p_ogg->skeleton.minor = 0;
2252 p_ogg->b_preparsing_done = false;
2253 p_ogg->b_es_created = false;
2255 /* */
2256 if( p_ogg->p_meta )
2257 vlc_meta_Delete( p_ogg->p_meta );
2258 p_ogg->p_meta = NULL;
2260 for(int i=0; i<p_ogg->i_attachments; i++)
2261 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2262 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2264 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2266 if ( p_ogg->pp_seekpoints[i] )
2267 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2269 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2272 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2274 #ifdef HAVE_LIBVORBIS
2275 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2277 if( p_stream->special.vorbis.p_info )
2278 vorbis_info_clear( p_stream->special.vorbis.p_info );
2279 FREENULL( p_stream->special.vorbis.p_info );
2280 if( p_stream->special.vorbis.p_comment )
2281 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2282 FREENULL( p_stream->special.vorbis.p_comment );
2283 p_stream->special.vorbis.i_headers_flags = 0;
2285 #else
2286 VLC_UNUSED( p_stream );
2287 #endif
2291 * This function delete and release all data associated to a logical_stream_t
2293 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2295 demux_sys_t *p_sys = p_demux->p_sys;
2297 if( p_stream->p_es )
2298 es_out_Del( p_demux->out, p_stream->p_es );
2300 ogg_stream_clear( &p_stream->os );
2301 free( p_stream->p_headers );
2303 Ogg_CleanSpecificData( p_stream );
2305 es_format_Clean( &p_stream->fmt_old );
2306 es_format_Clean( &p_stream->fmt );
2308 if ( p_stream->idx != NULL)
2310 oggseek_index_entries_free( p_stream->idx );
2313 Ogg_FreeSkeleton( p_stream->p_skel );
2314 p_stream->p_skel = NULL;
2315 if( p_sys->p_skelstream == p_stream )
2316 p_sys->p_skelstream = NULL;
2318 /* Shouldn't happen */
2319 if ( unlikely( p_stream->p_preparse_block ) )
2321 block_ChainRelease( p_stream->p_preparse_block );
2322 p_stream->p_preparse_block = NULL;
2324 free( p_stream->prepcr.pp_blocks );
2326 free( p_stream );
2329 * This function check if a we need to reset a decoder in case we are
2330 * reusing an old ES
2332 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2334 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2335 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2336 unsigned i_new_count;
2337 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2338 i_new_count = 0;
2340 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2341 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2342 unsigned i_old_count;
2343 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2344 i_old_count = 0;
2346 bool b_match = i_new_count == i_old_count;
2347 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2349 /* Ignore vorbis comment */
2350 if( i == 1 )
2351 continue;
2352 if( pi_new_size[i] != pi_old_size[i] ||
2353 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2354 b_match = false;
2357 return b_match;
2360 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2361 const es_format_t *p_old )
2363 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2364 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2365 unsigned i_new_count;
2366 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2367 i_new_count = 0;
2368 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2369 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2370 unsigned i_old_count;
2371 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2372 i_old_count = 0;
2373 bool b_match = false;
2374 if( i_new_count == i_old_count && i_new_count > 0 )
2376 static const unsigned char default_map[2] = { 0, 1 };
2377 unsigned char *p_old_head;
2378 unsigned char *p_new_head;
2379 const unsigned char *p_old_map;
2380 const unsigned char *p_new_map;
2381 int i_old_channel_count;
2382 int i_new_channel_count;
2383 int i_old_stream_count;
2384 int i_new_stream_count;
2385 int i_old_coupled_count;
2386 int i_new_coupled_count;
2387 p_old_head = (unsigned char *)pp_old_data[0];
2388 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2389 p_old_map = default_map;
2390 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2392 i_old_channel_count = p_old_head[9];
2393 switch( p_old_head[18] )
2395 case 0:
2396 i_old_stream_count = 1;
2397 i_old_coupled_count = i_old_channel_count - 1;
2398 break;
2399 case 1:
2400 if( pi_old_size[0] >= 21U + i_old_channel_count )
2402 i_old_stream_count = p_old_head[19];
2403 i_old_coupled_count = p_old_head[20];
2404 p_old_map = p_old_head + 21;
2406 break;
2409 p_new_head = (unsigned char *)pp_new_data[0];
2410 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2411 p_new_map = default_map;
2412 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2414 i_new_channel_count = p_new_head[9];
2415 switch( p_new_head[18] )
2417 case 0:
2418 i_new_stream_count = 1;
2419 i_new_coupled_count = i_new_channel_count - 1;
2420 break;
2421 case 1:
2422 if( pi_new_size[0] >= 21U + i_new_channel_count )
2424 i_new_stream_count = p_new_head[19];
2425 i_new_coupled_count = p_new_head[20];
2426 p_new_map = p_new_head+21;
2428 break;
2431 b_match = i_old_channel_count == i_new_channel_count &&
2432 i_old_stream_count == i_new_stream_count &&
2433 i_old_coupled_count == i_new_coupled_count &&
2434 memcmp(p_old_map, p_new_map,
2435 i_new_channel_count*sizeof(*p_new_map)) == 0;
2438 return b_match;
2441 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2443 bool b_compatible = false;
2444 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2445 return true;
2447 /* Only Vorbis and Opus are supported. */
2448 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2449 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2450 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2451 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2453 if( !b_compatible )
2454 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2456 return !b_compatible;
2459 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2460 const void *p_headers, unsigned i_headers )
2462 demux_sys_t *p_ogg = p_demux->p_sys;
2463 int i_cover_score = 0;
2464 int i_cover_idx = 0;
2465 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2466 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2467 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2469 pf_replay_gain[i] = 0;
2470 pf_replay_peak[i] = 0;
2472 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2473 &p_ogg->i_attachments, &p_ogg->attachments,
2474 &i_cover_score, &i_cover_idx,
2475 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2476 &pf_replay_gain, &pf_replay_peak );
2477 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2479 char psz_url[128];
2480 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2481 p_ogg->attachments[i_cover_idx]->psz_name );
2482 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2485 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2487 if ( pf_replay_gain[i] != 0 )
2489 p_fmt->audio_replay_gain.pb_gain[i] = true;
2490 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2491 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2493 if ( pf_replay_peak[i] != 0 )
2495 p_fmt->audio_replay_gain.pb_peak[i] = true;
2496 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2497 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2501 if( p_ogg->i_seekpoints > 1 )
2503 p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2507 static inline uint32_t GetDW24BE( const uint8_t *p )
2509 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2510 #ifdef WORDS_BIGENDIAN
2511 i = bswap32(i);
2512 #endif
2513 return i;
2516 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2517 const uint8_t *p_headers, unsigned i_headers )
2519 /* Skip Streaminfo 42 bytes / 1st page */
2520 if(i_headers <= 46)
2521 return;
2522 p_headers += 42; i_headers -= 42;
2523 /* Block Header 1 + 3 bytes */
2524 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2525 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2527 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2531 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2532 const void *p_headers, unsigned i_headers, unsigned i_skip )
2534 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2535 void *pp_data[XIPH_MAX_HEADER_COUNT];
2536 unsigned i_count;
2538 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2539 return;
2540 /* TODO how to handle multiple comments properly ? */
2541 if( i_count >= 2 && pi_size[1] > i_skip )
2543 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2547 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2549 demux_sys_t *p_ogg = p_demux->p_sys;
2551 switch( p_fmt->i_codec )
2553 /* 3 headers with the 2° one being the comments */
2554 case VLC_CODEC_VORBIS:
2555 case VLC_CODEC_THEORA:
2556 case VLC_CODEC_DAALA:
2557 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2558 break;
2559 case VLC_CODEC_OPUS:
2560 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2561 break;
2562 case VLC_CODEC_SPEEX:
2563 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2564 break;
2565 case VLC_CODEC_VP8:
2566 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2567 break;
2568 /* N headers with the 2° one being the comments */
2569 case VLC_CODEC_KATE:
2570 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2571 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2572 break;
2574 /* TODO */
2575 case VLC_CODEC_FLAC:
2576 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2577 break;
2579 /* No meta data */
2580 case VLC_CODEC_CMML: /* CMML is XML text, doesn't have Vorbis comments */
2581 case VLC_CODEC_DIRAC:
2582 default:
2583 break;
2585 if( p_ogg->p_meta )
2586 p_demux->info.i_update |= INPUT_UPDATE_META;
2589 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2590 ogg_packet *p_oggpacket )
2592 bs_t bitstream;
2593 unsigned int i_fps_numerator;
2594 unsigned int i_fps_denominator;
2595 int i_keyframe_frequency_force;
2596 int i_major;
2597 int i_minor;
2598 int i_subminor;
2599 int i_version;
2601 /* Signal that we want to keep a backup of the theora
2602 * stream headers. They will be used when switching between
2603 * audio streams. */
2604 p_stream->b_force_backup = true;
2606 /* Cheat and get additionnal info ;) */
2607 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2608 bs_skip( &bitstream, 56 );
2610 i_major = bs_read( &bitstream, 8 ); /* major version num */
2611 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2612 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2614 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2615 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2616 bs_read( &bitstream, 24 ); /* frame width */
2617 bs_read( &bitstream, 24 ); /* frame height */
2618 bs_read( &bitstream, 8 ); /* x offset */
2619 bs_read( &bitstream, 8 ); /* y offset */
2621 i_fps_numerator = bs_read( &bitstream, 32 );
2622 i_fps_denominator = bs_read( &bitstream, 32 );
2623 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2624 bs_read( &bitstream, 24 ); /* aspect_numerator */
2625 bs_read( &bitstream, 24 ); /* aspect_denominator */
2627 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2628 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2630 bs_read( &bitstream, 8 ); /* colorspace */
2631 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2632 bs_read( &bitstream, 6 ); /* quality */
2634 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2636 /* granule_shift = i_log( frequency_force -1 ) */
2637 p_stream->i_granule_shift = 0;
2638 i_keyframe_frequency_force--;
2639 while( i_keyframe_frequency_force )
2641 p_stream->i_granule_shift++;
2642 i_keyframe_frequency_force >>= 1;
2645 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2646 p_stream->i_keyframe_offset = 0;
2647 p_stream->f_rate = ((double)i_fps_numerator) / i_fps_denominator;
2648 if ( p_stream->f_rate == 0 ) return false;
2650 if ( i_version >= 3002001 )
2652 p_stream->i_keyframe_offset = 1;
2654 return true;
2657 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2658 ogg_packet *p_oggpacket )
2660 oggpack_buffer opb;
2661 uint32_t i_timebase_numerator;
2662 uint32_t i_timebase_denominator;
2663 int i_keyframe_frequency_force;
2664 uint8_t i_major;
2665 uint8_t i_minor;
2666 uint8_t i_subminor;
2667 int i_version;
2669 /* Signal that we want to keep a backup of the daala
2670 * stream headers. They will be used when switching between
2671 * audio streams. */
2672 p_stream->b_force_backup = true;
2674 /* Cheat and get additionnal info ;) */
2675 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2676 oggpack_adv( &opb, 48 );
2678 i_major = oggpack_read( &opb, 8 ); /* major version num */
2679 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2680 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2682 oggpack_adv( &opb, 32 ); /* width */
2683 oggpack_adv( &opb, 32 ); /* height */
2685 oggpack_adv( &opb, 32 ); /* aspect numerator */
2686 oggpack_adv( &opb, 32 ); /* aspect denominator */
2687 i_timebase_numerator = oggpack_read( &opb, 32 );
2689 i_timebase_denominator = oggpack_read( &opb, 32 );
2690 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2692 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2693 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2695 oggpack_adv( &opb, 32 ); /* frame duration */
2697 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2699 /* granule_shift = i_log( frequency_force -1 ) */
2700 p_stream->i_granule_shift = 0;
2701 i_keyframe_frequency_force--;
2702 while( i_keyframe_frequency_force )
2704 p_stream->i_granule_shift++;
2705 i_keyframe_frequency_force >>= 1;
2708 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2709 VLC_UNUSED(i_version);
2710 p_stream->i_keyframe_offset = 0;
2711 p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
2712 if ( p_stream->f_rate == 0 ) return false;
2714 return true;
2717 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2718 ogg_packet *p_oggpacket )
2720 oggpack_buffer opb;
2722 /* Signal that we want to keep a backup of the vorbis
2723 * stream headers. They will be used when switching between
2724 * audio streams. */
2725 p_stream->b_force_backup = true;
2727 /* Cheat and get additionnal info ;) */
2728 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2729 oggpack_adv( &opb, 88 );
2730 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2731 fill_channels_info(&p_stream->fmt.audio);
2732 p_stream->f_rate = p_stream->fmt.audio.i_rate =
2733 oggpack_read( &opb, 32 );
2734 oggpack_adv( &opb, 32 );
2735 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2736 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2737 if ( p_stream->f_rate == 0 ) return false;
2738 return true;
2740 #ifdef HAVE_LIBVORBIS
2741 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2742 ogg_packet *p_oggpacket, int i_number )
2744 switch( i_number )
2746 case VORBIS_HEADER_IDENTIFICATION:
2747 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2748 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2749 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2751 FREENULL( p_stream->special.vorbis.p_info );
2752 FREENULL( p_stream->special.vorbis.p_comment );
2753 break;
2755 vorbis_info_init( p_stream->special.vorbis.p_info );
2756 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2757 /* fallthrough */
2759 case VORBIS_HEADER_COMMENT:
2760 case VORBIS_HEADER_SETUP:
2761 if ( !p_stream->special.vorbis.p_info ||
2762 vorbis_synthesis_headerin(
2763 p_stream->special.vorbis.p_info,
2764 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2765 break;
2767 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2768 /* fallthrough */
2770 default:
2771 break;
2774 #endif
2776 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2777 ogg_packet *p_oggpacket )
2779 oggpack_buffer opb;
2781 /* Signal that we want to keep a backup of the speex
2782 * stream headers. They will be used when switching between
2783 * audio streams. */
2784 p_stream->b_force_backup = true;
2786 /* Cheat and get additionnal info ;) */
2787 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2788 oggpack_adv( &opb, 224 );
2789 oggpack_adv( &opb, 32 ); /* speex_version_id */
2790 oggpack_adv( &opb, 32 ); /* header_size */
2791 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2792 if ( p_stream->f_rate == 0 ) return false;
2793 oggpack_adv( &opb, 32 ); /* mode */
2794 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2795 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2796 fill_channels_info(&p_stream->fmt.audio);
2797 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2798 p_stream->special.speex.i_framesize =
2799 oggpack_read( &opb, 32 ); /* frame_size */
2800 oggpack_adv( &opb, 32 ); /* vbr */
2801 p_stream->special.speex.i_framesperpacket =
2802 oggpack_read( &opb, 32 ); /* frames_per_packet */
2803 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2804 return true;
2807 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2808 ogg_packet *p_oggpacket )
2810 oggpack_buffer opb;
2812 /* Signal that we want to keep a backup of the opus
2813 * stream headers. They will be used when switching between
2814 * audio streams. */
2815 p_stream->b_force_backup = true;
2817 /* All OggOpus streams are timestamped at 48kHz and
2818 * can be played at 48kHz. */
2819 p_stream->f_rate = p_stream->fmt.audio.i_rate = 48000;
2820 p_stream->fmt.i_bitrate = 0;
2822 /* Cheat and get additional info ;) */
2823 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2824 oggpack_adv( &opb, 64 );
2825 oggpack_adv( &opb, 8 ); /* version_id */
2826 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2827 fill_channels_info(&p_stream->fmt.audio);
2828 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2829 /* For Opus, trash the first 80 ms of decoded output as
2830 well, to avoid blowing out speakers if we get unlucky.
2831 Opus predicts content from prior frames, which can go
2832 badly if we seek right where the stream goes from very
2833 quiet to very loud. It will converge after a bit. */
2834 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2837 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2838 ogg_packet *p_oggpacket )
2840 /* Parse the STREAMINFO metadata */
2841 bs_t s;
2843 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2845 bs_read( &s, 1 );
2846 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2848 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2849 return false;
2852 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2854 bs_skip( &s, 80 );
2855 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2856 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2857 fill_channels_info(&p_stream->fmt.audio);
2859 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
2860 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
2861 if ( p_stream->f_rate == 0 ) return false;
2863 else
2865 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2868 /* Fake this as the last metadata block */
2869 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2870 return true;
2873 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2874 ogg_packet *p_oggpacket )
2876 oggpack_buffer opb;
2877 uint32_t gnum;
2878 uint32_t gden;
2879 int n;
2880 char *psz_desc;
2882 /* Signal that we want to keep a backup of the kate
2883 * stream headers. They will be used when switching between
2884 * kate streams. */
2885 p_stream->b_force_backup = true;
2887 /* Cheat and get additionnal info ;) */
2888 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2889 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2890 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2891 oggpack_adv( &opb, 3*8 );
2892 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2893 oggpack_adv( &opb, 8*8 ); /* reserved */
2894 gnum = oggpack_read( &opb, 32 );
2895 gden = oggpack_read( &opb, 32 );
2896 gden = __MAX( gden, 1 );
2897 p_stream->f_rate = (double)gnum/gden;
2898 if ( p_stream->f_rate == 0 ) return false;
2900 p_stream->fmt.psz_language = malloc(16);
2901 if( p_stream->fmt.psz_language )
2903 for( n = 0; n < 16; n++ )
2904 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2905 p_stream->fmt.psz_language[15] = 0; /* just in case */
2907 else
2909 for( n = 0; n < 16; n++ )
2910 oggpack_read(&opb,8);
2912 p_stream->fmt.psz_description = malloc(16);
2913 if( p_stream->fmt.psz_description )
2915 for( n = 0; n < 16; n++ )
2916 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2917 p_stream->fmt.psz_description[15] = 0; /* just in case */
2919 /* Now find a localized user readable description for this category */
2920 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2921 if( psz_desc )
2923 free( p_stream->fmt.psz_description );
2924 p_stream->fmt.psz_description = psz_desc;
2927 else
2929 for( n = 0; n < 16; n++ )
2930 oggpack_read(&opb,8);
2933 return true;
2936 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2937 ogg_packet *p_oggpacket )
2939 switch( p_oggpacket->packet[5] )
2941 /* STREAMINFO */
2942 case 0x01:
2943 /* Mapping version */
2944 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2945 return false;
2946 p_stream->i_granule_shift = 32;
2947 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2948 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2949 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2950 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2951 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2952 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2953 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2954 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2955 p_stream->fmt.video.i_frame_rate_base =
2956 __MAX( p_stream->fmt.video.i_frame_rate_base, 1 );
2957 p_stream->f_rate = (double) p_stream->fmt.video.i_frame_rate / p_stream->fmt.video.i_frame_rate_base;
2958 if ( p_stream->f_rate == 0 ) return false;
2959 return true;
2960 /* METADATA */
2961 case 0x02:
2962 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2963 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2964 return true;
2965 default:
2966 return false;
2970 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2971 bool *b_force_backup, bool *b_packet_out )
2973 if( p_stream->fmt.i_cat != UNKNOWN_ES )
2974 return;
2976 if( !strncmp(psz_value, "audio/x-wav", 11) )
2978 /* n.b. WAVs are unsupported right now */
2979 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2980 free( p_stream->fmt.psz_description );
2981 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2983 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2984 !strncmp(psz_value, "audio/vorbis", 12) )
2986 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
2988 *b_force_backup = true;
2990 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2991 !strncmp(psz_value, "audio/speex", 11) )
2993 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
2995 *b_force_backup = true;
2997 else if( !strncmp(psz_value, "audio/flac", 10) )
2999 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
3001 *b_force_backup = true;
3003 else if( !strncmp(psz_value, "video/x-theora", 14) ||
3004 !strncmp(psz_value, "video/theora", 12) )
3006 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
3008 *b_force_backup = true;
3010 else if( !strncmp(psz_value, "video/x-daala", 13) ||
3011 !strncmp(psz_value, "video/daala", 11) )
3013 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
3015 *b_force_backup = true;
3017 else if( !strncmp(psz_value, "video/x-xvid", 12) )
3019 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
3021 *b_force_backup = true;
3023 else if( !strncmp(psz_value, "video/mpeg", 10) )
3025 /* n.b. MPEG streams are unsupported right now */
3026 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3028 else if( !strncmp(psz_value, "text/x-cmml", 11) ||
3029 !strncmp(psz_value, "text/cmml", 9) )
3031 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_CMML );
3032 *b_packet_out = true;
3034 else if( !strncmp(psz_value, "application/kate", 16) )
3036 /* ??? */
3037 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3038 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3040 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3042 es_format_Change( &p_stream->fmt, VIDEO_ES, 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 demux_sys_t *p_sys = p_demux->p_sys;
3122 p_sys->p_skelstream = p_stream;
3123 /* There can be only 1 skeleton for streams */
3124 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3125 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3126 if ( asprintf( & p_stream->fmt.psz_description,
3127 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3128 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3129 p_stream->fmt.psz_description = NULL;
3132 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3134 demux_sys_t *p_sys = p_demux->p_sys;
3136 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3138 /* Find the matching stream for this skeleton data */
3139 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3140 logical_stream_t *p_target_stream = NULL;
3141 for ( int i=0; i< p_sys->i_streams; i++ )
3143 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3145 p_target_stream = p_sys->pp_stream[i];
3146 break;
3149 if ( !p_target_stream ) return;
3151 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3152 if ( !p_skel )
3154 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3155 if ( !p_skel ) return;
3156 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3157 p_skel->p_index = NULL;
3158 p_target_stream->p_skel = p_skel;
3161 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3162 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3163 const unsigned char *p = p_messages;
3164 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3166 if ( *p == 0x0D && *(p+1) == 0x0A )
3168 char *psz_message = strndup( (const char *) p_messages,
3169 p - p_messages );
3170 if ( psz_message )
3172 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3173 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3175 if ( p < p_boundary - 1 ) p_messages = p + 2;
3177 p++;
3182 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3183 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3184 unsigned const char *p_end,
3185 uint64_t *pi_value )
3187 int i_shift = 0;
3188 int64_t i_read = 0;
3189 *pi_value = 0;
3191 while ( p_begin < p_end )
3193 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3194 *pi_value = *pi_value | ( i_read << i_shift );
3195 i_shift += 7;
3196 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3199 *pi_value = GetQWLE( pi_value );
3200 return p_begin;
3203 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3205 demux_sys_t *p_sys = p_demux->p_sys;
3207 if( p_sys->skeleton.major < 4
3208 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3209 ) return;
3211 /* Find the matching stream for this skeleton data */
3212 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3213 logical_stream_t *p_stream = NULL;
3214 for ( int i=0; i< p_sys->i_streams; i++ )
3216 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3218 p_stream = p_sys->pp_stream[i];
3219 break;
3222 if ( !p_stream || !p_stream->p_skel ) return;
3223 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3224 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3225 if ( !i_keypoints ) return;
3227 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3228 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3229 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3230 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3231 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3232 uint64_t i_offset = 0;
3233 uint64_t i_time = 0;
3234 uint64_t i_keypoints_found = 0;
3236 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3238 uint64_t i_val;
3239 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3240 i_offset += i_val;
3241 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3242 i_time += i_val * p_stream->p_skel->i_indexstampden;
3243 i_keypoints_found++;
3246 if ( i_keypoints_found != i_keypoints )
3248 msg_Warn( p_demux, "Invalid Index: missing entries" );
3249 return;
3252 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3253 if ( !p_stream->p_skel->p_index ) return;
3254 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3255 p_oggpacket->bytes - 42 );
3256 p_stream->p_skel->i_index = i_keypoints_found;
3257 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3260 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3262 if ( !p_skel ) return;
3263 for ( int i=0; i< p_skel->i_messages; i++ )
3264 free( p_skel->ppsz_messages[i] );
3265 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3266 free( p_skel->p_index );
3267 free( p_skel );
3270 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3272 if ( !p_stream->p_skel ) return;
3273 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3275 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3276 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3278 free( p_stream->fmt.psz_description );
3279 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3281 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3283 bool b_foo;
3284 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo, &b_foo );
3289 /* Return true if there's a skeleton exact match */
3290 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
3291 int64_t *pi_lower, int64_t *pi_upper )
3293 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
3294 return false;
3296 /* Validate range */
3297 if ( i_time < p_stream->p_skel->i_indexfirstnum
3298 * p_stream->p_skel->i_indexstampden ||
3299 i_time > p_stream->p_skel->i_indexlastnum
3300 * p_stream->p_skel->i_indexstampden ) return false;
3302 /* Then Lookup its index */
3303 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3304 struct
3306 int64_t i_pos;
3307 int64_t i_time;
3308 } current = { 0, 0 }, prev = { -1, -1 };
3310 uint64_t i_keypoints_found = 0;
3312 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3313 && i_keypoints_found < p_stream->p_skel->i_index )
3315 uint64_t i_val;
3316 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3317 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3318 current.i_pos += i_val;
3319 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3320 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3321 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3322 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3324 i_keypoints_found++;
3326 if ( i_time <= current.i_time )
3328 *pi_lower = prev.i_pos;
3329 *pi_upper = current.i_pos;
3330 return ( i_time == current.i_time );
3332 prev = current;
3334 return false;
3337 static uint32_t dirac_uint( bs_t *p_bs )
3339 uint32_t u_count = 0, u_value = 0;
3341 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3343 u_count++;
3344 u_value <<= 1;
3345 u_value |= bs_read( p_bs, 1 );
3348 return (1<<u_count) - 1 + u_value;
3351 static int dirac_bool( bs_t *p_bs )
3353 return bs_read( p_bs, 1 );
3356 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3357 ogg_packet *p_oggpacket )
3359 static const struct {
3360 uint32_t u_n /* numerator */, u_d /* denominator */;
3361 } p_dirac_frate_tbl[] = { /* table 10.3 */
3362 {1,1}, /* this first value is never used */
3363 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3364 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3366 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3368 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3369 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3371 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3373 bs_t bs;
3375 p_stream->i_granule_shift = 22; /* not 32 */
3377 /* Backing up stream headers is not required -- seqhdrs are repeated
3378 * thoughout the stream at suitable decoding start points */
3379 p_stream->b_force_backup = false;
3381 /* read in useful bits from sequence header */
3382 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3383 bs_skip( &bs, 13*8); /* parse_info_header */
3384 dirac_uint( &bs ); /* major_version */
3385 dirac_uint( &bs ); /* minor_version */
3386 dirac_uint( &bs ); /* profile */
3387 dirac_uint( &bs ); /* level */
3389 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3390 if( u_video_format >= u_dirac_vidfmt_frate )
3392 /* don't know how to parse this ogg dirac stream */
3393 return false;
3396 if( dirac_bool( &bs ) )
3398 dirac_uint( &bs ); /* frame_width */
3399 dirac_uint( &bs ); /* frame_height */
3402 if( dirac_bool( &bs ) )
3404 dirac_uint( &bs ); /* chroma_format */
3407 if( dirac_bool( &bs ) )
3409 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3411 else
3412 p_stream->special.dirac.b_interlaced = false;
3414 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3415 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3416 u_d = __MAX( u_d, 1 );
3417 if( dirac_bool( &bs ) )
3419 uint32_t u_frame_rate_index = dirac_uint( &bs );
3420 if( u_frame_rate_index >= u_dirac_frate_tbl )
3422 /* something is wrong with this stream */
3423 return false;
3425 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3426 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3427 if( u_frame_rate_index == 0 )
3429 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3430 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3433 p_stream->f_rate = (float) u_n / u_d;
3434 if ( p_stream->f_rate == 0 ) return false;
3436 return true;
3439 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3440 ogg_packet *p_oggpacket )
3442 uint64_t i_granulerate_numerator;
3443 uint64_t i_granulerate_denominator;
3444 int i_major;
3445 int i_minor;
3447 es_format_Change( &p_stream->fmt, VIDEO_ES, 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;