demux: heif: refactor extents reading
[vlc.git] / modules / demux / ogg.c
blobf4601d00077db6789544cd8e230b769c7909b195
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 #ifdef HAVE_LIBVORBIS
33 #include <vorbis/codec.h>
34 #endif
36 #include <vlc_common.h>
37 #include <vlc_plugin.h>
38 #include <vlc_access.h>
39 #include <vlc_demux.h>
40 #include <vlc_meta.h>
41 #include <vlc_input.h>
43 #include <ogg/ogg.h>
45 #include <vlc_codecs.h>
46 #include <vlc_bits.h>
47 #include "xiph.h"
48 #include "xiph_metadata.h"
49 #include "ogg.h"
50 #include "oggseek.h"
51 #include "ogg_granule.h"
52 #include "opus.h"
54 /*****************************************************************************
55 * Module descriptor
56 *****************************************************************************/
57 static int Open ( vlc_object_t * );
58 static void Close( vlc_object_t * );
60 vlc_module_begin ()
61 set_shortname ( "OGG" )
62 set_description( N_("OGG demuxer" ) )
63 set_category( CAT_INPUT )
64 set_subcategory( SUBCAT_INPUT_DEMUX )
65 set_capability( "demux", 50 )
66 set_callbacks( Open, Close )
67 add_shortcut( "ogg" )
68 vlc_module_end ()
71 /*****************************************************************************
72 * Definitions of structures and functions used by this plugins
73 *****************************************************************************/
75 /* OggDS headers for the new header format (used in ogm files) */
76 typedef struct
78 ogg_int32_t width;
79 ogg_int32_t height;
80 } stream_header_video_t;
82 typedef struct
84 ogg_int16_t channels;
85 ogg_int16_t padding;
86 ogg_int16_t blockalign;
87 ogg_int32_t avgbytespersec;
88 } stream_header_audio_t;
90 typedef struct
92 char streamtype[8];
93 char subtype[4];
95 ogg_int32_t size; /* size of the structure */
97 ogg_int64_t time_unit; /* in reference time */
98 ogg_int64_t samples_per_unit;
99 ogg_int32_t default_len; /* in media time */
101 ogg_int32_t buffersize;
102 ogg_int16_t bits_per_sample;
103 ogg_int16_t padding;
105 union
107 /* Video specific */
108 stream_header_video_t video;
109 /* Audio specific */
110 stream_header_audio_t audio;
111 } sh;
112 } stream_header_t;
114 #define VORBIS_HEADER_IDENTIFICATION 1
115 #define VORBIS_HEADER_COMMENT 2
116 #define VORBIS_HEADER_SETUP 3
117 #define VORBIS_HEADER_TO_FLAG(i) (1 << (i - 1))
118 #define VORBIS_HEADERS_VALID(p_stream) \
119 ((p_stream->special.vorbis.i_headers_flags & 0x07) == 0x07) // 0b111
121 /*****************************************************************************
122 * Local prototypes
123 *****************************************************************************/
124 static int Demux ( demux_t * );
125 static int Control( demux_t *, int, va_list );
127 /* Bitstream manipulation */
128 static int Ogg_ReadPage ( demux_t *, ogg_page * );
129 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
130 static unsigned Ogg_OpusPacketDuration( ogg_packet * );
131 static void Ogg_QueueBlocks( demux_t *, logical_stream_t *, block_t * );
132 static void Ogg_SendQueuedBlock( demux_t *, logical_stream_t * );
134 static inline bool Ogg_HasQueuedBlocks( const logical_stream_t *p_stream )
136 return ( p_stream->queue.p_blocks != NULL );
139 static void Ogg_CreateES( demux_t *p_demux );
140 static int Ogg_BeginningOfStream( demux_t *p_demux );
141 static int Ogg_FindLogicalStreams( demux_t *p_demux );
142 static void Ogg_EndOfStream( demux_t *p_demux );
144 /* */
145 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream );
146 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
147 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
148 static void Ogg_ResetStream( logical_stream_t *p_stream );
150 /* */
151 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
153 /* Logical bitstream headers */
154 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
155 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
156 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
157 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
158 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
159 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
160 static bool Ogg_ReadFlacStreamInfo( demux_t *, logical_stream_t *, ogg_packet * );
161 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
162 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
163 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
164 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
165 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *, ogg_packet * );
167 /* Skeleton */
168 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
169 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
170 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
171 static void Ogg_ApplySkeleton( logical_stream_t * );
173 /* Special decoding */
174 static void Ogg_CleanSpecificData( logical_stream_t * );
175 #ifdef HAVE_LIBVORBIS
176 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
177 #endif
179 static void fill_channels_info(audio_format_t *audio)
181 static const int pi_channels_map[9] =
184 AOUT_CHAN_CENTER,
185 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
186 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
187 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
188 | AOUT_CHAN_REARRIGHT,
189 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
190 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
191 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
192 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
193 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
194 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
195 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
196 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
197 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
198 | AOUT_CHAN_LFE,
201 unsigned chans = audio->i_channels;
202 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
203 audio->i_physical_channels = pi_channels_map[chans];
206 /*****************************************************************************
207 * Open: initializes ogg demux structures
208 *****************************************************************************/
209 static int Open( vlc_object_t * p_this )
211 demux_t *p_demux = (demux_t *)p_this;
212 demux_sys_t *p_sys;
213 const uint8_t *p_peek;
215 /* Check if we are dealing with an ogg stream */
216 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
217 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
219 char *psz_mime = stream_ContentType( p_demux->s );
220 if( !psz_mime )
222 return VLC_EGENERIC;
224 else if ( strcmp( psz_mime, "application/ogg" ) &&
225 strcmp( psz_mime, "video/ogg" ) &&
226 strcmp( psz_mime, "audio/ogg" ) )
228 free( psz_mime );
229 return VLC_EGENERIC;
231 free( psz_mime );
234 /* */
235 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
236 if( !p_sys )
237 return VLC_ENOMEM;
239 p_sys->i_length = -1;
240 p_sys->b_preparsing_done = false;
242 /* Set exported functions */
243 p_demux->pf_demux = Demux;
244 p_demux->pf_control = Control;
246 /* Initialize the Ogg physical bitstream parser */
247 ogg_sync_init( &p_sys->oy );
249 /* */
250 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
253 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
255 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
256 Ogg_CreateES( p_demux );
258 return VLC_SUCCESS;
261 /*****************************************************************************
262 * Close: frees unused data
263 *****************************************************************************/
264 static void Close( vlc_object_t *p_this )
266 demux_t *p_demux = (demux_t *)p_this;
267 demux_sys_t *p_sys = p_demux->p_sys ;
269 /* Cleanup the bitstream parser */
270 ogg_sync_clear( &p_sys->oy );
272 Ogg_EndOfStream( p_demux );
274 if( p_sys->p_old_stream )
275 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
277 free( p_sys );
280 static vlc_tick_t Ogg_GetLastDTS( demux_t * p_demux )
282 demux_sys_t *p_sys = p_demux->p_sys;
284 vlc_tick_t i_dts = VLC_TICK_INVALID;
285 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
287 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
288 if ( p_stream->b_initializing )
289 continue;
290 if( p_stream->i_pcr > i_dts )
291 i_dts = p_stream->i_pcr;
294 return i_dts;
297 static vlc_tick_t Ogg_GeneratePCR( demux_t * p_demux, bool b_drain )
299 demux_sys_t *p_sys = p_demux->p_sys;
300 /* We will consider the lowest PCR among tracks, because the audio core badly
301 * handles PCR rewind (mute)
303 vlc_tick_t i_pcr_candidate = VLC_TICK_INVALID;
304 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
306 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
307 if( p_stream->fmt.i_cat == SPU_ES )
308 continue;
309 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
310 continue;
311 if( p_stream->i_pcr == VLC_TICK_INVALID )
312 continue;
313 if ( (!b_drain && p_stream->b_finished) || p_stream->b_initializing )
314 continue;
315 if( i_pcr_candidate == VLC_TICK_INVALID ||
316 p_stream->i_pcr < i_pcr_candidate )
318 i_pcr_candidate = p_stream->i_pcr;
322 return i_pcr_candidate;
325 static void Ogg_OutputQueues( demux_t *p_demux, bool b_drain )
327 demux_sys_t *p_sys = p_demux->p_sys;
328 vlc_tick_t i_pcr;
330 /* Generate First PCR */
331 if( p_sys->i_pcr == VLC_TICK_INVALID )
333 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
334 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
336 p_sys->i_pcr = i_pcr;
337 if( likely( !p_sys->b_slave ) )
338 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
342 if( p_sys->i_pcr != VLC_TICK_INVALID )
344 bool b_continue;
347 b_continue = false;
348 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
350 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
351 if( Ogg_HasQueuedBlocks( p_stream ) )
352 Ogg_SendQueuedBlock( p_demux, p_stream );
353 b_continue |= Ogg_HasQueuedBlocks( p_stream );
356 /* Generate Current PCR */
357 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
358 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
360 p_sys->i_pcr = i_pcr;
361 if( likely( !p_sys->b_slave ) )
362 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
364 } while ( b_continue );
369 /*****************************************************************************
370 * Demux: reads and demuxes data packets
371 *****************************************************************************
372 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
373 *****************************************************************************/
374 static int Demux( demux_t * p_demux )
376 demux_sys_t *p_sys = p_demux->p_sys;
377 ogg_packet oggpacket;
378 int i_stream;
379 bool b_canseek;
381 int i_active_streams = p_sys->i_streams;
382 for ( int i=0; i < p_sys->i_streams; i++ )
384 if ( p_sys->pp_stream[i]->b_finished )
385 i_active_streams--;
388 if ( i_active_streams == 0 )
390 if ( p_sys->i_streams ) /* All finished */
392 msg_Dbg( p_demux, "end of a group of %d logical streams", p_sys->i_streams );
394 Ogg_OutputQueues( p_demux, true );
396 vlc_tick_t i_lastdts = Ogg_GetLastDTS( p_demux );
398 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
399 * only 1 ES is supported (common case for ogg web radio) */
400 if( p_sys->i_streams == 1 && p_sys->pp_stream[0]->p_es )
402 if( p_sys->p_old_stream ) /* if no setupEs has reused */
403 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
404 p_sys->p_old_stream = p_sys->pp_stream[0];
405 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
408 Ogg_EndOfStream( p_demux );
409 p_sys->b_chained_boundary = true;
411 if( i_lastdts != VLC_TICK_INVALID )
413 p_sys->i_nzpcr_offset = i_lastdts - VLC_TICK_0;
414 if( likely( !p_sys->b_slave ) )
415 es_out_SetPCR( p_demux->out, i_lastdts );
417 p_sys->i_pcr = VLC_TICK_INVALID;
420 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
421 return VLC_DEMUXER_EOF;
423 msg_Dbg( p_demux, "beginning of a group of logical streams" );
425 if ( !p_sys->b_chained_boundary )
427 /* Find the real duration */
428 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
429 if ( b_canseek )
430 Oggseek_ProbeEnd( p_demux );
432 else
434 p_sys->b_chained_boundary = false;
438 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
439 Ogg_CreateES( p_demux );
442 * The first data page of a physical stream is stored in the relevant logical stream
443 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
444 * stream it belongs to if we haven't processed this first page yet. If we do, we
445 * will only process that first page whenever we find the second page for this stream.
446 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
447 * the second page will arrive real quick, this is not fine for Kate, whose second
448 * data page will typically arrive much later.
449 * This means it is now possible to seek right at the start of a stream where the last
450 * logical stream is Kate, without having to wait for the second data page to unblock
451 * the first one, which is the one that triggers the 'no more headers to backup' code.
452 * And, as we all know, seeking without having backed up all headers is bad, since the
453 * codec will fail to initialize if it's missing its headers.
455 if( !p_sys->b_page_waiting)
458 * Demux an ogg page from the stream
460 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
461 return VLC_DEMUXER_EOF; /* EOF */
462 /* Test for End of Stream */
463 if( ogg_page_eos( &p_sys->current_page ) )
465 /* If we delayed restarting encoders/SET_ES_FMT for more
466 * skeleton provided configuration */
467 if ( p_sys->p_skelstream )
469 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
471 msg_Dbg( p_demux, "End of Skeleton" );
472 p_sys->b_preparsing_done = true;
473 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
475 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
476 Ogg_ApplySkeleton( p_stream );
481 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
483 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
485 p_sys->pp_stream[i_stream]->b_finished = true;
486 break;
492 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
494 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
496 /* if we've just pulled page, look for the right logical stream */
497 if( !p_sys->b_page_waiting )
499 if( p_sys->i_streams == 1 &&
500 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
502 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
503 Ogg_ResetStream( p_stream );
504 if( p_stream->i_pcr != VLC_TICK_INVALID )
505 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TICK_0;
506 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
509 /* Does fail if serialno differs */
510 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
512 continue;
516 /* clear the finished flag if pages after eos (ex: after a seek) */
517 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
518 p_stream->b_finished = false;
520 DemuxDebug(
521 if ( p_stream->fmt.i_cat == VIDEO_ES )
522 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
523 ogg_page_pageno( &p_sys->current_page ),
524 ogg_page_granulepos( &p_sys->current_page ),
525 ogg_page_packets( &p_sys->current_page ),
526 ogg_page_continued(&p_sys->current_page),
527 p_sys->current_page.body_len )
530 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
532 /* Read info from any secondary header packets, if there are any */
533 if( p_stream->i_secondary_header_packets > 0 )
535 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
536 oggpacket.bytes >= 7 &&
537 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
539 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
540 p_stream->i_secondary_header_packets = 0;
542 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
543 oggpacket.bytes >= 6 &&
544 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
546 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
547 p_stream->i_secondary_header_packets = 0;
549 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
550 oggpacket.bytes >= 7 &&
551 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
553 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
554 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
555 p_stream->i_secondary_header_packets = 0;
558 /* update start of data pointer */
559 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
562 if( p_stream->b_reinit )
564 p_stream->b_reinit = false;
565 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
567 p_stream->i_skip_frames = p_stream->i_pre_skip;
571 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
575 if( !p_sys->b_page_waiting )
576 break;
579 /* if a page was waiting, it's now processed */
580 p_sys->b_page_waiting = false;
582 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
583 p_sys->b_preparsing_done = false;
584 else
585 p_sys->b_preparsing_done = true;
587 if( p_sys->b_preparsing_done )
589 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
591 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
592 if ( p_stream->b_initializing )
594 /* We have 1 or more streams needing more than 1 page for preparsing */
595 p_sys->b_preparsing_done = false;
596 break;
601 if( p_sys->b_preparsing_done )
602 Ogg_OutputQueues( p_demux, false );
604 return VLC_DEMUXER_SUCCESS;
607 static void Ogg_ResetStream( logical_stream_t *p_stream )
609 #ifdef HAVE_LIBVORBIS
610 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
612 p_stream->special.vorbis.i_prev_blocksize = 0;
614 #endif
615 /* we'll trash all the data until we find the next pcr */
616 p_stream->b_reinit = true;
617 p_stream->i_pcr = VLC_TICK_INVALID;
618 p_stream->i_next_block_flags = 0;
619 date_Set( &p_stream->dts, VLC_TICK_INVALID );
620 ogg_stream_reset( &p_stream->os );
621 block_ChainRelease( p_stream->queue.p_blocks );
622 p_stream->queue.p_blocks = NULL;
623 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
626 static void Ogg_PreparePostSeek( demux_sys_t *p_sys )
628 for( int i = 0; i < p_sys->i_streams; i++ )
630 Ogg_ResetStream( p_sys->pp_stream[i] );
631 p_sys->pp_stream[i]->i_next_block_flags = BLOCK_FLAG_DISCONTINUITY;
634 ogg_sync_reset( &p_sys->oy );
635 p_sys->i_pcr = VLC_TICK_INVALID;
638 static logical_stream_t * Ogg_GetSelectedStream( demux_t *p_demux )
640 demux_sys_t *p_sys = p_demux->p_sys;
641 logical_stream_t *p_stream = NULL;
642 for( int i=0; i<p_sys->i_streams; i++ )
644 logical_stream_t *p_candidate = p_sys->pp_stream[i];
645 if ( !p_candidate->p_es ) continue;
647 bool b_selected = false;
648 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
649 p_candidate->p_es, &b_selected );
650 if ( !b_selected ) continue;
652 if ( !p_stream && p_candidate->fmt.i_cat == AUDIO_ES )
654 p_stream = p_candidate;
655 continue; /* Try to find video anyway */
658 if ( p_candidate->fmt.i_cat == VIDEO_ES )
660 p_stream = p_candidate;
661 break;
664 return p_stream;
667 /*****************************************************************************
668 * Control:
669 *****************************************************************************/
670 static int Control( demux_t *p_demux, int i_query, va_list args )
672 demux_sys_t *p_sys = p_demux->p_sys;
673 vlc_meta_t *p_meta;
674 vlc_tick_t i64;
675 double *pf, f;
676 bool *pb_bool, b, acc;
677 logical_stream_t *p_stream;
679 switch( i_query )
681 case DEMUX_CAN_SEEK:
682 return vlc_stream_vaControl( p_demux->s, i_query, args );
684 case DEMUX_GET_META:
685 p_meta = va_arg( args, vlc_meta_t * );
686 if( p_sys->p_meta )
687 vlc_meta_Merge( p_meta, p_sys->p_meta );
688 return VLC_SUCCESS;
690 case DEMUX_HAS_UNSUPPORTED_META:
691 pb_bool = va_arg( args, bool* );
692 *pb_bool = true;
693 return VLC_SUCCESS;
695 case DEMUX_SET_NEXT_DEMUX_TIME:
696 p_sys->b_slave = true;
697 return VLC_EGENERIC;
699 case DEMUX_GET_TIME:
700 if( p_sys->i_pcr != VLC_TICK_INVALID || p_sys->b_slave )
702 *va_arg( args, vlc_tick_t * ) = p_sys->i_pcr;
703 return VLC_SUCCESS;
705 return VLC_EGENERIC;
707 case DEMUX_SET_TIME:
709 i64 = va_arg( args, vlc_tick_t );
710 acc = va_arg( args, int );
711 p_stream = Ogg_GetSelectedStream( p_demux );
712 if ( !p_stream )
714 msg_Err( p_demux, "No selected seekable stream found" );
715 return VLC_EGENERIC;
717 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
718 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TICK_0 + i64, b ) )
720 Ogg_PreparePostSeek( p_sys );
721 if( acc )
722 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
723 VLC_TICK_0 + i64 );
724 return VLC_SUCCESS;
726 else
727 return VLC_EGENERIC;
730 case DEMUX_GET_ATTACHMENTS:
732 input_attachment_t ***ppp_attach =
733 va_arg( args, input_attachment_t *** );
734 int *pi_int = va_arg( args, int * );
736 if( p_sys->i_attachments <= 0 )
737 return VLC_EGENERIC;
739 *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
740 if (!**ppp_attach)
741 return VLC_ENOMEM;
742 *pi_int = p_sys->i_attachments;
743 for( int i = 0; i < p_sys->i_attachments; i++ )
744 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
745 return VLC_SUCCESS;
748 case DEMUX_GET_POSITION:
749 pf = va_arg( args, double * );
750 if( p_sys->i_length > 0 && p_sys->i_pcr != VLC_TICK_INVALID )
752 *pf = (double) p_sys->i_pcr /
753 (double) vlc_tick_from_sec( p_sys->i_length );
755 else if( stream_Size( p_demux->s ) > 0 )
757 *pf = (double) vlc_stream_Tell( p_demux->s ) / stream_Size( p_demux->s );
759 else *pf = 0.0;
760 return VLC_SUCCESS;
762 case DEMUX_SET_POSITION:
763 /* forbid seeking if we haven't initialized all logical bitstreams yet;
764 if we allowed, some headers would not get backed up and decoder init
765 would fail, making that logical stream unusable */
766 for ( int i=0; i< p_sys->i_streams; i++ )
768 if ( p_sys->pp_stream[i]->b_initializing )
769 return VLC_EGENERIC;
772 p_stream = Ogg_GetSelectedStream( p_demux );
773 if ( !p_stream )
775 msg_Err( p_demux, "No selected seekable stream found" );
776 return VLC_EGENERIC;
779 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
781 f = va_arg( args, double );
782 acc = va_arg( args, int );
783 if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
785 Ogg_PreparePostSeek( p_sys );
786 return Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
789 assert( p_sys->i_length > 0 );
790 i64 = vlc_tick_from_sec( f * p_sys->i_length );
791 Ogg_PreparePostSeek( p_sys );
792 if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, VLC_TICK_0 + i64 ) >= 0 )
794 if( acc )
795 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
796 VLC_TICK_0 + i64 );
797 return VLC_SUCCESS;
800 return VLC_EGENERIC;
802 case DEMUX_GET_LENGTH:
803 if ( p_sys->i_length < 0 )
804 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
805 1, i_query, args );
806 *va_arg( args, vlc_tick_t * ) = vlc_tick_from_sec(p_sys->i_length);
807 return VLC_SUCCESS;
809 case DEMUX_GET_TITLE_INFO:
811 input_title_t ***ppp_title = va_arg( args, input_title_t *** );
812 int *pi_int = va_arg( args, int* );
813 int *pi_title_offset = va_arg( args, int* );
814 int *pi_seekpoint_offset = va_arg( args, int* );
816 if( p_sys->i_seekpoints > 0 )
818 *pi_int = 1;
819 *ppp_title = malloc( sizeof( input_title_t* ) );
820 input_title_t *p_title = (*ppp_title)[0] = vlc_input_title_New();
821 for( int i = 0; i < p_sys->i_seekpoints; i++ )
823 seekpoint_t *p_seekpoint_copy = vlc_seekpoint_Duplicate( p_sys->pp_seekpoints[i] );
824 if ( likely( p_seekpoint_copy ) )
825 TAB_APPEND( p_title->i_seekpoint, p_title->seekpoint, p_seekpoint_copy );
827 *pi_title_offset = 0;
828 *pi_seekpoint_offset = 0;
829 return VLC_SUCCESS;
831 return VLC_EGENERIC;
833 case DEMUX_SET_TITLE:
835 const int i_title = va_arg( args, int );
836 if( i_title > 1 )
837 return VLC_EGENERIC;
838 return VLC_SUCCESS;
840 case DEMUX_SET_SEEKPOINT:
842 const int i_seekpoint = va_arg( args, int );
843 if( i_seekpoint > p_sys->i_seekpoints )
844 return VLC_EGENERIC;
846 for ( int i=0; i< p_sys->i_streams; i++ )
848 if ( p_sys->pp_stream[i]->b_initializing )
849 return VLC_EGENERIC;
852 i64 = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset;
854 p_stream = Ogg_GetSelectedStream( p_demux );
855 if ( !p_stream )
857 msg_Err( p_demux, "No selected seekable stream found" );
858 return VLC_EGENERIC;
861 vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
862 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TICK_0 + i64, b ) )
864 Ogg_PreparePostSeek( p_sys );
865 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
866 VLC_TICK_0 + i64 );
867 p_sys->updates |= INPUT_UPDATE_SEEKPOINT;
868 p_sys->cur_seekpoint = i_seekpoint;
869 return VLC_SUCCESS;
871 else
872 return VLC_EGENERIC;
874 case DEMUX_TEST_AND_CLEAR_FLAGS:
876 unsigned *restrict flags = va_arg( args, unsigned * );
877 *flags &= p_sys->updates;
878 p_sys->updates &= ~*flags;
879 return VLC_SUCCESS;
881 case DEMUX_GET_TITLE:
882 *va_arg( args, int * ) = 0;
883 return VLC_SUCCESS;
884 case DEMUX_GET_SEEKPOINT:
885 *va_arg( args, int * ) = p_sys->cur_seekpoint;
886 return VLC_SUCCESS;
888 default:
889 return demux_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
890 1, i_query, args );
894 /****************************************************************************
895 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
896 ****************************************************************************
897 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
898 * are at the end of stream.
899 ****************************************************************************/
900 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
902 demux_sys_t *p_ogg = p_demux->p_sys ;
903 int i_read = 0;
904 char *p_buffer;
906 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
908 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGGSEEK_BYTES_TO_READ );
910 i_read = vlc_stream_Read( p_demux->s, p_buffer, OGGSEEK_BYTES_TO_READ );
911 if( i_read <= 0 )
912 return VLC_EGENERIC;
914 ogg_sync_wrote( &p_ogg->oy, i_read );
917 return VLC_SUCCESS;
920 static void Ogg_SetNextFrame( demux_t *p_demux, logical_stream_t *p_stream,
921 ogg_packet *p_oggpacket )
923 VLC_UNUSED(p_demux);
924 ogg_int64_t i_granule = p_oggpacket->granulepos;
926 if( Ogg_GranuleIsValid( p_stream, i_granule ) )
928 vlc_tick_t i_endtime = Ogg_GranuleToTime( p_stream, i_granule, false, false );
929 assert( !p_stream->b_contiguous || i_endtime != VLC_TICK_INVALID );
930 if( i_endtime != VLC_TICK_INVALID )
932 date_Set( &p_stream->dts, i_endtime );
933 return;
937 /* Do Interpolation if can't compute directly from granule */
938 if( date_Get( &p_stream->dts ) != VLC_TICK_INVALID )
940 if( p_stream->fmt.i_cat == VIDEO_ES )
942 date_Increment( &p_stream->dts, 1 );
944 else if( p_stream->fmt.i_cat == AUDIO_ES )
946 int64_t i_samples = 0;
947 switch( p_stream->fmt.i_codec )
949 case VLC_CODEC_OPUS:
950 i_samples = Ogg_OpusPacketDuration( p_oggpacket );
951 break;
952 case VLC_CODEC_SPEEX:
953 i_samples = p_stream->special.speex.i_framesize *
954 p_stream->special.speex.i_framesperpacket;
955 break;
956 #ifdef HAVE_LIBVORBIS
957 case VLC_CODEC_VORBIS:
958 if( p_stream->special.vorbis.p_info &&
959 VORBIS_HEADERS_VALID(p_stream) )
961 long i_blocksize = vorbis_packet_blocksize(
962 p_stream->special.vorbis.p_info, p_oggpacket );
963 /* duration in samples per channel */
964 if ( p_stream->special.vorbis.i_prev_blocksize )
965 i_samples = ( i_blocksize + p_stream->special.vorbis.i_prev_blocksize ) / 4;
966 else
967 i_samples = i_blocksize / 2;
968 p_stream->special.vorbis.i_prev_blocksize = i_blocksize;
970 break;
971 #endif
972 default:
973 if( p_stream->fmt.i_bitrate )
975 i_samples = 8 * p_oggpacket->bytes * p_stream->dts.i_divider_num;
976 i_samples /= p_stream->fmt.i_bitrate / p_stream->dts.i_divider_den;
978 break;
980 date_Increment( &p_stream->dts, i_samples );
985 static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_stream )
987 vlc_tick_t i_enddts = VLC_TICK_INVALID;
989 #ifdef HAVE_LIBVORBIS
990 long i_prev_blocksize = 0;
991 #else
992 VLC_UNUSED(p_demux);
993 #endif
994 // PASS 1, set number of samples
995 unsigned i_total_samples = 0;
996 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
998 if( p_block->i_dts != VLC_TICK_INVALID )
1000 i_enddts = p_block->i_dts;
1001 break;
1004 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1005 continue;
1007 ogg_packet dumb_packet;
1008 dumb_packet.bytes = p_block->i_buffer;
1009 dumb_packet.packet = p_block->p_buffer;
1011 switch( p_stream->fmt.i_codec )
1013 case VLC_CODEC_SPEEX:
1014 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
1015 p_stream->special.speex.i_framesperpacket;
1016 break;
1017 case VLC_CODEC_OPUS:
1018 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
1019 break;
1020 #ifdef HAVE_LIBVORBIS
1021 case VLC_CODEC_VORBIS:
1023 if( !VORBIS_HEADERS_VALID(p_stream) )
1025 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
1026 break;
1028 long i_blocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info,
1029 &dumb_packet );
1030 if ( i_prev_blocksize )
1031 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
1032 else
1033 p_block->i_nb_samples = i_blocksize / 2;
1034 i_prev_blocksize = i_blocksize;
1035 break;
1037 #endif
1038 default:
1039 if( p_stream->fmt.i_cat == VIDEO_ES )
1040 p_block->i_nb_samples = 1;
1041 break;
1043 i_total_samples += p_block->i_nb_samples;
1046 // PASS 2
1047 if( i_enddts != VLC_TICK_INVALID )
1049 date_t d = p_stream->dts;
1050 date_Set( &d, i_enddts );
1051 i_enddts = date_Decrement( &d, i_total_samples );
1052 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
1054 if( p_block->i_dts != VLC_TICK_INVALID )
1055 break;
1056 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1057 continue;
1058 p_block->i_dts = date_Get( &d );
1059 date_Increment( &d, p_block->i_nb_samples );
1061 } /* else can't do anything, no timestamped blocks in stream */
1063 return i_enddts;
1066 static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream, block_t *p_block )
1068 demux_sys_t *p_sys = p_demux->p_sys;
1069 VLC_UNUSED(p_sys);
1071 if( p_block == NULL )
1073 assert( p_block != NULL );
1074 return;
1077 block_ChainLastAppend( &p_stream->queue.pp_append, p_block );
1079 if( p_stream->i_pcr == VLC_TICK_INVALID && p_block->i_dts != VLC_TICK_INVALID )
1081 /* fixup queue */
1082 p_stream->i_pcr = Ogg_FixupOutputQueue( p_demux, p_stream );
1085 DemuxDebug( msg_Dbg( p_demux, "%4.4s block queued > dts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1086 (char*)&p_stream->fmt.i_codec, p_block->i_dts, p_stream->i_pcr, p_sys->i_pcr ); )
1089 static void Ogg_SendQueuedBlock( demux_t *p_demux, logical_stream_t *p_stream )
1091 demux_sys_t *p_sys = p_demux->p_sys;
1093 if( Ogg_HasQueuedBlocks( p_stream ) )
1095 block_t *p_queued = p_stream->queue.p_blocks;
1096 p_stream->queue.p_blocks = p_queued->p_next;
1097 p_queued->p_next = NULL;
1099 if( p_queued->i_dts == VLC_TICK_INVALID )
1100 p_queued->i_dts = p_queued->i_pts;
1102 if( p_queued->i_flags & BLOCK_FLAG_HEADER )
1104 if( p_sys->i_nzpcr_offset > 0 || /* Don't send metadata from chained streams */
1105 p_stream->fmt.i_extra > 0 ) /* Don't send metadata if configured by extradata */
1107 block_Release( p_queued );
1108 goto end;
1110 p_queued->i_flags &= ~BLOCK_FLAG_HEADER;
1113 unsigned i_toskip = 0;
1114 if( p_stream->i_skip_frames > 0 )
1116 if( p_sys->i_nzpcr_offset > 0 )
1118 /* not preskip handling on chained streams */
1119 p_stream->i_skip_frames = 0;
1121 else
1123 i_toskip = __MIN( p_stream->i_skip_frames, p_queued->i_nb_samples );
1124 p_stream->i_skip_frames -= i_toskip;
1125 p_queued->i_nb_samples -= i_toskip;
1126 if( p_queued->i_nb_samples == 0 )
1127 p_queued->i_flags |= BLOCK_FLAG_PREROLL;
1131 p_queued->i_flags |= p_stream->i_next_block_flags;
1132 p_stream->i_next_block_flags = 0;
1133 p_stream->i_pcr = p_queued->i_dts;
1135 DemuxDebug( msg_Dbg( p_demux, "%4.4s block sent > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64
1136 " samples (%d/%d)",
1137 (char*)&p_stream->fmt.i_codec, p_queued->i_dts,
1138 p_queued->i_pts, p_stream->i_pcr, p_sys->i_pcr,
1139 p_queued->i_nb_samples, i_toskip ); );
1141 assert( p_sys->i_pcr != VLC_TICK_INVALID );
1143 if( p_stream->p_es )
1144 es_out_Send( p_demux->out, p_stream->p_es, p_queued );
1145 else
1146 block_Release( p_queued );
1149 end:
1150 if( p_stream->queue.p_blocks == NULL )
1151 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
1154 static bool Ogg_IsHeaderPacket( const logical_stream_t *p_stream,
1155 const ogg_packet *p_oggpacket )
1157 if ( p_stream->b_oggds )
1159 return p_oggpacket->bytes > 0 &&
1160 (p_oggpacket->packet[0] & PACKET_TYPE_HEADER);
1162 else return (p_oggpacket->granulepos == 0);
1165 /****************************************************************************
1166 * Ogg_DecodePacket: Decode an Ogg packet.
1167 ****************************************************************************/
1168 static void Ogg_DecodePacket( demux_t *p_demux,
1169 logical_stream_t *p_stream,
1170 ogg_packet *p_oggpacket )
1172 demux_sys_t *p_sys = p_demux->p_sys;
1173 block_t *p_block;
1174 bool b_selected;
1175 long i_header_len = 0;
1177 if( p_oggpacket->bytes >= 7 &&
1178 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1180 /* it's an Annodex packet -- skip it (do nothing) */
1181 return;
1183 else if( p_oggpacket->bytes >= 7 &&
1184 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1186 /* it's an AnxData packet -- skip it (do nothing) */
1187 return;
1189 else if( p_oggpacket->bytes >= 8 &&
1190 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1192 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1193 return;
1195 else if( p_oggpacket->bytes >= 6 &&
1196 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1198 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1199 return;
1201 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1202 p_oggpacket->bytes >= 7 &&
1203 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1205 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1206 return;
1209 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1210 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1212 /* Check the ES is selected */
1213 if ( !p_stream->p_es )
1214 b_selected = true;
1215 else
1216 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1217 p_stream->p_es, &b_selected );
1219 if( p_stream->b_force_backup )
1221 bool b_xiph;
1222 p_stream->i_packets_backup++;
1223 switch( p_stream->fmt.i_codec )
1225 case VLC_CODEC_VORBIS:
1226 #ifdef HAVE_LIBVORBIS
1227 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1228 #endif
1229 /* fallthrough */
1230 case VLC_CODEC_THEORA:
1231 if( p_stream->i_packets_backup == 3 )
1232 p_stream->b_force_backup = false;
1233 b_xiph = true;
1234 break;
1236 case VLC_CODEC_DAALA:
1237 if( p_stream->i_packets_backup == 3 )
1238 p_stream->b_force_backup = false;
1239 b_xiph = true;
1240 break;
1242 case VLC_CODEC_SPEEX:
1243 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1244 p_stream->b_force_backup = false;
1245 b_xiph = true;
1246 break;
1248 case VLC_CODEC_OPUS:
1249 if( p_stream->i_packets_backup == 2 )
1250 p_stream->b_force_backup = false;
1251 b_xiph = true;
1252 break;
1254 case VLC_CODEC_FLAC:
1255 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1257 p_stream->b_force_backup = false;
1259 if( p_stream->special.flac.b_old )
1261 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1263 else if( p_stream->i_packets_backup == 1 )
1265 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1267 p_oggpacket->packet += 9;
1268 p_oggpacket->bytes -= 9;
1271 b_xiph = false;
1272 break;
1274 case VLC_CODEC_KATE:
1275 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1276 p_stream->b_force_backup = false;
1277 b_xiph = true;
1278 break;
1280 default:
1281 p_stream->b_force_backup = false;
1282 b_xiph = false;
1283 break;
1286 /* Backup the ogg packet (likely an header packet) */
1287 if( !b_xiph )
1289 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1290 if( p_realloc )
1292 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1293 p_stream->i_headers += p_oggpacket->bytes;
1294 p_stream->p_headers = p_realloc;
1296 else
1298 free( p_stream->p_headers );
1299 p_stream->i_headers = 0;
1300 p_stream->p_headers = NULL;
1303 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1304 p_oggpacket->bytes, p_oggpacket->packet ) )
1306 p_stream->i_headers = 0;
1307 p_stream->p_headers = NULL;
1309 if( p_stream->i_headers > 0 )
1311 if( !p_stream->b_force_backup )
1313 /* Last header received, commit changes */
1314 free( p_stream->fmt.p_extra );
1316 p_stream->fmt.i_extra = p_stream->i_headers;
1317 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1318 if( p_stream->fmt.p_extra )
1319 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1320 p_stream->i_headers );
1321 else
1322 p_stream->fmt.i_extra = 0;
1324 if( p_stream->i_headers > 0 )
1325 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1326 p_stream->p_headers, p_stream->i_headers );
1328 /* we're not at BOS anymore for this logical stream */
1329 p_stream->b_initializing = false;
1333 b_selected = false; /* Discard the header packet */
1335 else
1337 p_stream->b_initializing = false;
1340 vlc_tick_t i_dts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, false );
1341 vlc_tick_t i_expected_dts = date_Get( &p_stream->dts ); /* Interpolated or previous end time */
1342 if( i_dts == VLC_TICK_INVALID )
1343 i_dts = i_expected_dts;
1344 else
1345 date_Set( &p_stream->dts, i_dts );
1347 /* Write end granule as next start, or do interpolation */
1348 bool b_header = Ogg_IsHeaderPacket( p_stream, p_oggpacket );
1349 if( !b_header )
1350 Ogg_SetNextFrame( p_demux, p_stream, p_oggpacket );
1352 if( !b_selected )
1354 /* This stream isn't currently selected so we don't need to decode it,
1355 * but we did need to store its pcr as it might be selected later on */
1356 if( !b_header && !p_stream->b_initializing )
1358 vlc_tick_t i_pcr = date_Get( &p_stream->dts );
1359 if( i_pcr != VLC_TICK_INVALID )
1360 p_stream->i_pcr = p_sys->i_nzpcr_offset + i_pcr;
1362 return;
1365 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) )
1366 return;
1368 /* Set effective timestamp */
1369 if( i_dts != VLC_TICK_INVALID )
1370 p_block->i_dts = p_sys->i_nzpcr_offset + i_dts;
1372 /* Vorbis and Opus can trim the end of a stream using granule positions. */
1373 if( p_oggpacket->e_o_s )
1375 vlc_tick_t i_endtime = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, false, false );
1376 if( i_endtime != VLC_TICK_INVALID && i_expected_dts != VLC_TICK_INVALID )
1378 p_block->i_length = i_endtime - i_expected_dts;
1379 p_block->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
1383 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS ) /* also required for trimming */
1384 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1386 DemuxDebug( msg_Dbg(p_demux, "%4.4s block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1387 (char *) &p_stream->fmt.i_codec, p_oggpacket->granulepos,
1388 p_block->i_dts, p_stream->i_skip_frames); )
1390 /* may need to preroll after a seek or in case of preskip */
1392 /* Conditional block fixes */
1393 if ( p_stream->fmt.i_cat == VIDEO_ES )
1395 if( Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1396 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1398 if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1400 if( p_oggpacket->granulepos > 0 )
1401 p_block->i_pts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, true );
1403 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1405 p_block->i_pts = p_block->i_dts;
1408 else if( p_stream->fmt.i_cat == AUDIO_ES )
1410 p_block->i_pts = p_block->i_dts;
1412 else if( p_stream->fmt.i_cat == SPU_ES )
1414 p_block->i_length = 0;
1415 p_block->i_pts = p_block->i_dts;
1418 if( p_stream->b_oggds )
1420 if( p_oggpacket->bytes <= 0 )
1422 msg_Dbg( p_demux, "discarding 0 sized packet" );
1423 block_Release( p_block );
1424 return;
1426 /* We remove the header from the packet */
1427 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1428 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1430 if( i_header_len >= p_oggpacket->bytes )
1432 msg_Dbg( p_demux, "discarding invalid packet" );
1433 block_Release( p_block );
1434 return;
1437 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1439 /* But with subtitles we need to retrieve the duration first */
1440 int i, lenbytes = 0;
1442 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1444 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1446 lenbytes = lenbytes << 8;
1447 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1450 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1451 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1452 p_oggpacket->packet[i_header_len + 1] != 0 &&
1453 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1454 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1456 p_block->i_length = (vlc_tick_t)lenbytes * 1000;
1460 i_header_len++;
1461 if( p_block->i_buffer >= (unsigned int)i_header_len )
1462 p_block->i_buffer -= i_header_len;
1463 else
1464 p_block->i_buffer = 0;
1467 if( b_header )
1468 p_block->i_flags |= BLOCK_FLAG_HEADER;
1470 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1471 p_oggpacket->bytes - i_header_len );
1473 Ogg_QueueBlocks( p_demux, p_stream, p_block );
1476 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1478 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1481 /****************************************************************************
1482 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1483 * stream and fill p_ogg.
1484 *****************************************************************************
1485 * The initial page of a logical stream is marked as a 'bos' page.
1486 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1487 * together and all of the initial pages must appear before any data pages.
1489 * On success this function returns VLC_SUCCESS.
1490 ****************************************************************************/
1491 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1493 demux_sys_t *p_ogg = p_demux->p_sys;
1494 ogg_packet oggpacket;
1496 p_ogg->i_total_length = stream_Size ( p_demux->s );
1497 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1500 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1503 if( ogg_page_bos( &p_ogg->current_page ) )
1506 /* All is wonderful in our fine fine little world.
1507 * We found the beginning of our first logical stream. */
1508 while( ogg_page_bos( &p_ogg->current_page ) )
1510 logical_stream_t *p_stream = malloc( sizeof(logical_stream_t) );
1511 if( unlikely( !p_stream ) )
1512 return VLC_ENOMEM;
1514 Ogg_LogicalStreamInit( p_stream );
1516 /* Setup the logical stream */
1517 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1518 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1520 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1522 /* Extract the initial header from the first page and verify
1523 * the codec type of this Ogg bitstream */
1524 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1526 /* error. stream version mismatch perhaps */
1527 msg_Err( p_demux, "error reading first page of "
1528 "Ogg bitstream data" );
1529 return VLC_EGENERIC;
1532 /* FIXME: check return value */
1533 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1535 /* Check for Vorbis header */
1536 if( oggpacket.bytes >= 7 &&
1537 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1539 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1540 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1541 msg_Dbg( p_demux, "found vorbis header" );
1542 else
1544 msg_Dbg( p_demux, "found invalid vorbis header" );
1545 Ogg_LogicalStreamDelete( p_demux, p_stream );
1546 p_stream = NULL;
1547 p_ogg->i_streams--;
1550 /* Check for Speex header */
1551 else if( oggpacket.bytes >= 5 &&
1552 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1554 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1555 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1556 msg_Dbg( p_demux, "found speex header, channels: %i, "
1557 "rate: %"PRIu32"/%"PRIu32", bitrate: %i, frames: %i group %i",
1558 p_stream->fmt.audio.i_channels,
1559 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1560 p_stream->fmt.i_bitrate,
1561 p_stream->special.speex.i_framesize,
1562 p_stream->special.speex.i_framesperpacket );
1563 else
1565 msg_Dbg( p_demux, "found invalid Speex header" );
1566 Ogg_LogicalStreamDelete( p_demux, p_stream );
1567 p_stream = NULL;
1568 p_ogg->i_streams--;
1571 /* Check for Opus header */
1572 else if( oggpacket.bytes >= 8 &&
1573 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1575 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1576 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1577 msg_Dbg( p_demux, "found opus header, channels: %i, "
1578 "pre-skip: %i",
1579 p_stream->fmt.audio.i_channels,
1580 (int)p_stream->i_pre_skip);
1581 p_stream->i_skip_frames = p_stream->i_pre_skip;
1583 /* Check for OLD Flac header */
1584 else if( oggpacket.bytes >= 4 &&
1585 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1587 msg_Dbg( p_demux, "found FLAC header" );
1589 /* Grrrr!!!! Did they really have to put all the
1590 * important info in the second header packet!!!
1591 * (STREAMINFO metadata is in the following packet) */
1592 p_stream->b_force_backup = true;
1593 p_stream->i_extra_headers_packets = 1;
1594 p_stream->special.flac.b_old = true;
1595 date_Init( &p_stream->dts, 48000, 1 ); /* better be safe since that's delayed */
1596 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1598 /* Check for Flac header (>= version 1.0.0) */
1599 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1600 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1601 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1603 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1604 oggpacket.packet[8];
1605 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1606 "(%i header packets)",
1607 oggpacket.packet[5], oggpacket.packet[6],
1608 i_packets );
1609 /* STREAMINFO is in current packet, and then
1610 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1611 p_stream->b_force_backup = true;
1612 p_stream->i_extra_headers_packets = i_packets;
1613 p_stream->special.flac.b_old = false;
1615 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1616 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1617 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1619 msg_Dbg( p_demux, "found invalid Flac header" );
1620 Ogg_LogicalStreamDelete( p_demux, p_stream );
1621 p_stream = NULL;
1622 p_ogg->i_streams--;
1624 p_stream->fmt.b_packetized = false;
1626 /* Check for Theora header */
1627 else if( oggpacket.bytes >= 7 &&
1628 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1630 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1631 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1632 msg_Dbg( p_demux,
1633 "found theora header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1634 p_stream->fmt.i_bitrate,
1635 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1636 else
1638 msg_Dbg( p_demux, "found invalid Theora header" );
1639 Ogg_LogicalStreamDelete( p_demux, p_stream );
1640 p_stream = NULL;
1641 p_ogg->i_streams--;
1644 /* Check for Daala header */
1645 else if( oggpacket.bytes >= 6 &&
1646 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1648 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1649 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1650 msg_Dbg( p_demux,
1651 "found daala header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1652 p_stream->fmt.i_bitrate,
1653 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1654 else
1656 msg_Dbg( p_demux, "found invalid Daala header" );
1657 Ogg_LogicalStreamDelete( p_demux, p_stream );
1658 p_stream = NULL;
1659 p_ogg->i_streams--;
1662 /* Check for Dirac header */
1663 else if( ( oggpacket.bytes >= 5 &&
1664 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1665 ( oggpacket.bytes >= 9 &&
1666 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1668 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1669 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1670 msg_Dbg( p_demux, "found dirac header" );
1671 else
1673 msg_Warn( p_demux, "found dirac header isn't decodable" );
1674 Ogg_LogicalStreamDelete( p_demux, p_stream );
1675 p_stream = NULL;
1676 p_ogg->i_streams--;
1679 /* Check for VP8 header */
1680 else if( oggpacket.bytes >= 26 &&
1681 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1683 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1684 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1685 msg_Dbg( p_demux, "found VP8 header "
1686 "fps: %"PRIu32"/%"PRIu32", width:%i; height:%i",
1687 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1688 p_stream->fmt.video.i_width,
1689 p_stream->fmt.video.i_height );
1690 else
1692 msg_Dbg( p_demux, "invalid VP8 header found");
1693 Ogg_LogicalStreamDelete( p_demux, p_stream );
1694 p_stream = NULL;
1695 p_ogg->i_streams--;
1698 /* Check for Annodex header */
1699 else if( oggpacket.bytes >= 7 &&
1700 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1702 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1703 /* kill annodex track */
1704 FREENULL( p_stream );
1705 p_ogg->i_streams--;
1707 /* Check for Annodex header */
1708 else if( oggpacket.bytes >= 7 &&
1709 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1711 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1713 /* Check for Kate header */
1714 else if( oggpacket.bytes >= 8 &&
1715 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1717 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1718 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1719 msg_Dbg( p_demux, "found kate header" );
1720 else
1722 msg_Dbg( p_demux, "invalid kate header found");
1723 Ogg_LogicalStreamDelete( p_demux, p_stream );
1724 p_stream = NULL;
1725 p_ogg->i_streams--;
1728 /* Check for OggDS */
1729 else if( oggpacket.bytes >= 142 &&
1730 !memcmp( &oggpacket.packet[1],
1731 "Direct Show Samples embedded in Ogg", 35 ))
1733 /* Old header type */
1734 p_stream->b_oggds = true;
1735 p_stream->b_contiguous = false;
1736 /* Check for video header (old format) */
1737 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1738 oggpacket.bytes >= 184 )
1740 es_format_Change( &p_stream->fmt, VIDEO_ES,
1741 VLC_FOURCC( oggpacket.packet[68],
1742 oggpacket.packet[69],
1743 oggpacket.packet[70],
1744 oggpacket.packet[71] ) );
1745 msg_Dbg( p_demux, "found video header of type: %.4s",
1746 (char *)&p_stream->fmt.i_codec );
1748 unsigned num = OGGDS_RESOLUTION;
1749 unsigned den = GetQWLE(oggpacket.packet+164);
1750 vlc_ureduce( &num, &den, num, den > 0 ? den : 1, OGGDS_RESOLUTION );
1751 p_stream->fmt.video.i_frame_rate = num;
1752 p_stream->fmt.video.i_frame_rate_base = den;
1753 date_Init( &p_stream->dts, num, den );
1754 p_stream->fmt.video.i_bits_per_pixel =
1755 GetWLE((oggpacket.packet+182));
1756 if( !p_stream->fmt.video.i_bits_per_pixel )
1757 /* hack, FIXME */
1758 p_stream->fmt.video.i_bits_per_pixel = 24;
1759 p_stream->fmt.video.i_width =
1760 GetDWLE((oggpacket.packet+176));
1761 p_stream->fmt.video.i_height =
1762 GetDWLE((oggpacket.packet+180));
1763 p_stream->fmt.video.i_visible_width =
1764 p_stream->fmt.video.i_width;
1765 p_stream->fmt.video.i_visible_height =
1766 p_stream->fmt.video.i_height;
1768 msg_Dbg( p_demux,
1769 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1770 p_stream->fmt.video.i_frame_rate,
1771 p_stream->fmt.video.i_frame_rate_base,
1772 p_stream->fmt.video.i_width,
1773 p_stream->fmt.video.i_height,
1774 p_stream->fmt.video.i_bits_per_pixel);
1776 if ( !p_stream->fmt.video.i_frame_rate ||
1777 !p_stream->fmt.video.i_frame_rate_base )
1779 Ogg_LogicalStreamDelete( p_demux, p_stream );
1780 p_stream = NULL;
1781 p_ogg->i_streams--;
1784 /* Check for audio header (old format) */
1785 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1787 int i_extra_size;
1788 unsigned int i_format_tag;
1790 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1792 i_extra_size = GetWLE((oggpacket.packet+140));
1793 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1795 p_stream->fmt.i_extra = i_extra_size;
1796 p_stream->fmt.p_extra = malloc( i_extra_size );
1797 if( p_stream->fmt.p_extra )
1798 memcpy( p_stream->fmt.p_extra,
1799 oggpacket.packet + 142, i_extra_size );
1800 else
1801 p_stream->fmt.i_extra = 0;
1804 i_format_tag = GetWLE((oggpacket.packet+124));
1805 p_stream->fmt.audio.i_channels =
1806 GetWLE((oggpacket.packet+126));
1807 fill_channels_info(&p_stream->fmt.audio);
1808 p_stream->fmt.audio.i_rate =
1809 GetDWLE((oggpacket.packet+128));
1810 p_stream->fmt.i_bitrate =
1811 GetDWLE((oggpacket.packet+132)) * 8;
1812 p_stream->fmt.audio.i_blockalign =
1813 GetWLE((oggpacket.packet+136));
1814 p_stream->fmt.audio.i_bitspersample =
1815 GetWLE((oggpacket.packet+138));
1817 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
1819 wf_tag_to_fourcc( i_format_tag,
1820 &p_stream->fmt.i_codec, 0 );
1822 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1824 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1825 ( i_format_tag >> 8 ) & 0xff,
1826 i_format_tag & 0xff );
1829 msg_Dbg( p_demux, "found audio header of type: %.4s",
1830 (char *)&p_stream->fmt.i_codec );
1831 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1832 "%dbits/sample %dkb/s",
1833 i_format_tag,
1834 p_stream->fmt.audio.i_channels,
1835 p_stream->fmt.audio.i_rate,
1836 p_stream->fmt.audio.i_bitspersample,
1837 p_stream->fmt.i_bitrate / 1024 );
1839 if ( p_stream->fmt.audio.i_rate == 0 )
1841 msg_Dbg( p_demux, "invalid oggds audio header" );
1842 Ogg_LogicalStreamDelete( p_demux, p_stream );
1843 p_stream = NULL;
1844 p_ogg->i_streams--;
1847 else
1849 msg_Dbg( p_demux, "stream %d has an old header "
1850 "but is of an unknown type", p_ogg->i_streams-1 );
1851 FREENULL( p_stream );
1852 p_ogg->i_streams--;
1855 /* Check for OggDS */
1856 else if( oggpacket.bytes >= 44+1 &&
1857 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1859 stream_header_t tmp;
1860 stream_header_t *st = &tmp;
1862 p_stream->b_oggds = true;
1863 p_stream->b_contiguous = false;
1865 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1866 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1867 st->size = GetDWLE( &oggpacket.packet[1+12] );
1868 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1869 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1870 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1871 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1872 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1874 /* Check for video header (new format) */
1875 if( !strncmp( st->streamtype, "video", 5 ) &&
1876 oggpacket.bytes >= 52+1 )
1878 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1879 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1881 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1883 /* We need to get rid of the header packet */
1884 ogg_stream_packetout( &p_stream->os, &oggpacket );
1886 p_stream->fmt.i_codec =
1887 VLC_FOURCC( st->subtype[0], st->subtype[1],
1888 st->subtype[2], st->subtype[3] );
1889 msg_Dbg( p_demux, "found video header of type: %.4s",
1890 (char *)&p_stream->fmt.i_codec );
1892 /* FIXME: no clue where it's from */
1893 if( st->time_unit <= 0 )
1894 st->time_unit = 400000;
1895 unsigned num, den;
1896 vlc_ureduce( &num, &den,
1897 st->samples_per_unit * OGGDS_RESOLUTION,
1898 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1899 OGGDS_RESOLUTION );
1900 date_Init( &p_stream->dts, num, den );
1901 p_stream->fmt.video.i_frame_rate = num;
1902 p_stream->fmt.video.i_frame_rate_base = den;
1903 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1904 p_stream->fmt.video.i_width = st->sh.video.width;
1905 p_stream->fmt.video.i_height = st->sh.video.height;
1906 p_stream->fmt.video.i_visible_width =
1907 p_stream->fmt.video.i_width;
1908 p_stream->fmt.video.i_visible_height =
1909 p_stream->fmt.video.i_height;
1911 msg_Dbg( p_demux,
1912 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1913 p_stream->fmt.video.i_frame_rate,
1914 p_stream->fmt.video.i_frame_rate_base,
1915 p_stream->fmt.video.i_width,
1916 p_stream->fmt.video.i_height,
1917 p_stream->fmt.video.i_bits_per_pixel );
1919 /* Check for audio header (new format) */
1920 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1921 oggpacket.bytes >= 56+1 )
1923 char p_buffer[5];
1924 int i_extra_size;
1925 int i_format_tag;
1927 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1928 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1929 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1931 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1933 /* We need to get rid of the header packet */
1934 ogg_stream_packetout( &p_stream->os, &oggpacket );
1936 i_extra_size = st->size - 56;
1938 if( i_extra_size > 0 &&
1939 i_extra_size < oggpacket.bytes - 1 - 56 )
1941 p_stream->fmt.i_extra = i_extra_size;
1942 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1943 if( p_stream->fmt.p_extra )
1944 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1945 p_stream->fmt.i_extra );
1946 else
1947 p_stream->fmt.i_extra = 0;
1950 memcpy( p_buffer, st->subtype, 4 );
1951 p_buffer[4] = '\0';
1952 i_format_tag = strtol(p_buffer,NULL,16);
1953 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1954 fill_channels_info(&p_stream->fmt.audio);
1956 unsigned num,den;
1957 vlc_ureduce( &num, &den,
1958 st->samples_per_unit * OGGDS_RESOLUTION,
1959 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1960 OGGDS_RESOLUTION );
1961 date_Init( &p_stream->dts, num, den );
1962 p_stream->fmt.audio.i_rate = num / den;
1963 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1964 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1965 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1967 wf_tag_to_fourcc( i_format_tag,
1968 &p_stream->fmt.i_codec, 0 );
1970 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1972 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1973 ( i_format_tag >> 8 ) & 0xff,
1974 i_format_tag & 0xff );
1977 msg_Dbg( p_demux, "found audio header of type: %.4s",
1978 (char *)&p_stream->fmt.i_codec );
1979 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1980 "%dbits/sample %dkb/s",
1981 i_format_tag,
1982 p_stream->fmt.audio.i_channels,
1983 p_stream->fmt.audio.i_rate,
1984 p_stream->fmt.audio.i_bitspersample,
1985 p_stream->fmt.i_bitrate / 1024 );
1986 if ( p_stream->fmt.audio.i_rate == 0 )
1988 msg_Dbg( p_demux, "invalid oggds audio header" );
1989 Ogg_LogicalStreamDelete( p_demux, p_stream );
1990 p_stream = NULL;
1991 p_ogg->i_streams--;
1994 /* Check for text (subtitles) header */
1995 else if( !strncmp(st->streamtype, "text", 4) )
1997 /* We need to get rid of the header packet */
1998 ogg_stream_packetout( &p_stream->os, &oggpacket );
2000 msg_Dbg( p_demux, "found text subtitle header" );
2001 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2002 date_Init( &p_stream->dts, 1000, 1 ); /* granulepos is in millisec */
2004 else
2006 msg_Dbg( p_demux, "stream %d has a header marker "
2007 "but is of an unknown type", p_ogg->i_streams-1 );
2008 FREENULL( p_stream );
2009 p_ogg->i_streams--;
2012 else if( oggpacket.bytes >= 8 &&
2013 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2016 /* Skeleton */
2017 msg_Dbg( p_demux, "stream %d is a skeleton",
2018 p_ogg->i_streams-1 );
2019 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2021 /* Check for OggSpots header */
2022 else if( oggpacket.bytes >= 8 &&
2023 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2025 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2026 msg_Dbg( p_demux,
2027 "found OggSpots header, time resolution: %u/%u",
2028 p_stream->fmt.video.i_frame_rate,
2029 p_stream->fmt.video.i_frame_rate_base );
2030 else
2032 msg_Err( p_demux, "found invalid OggSpots header" );
2033 Ogg_LogicalStreamDelete( p_demux, p_stream );
2034 p_stream = NULL;
2035 p_ogg->i_streams--;
2038 else
2040 Ogg_LogicalStreamDelete( p_demux, p_stream );
2041 p_stream = NULL;
2042 p_ogg->i_streams--;
2043 msg_Dbg( p_demux, "stream %d is of unknown type",
2044 p_ogg->i_streams );
2047 /* we'll need to get all headers */
2048 if ( p_stream )
2049 p_stream->b_initializing &= p_stream->b_force_backup;
2051 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2052 return VLC_EGENERIC;
2055 /* This is the first data page, which means we are now finished
2056 * with the initial pages. We just need to store it in the relevant
2057 * bitstream. */
2058 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2060 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2061 &p_ogg->current_page ) == 0 )
2063 p_ogg->b_page_waiting = true;
2064 break;
2068 return VLC_SUCCESS;
2072 return VLC_EGENERIC;
2075 /****************************************************************************
2076 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2077 ****************************************************************************/
2078 static void Ogg_CreateES( demux_t *p_demux )
2080 demux_sys_t *p_ogg = p_demux->p_sys;
2081 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2082 int i_stream;
2084 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2086 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2088 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2090 /* Better be safe than sorry when possible with ogm */
2091 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2092 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2093 p_stream->fmt.b_packetized = false;
2095 /* Try first to reuse an old ES */
2096 if( p_old_stream &&
2097 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2098 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec &&
2099 p_old_stream->p_es != NULL && p_stream->p_es != NULL )
2101 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2103 p_stream->p_es = p_old_stream->p_es;
2104 p_stream->b_finished = false;
2105 p_stream->b_reinit = false;
2106 p_stream->b_initializing = false;
2107 p_stream->i_pre_skip = 0;
2108 es_format_Clean( &p_stream->fmt_old );
2109 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2110 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2112 p_old_stream->p_es = NULL;
2113 p_old_stream = NULL;
2114 if ( b_resetdecoder )
2116 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2117 p_stream->p_es, &p_stream->fmt );
2120 else
2122 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2127 if( p_ogg->p_old_stream )
2129 if( p_ogg->p_old_stream->p_es )
2130 msg_Dbg( p_demux, "old stream not reused" );
2131 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2132 p_ogg->p_old_stream = NULL;
2134 p_ogg->b_es_created = true;
2137 /****************************************************************************
2138 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2139 * Elementary streams.
2140 ****************************************************************************/
2141 static int Ogg_BeginningOfStream( demux_t *p_demux )
2143 demux_sys_t *p_ogg = p_demux->p_sys ;
2144 int i_stream;
2146 /* Find the logical streams embedded in the physical stream and
2147 * initialize our p_ogg structure. */
2148 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2150 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2151 return VLC_EGENERIC;
2154 p_ogg->i_bitrate = 0;
2156 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2158 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2160 p_stream->p_es = NULL;
2162 /* initialise kframe index */
2163 p_stream->idx=NULL;
2165 if ( p_stream->fmt.i_bitrate == 0 &&
2166 ( p_stream->fmt.i_cat == VIDEO_ES ||
2167 p_stream->fmt.i_cat == AUDIO_ES ) )
2168 p_ogg->b_partial_bitrate = true;
2169 else
2170 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2172 p_stream->i_pcr = VLC_TICK_INVALID;
2173 p_stream->b_reinit = false;
2176 /* get total frame count for video stream; we will need this for seeking */
2177 p_ogg->i_total_frames = 0;
2179 return VLC_SUCCESS;
2182 /****************************************************************************
2183 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2184 ****************************************************************************/
2185 static void Ogg_EndOfStream( demux_t *p_demux )
2187 demux_sys_t *p_ogg = p_demux->p_sys ;
2188 int i_stream;
2190 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2191 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2192 free( p_ogg->pp_stream );
2194 /* Reinit p_ogg */
2195 p_ogg->i_bitrate = 0;
2196 p_ogg->i_streams = 0;
2197 p_ogg->pp_stream = NULL;
2198 p_ogg->skeleton.major = 0;
2199 p_ogg->skeleton.minor = 0;
2200 p_ogg->b_preparsing_done = false;
2201 p_ogg->b_es_created = false;
2203 /* */
2204 if( p_ogg->p_meta )
2205 vlc_meta_Delete( p_ogg->p_meta );
2206 p_ogg->p_meta = NULL;
2208 for(int i=0; i<p_ogg->i_attachments; i++)
2209 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2210 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2212 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2214 if ( p_ogg->pp_seekpoints[i] )
2215 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2217 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2220 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2222 #ifdef HAVE_LIBVORBIS
2223 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2225 if( p_stream->special.vorbis.p_info )
2226 vorbis_info_clear( p_stream->special.vorbis.p_info );
2227 FREENULL( p_stream->special.vorbis.p_info );
2228 if( p_stream->special.vorbis.p_comment )
2229 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2230 FREENULL( p_stream->special.vorbis.p_comment );
2231 p_stream->special.vorbis.i_headers_flags = 0;
2233 #else
2234 VLC_UNUSED( p_stream );
2235 #endif
2238 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream )
2240 memset( p_stream, 0, sizeof(logical_stream_t) );
2241 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
2242 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
2243 p_stream->i_pcr = VLC_TICK_INVALID;
2244 date_Set( &p_stream->dts, VLC_TICK_INVALID );
2245 p_stream->b_initializing = true;
2246 p_stream->b_contiguous = true; /* default */
2247 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
2251 * This function delete and release all data associated to a logical_stream_t
2253 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2255 demux_sys_t *p_sys = p_demux->p_sys;
2257 if( p_stream->p_es )
2258 es_out_Del( p_demux->out, p_stream->p_es );
2260 ogg_stream_clear( &p_stream->os );
2261 free( p_stream->p_headers );
2263 Ogg_CleanSpecificData( p_stream );
2265 es_format_Clean( &p_stream->fmt_old );
2266 es_format_Clean( &p_stream->fmt );
2268 if ( p_stream->idx != NULL)
2270 oggseek_index_entries_free( p_stream->idx );
2273 Ogg_FreeSkeleton( p_stream->p_skel );
2274 p_stream->p_skel = NULL;
2275 if( p_sys->p_skelstream == p_stream )
2276 p_sys->p_skelstream = NULL;
2278 /* Shouldn't happen */
2279 block_ChainRelease( p_stream->queue.p_blocks );
2281 free( p_stream );
2284 * This function check if a we need to reset a decoder in case we are
2285 * reusing an old ES
2287 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2289 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2290 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2291 unsigned i_new_count;
2292 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2293 i_new_count = 0;
2295 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2296 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2297 unsigned i_old_count;
2298 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2299 i_old_count = 0;
2301 bool b_match = i_new_count == i_old_count;
2302 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2304 /* Ignore vorbis comment */
2305 if( i == 1 )
2306 continue;
2307 if( pi_new_size[i] != pi_old_size[i] ||
2308 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2309 b_match = false;
2312 return b_match;
2315 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2316 const es_format_t *p_old )
2318 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2319 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2320 unsigned i_new_count;
2321 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2322 i_new_count = 0;
2323 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2324 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2325 unsigned i_old_count;
2326 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2327 i_old_count = 0;
2328 bool b_match = false;
2329 if( i_new_count == i_old_count && i_new_count > 0 )
2331 static const unsigned char default_map[2] = { 0, 1 };
2332 unsigned char *p_old_head;
2333 unsigned char *p_new_head;
2334 const unsigned char *p_old_map;
2335 const unsigned char *p_new_map;
2336 int i_old_channel_count;
2337 int i_new_channel_count;
2338 int i_old_stream_count;
2339 int i_new_stream_count;
2340 int i_old_coupled_count;
2341 int i_new_coupled_count;
2342 p_old_head = (unsigned char *)pp_old_data[0];
2343 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2344 p_old_map = default_map;
2345 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2347 i_old_channel_count = p_old_head[9];
2348 switch( p_old_head[18] )
2350 case 0:
2351 i_old_stream_count = 1;
2352 i_old_coupled_count = i_old_channel_count - 1;
2353 break;
2354 case 1:
2355 if( pi_old_size[0] >= 21U + i_old_channel_count )
2357 i_old_stream_count = p_old_head[19];
2358 i_old_coupled_count = p_old_head[20];
2359 p_old_map = p_old_head + 21;
2361 break;
2364 p_new_head = (unsigned char *)pp_new_data[0];
2365 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2366 p_new_map = default_map;
2367 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2369 i_new_channel_count = p_new_head[9];
2370 switch( p_new_head[18] )
2372 case 0:
2373 i_new_stream_count = 1;
2374 i_new_coupled_count = i_new_channel_count - 1;
2375 break;
2376 case 1:
2377 if( pi_new_size[0] >= 21U + i_new_channel_count )
2379 i_new_stream_count = p_new_head[19];
2380 i_new_coupled_count = p_new_head[20];
2381 p_new_map = p_new_head+21;
2383 break;
2386 b_match = i_old_channel_count == i_new_channel_count &&
2387 i_old_stream_count == i_new_stream_count &&
2388 i_old_coupled_count == i_new_coupled_count &&
2389 memcmp(p_old_map, p_new_map,
2390 i_new_channel_count*sizeof(*p_new_map)) == 0;
2393 return b_match;
2396 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2398 bool b_compatible = false;
2399 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2400 return true;
2402 /* Only Vorbis and Opus are supported. */
2403 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2404 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2405 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2406 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2407 else if( p_stream->fmt.i_codec == VLC_CODEC_FLAC )
2408 b_compatible = !p_stream->fmt.b_packetized;
2410 if( !b_compatible )
2411 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2413 return !b_compatible;
2416 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2417 const void *p_headers, unsigned i_headers )
2419 demux_sys_t *p_ogg = p_demux->p_sys;
2420 int i_cover_score = 0;
2421 int i_cover_idx = 0;
2422 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2423 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2424 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2426 pf_replay_gain[i] = 0;
2427 pf_replay_peak[i] = 0;
2429 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2430 &p_ogg->i_attachments, &p_ogg->attachments,
2431 &i_cover_score, &i_cover_idx,
2432 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2433 &pf_replay_gain, &pf_replay_peak );
2434 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2436 char psz_url[128];
2437 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2438 p_ogg->attachments[i_cover_idx]->psz_name );
2439 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2442 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2444 if ( pf_replay_gain[i] != 0 )
2446 p_fmt->audio_replay_gain.pb_gain[i] = true;
2447 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2448 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2450 if ( pf_replay_peak[i] != 0 )
2452 p_fmt->audio_replay_gain.pb_peak[i] = true;
2453 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2454 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2458 if( p_ogg->i_seekpoints > 1 )
2460 p_ogg->updates |= INPUT_UPDATE_TITLE_LIST;
2464 static inline uint32_t GetDW24BE( const uint8_t *p )
2466 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2467 #ifdef WORDS_BIGENDIAN
2468 i = vlc_bswap32(i);
2469 #endif
2470 return i;
2473 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2474 const uint8_t *p_headers, unsigned i_headers )
2476 /* Skip Streaminfo 42 bytes / 1st page */
2477 if(i_headers <= 46)
2478 return;
2479 p_headers += 42; i_headers -= 42;
2480 /* Block Header 1 + 3 bytes */
2481 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2482 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2484 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2488 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2489 const void *p_headers, unsigned i_headers, unsigned i_skip )
2491 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2492 void *pp_data[XIPH_MAX_HEADER_COUNT];
2493 unsigned i_count;
2495 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2496 return;
2497 /* TODO how to handle multiple comments properly ? */
2498 if( i_count >= 2 && pi_size[1] > i_skip )
2500 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2504 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2506 demux_sys_t *p_ogg = p_demux->p_sys;
2508 switch( p_fmt->i_codec )
2510 /* 3 headers with the 2° one being the comments */
2511 case VLC_CODEC_VORBIS:
2512 case VLC_CODEC_THEORA:
2513 case VLC_CODEC_DAALA:
2514 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2515 break;
2516 case VLC_CODEC_OPUS:
2517 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2518 break;
2519 case VLC_CODEC_SPEEX:
2520 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2521 break;
2522 case VLC_CODEC_VP8:
2523 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2524 break;
2525 /* N headers with the 2° one being the comments */
2526 case VLC_CODEC_KATE:
2527 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2528 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2529 break;
2531 /* TODO */
2532 case VLC_CODEC_FLAC:
2533 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2534 break;
2536 /* No meta data */
2537 case VLC_CODEC_DIRAC:
2538 default:
2539 break;
2541 if( p_ogg->p_meta )
2542 p_ogg->updates |= INPUT_UPDATE_META;
2545 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2546 ogg_packet *p_oggpacket )
2548 bs_t bitstream;
2549 unsigned int i_fps_numerator;
2550 unsigned int i_fps_denominator;
2551 int i_keyframe_frequency_force;
2552 int i_major;
2553 int i_minor;
2554 int i_subminor;
2555 int i_version;
2557 /* Signal that we want to keep a backup of the theora
2558 * stream headers. They will be used when switching between
2559 * audio streams. */
2560 p_stream->b_force_backup = true;
2562 /* Cheat and get additionnal info ;) */
2563 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2564 bs_skip( &bitstream, 56 );
2566 i_major = bs_read( &bitstream, 8 ); /* major version num */
2567 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2568 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2570 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2571 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2572 bs_read( &bitstream, 24 ); /* frame width */
2573 bs_read( &bitstream, 24 ); /* frame height */
2574 bs_read( &bitstream, 8 ); /* x offset */
2575 bs_read( &bitstream, 8 ); /* y offset */
2577 i_fps_numerator = bs_read( &bitstream, 32 );
2578 i_fps_denominator = bs_read( &bitstream, 32 );
2579 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2580 bs_read( &bitstream, 24 ); /* aspect_numerator */
2581 bs_read( &bitstream, 24 ); /* aspect_denominator */
2583 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2584 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2586 bs_read( &bitstream, 8 ); /* colorspace */
2587 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2588 bs_read( &bitstream, 6 ); /* quality */
2590 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2592 /* granule_shift = i_log( frequency_force -1 ) */
2593 p_stream->i_granule_shift = 0;
2594 i_keyframe_frequency_force--;
2595 while( i_keyframe_frequency_force )
2597 p_stream->i_granule_shift++;
2598 i_keyframe_frequency_force >>= 1;
2601 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2602 p_stream->i_keyframe_offset = 0;
2603 if ( !i_fps_denominator || !i_fps_numerator )
2604 return false;
2605 date_Init( &p_stream->dts, i_fps_numerator, i_fps_denominator );
2607 if ( i_version >= 3002001 )
2609 p_stream->i_keyframe_offset = 1;
2611 return true;
2614 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2615 ogg_packet *p_oggpacket )
2617 oggpack_buffer opb;
2618 uint32_t i_timebase_numerator;
2619 uint32_t i_timebase_denominator;
2620 int i_keyframe_frequency_force;
2621 uint8_t i_major;
2622 uint8_t i_minor;
2623 uint8_t i_subminor;
2624 int i_version;
2626 /* Signal that we want to keep a backup of the daala
2627 * stream headers. They will be used when switching between
2628 * audio streams. */
2629 p_stream->b_force_backup = true;
2631 /* Cheat and get additionnal info ;) */
2632 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2633 oggpack_adv( &opb, 48 );
2635 i_major = oggpack_read( &opb, 8 ); /* major version num */
2636 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2637 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2639 oggpack_adv( &opb, 32 ); /* width */
2640 oggpack_adv( &opb, 32 ); /* height */
2642 oggpack_adv( &opb, 32 ); /* aspect numerator */
2643 oggpack_adv( &opb, 32 ); /* aspect denominator */
2644 i_timebase_numerator = oggpack_read( &opb, 32 );
2646 i_timebase_denominator = oggpack_read( &opb, 32 );
2647 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2649 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2650 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2652 oggpack_adv( &opb, 32 ); /* frame duration */
2654 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2656 /* granule_shift = i_log( frequency_force -1 ) */
2657 p_stream->i_granule_shift = 0;
2658 i_keyframe_frequency_force--;
2659 while( i_keyframe_frequency_force )
2661 p_stream->i_granule_shift++;
2662 i_keyframe_frequency_force >>= 1;
2665 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2666 VLC_UNUSED(i_version);
2667 p_stream->i_keyframe_offset = 0;
2668 if ( !i_timebase_numerator || !i_timebase_denominator )
2669 return false;
2670 date_Init( &p_stream->dts, i_timebase_numerator, i_timebase_denominator );
2672 return true;
2675 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2676 ogg_packet *p_oggpacket )
2678 oggpack_buffer opb;
2680 /* Signal that we want to keep a backup of the vorbis
2681 * stream headers. They will be used when switching between
2682 * audio streams. */
2683 p_stream->b_force_backup = true;
2685 /* Cheat and get additionnal info ;) */
2686 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2687 oggpack_adv( &opb, 88 );
2688 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2689 fill_channels_info(&p_stream->fmt.audio);
2690 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2691 if( p_stream->fmt.audio.i_rate == 0 )
2692 return false;
2693 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2695 oggpack_adv( &opb, 32 );
2696 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2697 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2698 return true;
2700 #ifdef HAVE_LIBVORBIS
2701 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2702 ogg_packet *p_oggpacket, int i_number )
2704 switch( i_number )
2706 case VORBIS_HEADER_IDENTIFICATION:
2707 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2708 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2709 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2711 FREENULL( p_stream->special.vorbis.p_info );
2712 FREENULL( p_stream->special.vorbis.p_comment );
2713 break;
2715 vorbis_info_init( p_stream->special.vorbis.p_info );
2716 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2717 /* fallthrough */
2719 case VORBIS_HEADER_COMMENT:
2720 case VORBIS_HEADER_SETUP:
2721 if ( !p_stream->special.vorbis.p_info ||
2722 vorbis_synthesis_headerin(
2723 p_stream->special.vorbis.p_info,
2724 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2725 break;
2727 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2728 /* fallthrough */
2730 default:
2731 break;
2734 #endif
2736 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2737 ogg_packet *p_oggpacket )
2739 oggpack_buffer opb;
2741 /* Signal that we want to keep a backup of the speex
2742 * stream headers. They will be used when switching between
2743 * audio streams. */
2744 p_stream->b_force_backup = true;
2746 /* Cheat and get additionnal info ;) */
2747 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2748 oggpack_adv( &opb, 224 );
2749 oggpack_adv( &opb, 32 ); /* speex_version_id */
2750 oggpack_adv( &opb, 32 ); /* header_size */
2751 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2752 if ( !p_stream->fmt.audio.i_rate )
2753 return false;
2754 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2755 oggpack_adv( &opb, 32 ); /* mode */
2756 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2757 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2758 fill_channels_info(&p_stream->fmt.audio);
2759 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2760 p_stream->special.speex.i_framesize =
2761 oggpack_read( &opb, 32 ); /* frame_size */
2762 oggpack_adv( &opb, 32 ); /* vbr */
2763 p_stream->special.speex.i_framesperpacket =
2764 oggpack_read( &opb, 32 ); /* frames_per_packet */
2765 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2766 return true;
2769 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2770 ogg_packet *p_oggpacket )
2772 oggpack_buffer opb;
2774 /* Signal that we want to keep a backup of the opus
2775 * stream headers. They will be used when switching between
2776 * audio streams. */
2777 p_stream->b_force_backup = true;
2779 /* All OggOpus streams are timestamped at 48kHz and
2780 * can be played at 48kHz. */
2781 p_stream->fmt.audio.i_rate = 48000;
2782 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2783 p_stream->fmt.i_bitrate = 0;
2785 /* Cheat and get additional info ;) */
2786 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2787 oggpack_adv( &opb, 64 );
2788 oggpack_adv( &opb, 8 ); /* version_id */
2789 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2790 fill_channels_info(&p_stream->fmt.audio);
2791 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2792 /* For Opus, trash the first 80 ms of decoded output as
2793 well, to avoid blowing out speakers if we get unlucky.
2794 Opus predicts content from prior frames, which can go
2795 badly if we seek right where the stream goes from very
2796 quiet to very loud. It will converge after a bit. */
2797 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2800 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2801 ogg_packet *p_oggpacket )
2803 /* Parse the STREAMINFO metadata */
2804 bs_t s;
2806 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2808 bs_read( &s, 1 );
2809 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2811 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2812 return false;
2815 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2817 bs_skip( &s, 80 );
2818 p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2819 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2820 fill_channels_info(&p_stream->fmt.audio);
2822 msg_Dbg( p_demux, "FLAC header, channels: %"PRIu8", rate: %u",
2823 p_stream->fmt.audio.i_channels, p_stream->fmt.audio.i_rate );
2824 if ( p_stream->fmt.audio.i_rate == 0 )
2825 return false;
2826 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2828 else
2830 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2833 /* Fake this as the last metadata block */
2834 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2835 return true;
2838 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2839 ogg_packet *p_oggpacket )
2841 oggpack_buffer opb;
2842 uint32_t gnum;
2843 uint32_t gden;
2844 int n;
2845 char *psz_desc;
2847 /* Signal that we want to keep a backup of the kate
2848 * stream headers. They will be used when switching between
2849 * kate streams. */
2850 p_stream->b_force_backup = true;
2852 /* Cheat and get additionnal info ;) */
2853 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2854 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2855 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2856 oggpack_adv( &opb, 3*8 );
2857 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2858 oggpack_adv( &opb, 8*8 ); /* reserved */
2859 gnum = oggpack_read( &opb, 32 );
2860 gden = oggpack_read( &opb, 32 );
2861 gden = __MAX( gden, 1 );
2862 if ( !gnum || !gden )
2863 return false;
2864 date_Init( &p_stream->dts, gnum, gden );
2866 p_stream->fmt.psz_language = malloc(16);
2867 if( p_stream->fmt.psz_language )
2869 for( n = 0; n < 16; n++ )
2870 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2871 p_stream->fmt.psz_language[15] = 0; /* just in case */
2873 else
2875 for( n = 0; n < 16; n++ )
2876 oggpack_read(&opb,8);
2878 p_stream->fmt.psz_description = malloc(16);
2879 if( p_stream->fmt.psz_description )
2881 for( n = 0; n < 16; n++ )
2882 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2883 p_stream->fmt.psz_description[15] = 0; /* just in case */
2885 /* Now find a localized user readable description for this category */
2886 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2887 if( psz_desc )
2889 free( p_stream->fmt.psz_description );
2890 p_stream->fmt.psz_description = psz_desc;
2893 else
2895 for( n = 0; n < 16; n++ )
2896 oggpack_read(&opb,8);
2899 return true;
2902 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2903 ogg_packet *p_oggpacket )
2905 switch( p_oggpacket->packet[5] )
2907 /* STREAMINFO */
2908 case 0x01:
2909 /* Mapping version */
2910 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2911 return false;
2912 p_stream->i_granule_shift = 32;
2913 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2914 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2915 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2916 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2917 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2918 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2919 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2920 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2921 if ( !p_stream->fmt.video.i_frame_rate || !p_stream->fmt.video.i_frame_rate_base )
2922 return false;
2923 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
2924 p_stream->fmt.video.i_frame_rate_base );
2925 return true;
2926 /* METADATA */
2927 case 0x02:
2928 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2929 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2930 return true;
2931 default:
2932 return false;
2936 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2937 bool *b_force_backup )
2939 if( p_stream->fmt.i_cat != UNKNOWN_ES )
2940 return;
2942 if( !strncmp(psz_value, "audio/x-wav", 11) )
2944 /* n.b. WAVs are unsupported right now */
2945 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2946 free( p_stream->fmt.psz_description );
2947 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2949 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2950 !strncmp(psz_value, "audio/vorbis", 12) )
2952 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
2954 *b_force_backup = true;
2956 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2957 !strncmp(psz_value, "audio/speex", 11) )
2959 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
2961 *b_force_backup = true;
2963 else if( !strncmp(psz_value, "audio/flac", 10) )
2965 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
2967 *b_force_backup = true;
2969 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2970 !strncmp(psz_value, "video/theora", 12) )
2972 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
2974 *b_force_backup = true;
2976 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2977 !strncmp(psz_value, "video/daala", 11) )
2979 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
2981 *b_force_backup = true;
2983 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2985 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
2987 *b_force_backup = true;
2989 else if( !strncmp(psz_value, "video/mpeg", 10) )
2991 /* n.b. MPEG streams are unsupported right now */
2992 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
2994 else if( !strncmp(psz_value, "application/kate", 16) )
2996 /* ??? */
2997 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2998 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3000 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3002 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3006 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3007 logical_stream_t *p_stream,
3008 ogg_packet *p_oggpacket )
3010 if( p_oggpacket->bytes >= 28 &&
3011 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3013 oggpack_buffer opb;
3015 uint16_t major_version;
3016 uint16_t minor_version;
3017 uint64_t timebase_numerator;
3018 uint64_t timebase_denominator;
3020 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3022 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3023 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3024 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3025 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3026 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3027 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3029 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3030 "Timebase %"PRId64" / %"PRId64,
3031 major_version, minor_version,
3032 timebase_numerator, timebase_denominator );
3034 else if( p_oggpacket->bytes >= 42 &&
3035 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3037 uint64_t granule_rate_numerator;
3038 uint64_t granule_rate_denominator;
3039 char content_type_string[1024];
3041 /* Read in Annodex header fields */
3043 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3044 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3045 p_stream->i_secondary_header_packets =
3046 GetDWLE( &p_oggpacket->packet[24] );
3048 /* we are guaranteed that the first header field will be
3049 * the content-type (by the Annodex standard) */
3050 content_type_string[0] = '\0';
3051 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3053 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3054 p_oggpacket->bytes - 1 );
3055 if( p && p[0] == '\r' && p[1] == '\n' )
3056 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3057 content_type_string );
3060 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3061 granule_rate_numerator, granule_rate_denominator,
3062 p_stream->i_secondary_header_packets, content_type_string );
3064 if( granule_rate_numerator && granule_rate_denominator )
3065 date_Init( &p_stream->dts, granule_rate_numerator, granule_rate_denominator );
3067 /* What type of file do we have?
3068 * strcmp is safe to use here because we've extracted
3069 * content_type_string from the stream manually */
3070 Ogg_ApplyContentType( p_stream, content_type_string,
3071 &p_stream->b_force_backup );
3075 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3076 ogg_packet *p_oggpacket )
3078 demux_sys_t *p_sys = p_demux->p_sys;
3080 p_sys->p_skelstream = p_stream;
3081 /* There can be only 1 skeleton for streams */
3082 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3083 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3084 if ( asprintf( & p_stream->fmt.psz_description,
3085 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3086 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3087 p_stream->fmt.psz_description = NULL;
3090 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3092 demux_sys_t *p_sys = p_demux->p_sys;
3094 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3096 /* Find the matching stream for this skeleton data */
3097 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3098 logical_stream_t *p_target_stream = NULL;
3099 for ( int i=0; i< p_sys->i_streams; i++ )
3101 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3103 p_target_stream = p_sys->pp_stream[i];
3104 break;
3107 if ( !p_target_stream ) return;
3109 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3110 if ( !p_skel )
3112 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3113 if ( !p_skel ) return;
3114 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3115 p_skel->p_index = NULL;
3116 p_target_stream->p_skel = p_skel;
3119 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3120 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3121 const unsigned char *p = p_messages;
3122 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3124 if ( *p == 0x0D && *(p+1) == 0x0A )
3126 char *psz_message = strndup( (const char *) p_messages,
3127 p - p_messages );
3128 if ( psz_message )
3130 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3131 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3133 if ( p < p_boundary - 1 ) p_messages = p + 2;
3135 p++;
3140 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3141 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3142 unsigned const char *p_end,
3143 uint64_t *pi_value )
3145 int i_shift = 0;
3146 int64_t i_read = 0;
3147 *pi_value = 0;
3149 while ( p_begin < p_end )
3151 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3152 *pi_value = *pi_value | ( i_read << i_shift );
3153 i_shift += 7;
3154 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3157 *pi_value = GetQWLE( pi_value );
3158 return p_begin;
3161 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3163 demux_sys_t *p_sys = p_demux->p_sys;
3165 if( p_sys->skeleton.major < 4
3166 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3167 ) return;
3169 /* Find the matching stream for this skeleton data */
3170 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3171 logical_stream_t *p_stream = NULL;
3172 for ( int i=0; i< p_sys->i_streams; i++ )
3174 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3176 p_stream = p_sys->pp_stream[i];
3177 break;
3180 if ( !p_stream || !p_stream->p_skel ) return;
3181 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3182 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3183 if ( !i_keypoints ) return;
3185 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3186 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3187 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3188 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3189 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3190 uint64_t i_offset = 0;
3191 uint64_t i_time = 0;
3192 uint64_t i_keypoints_found = 0;
3194 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3196 uint64_t i_val;
3197 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3198 i_offset += i_val;
3199 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3200 i_time += i_val * p_stream->p_skel->i_indexstampden;
3201 i_keypoints_found++;
3204 if ( i_keypoints_found != i_keypoints )
3206 msg_Warn( p_demux, "Invalid Index: missing entries" );
3207 return;
3210 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3211 if ( !p_stream->p_skel->p_index ) return;
3212 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3213 p_oggpacket->bytes - 42 );
3214 p_stream->p_skel->i_index = i_keypoints_found;
3215 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3218 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3220 if ( !p_skel ) return;
3221 for ( int i=0; i< p_skel->i_messages; i++ )
3222 free( p_skel->ppsz_messages[i] );
3223 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3224 free( p_skel->p_index );
3225 free( p_skel );
3228 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3230 if ( !p_stream->p_skel ) return;
3231 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3233 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3234 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3236 free( p_stream->fmt.psz_description );
3237 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3239 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3241 bool b_foo;
3242 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo );
3247 /* Return true if there's a skeleton exact match */
3248 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, vlc_tick_t i_time,
3249 int64_t *pi_lower, int64_t *pi_upper )
3251 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index ||
3252 i_time == VLC_TICK_INVALID )
3253 return false;
3255 i_time -= VLC_TICK_0;
3257 /* Validate range */
3258 if ( i_time < p_stream->p_skel->i_indexfirstnum
3259 * p_stream->p_skel->i_indexstampden ||
3260 i_time > p_stream->p_skel->i_indexlastnum
3261 * p_stream->p_skel->i_indexstampden ) return false;
3263 /* Then Lookup its index */
3264 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3265 struct
3267 int64_t i_pos;
3268 vlc_tick_t i_time;
3269 } current = { 0, 0 }, prev = { -1, -1 };
3271 uint64_t i_keypoints_found = 0;
3273 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3274 && i_keypoints_found < p_stream->p_skel->i_index )
3276 uint64_t i_val;
3277 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3278 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3279 current.i_pos += i_val;
3280 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3281 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3282 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3283 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3285 i_keypoints_found++;
3287 if ( i_time <= current.i_time )
3289 *pi_lower = prev.i_pos;
3290 *pi_upper = current.i_pos;
3291 return ( i_time == current.i_time );
3293 prev = current;
3295 return false;
3298 static uint32_t dirac_uint( bs_t *p_bs )
3300 uint32_t u_count = 0, u_value = 0;
3302 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3304 u_count++;
3305 u_value <<= 1;
3306 u_value |= bs_read( p_bs, 1 );
3309 return (1<<u_count) - 1 + u_value;
3312 static int dirac_bool( bs_t *p_bs )
3314 return bs_read( p_bs, 1 );
3317 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3318 ogg_packet *p_oggpacket )
3320 p_stream->special.dirac.b_old = (p_oggpacket->packet[0] == 'K');
3322 static const struct {
3323 uint32_t u_n /* numerator */, u_d /* denominator */;
3324 } p_dirac_frate_tbl[] = { /* table 10.3 */
3325 {1,1}, /* this first value is never used */
3326 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3327 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3329 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3331 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3332 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3334 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3336 bs_t bs;
3338 /* Backing up stream headers is not required -- seqhdrs are repeated
3339 * thoughout the stream at suitable decoding start points */
3340 p_stream->b_force_backup = false;
3342 /* read in useful bits from sequence header */
3343 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3344 bs_skip( &bs, 13*8); /* parse_info_header */
3345 dirac_uint( &bs ); /* major_version */
3346 dirac_uint( &bs ); /* minor_version */
3347 dirac_uint( &bs ); /* profile */
3348 dirac_uint( &bs ); /* level */
3350 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3351 if( u_video_format >= u_dirac_vidfmt_frate )
3353 /* don't know how to parse this ogg dirac stream */
3354 return false;
3357 if( dirac_bool( &bs ) )
3359 dirac_uint( &bs ); /* frame_width */
3360 dirac_uint( &bs ); /* frame_height */
3363 if( dirac_bool( &bs ) )
3365 dirac_uint( &bs ); /* chroma_format */
3368 if( dirac_bool( &bs ) )
3370 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3372 else
3373 p_stream->special.dirac.b_interlaced = false;
3375 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3376 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3377 u_d = __MAX( u_d, 1 );
3378 if( dirac_bool( &bs ) )
3380 uint32_t u_frame_rate_index = dirac_uint( &bs );
3381 if( u_frame_rate_index >= u_dirac_frate_tbl )
3383 /* something is wrong with this stream */
3384 return false;
3386 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3387 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3388 if( u_frame_rate_index == 0 )
3390 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3391 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3395 if( !u_n || !u_d )
3396 return false;
3399 * NB, OggDirac granulepos values are in units of 2*picturerate
3400 * When picture_coding_mode = 0 (progressive),
3401 * pt increments by two for each picture in display order.
3402 * When picture_coding_mode = 1 (interlace),
3403 * pt increments by one for each field in display order. */
3404 date_Init( &p_stream->dts, 2 * u_n, u_d );
3406 return true;
3409 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3410 ogg_packet *p_oggpacket )
3412 uint64_t i_granulerate_numerator;
3413 uint64_t i_granulerate_denominator;
3414 int i_major;
3415 int i_minor;
3417 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3419 /* Signal that we want to keep a backup of the OggSpots
3420 * stream headers. They will be used when switching between
3421 * audio streams. */
3422 p_stream->b_force_backup = true;
3424 /* Cheat and get additionnal info ;) */
3425 if ( p_oggpacket->bytes != 52 )
3427 /* The OggSpots header is always 52 bytes */
3428 return false;
3431 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3432 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3433 if ( i_major != 0 || i_minor != 1 )
3435 return false;
3438 /* Granule rate */
3439 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3440 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3441 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3443 return false;
3446 /* The OggSpots spec contained an error and there are implementations out
3447 * there that used the wrong value. So we detect that case and switch
3448 * numerator and denominator in that case */
3449 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3451 i_granulerate_numerator = 30;
3452 i_granulerate_denominator = 1;
3455 if ( !i_granulerate_numerator || !i_granulerate_denominator )
3456 return false;
3458 /* Normalize granulerate */
3459 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3460 &p_stream->fmt.video.i_frame_rate_base,
3461 i_granulerate_numerator, i_granulerate_denominator, 0);
3463 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
3464 p_stream->fmt.video.i_frame_rate_base );
3466 p_stream->i_granule_shift = p_oggpacket->packet[28];
3468 return true;