demux: ogg: only invalid pts on no granule interpolation
[vlc.git] / modules / demux / ogg.c
blob5ef358692bdebf2a69b60f196c58e0d2a1137be4
1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@netcourrier.com>
7 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #ifdef HAVE_LIBVORBIS
32 #include <vorbis/codec.h>
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_demux.h>
39 #include <vlc_meta.h>
40 #include <vlc_input.h>
42 #include <ogg/ogg.h>
44 #include <vlc_codecs.h>
45 #include <vlc_bits.h>
46 #include "xiph.h"
47 #include "xiph_metadata.h"
48 #include "ogg.h"
49 #include "oggseek.h"
50 #include "ogg_granule.h"
51 #include "opus.h"
53 /*****************************************************************************
54 * Module descriptor
55 *****************************************************************************/
56 static int Open ( vlc_object_t * );
57 static void Close( vlc_object_t * );
59 vlc_module_begin ()
60 set_shortname ( "OGG" )
61 set_description( N_("OGG demuxer" ) )
62 set_category( CAT_INPUT )
63 set_subcategory( SUBCAT_INPUT_DEMUX )
64 set_capability( "demux", 50 )
65 set_callbacks( Open, Close )
66 add_shortcut( "ogg" )
67 vlc_module_end ()
70 /*****************************************************************************
71 * Definitions of structures and functions used by this plugins
72 *****************************************************************************/
74 /* OggDS headers for the new header format (used in ogm files) */
75 typedef struct
77 ogg_int32_t width;
78 ogg_int32_t height;
79 } stream_header_video_t;
81 typedef struct
83 ogg_int16_t channels;
84 ogg_int16_t padding;
85 ogg_int16_t blockalign;
86 ogg_int32_t avgbytespersec;
87 } stream_header_audio_t;
89 typedef struct
91 char streamtype[8];
92 char subtype[4];
94 ogg_int32_t size; /* size of the structure */
96 ogg_int64_t time_unit; /* in reference time */
97 ogg_int64_t samples_per_unit;
98 ogg_int32_t default_len; /* in media time */
100 ogg_int32_t buffersize;
101 ogg_int16_t bits_per_sample;
102 ogg_int16_t padding;
104 union
106 /* Video specific */
107 stream_header_video_t video;
108 /* Audio specific */
109 stream_header_audio_t audio;
110 } sh;
111 } stream_header_t;
113 #define VORBIS_HEADER_IDENTIFICATION 1
114 #define VORBIS_HEADER_COMMENT 2
115 #define VORBIS_HEADER_SETUP 3
116 #define VORBIS_HEADER_TO_FLAG(i) (1 << (i - 1))
117 #define VORBIS_HEADERS_VALID(p_stream) \
118 ((p_stream->special.vorbis.i_headers_flags & 0x07) == 0x07) // 0b111
120 /*****************************************************************************
121 * Local prototypes
122 *****************************************************************************/
123 static int Demux ( demux_t * );
124 static int Control( demux_t *, int, va_list );
126 /* Bitstream manipulation */
127 static int Ogg_ReadPage ( demux_t *, ogg_page * );
128 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
129 static unsigned Ogg_OpusPacketDuration( ogg_packet * );
130 static void Ogg_QueueBlocks( demux_t *, logical_stream_t *, block_t * );
131 static void Ogg_SendQueuedBlock( demux_t *, logical_stream_t * );
133 static inline bool Ogg_HasQueuedBlocks( const logical_stream_t *p_stream )
135 return ( p_stream->queue.p_blocks != NULL );
138 static void Ogg_CreateES( demux_t *p_demux );
139 static int Ogg_BeginningOfStream( demux_t *p_demux );
140 static int Ogg_FindLogicalStreams( demux_t *p_demux );
141 static void Ogg_EndOfStream( demux_t *p_demux );
143 /* */
144 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream );
145 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream );
146 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
147 static void Ogg_ResetStream( logical_stream_t *p_stream );
149 /* */
150 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
152 /* Logical bitstream headers */
153 static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
154 static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
155 static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
156 static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
157 static void Ogg_ReadOpusHeader( logical_stream_t *, ogg_packet * );
158 static bool Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
159 static bool Ogg_ReadFlacStreamInfo( demux_t *, logical_stream_t *, ogg_packet * );
160 static void Ogg_ReadAnnodexHeader( demux_t *, logical_stream_t *, ogg_packet * );
161 static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
162 static bool Ogg_ReadVP8Header( demux_t *, logical_stream_t *, ogg_packet * );
163 static void Ogg_ReadSkeletonHeader( demux_t *, logical_stream_t *, ogg_packet * );
164 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *, ogg_packet * );
166 /* Skeleton */
167 static void Ogg_ReadSkeletonBones( demux_t *, ogg_packet * );
168 static void Ogg_ReadSkeletonIndex( demux_t *, ogg_packet * );
169 static void Ogg_FreeSkeleton( ogg_skeleton_t * );
170 static void Ogg_ApplySkeleton( logical_stream_t * );
172 /* Special decoding */
173 static void Ogg_CleanSpecificData( logical_stream_t * );
174 #ifdef HAVE_LIBVORBIS
175 static void Ogg_DecodeVorbisHeader( logical_stream_t *, ogg_packet *, int );
176 #endif
178 static void fill_channels_info(audio_format_t *audio)
180 static const int pi_channels_map[9] =
183 AOUT_CHAN_CENTER,
184 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
185 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
186 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
187 | AOUT_CHAN_REARRIGHT,
188 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
189 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
190 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
191 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
192 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
193 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
194 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
195 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
196 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
197 | AOUT_CHAN_LFE,
200 unsigned chans = audio->i_channels;
201 if (chans < sizeof(pi_channels_map) / sizeof(pi_channels_map[0]))
202 audio->i_physical_channels = pi_channels_map[chans];
205 /*****************************************************************************
206 * Open: initializes ogg demux structures
207 *****************************************************************************/
208 static int Open( vlc_object_t * p_this )
210 demux_t *p_demux = (demux_t *)p_this;
211 demux_sys_t *p_sys;
212 const uint8_t *p_peek;
214 /* Check if we are dealing with an ogg stream */
215 if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
216 if( !p_demux->obj.force && memcmp( p_peek, "OggS", 4 ) )
218 char *psz_mime = stream_ContentType( p_demux->s );
219 if( !psz_mime )
221 return VLC_EGENERIC;
223 else if ( strcmp( psz_mime, "application/ogg" ) &&
224 strcmp( psz_mime, "video/ogg" ) &&
225 strcmp( psz_mime, "audio/ogg" ) )
227 free( psz_mime );
228 return VLC_EGENERIC;
230 free( psz_mime );
233 /* */
234 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
235 if( !p_sys )
236 return VLC_ENOMEM;
238 p_sys->i_length = -1;
239 p_sys->b_preparsing_done = false;
241 /* Set exported functions */
242 p_demux->pf_demux = Demux;
243 p_demux->pf_control = Control;
245 /* Initialize the Ogg physical bitstream parser */
246 ogg_sync_init( &p_sys->oy );
248 /* */
249 TAB_INIT( p_sys->i_seekpoints, p_sys->pp_seekpoints );
252 while ( !p_sys->b_preparsing_done && p_demux->pf_demux( p_demux ) > 0 )
254 if ( p_sys->b_preparsing_done && p_demux->b_preparsing )
255 Ogg_CreateES( p_demux );
257 return VLC_SUCCESS;
260 /*****************************************************************************
261 * Close: frees unused data
262 *****************************************************************************/
263 static void Close( vlc_object_t *p_this )
265 demux_t *p_demux = (demux_t *)p_this;
266 demux_sys_t *p_sys = p_demux->p_sys ;
268 /* Cleanup the bitstream parser */
269 ogg_sync_clear( &p_sys->oy );
271 Ogg_EndOfStream( p_demux );
273 if( p_sys->p_old_stream )
274 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
276 free( p_sys );
279 static vlc_tick_t Ogg_GetLastDTS( demux_t * p_demux )
281 demux_sys_t *p_sys = p_demux->p_sys;
283 vlc_tick_t i_dts = VLC_TICK_INVALID;
284 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
286 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
287 if ( p_stream->b_initializing )
288 continue;
289 if( p_stream->i_pcr > i_dts )
290 i_dts = p_stream->i_pcr;
293 return i_dts;
296 static vlc_tick_t Ogg_GeneratePCR( demux_t * p_demux, bool b_drain )
298 demux_sys_t *p_sys = p_demux->p_sys;
299 /* We will consider the lowest PCR among tracks, because the audio core badly
300 * handles PCR rewind (mute)
302 vlc_tick_t i_pcr_candidate = VLC_TICK_INVALID;
303 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
305 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
306 if( p_stream->fmt.i_cat == SPU_ES )
307 continue;
308 if( p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS )
309 continue;
310 if( p_stream->i_pcr == VLC_TICK_INVALID )
311 continue;
312 if ( (!b_drain && p_stream->b_finished) || p_stream->b_initializing )
313 continue;
314 if( i_pcr_candidate == VLC_TICK_INVALID ||
315 p_stream->i_pcr < i_pcr_candidate )
317 i_pcr_candidate = p_stream->i_pcr;
321 return i_pcr_candidate;
324 static void Ogg_OutputQueues( demux_t *p_demux, bool b_drain )
326 demux_sys_t *p_sys = p_demux->p_sys;
327 vlc_tick_t i_pcr;
329 /* Generate First PCR */
330 if( p_sys->i_pcr == VLC_TICK_INVALID )
332 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
333 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
335 p_sys->i_pcr = i_pcr;
336 if( likely( !p_sys->b_slave ) )
337 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
341 if( p_sys->i_pcr != VLC_TICK_INVALID )
343 bool b_continue;
346 b_continue = false;
347 for( int i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
349 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
350 if( Ogg_HasQueuedBlocks( p_stream ) )
351 Ogg_SendQueuedBlock( p_demux, p_stream );
352 b_continue |= Ogg_HasQueuedBlocks( p_stream );
355 /* Generate Current PCR */
356 i_pcr = Ogg_GeneratePCR( p_demux, b_drain );
357 if( i_pcr != VLC_TICK_INVALID && i_pcr != p_sys->i_pcr )
359 p_sys->i_pcr = i_pcr;
360 if( likely( !p_sys->b_slave ) )
361 es_out_SetPCR( p_demux->out, p_sys->i_pcr );
363 } while ( b_continue );
368 /*****************************************************************************
369 * Demux: reads and demuxes data packets
370 *****************************************************************************
371 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
372 *****************************************************************************/
373 static int Demux( demux_t * p_demux )
375 demux_sys_t *p_sys = p_demux->p_sys;
376 ogg_packet oggpacket;
377 int i_stream;
378 bool b_canseek;
380 int i_active_streams = p_sys->i_streams;
381 for ( int i=0; i < p_sys->i_streams; i++ )
383 if ( p_sys->pp_stream[i]->b_finished )
384 i_active_streams--;
387 if ( i_active_streams == 0 )
389 if ( p_sys->i_streams ) /* All finished */
391 msg_Dbg( p_demux, "end of a group of %d logical streams", p_sys->i_streams );
393 Ogg_OutputQueues( p_demux, true );
395 vlc_tick_t i_lastdts = Ogg_GetLastDTS( p_demux );
397 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
398 * only 1 ES is supported (common case for ogg web radio) */
399 if( p_sys->i_streams == 1 && p_sys->pp_stream[0]->p_es )
401 if( p_sys->p_old_stream ) /* if no setupEs has reused */
402 Ogg_LogicalStreamDelete( p_demux, p_sys->p_old_stream );
403 p_sys->p_old_stream = p_sys->pp_stream[0];
404 TAB_CLEAN( p_sys->i_streams, p_sys->pp_stream );
407 Ogg_EndOfStream( p_demux );
408 p_sys->b_chained_boundary = true;
410 if( i_lastdts != VLC_TICK_INVALID )
412 p_sys->i_nzpcr_offset = i_lastdts - VLC_TICK_0;
413 if( likely( !p_sys->b_slave ) )
414 es_out_SetPCR( p_demux->out, i_lastdts );
416 p_sys->i_pcr = VLC_TICK_INVALID;
419 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
420 return VLC_DEMUXER_EOF;
422 msg_Dbg( p_demux, "beginning of a group of logical streams" );
424 if ( !p_sys->b_chained_boundary )
426 /* Find the real duration */
427 vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
428 if ( b_canseek )
429 Oggseek_ProbeEnd( p_demux );
431 else
433 p_sys->b_chained_boundary = false;
437 if ( p_sys->b_preparsing_done && !p_sys->b_es_created )
438 Ogg_CreateES( p_demux );
441 * The first data page of a physical stream is stored in the relevant logical stream
442 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
443 * stream it belongs to if we haven't processed this first page yet. If we do, we
444 * will only process that first page whenever we find the second page for this stream.
445 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
446 * the second page will arrive real quick, this is not fine for Kate, whose second
447 * data page will typically arrive much later.
448 * This means it is now possible to seek right at the start of a stream where the last
449 * logical stream is Kate, without having to wait for the second data page to unblock
450 * the first one, which is the one that triggers the 'no more headers to backup' code.
451 * And, as we all know, seeking without having backed up all headers is bad, since the
452 * codec will fail to initialize if it's missing its headers.
454 if( !p_sys->b_page_waiting)
457 * Demux an ogg page from the stream
459 if( Ogg_ReadPage( p_demux, &p_sys->current_page ) != VLC_SUCCESS )
460 return VLC_DEMUXER_EOF; /* EOF */
461 /* Test for End of Stream */
462 if( ogg_page_eos( &p_sys->current_page ) )
464 /* If we delayed restarting encoders/SET_ES_FMT for more
465 * skeleton provided configuration */
466 if ( p_sys->p_skelstream )
468 if ( p_sys->p_skelstream->i_serial_no == ogg_page_serialno(&p_sys->current_page) )
470 msg_Dbg( p_demux, "End of Skeleton" );
471 p_sys->b_preparsing_done = true;
472 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
474 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
475 Ogg_ApplySkeleton( p_stream );
480 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
482 if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
484 p_sys->pp_stream[i_stream]->b_finished = true;
485 break;
491 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
493 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
495 /* if we've just pulled page, look for the right logical stream */
496 if( !p_sys->b_page_waiting )
498 if( p_sys->i_streams == 1 &&
499 ogg_page_serialno( &p_sys->current_page ) != p_stream->os.serialno )
501 msg_Err( p_demux, "Broken Ogg stream (serialno) mismatch" );
502 Ogg_ResetStream( p_stream );
503 if( p_stream->i_pcr != VLC_TICK_INVALID )
504 p_sys->i_nzpcr_offset = p_stream->i_pcr - VLC_TICK_0;
505 ogg_stream_reset_serialno( &p_stream->os, ogg_page_serialno( &p_sys->current_page ) );
508 /* Does fail if serialno differs */
509 if( ogg_stream_pagein( &p_stream->os, &p_sys->current_page ) != 0 )
511 continue;
515 /* clear the finished flag if pages after eos (ex: after a seek) */
516 if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
517 p_stream->b_finished = false;
519 DemuxDebug(
520 if ( p_stream->fmt.i_cat == VIDEO_ES )
521 msg_Dbg(p_demux, "DEMUX READ pageno %ld g%"PRId64" (%d packets) cont %d %ld bytes",
522 ogg_page_pageno( &p_sys->current_page ),
523 ogg_page_granulepos( &p_sys->current_page ),
524 ogg_page_packets( &p_sys->current_page ),
525 ogg_page_continued(&p_sys->current_page),
526 p_sys->current_page.body_len )
529 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
531 /* Read info from any secondary header packets, if there are any */
532 if( p_stream->i_secondary_header_packets > 0 )
534 if( p_stream->fmt.i_codec == VLC_CODEC_THEORA &&
535 oggpacket.bytes >= 7 &&
536 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
538 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
539 p_stream->i_secondary_header_packets = 0;
541 else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
542 oggpacket.bytes >= 6 &&
543 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
545 Ogg_ReadDaalaHeader( p_stream, &oggpacket );
546 p_stream->i_secondary_header_packets = 0;
548 else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
549 oggpacket.bytes >= 7 &&
550 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
552 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
553 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
554 p_stream->i_secondary_header_packets = 0;
557 /* update start of data pointer */
558 p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
561 if( p_stream->b_reinit )
563 p_stream->b_reinit = false;
564 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
566 p_stream->i_skip_frames = p_stream->i_pre_skip;
570 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
574 if( !p_sys->b_page_waiting )
575 break;
578 /* if a page was waiting, it's now processed */
579 p_sys->b_page_waiting = false;
581 if ( p_sys->p_skelstream && !p_sys->p_skelstream->b_finished )
582 p_sys->b_preparsing_done = false;
583 else
584 p_sys->b_preparsing_done = true;
586 if( p_sys->b_preparsing_done )
588 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
590 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
591 if ( p_stream->b_initializing )
593 /* We have 1 or more streams needing more than 1 page for preparsing */
594 p_sys->b_preparsing_done = false;
595 break;
600 if( p_sys->b_preparsing_done )
601 Ogg_OutputQueues( p_demux, false );
603 return VLC_DEMUXER_SUCCESS;
606 static void Ogg_ResetStream( logical_stream_t *p_stream )
608 #ifdef HAVE_LIBVORBIS
609 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
611 p_stream->special.vorbis.i_prev_blocksize = 0;
613 #endif
614 /* we'll trash all the data until we find the next pcr */
615 p_stream->b_reinit = true;
616 p_stream->i_pcr = VLC_TICK_INVALID;
617 p_stream->i_next_block_flags = 0;
618 p_stream->b_interpolation_failed = false;
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 if( i_samples == 0 )
981 p_stream->b_interpolation_failed = true;
982 else
983 date_Increment( &p_stream->dts, i_samples );
988 static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_stream )
990 vlc_tick_t i_enddts = VLC_TICK_INVALID;
992 #ifdef HAVE_LIBVORBIS
993 long i_prev_blocksize = 0;
994 #else
995 VLC_UNUSED(p_demux);
996 #endif
997 // PASS 1, set number of samples
998 unsigned i_total_samples = 0;
999 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
1001 if( p_block->i_dts != VLC_TICK_INVALID )
1003 i_enddts = p_block->i_dts;
1004 break;
1007 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1008 continue;
1010 ogg_packet dumb_packet;
1011 dumb_packet.bytes = p_block->i_buffer;
1012 dumb_packet.packet = p_block->p_buffer;
1014 switch( p_stream->fmt.i_codec )
1016 case VLC_CODEC_SPEEX:
1017 p_block->i_nb_samples = p_stream->special.speex.i_framesize *
1018 p_stream->special.speex.i_framesperpacket;
1019 break;
1020 case VLC_CODEC_OPUS:
1021 p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
1022 break;
1023 #ifdef HAVE_LIBVORBIS
1024 case VLC_CODEC_VORBIS:
1026 if( !VORBIS_HEADERS_VALID(p_stream) )
1028 msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
1029 break;
1031 long i_blocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info,
1032 &dumb_packet );
1033 if ( i_prev_blocksize )
1034 p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
1035 else
1036 p_block->i_nb_samples = i_blocksize / 2;
1037 i_prev_blocksize = i_blocksize;
1038 break;
1040 #endif
1041 default:
1042 if( p_stream->fmt.i_cat == VIDEO_ES )
1043 p_block->i_nb_samples = 1;
1044 break;
1046 i_total_samples += p_block->i_nb_samples;
1049 // PASS 2
1050 if( i_enddts != VLC_TICK_INVALID )
1052 date_t d = p_stream->dts;
1053 date_Set( &d, i_enddts );
1054 i_enddts = date_Decrement( &d, i_total_samples );
1055 for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
1057 if( p_block->i_dts != VLC_TICK_INVALID )
1058 break;
1059 if( p_block->i_flags & BLOCK_FLAG_HEADER )
1060 continue;
1061 p_block->i_dts = date_Get( &d );
1062 date_Increment( &d, p_block->i_nb_samples );
1064 } /* else can't do anything, no timestamped blocks in stream */
1066 return i_enddts;
1069 static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream, block_t *p_block )
1071 demux_sys_t *p_sys = p_demux->p_sys;
1072 VLC_UNUSED(p_sys);
1074 if( p_block == NULL )
1076 assert( p_block != NULL );
1077 return;
1080 block_ChainLastAppend( &p_stream->queue.pp_append, p_block );
1082 if( p_stream->i_pcr == VLC_TICK_INVALID && p_block->i_dts != VLC_TICK_INVALID )
1084 /* fixup queue */
1085 p_stream->i_pcr = Ogg_FixupOutputQueue( p_demux, p_stream );
1088 DemuxDebug( msg_Dbg( p_demux, "%4.4s block queued > dts %"PRId64" spcr %"PRId64" pcr %"PRId64,
1089 (char*)&p_stream->fmt.i_codec, p_block->i_dts, p_stream->i_pcr, p_sys->i_pcr ); )
1092 static void Ogg_SendQueuedBlock( demux_t *p_demux, logical_stream_t *p_stream )
1094 demux_sys_t *p_sys = p_demux->p_sys;
1096 if( Ogg_HasQueuedBlocks( p_stream ) )
1098 block_t *p_queued = p_stream->queue.p_blocks;
1099 p_stream->queue.p_blocks = p_queued->p_next;
1100 p_queued->p_next = NULL;
1102 if( p_queued->i_dts == VLC_TICK_INVALID )
1103 p_queued->i_dts = p_queued->i_pts;
1105 if( p_queued->i_flags & BLOCK_FLAG_HEADER )
1107 if( p_sys->i_nzpcr_offset > 0 || /* Don't send metadata from chained streams */
1108 p_stream->fmt.i_extra > 0 ) /* Don't send metadata if configured by extradata */
1110 block_Release( p_queued );
1111 goto end;
1113 p_queued->i_flags &= ~BLOCK_FLAG_HEADER;
1116 unsigned i_toskip = 0;
1117 if( p_stream->i_skip_frames > 0 )
1119 if( p_sys->i_nzpcr_offset > 0 )
1121 /* not preskip handling on chained streams */
1122 p_stream->i_skip_frames = 0;
1124 else
1126 i_toskip = __MIN( p_stream->i_skip_frames, p_queued->i_nb_samples );
1127 p_stream->i_skip_frames -= i_toskip;
1128 p_queued->i_nb_samples -= i_toskip;
1129 if( p_queued->i_nb_samples == 0 )
1130 p_queued->i_flags |= BLOCK_FLAG_PREROLL;
1134 p_queued->i_flags |= p_stream->i_next_block_flags;
1135 p_stream->i_next_block_flags = 0;
1136 p_stream->i_pcr = p_queued->i_dts;
1138 DemuxDebug( msg_Dbg( p_demux, "%4.4s block sent > dts %"PRId64" pts %"PRId64" spcr %"PRId64" pcr %"PRId64
1139 " samples (%d/%d)",
1140 (char*)&p_stream->fmt.i_codec, p_queued->i_dts,
1141 p_queued->i_pts, p_stream->i_pcr, p_sys->i_pcr,
1142 p_queued->i_nb_samples, i_toskip ); );
1144 assert( p_sys->i_pcr != VLC_TICK_INVALID );
1146 if( p_stream->p_es )
1147 es_out_Send( p_demux->out, p_stream->p_es, p_queued );
1148 else
1149 block_Release( p_queued );
1152 end:
1153 if( p_stream->queue.p_blocks == NULL )
1154 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
1157 static bool Ogg_IsHeaderPacket( const logical_stream_t *p_stream,
1158 const ogg_packet *p_oggpacket )
1160 if ( p_stream->b_oggds )
1162 return p_oggpacket->bytes > 0 &&
1163 (p_oggpacket->packet[0] & PACKET_TYPE_HEADER);
1165 else return ( p_oggpacket->granulepos == 0 && p_stream->i_first_frame_index > 0 );
1168 /****************************************************************************
1169 * Ogg_DecodePacket: Decode an Ogg packet.
1170 ****************************************************************************/
1171 static void Ogg_DecodePacket( demux_t *p_demux,
1172 logical_stream_t *p_stream,
1173 ogg_packet *p_oggpacket )
1175 demux_sys_t *p_sys = p_demux->p_sys;
1176 block_t *p_block;
1177 bool b_selected;
1178 long i_header_len = 0;
1180 if( p_oggpacket->bytes >= 7 &&
1181 ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
1183 /* it's an Annodex packet -- skip it (do nothing) */
1184 return;
1186 else if( p_oggpacket->bytes >= 7 &&
1187 ! memcmp ( p_oggpacket->packet, "AnxData", 7 ) )
1189 /* it's an AnxData packet -- skip it (do nothing) */
1190 return;
1192 else if( p_oggpacket->bytes >= 8 &&
1193 ! memcmp ( p_oggpacket->packet, "fisbone", 8 ) )
1195 Ogg_ReadSkeletonBones( p_demux, p_oggpacket );
1196 return;
1198 else if( p_oggpacket->bytes >= 6 &&
1199 ! memcmp ( p_oggpacket->packet, "index", 6 ) )
1201 Ogg_ReadSkeletonIndex( p_demux, p_oggpacket );
1202 return;
1204 else if( p_stream->fmt.i_codec == VLC_CODEC_VP8 &&
1205 p_oggpacket->bytes >= 7 &&
1206 !memcmp( p_oggpacket->packet, "OVP80\x02\x20", 7 ) )
1208 Ogg_ReadVP8Header( p_demux, p_stream, p_oggpacket );
1209 return;
1212 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
1213 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
1215 /* Check the ES is selected */
1216 if ( !p_stream->p_es )
1217 b_selected = true;
1218 else
1219 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
1220 p_stream->p_es, &b_selected );
1222 if( p_stream->b_force_backup )
1224 bool b_xiph;
1225 p_stream->i_packets_backup++;
1226 switch( p_stream->fmt.i_codec )
1228 case VLC_CODEC_VORBIS:
1229 #ifdef HAVE_LIBVORBIS
1230 Ogg_DecodeVorbisHeader( p_stream, p_oggpacket, p_stream->i_packets_backup );
1231 #endif
1232 /* fallthrough */
1233 case VLC_CODEC_THEORA:
1234 if( p_stream->i_packets_backup == 3 )
1235 p_stream->b_force_backup = false;
1236 b_xiph = true;
1237 break;
1239 case VLC_CODEC_DAALA:
1240 if( p_stream->i_packets_backup == 3 )
1241 p_stream->b_force_backup = false;
1242 b_xiph = true;
1243 break;
1245 case VLC_CODEC_SPEEX:
1246 if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
1247 p_stream->b_force_backup = false;
1248 b_xiph = true;
1249 break;
1251 case VLC_CODEC_OPUS:
1252 if( p_stream->i_packets_backup == 2 )
1253 p_stream->b_force_backup = false;
1254 b_xiph = true;
1255 break;
1257 case VLC_CODEC_FLAC:
1258 if( p_stream->i_packets_backup == 1 + p_stream->i_extra_headers_packets )
1260 p_stream->b_force_backup = false;
1262 if( p_stream->special.flac.b_old )
1264 Ogg_ReadFlacStreamInfo( p_demux, p_stream, p_oggpacket );
1266 else if( p_stream->i_packets_backup == 1 )
1268 if( p_oggpacket->bytes >= 9 ) /* Point to Flac for extradata */
1270 p_oggpacket->packet += 9;
1271 p_oggpacket->bytes -= 9;
1274 b_xiph = false;
1275 break;
1277 case VLC_CODEC_KATE:
1278 if( p_stream->i_packets_backup == p_stream->special.kate.i_num_headers )
1279 p_stream->b_force_backup = false;
1280 b_xiph = true;
1281 break;
1283 default:
1284 p_stream->b_force_backup = false;
1285 b_xiph = false;
1286 break;
1289 /* Backup the ogg packet (likely an header packet) */
1290 if( !b_xiph )
1292 uint8_t *p_realloc = realloc( p_stream->p_headers, p_stream->i_headers + p_oggpacket->bytes );
1293 if( p_realloc )
1295 memcpy( &p_realloc[p_stream->i_headers], p_oggpacket->packet, p_oggpacket->bytes );
1296 p_stream->i_headers += p_oggpacket->bytes;
1297 p_stream->p_headers = p_realloc;
1299 else
1301 free( p_stream->p_headers );
1302 p_stream->i_headers = 0;
1303 p_stream->p_headers = NULL;
1306 else if( xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,
1307 p_oggpacket->bytes, p_oggpacket->packet ) )
1309 p_stream->i_headers = 0;
1310 p_stream->p_headers = NULL;
1312 if( p_stream->i_headers > 0 )
1314 if( !p_stream->b_force_backup )
1316 /* Last header received, commit changes */
1317 free( p_stream->fmt.p_extra );
1319 p_stream->fmt.i_extra = p_stream->i_headers;
1320 p_stream->fmt.p_extra = malloc( p_stream->i_headers );
1321 if( p_stream->fmt.p_extra )
1322 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
1323 p_stream->i_headers );
1324 else
1325 p_stream->fmt.i_extra = 0;
1327 if( p_stream->i_headers > 0 )
1328 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
1329 p_stream->p_headers, p_stream->i_headers );
1331 /* we're not at BOS anymore for this logical stream */
1332 p_stream->b_initializing = false;
1336 b_selected = false; /* Discard the header packet */
1338 else
1340 p_stream->b_initializing = false;
1343 vlc_tick_t i_dts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, false );
1344 vlc_tick_t i_expected_dts = p_stream->b_interpolation_failed ? VLC_TICK_INVALID :
1345 date_Get( &p_stream->dts ); /* Interpolated or previous end time */
1346 if( i_dts == VLC_TICK_INVALID )
1347 i_dts = i_expected_dts;
1348 else
1349 date_Set( &p_stream->dts, i_dts );
1351 /* Write end granule as next start, or do interpolation */
1352 bool b_header = Ogg_IsHeaderPacket( p_stream, p_oggpacket );
1353 if( !b_header )
1354 Ogg_SetNextFrame( p_demux, p_stream, p_oggpacket );
1356 if( !b_selected )
1358 /* This stream isn't currently selected so we don't need to decode it,
1359 * but we did need to store its pcr as it might be selected later on */
1360 if( !b_header && !p_stream->b_initializing )
1362 vlc_tick_t i_pcr = date_Get( &p_stream->dts );
1363 if( i_pcr != VLC_TICK_INVALID )
1364 p_stream->i_pcr = p_sys->i_nzpcr_offset + i_pcr;
1366 return;
1369 if( !( p_block = block_Alloc( p_oggpacket->bytes ) ) )
1370 return;
1372 /* Set effective timestamp */
1373 if( i_dts != VLC_TICK_INVALID )
1374 p_block->i_dts = p_sys->i_nzpcr_offset + i_dts;
1376 /* Vorbis and Opus can trim the end of a stream using granule positions. */
1377 if( p_oggpacket->e_o_s )
1379 vlc_tick_t i_endtime = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, false, false );
1380 if( i_endtime != VLC_TICK_INVALID && i_expected_dts != VLC_TICK_INVALID )
1382 p_block->i_length = i_endtime - i_expected_dts;
1383 p_block->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
1387 if( p_stream->fmt.i_codec == VLC_CODEC_OPUS ) /* also required for trimming */
1388 p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket );
1390 DemuxDebug( msg_Dbg(p_demux, "%4.4s block set from granule %"PRId64" to pts/pcr %"PRId64" skip %d",
1391 (char *) &p_stream->fmt.i_codec, p_oggpacket->granulepos,
1392 p_block->i_dts, p_stream->i_skip_frames); )
1394 /* may need to preroll after a seek or in case of preskip */
1396 /* Conditional block fixes */
1397 if ( p_stream->fmt.i_cat == VIDEO_ES )
1399 if( Ogg_IsKeyFrame( p_stream, p_oggpacket ) )
1400 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1402 if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
1404 if( p_oggpacket->granulepos > 0 )
1405 p_block->i_pts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, true );
1407 else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
1409 p_block->i_pts = p_block->i_dts;
1412 else if( p_stream->fmt.i_cat == AUDIO_ES )
1414 if( p_stream->b_interpolation_failed && p_oggpacket->granulepos < 0 )
1415 p_block->i_pts = VLC_TICK_INVALID;
1416 else
1417 p_block->i_pts = p_block->i_dts;
1419 else if( p_stream->fmt.i_cat == SPU_ES )
1421 p_block->i_length = 0;
1422 p_block->i_pts = p_block->i_dts;
1425 p_stream->b_interpolation_failed = false;
1427 if( p_stream->b_oggds )
1429 if( p_oggpacket->bytes <= 0 )
1431 msg_Dbg( p_demux, "discarding 0 sized packet" );
1432 block_Release( p_block );
1433 return;
1435 /* We remove the header from the packet */
1436 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
1437 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
1439 if( i_header_len >= p_oggpacket->bytes )
1441 msg_Dbg( p_demux, "discarding invalid packet" );
1442 block_Release( p_block );
1443 return;
1446 if( p_stream->fmt.i_codec == VLC_CODEC_SUBT)
1448 /* But with subtitles we need to retrieve the duration first */
1449 int i, lenbytes = 0;
1451 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
1453 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
1455 lenbytes = lenbytes << 8;
1456 lenbytes += *(p_oggpacket->packet + i_header_len - i);
1459 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
1460 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
1461 p_oggpacket->packet[i_header_len + 1] != 0 &&
1462 p_oggpacket->packet[i_header_len + 1] != '\n' &&
1463 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
1465 p_block->i_length = (vlc_tick_t)lenbytes * 1000;
1469 i_header_len++;
1470 if( p_block->i_buffer >= (unsigned int)i_header_len )
1471 p_block->i_buffer -= i_header_len;
1472 else
1473 p_block->i_buffer = 0;
1476 if( b_header )
1477 p_block->i_flags |= BLOCK_FLAG_HEADER;
1479 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
1480 p_oggpacket->bytes - i_header_len );
1482 Ogg_QueueBlocks( p_demux, p_stream, p_block );
1485 static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
1487 return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes);
1490 /****************************************************************************
1491 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1492 * stream and fill p_ogg.
1493 *****************************************************************************
1494 * The initial page of a logical stream is marked as a 'bos' page.
1495 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1496 * together and all of the initial pages must appear before any data pages.
1498 * On success this function returns VLC_SUCCESS.
1499 ****************************************************************************/
1500 static int Ogg_FindLogicalStreams( demux_t *p_demux )
1502 demux_sys_t *p_ogg = p_demux->p_sys;
1503 ogg_packet oggpacket;
1505 p_ogg->i_total_length = stream_Size ( p_demux->s );
1506 msg_Dbg( p_demux, "File length is %"PRId64" bytes", p_ogg->i_total_length );
1509 while( Ogg_ReadPage( p_demux, &p_ogg->current_page ) == VLC_SUCCESS )
1512 if( ogg_page_bos( &p_ogg->current_page ) )
1515 /* All is wonderful in our fine fine little world.
1516 * We found the beginning of our first logical stream. */
1517 while( ogg_page_bos( &p_ogg->current_page ) )
1519 logical_stream_t *p_stream = malloc( sizeof(logical_stream_t) );
1520 if( unlikely( !p_stream ) )
1521 return VLC_ENOMEM;
1523 Ogg_LogicalStreamInit( p_stream );
1525 /* Setup the logical stream */
1526 p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
1527 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
1529 TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
1531 /* Extract the initial header from the first page and verify
1532 * the codec type of this Ogg bitstream */
1533 if( ogg_stream_pagein( &p_stream->os, &p_ogg->current_page ) < 0 )
1535 /* error. stream version mismatch perhaps */
1536 msg_Err( p_demux, "error reading first page of "
1537 "Ogg bitstream data" );
1538 return VLC_EGENERIC;
1541 /* FIXME: check return value */
1542 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
1544 /* Check for Vorbis header */
1545 if( oggpacket.bytes >= 7 &&
1546 ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
1548 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS);
1549 if ( Ogg_ReadVorbisHeader( p_stream, &oggpacket ) )
1550 msg_Dbg( p_demux, "found vorbis header" );
1551 else
1553 msg_Dbg( p_demux, "found invalid vorbis header" );
1554 Ogg_LogicalStreamDelete( p_demux, p_stream );
1555 p_stream = NULL;
1556 p_ogg->i_streams--;
1559 /* Check for Speex header */
1560 else if( oggpacket.bytes >= 5 &&
1561 ! memcmp( oggpacket.packet, "Speex", 5 ) )
1563 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
1564 if ( Ogg_ReadSpeexHeader( p_stream, &oggpacket ) )
1565 msg_Dbg( p_demux, "found speex header, channels: %i, "
1566 "rate: %"PRIu32"/%"PRIu32", bitrate: %i, frames: %i group %i",
1567 p_stream->fmt.audio.i_channels,
1568 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1569 p_stream->fmt.i_bitrate,
1570 p_stream->special.speex.i_framesize,
1571 p_stream->special.speex.i_framesperpacket );
1572 else
1574 msg_Dbg( p_demux, "found invalid Speex header" );
1575 Ogg_LogicalStreamDelete( p_demux, p_stream );
1576 p_stream = NULL;
1577 p_ogg->i_streams--;
1580 /* Check for Opus header */
1581 else if( oggpacket.bytes >= 8 &&
1582 ! memcmp( oggpacket.packet, "OpusHead", 8 ) )
1584 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_OPUS );
1585 Ogg_ReadOpusHeader( p_stream, &oggpacket );
1586 msg_Dbg( p_demux, "found opus header, channels: %i, "
1587 "pre-skip: %i",
1588 p_stream->fmt.audio.i_channels,
1589 (int)p_stream->i_pre_skip);
1590 p_stream->i_skip_frames = p_stream->i_pre_skip;
1592 /* Check for OLD Flac header */
1593 else if( oggpacket.bytes >= 4 &&
1594 ! memcmp( oggpacket.packet, "fLaC", 4 ) )
1596 msg_Dbg( p_demux, "found FLAC header" );
1598 /* Grrrr!!!! Did they really have to put all the
1599 * important info in the second header packet!!!
1600 * (STREAMINFO metadata is in the following packet) */
1601 p_stream->b_force_backup = true;
1602 p_stream->i_extra_headers_packets = 1;
1603 p_stream->special.flac.b_old = true;
1604 date_Init( &p_stream->dts, 48000, 1 ); /* better be safe since that's delayed */
1605 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1607 /* Check for Flac header (>= version 1.0.0) */
1608 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
1609 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
1610 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
1612 int i_packets = ((int)oggpacket.packet[7]) << 8 |
1613 oggpacket.packet[8];
1614 msg_Dbg( p_demux, "found FLAC header version %i.%i "
1615 "(%i header packets)",
1616 oggpacket.packet[5], oggpacket.packet[6],
1617 i_packets );
1618 /* STREAMINFO is in current packet, and then
1619 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1620 p_stream->b_force_backup = true;
1621 p_stream->i_extra_headers_packets = i_packets;
1622 p_stream->special.flac.b_old = false;
1624 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
1625 oggpacket.packet += 13; oggpacket.bytes -= 13; /* Point to the streaminfo */
1626 if ( !Ogg_ReadFlacStreamInfo( p_demux, p_stream, &oggpacket ) )
1628 msg_Dbg( p_demux, "found invalid Flac header" );
1629 Ogg_LogicalStreamDelete( p_demux, p_stream );
1630 p_stream = NULL;
1631 p_ogg->i_streams--;
1633 p_stream->fmt.b_packetized = false;
1635 /* Check for Theora header */
1636 else if( oggpacket.bytes >= 7 &&
1637 ! memcmp( oggpacket.packet, "\x80theora", 7 ) )
1639 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
1640 if ( Ogg_ReadTheoraHeader( p_stream, &oggpacket ) )
1641 msg_Dbg( p_demux,
1642 "found theora header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1643 p_stream->fmt.i_bitrate,
1644 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1645 else
1647 msg_Dbg( p_demux, "found invalid Theora header" );
1648 Ogg_LogicalStreamDelete( p_demux, p_stream );
1649 p_stream = NULL;
1650 p_ogg->i_streams--;
1653 /* Check for Daala header */
1654 else if( oggpacket.bytes >= 6 &&
1655 ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
1657 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
1658 if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
1659 msg_Dbg( p_demux,
1660 "found daala header, bitrate: %i, rate: %"PRIu32"/%"PRIu32,
1661 p_stream->fmt.i_bitrate,
1662 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den );
1663 else
1665 msg_Dbg( p_demux, "found invalid Daala header" );
1666 Ogg_LogicalStreamDelete( p_demux, p_stream );
1667 p_stream = NULL;
1668 p_ogg->i_streams--;
1671 /* Check for Dirac header */
1672 else if( ( oggpacket.bytes >= 5 &&
1673 ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
1674 ( oggpacket.bytes >= 9 &&
1675 ! memcmp( oggpacket.packet, "KW-DIRAC\x00", 9 ) ) )
1677 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DIRAC );
1678 if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
1679 msg_Dbg( p_demux, "found dirac header" );
1680 else
1682 msg_Warn( p_demux, "found dirac header isn't decodable" );
1683 Ogg_LogicalStreamDelete( p_demux, p_stream );
1684 p_stream = NULL;
1685 p_ogg->i_streams--;
1688 /* Check for VP8 header */
1689 else if( oggpacket.bytes >= 26 &&
1690 ! memcmp( oggpacket.packet, "OVP80", 5 ) )
1692 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
1693 if ( Ogg_ReadVP8Header( p_demux, p_stream, &oggpacket ) )
1694 msg_Dbg( p_demux, "found VP8 header "
1695 "fps: %"PRIu32"/%"PRIu32", width:%i; height:%i",
1696 p_stream->dts.i_divider_num, p_stream->dts.i_divider_den,
1697 p_stream->fmt.video.i_width,
1698 p_stream->fmt.video.i_height );
1699 else
1701 msg_Dbg( p_demux, "invalid VP8 header found");
1702 Ogg_LogicalStreamDelete( p_demux, p_stream );
1703 p_stream = NULL;
1704 p_ogg->i_streams--;
1707 /* Check for Annodex header */
1708 else if( oggpacket.bytes >= 7 &&
1709 ! memcmp( oggpacket.packet, "Annodex", 7 ) )
1711 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1712 /* kill annodex track */
1713 FREENULL( p_stream );
1714 p_ogg->i_streams--;
1716 /* Check for Annodex header */
1717 else if( oggpacket.bytes >= 7 &&
1718 ! memcmp( oggpacket.packet, "AnxData", 7 ) )
1720 Ogg_ReadAnnodexHeader( p_demux, p_stream, &oggpacket );
1722 /* Check for Kate header */
1723 else if( oggpacket.bytes >= 8 &&
1724 ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
1726 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_KATE );
1727 if ( Ogg_ReadKateHeader( p_stream, &oggpacket ) )
1728 msg_Dbg( p_demux, "found kate header" );
1729 else
1731 msg_Dbg( p_demux, "invalid kate header found");
1732 Ogg_LogicalStreamDelete( p_demux, p_stream );
1733 p_stream = NULL;
1734 p_ogg->i_streams--;
1737 /* Check for OggDS */
1738 else if( oggpacket.bytes >= 142 &&
1739 !memcmp( &oggpacket.packet[1],
1740 "Direct Show Samples embedded in Ogg", 35 ))
1742 /* Old header type */
1743 p_stream->b_oggds = true;
1744 p_stream->b_contiguous = false;
1745 /* Check for video header (old format) */
1746 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
1747 oggpacket.bytes >= 184 )
1749 es_format_Change( &p_stream->fmt, VIDEO_ES,
1750 VLC_FOURCC( oggpacket.packet[68],
1751 oggpacket.packet[69],
1752 oggpacket.packet[70],
1753 oggpacket.packet[71] ) );
1754 msg_Dbg( p_demux, "found video header of type: %.4s",
1755 (char *)&p_stream->fmt.i_codec );
1757 unsigned num = OGGDS_RESOLUTION;
1758 unsigned den = GetQWLE(oggpacket.packet+164);
1759 vlc_ureduce( &num, &den, num, den > 0 ? den : 1, OGGDS_RESOLUTION );
1760 p_stream->fmt.video.i_frame_rate = num;
1761 p_stream->fmt.video.i_frame_rate_base = den;
1762 date_Init( &p_stream->dts, num, den );
1763 p_stream->fmt.video.i_bits_per_pixel =
1764 GetWLE((oggpacket.packet+182));
1765 if( !p_stream->fmt.video.i_bits_per_pixel )
1766 /* hack, FIXME */
1767 p_stream->fmt.video.i_bits_per_pixel = 24;
1768 p_stream->fmt.video.i_width =
1769 GetDWLE((oggpacket.packet+176));
1770 p_stream->fmt.video.i_height =
1771 GetDWLE((oggpacket.packet+180));
1772 p_stream->fmt.video.i_visible_width =
1773 p_stream->fmt.video.i_width;
1774 p_stream->fmt.video.i_visible_height =
1775 p_stream->fmt.video.i_height;
1777 msg_Dbg( p_demux,
1778 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1779 p_stream->fmt.video.i_frame_rate,
1780 p_stream->fmt.video.i_frame_rate_base,
1781 p_stream->fmt.video.i_width,
1782 p_stream->fmt.video.i_height,
1783 p_stream->fmt.video.i_bits_per_pixel);
1785 if ( !p_stream->fmt.video.i_frame_rate ||
1786 !p_stream->fmt.video.i_frame_rate_base )
1788 Ogg_LogicalStreamDelete( p_demux, p_stream );
1789 p_stream = NULL;
1790 p_ogg->i_streams--;
1793 /* Check for audio header (old format) */
1794 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
1796 int i_extra_size;
1797 unsigned int i_format_tag;
1799 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1801 i_extra_size = GetWLE((oggpacket.packet+140));
1802 if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
1804 p_stream->fmt.i_extra = i_extra_size;
1805 p_stream->fmt.p_extra = malloc( i_extra_size );
1806 if( p_stream->fmt.p_extra )
1807 memcpy( p_stream->fmt.p_extra,
1808 oggpacket.packet + 142, i_extra_size );
1809 else
1810 p_stream->fmt.i_extra = 0;
1813 i_format_tag = GetWLE((oggpacket.packet+124));
1814 p_stream->fmt.audio.i_channels =
1815 GetWLE((oggpacket.packet+126));
1816 fill_channels_info(&p_stream->fmt.audio);
1817 p_stream->fmt.audio.i_rate =
1818 GetDWLE((oggpacket.packet+128));
1819 p_stream->fmt.i_bitrate =
1820 GetDWLE((oggpacket.packet+132)) * 8;
1821 p_stream->fmt.audio.i_blockalign =
1822 GetWLE((oggpacket.packet+136));
1823 p_stream->fmt.audio.i_bitspersample =
1824 GetWLE((oggpacket.packet+138));
1826 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
1828 wf_tag_to_fourcc( i_format_tag,
1829 &p_stream->fmt.i_codec, 0 );
1831 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1833 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1834 ( i_format_tag >> 8 ) & 0xff,
1835 i_format_tag & 0xff );
1838 msg_Dbg( p_demux, "found audio header of type: %.4s",
1839 (char *)&p_stream->fmt.i_codec );
1840 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1841 "%dbits/sample %dkb/s",
1842 i_format_tag,
1843 p_stream->fmt.audio.i_channels,
1844 p_stream->fmt.audio.i_rate,
1845 p_stream->fmt.audio.i_bitspersample,
1846 p_stream->fmt.i_bitrate / 1024 );
1848 if ( p_stream->fmt.audio.i_rate == 0 )
1850 msg_Dbg( p_demux, "invalid oggds audio header" );
1851 Ogg_LogicalStreamDelete( p_demux, p_stream );
1852 p_stream = NULL;
1853 p_ogg->i_streams--;
1856 else
1858 msg_Dbg( p_demux, "stream %d has an old header "
1859 "but is of an unknown type", p_ogg->i_streams-1 );
1860 FREENULL( p_stream );
1861 p_ogg->i_streams--;
1864 /* Check for OggDS */
1865 else if( oggpacket.bytes >= 44+1 &&
1866 (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
1868 stream_header_t tmp;
1869 stream_header_t *st = &tmp;
1871 p_stream->b_oggds = true;
1872 p_stream->b_contiguous = false;
1874 memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
1875 memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
1876 st->size = GetDWLE( &oggpacket.packet[1+12] );
1877 st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
1878 st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
1879 st->default_len = GetDWLE( &oggpacket.packet[1+32] );
1880 st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
1881 st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
1883 /* Check for video header (new format) */
1884 if( !strncmp( st->streamtype, "video", 5 ) &&
1885 oggpacket.bytes >= 52+1 )
1887 st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
1888 st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
1890 es_format_Change( &p_stream->fmt, VIDEO_ES, 0 );
1892 /* We need to get rid of the header packet */
1893 ogg_stream_packetout( &p_stream->os, &oggpacket );
1895 p_stream->fmt.i_codec =
1896 VLC_FOURCC( st->subtype[0], st->subtype[1],
1897 st->subtype[2], st->subtype[3] );
1898 msg_Dbg( p_demux, "found video header of type: %.4s",
1899 (char *)&p_stream->fmt.i_codec );
1901 /* FIXME: no clue where it's from */
1902 if( st->time_unit <= 0 )
1903 st->time_unit = 400000;
1904 unsigned num, den;
1905 vlc_ureduce( &num, &den,
1906 st->samples_per_unit * OGGDS_RESOLUTION,
1907 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1908 OGGDS_RESOLUTION );
1909 date_Init( &p_stream->dts, num, den );
1910 p_stream->fmt.video.i_frame_rate = num;
1911 p_stream->fmt.video.i_frame_rate_base = den;
1912 p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
1913 p_stream->fmt.video.i_width = st->sh.video.width;
1914 p_stream->fmt.video.i_height = st->sh.video.height;
1915 p_stream->fmt.video.i_visible_width =
1916 p_stream->fmt.video.i_width;
1917 p_stream->fmt.video.i_visible_height =
1918 p_stream->fmt.video.i_height;
1920 msg_Dbg( p_demux,
1921 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1922 p_stream->fmt.video.i_frame_rate,
1923 p_stream->fmt.video.i_frame_rate_base,
1924 p_stream->fmt.video.i_width,
1925 p_stream->fmt.video.i_height,
1926 p_stream->fmt.video.i_bits_per_pixel );
1928 /* Check for audio header (new format) */
1929 else if( !strncmp( st->streamtype, "audio", 5 ) &&
1930 oggpacket.bytes >= 56+1 )
1932 char p_buffer[5];
1933 int i_extra_size;
1934 int i_format_tag;
1936 st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
1937 st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
1938 st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
1940 es_format_Change( &p_stream->fmt, AUDIO_ES, 0 );
1942 /* We need to get rid of the header packet */
1943 ogg_stream_packetout( &p_stream->os, &oggpacket );
1945 i_extra_size = st->size - 56;
1947 if( i_extra_size > 0 &&
1948 i_extra_size < oggpacket.bytes - 1 - 56 )
1950 p_stream->fmt.i_extra = i_extra_size;
1951 p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
1952 if( p_stream->fmt.p_extra )
1953 memcpy( p_stream->fmt.p_extra, oggpacket.packet + 57,
1954 p_stream->fmt.i_extra );
1955 else
1956 p_stream->fmt.i_extra = 0;
1959 memcpy( p_buffer, st->subtype, 4 );
1960 p_buffer[4] = '\0';
1961 i_format_tag = strtol(p_buffer,NULL,16);
1962 p_stream->fmt.audio.i_channels = st->sh.audio.channels;
1963 fill_channels_info(&p_stream->fmt.audio);
1965 unsigned num,den;
1966 vlc_ureduce( &num, &den,
1967 st->samples_per_unit * OGGDS_RESOLUTION,
1968 st->time_unit > 0 ? st->time_unit : OGGDS_RESOLUTION,
1969 OGGDS_RESOLUTION );
1970 date_Init( &p_stream->dts, num, den );
1971 p_stream->fmt.audio.i_rate = num / den;
1972 p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
1973 p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
1974 p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
1976 wf_tag_to_fourcc( i_format_tag,
1977 &p_stream->fmt.i_codec, 0 );
1979 if( p_stream->fmt.i_codec == VLC_CODEC_UNKNOWN )
1981 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
1982 ( i_format_tag >> 8 ) & 0xff,
1983 i_format_tag & 0xff );
1986 msg_Dbg( p_demux, "found audio header of type: %.4s",
1987 (char *)&p_stream->fmt.i_codec );
1988 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
1989 "%dbits/sample %dkb/s",
1990 i_format_tag,
1991 p_stream->fmt.audio.i_channels,
1992 p_stream->fmt.audio.i_rate,
1993 p_stream->fmt.audio.i_bitspersample,
1994 p_stream->fmt.i_bitrate / 1024 );
1995 if ( p_stream->fmt.audio.i_rate == 0 )
1997 msg_Dbg( p_demux, "invalid oggds audio header" );
1998 Ogg_LogicalStreamDelete( p_demux, p_stream );
1999 p_stream = NULL;
2000 p_ogg->i_streams--;
2003 /* Check for text (subtitles) header */
2004 else if( !strncmp(st->streamtype, "text", 4) )
2006 /* We need to get rid of the header packet */
2007 ogg_stream_packetout( &p_stream->os, &oggpacket );
2009 msg_Dbg( p_demux, "found text subtitle header" );
2010 es_format_Change( &p_stream->fmt, SPU_ES, VLC_CODEC_SUBT );
2011 date_Init( &p_stream->dts, 1000, 1 ); /* granulepos is in millisec */
2013 else
2015 msg_Dbg( p_demux, "stream %d has a header marker "
2016 "but is of an unknown type", p_ogg->i_streams-1 );
2017 FREENULL( p_stream );
2018 p_ogg->i_streams--;
2021 else if( oggpacket.bytes >= 8 &&
2022 ! memcmp( oggpacket.packet, "fishead\0", 8 ) )
2025 /* Skeleton */
2026 msg_Dbg( p_demux, "stream %d is a skeleton",
2027 p_ogg->i_streams-1 );
2028 Ogg_ReadSkeletonHeader( p_demux, p_stream, &oggpacket );
2030 /* Check for OggSpots header */
2031 else if( oggpacket.bytes >= 8 &&
2032 ! memcmp( oggpacket.packet, "SPOTS\0\0", 8 ) )
2034 if ( Ogg_ReadOggSpotsHeader( p_stream, &oggpacket ) )
2035 msg_Dbg( p_demux,
2036 "found OggSpots header, time resolution: %u/%u",
2037 p_stream->fmt.video.i_frame_rate,
2038 p_stream->fmt.video.i_frame_rate_base );
2039 else
2041 msg_Err( p_demux, "found invalid OggSpots header" );
2042 Ogg_LogicalStreamDelete( p_demux, p_stream );
2043 p_stream = NULL;
2044 p_ogg->i_streams--;
2047 else
2049 Ogg_LogicalStreamDelete( p_demux, p_stream );
2050 p_stream = NULL;
2051 p_ogg->i_streams--;
2052 msg_Dbg( p_demux, "stream %d is of unknown type",
2053 p_ogg->i_streams );
2056 /* we'll need to get all headers */
2057 if ( p_stream )
2058 p_stream->b_initializing &= p_stream->b_force_backup;
2060 if( Ogg_ReadPage( p_demux, &p_ogg->current_page ) != VLC_SUCCESS )
2061 return VLC_EGENERIC;
2064 /* This is the first data page, which means we are now finished
2065 * with the initial pages. We just need to store it in the relevant
2066 * bitstream. */
2067 for( int i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
2069 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
2070 &p_ogg->current_page ) == 0 )
2072 p_ogg->b_page_waiting = true;
2073 break;
2077 return VLC_SUCCESS;
2081 return VLC_EGENERIC;
2084 /****************************************************************************
2085 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2086 ****************************************************************************/
2087 static void Ogg_CreateES( demux_t *p_demux )
2089 demux_sys_t *p_ogg = p_demux->p_sys;
2090 logical_stream_t *p_old_stream = p_ogg->p_old_stream;
2091 int i_stream;
2093 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2095 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2097 if ( p_stream->p_es == NULL && !p_stream->b_finished )
2099 /* Better be safe than sorry when possible with ogm */
2100 if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
2101 p_stream->fmt.i_codec == VLC_CODEC_A52 )
2102 p_stream->fmt.b_packetized = false;
2104 /* Try first to reuse an old ES */
2105 if( p_old_stream &&
2106 p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&
2107 p_old_stream->fmt.i_codec == p_stream->fmt.i_codec &&
2108 p_old_stream->p_es != NULL && p_stream->p_es != NULL )
2110 msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );
2112 p_stream->p_es = p_old_stream->p_es;
2113 p_stream->b_finished = false;
2114 p_stream->b_reinit = false;
2115 p_stream->b_initializing = false;
2116 p_stream->i_pre_skip = 0;
2117 es_format_Clean( &p_stream->fmt_old );
2118 es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );
2119 bool b_resetdecoder = Ogg_LogicalStreamResetEsFormat( p_demux, p_stream );
2121 p_old_stream->p_es = NULL;
2122 p_old_stream = NULL;
2123 if ( b_resetdecoder )
2125 es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
2126 p_stream->p_es, &p_stream->fmt );
2129 else
2131 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
2136 if( p_ogg->p_old_stream )
2138 if( p_ogg->p_old_stream->p_es )
2139 msg_Dbg( p_demux, "old stream not reused" );
2140 Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
2141 p_ogg->p_old_stream = NULL;
2143 p_ogg->b_es_created = true;
2146 /****************************************************************************
2147 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2148 * Elementary streams.
2149 ****************************************************************************/
2150 static int Ogg_BeginningOfStream( demux_t *p_demux )
2152 demux_sys_t *p_ogg = p_demux->p_sys ;
2153 int i_stream;
2155 /* Find the logical streams embedded in the physical stream and
2156 * initialize our p_ogg structure. */
2157 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
2159 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
2160 return VLC_EGENERIC;
2163 p_ogg->i_bitrate = 0;
2165 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2167 logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
2169 p_stream->p_es = NULL;
2171 /* initialise kframe index */
2172 p_stream->idx=NULL;
2174 if ( p_stream->fmt.i_bitrate == 0 &&
2175 ( p_stream->fmt.i_cat == VIDEO_ES ||
2176 p_stream->fmt.i_cat == AUDIO_ES ) )
2177 p_ogg->b_partial_bitrate = true;
2178 else
2179 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
2181 p_stream->i_pcr = VLC_TICK_INVALID;
2182 p_stream->b_reinit = false;
2185 /* get total frame count for video stream; we will need this for seeking */
2186 p_ogg->i_total_frames = 0;
2188 return VLC_SUCCESS;
2191 /****************************************************************************
2192 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2193 ****************************************************************************/
2194 static void Ogg_EndOfStream( demux_t *p_demux )
2196 demux_sys_t *p_ogg = p_demux->p_sys ;
2197 int i_stream;
2199 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
2200 Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );
2201 free( p_ogg->pp_stream );
2203 /* Reinit p_ogg */
2204 p_ogg->i_bitrate = 0;
2205 p_ogg->i_streams = 0;
2206 p_ogg->pp_stream = NULL;
2207 p_ogg->skeleton.major = 0;
2208 p_ogg->skeleton.minor = 0;
2209 p_ogg->b_preparsing_done = false;
2210 p_ogg->b_es_created = false;
2212 /* */
2213 if( p_ogg->p_meta )
2214 vlc_meta_Delete( p_ogg->p_meta );
2215 p_ogg->p_meta = NULL;
2217 for(int i=0; i<p_ogg->i_attachments; i++)
2218 vlc_input_attachment_Delete( p_ogg->attachments[i] );
2219 TAB_CLEAN(p_ogg->i_attachments, p_ogg->attachments);
2221 for ( int i=0; i < p_ogg->i_seekpoints; i++ )
2223 if ( p_ogg->pp_seekpoints[i] )
2224 vlc_seekpoint_Delete( p_ogg->pp_seekpoints[i] );
2226 TAB_CLEAN( p_ogg->i_seekpoints, p_ogg->pp_seekpoints );
2229 static void Ogg_CleanSpecificData( logical_stream_t *p_stream )
2231 #ifdef HAVE_LIBVORBIS
2232 if ( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2234 if( p_stream->special.vorbis.p_info )
2235 vorbis_info_clear( p_stream->special.vorbis.p_info );
2236 FREENULL( p_stream->special.vorbis.p_info );
2237 if( p_stream->special.vorbis.p_comment )
2238 vorbis_comment_clear( p_stream->special.vorbis.p_comment );
2239 FREENULL( p_stream->special.vorbis.p_comment );
2240 p_stream->special.vorbis.i_headers_flags = 0;
2242 #else
2243 VLC_UNUSED( p_stream );
2244 #endif
2247 static void Ogg_LogicalStreamInit( logical_stream_t *p_stream )
2249 memset( p_stream, 0, sizeof(logical_stream_t) );
2250 es_format_Init( &p_stream->fmt, UNKNOWN_ES, 0 );
2251 es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
2252 p_stream->i_pcr = VLC_TICK_INVALID;
2253 p_stream->i_first_frame_index = 1;
2254 date_Set( &p_stream->dts, VLC_TICK_INVALID );
2255 p_stream->b_initializing = true;
2256 p_stream->b_contiguous = true; /* default */
2257 p_stream->queue.pp_append = &p_stream->queue.p_blocks;
2261 * This function delete and release all data associated to a logical_stream_t
2263 static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream )
2265 demux_sys_t *p_sys = p_demux->p_sys;
2267 if( p_stream->p_es )
2268 es_out_Del( p_demux->out, p_stream->p_es );
2270 ogg_stream_clear( &p_stream->os );
2271 free( p_stream->p_headers );
2273 Ogg_CleanSpecificData( p_stream );
2275 es_format_Clean( &p_stream->fmt_old );
2276 es_format_Clean( &p_stream->fmt );
2278 if ( p_stream->idx != NULL)
2280 oggseek_index_entries_free( p_stream->idx );
2283 Ogg_FreeSkeleton( p_stream->p_skel );
2284 p_stream->p_skel = NULL;
2285 if( p_sys->p_skelstream == p_stream )
2286 p_sys->p_skelstream = NULL;
2288 /* Shouldn't happen */
2289 block_ChainRelease( p_stream->queue.p_blocks );
2291 free( p_stream );
2294 * This function check if a we need to reset a decoder in case we are
2295 * reusing an old ES
2297 static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old )
2299 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2300 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2301 unsigned i_new_count;
2302 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2303 i_new_count = 0;
2305 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2306 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2307 unsigned i_old_count;
2308 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2309 i_old_count = 0;
2311 bool b_match = i_new_count == i_old_count;
2312 for( unsigned i = 0; i < i_new_count && b_match; i++ )
2314 /* Ignore vorbis comment */
2315 if( i == 1 )
2316 continue;
2317 if( pi_new_size[i] != pi_old_size[i] ||
2318 memcmp( pp_new_data[i], pp_old_data[i], pi_new_size[i] ) )
2319 b_match = false;
2322 return b_match;
2325 static bool Ogg_IsOpusFormatCompatible( const es_format_t *p_new,
2326 const es_format_t *p_old )
2328 unsigned pi_new_size[XIPH_MAX_HEADER_COUNT];
2329 void *pp_new_data[XIPH_MAX_HEADER_COUNT];
2330 unsigned i_new_count;
2331 if( xiph_SplitHeaders(pi_new_size, pp_new_data, &i_new_count, p_new->i_extra, p_new->p_extra ) )
2332 i_new_count = 0;
2333 unsigned pi_old_size[XIPH_MAX_HEADER_COUNT];
2334 void *pp_old_data[XIPH_MAX_HEADER_COUNT];
2335 unsigned i_old_count;
2336 if( xiph_SplitHeaders(pi_old_size, pp_old_data, &i_old_count, p_old->i_extra, p_old->p_extra ) )
2337 i_old_count = 0;
2338 bool b_match = false;
2339 if( i_new_count == i_old_count && i_new_count > 0 )
2341 static const unsigned char default_map[2] = { 0, 1 };
2342 unsigned char *p_old_head;
2343 unsigned char *p_new_head;
2344 const unsigned char *p_old_map;
2345 const unsigned char *p_new_map;
2346 int i_old_channel_count;
2347 int i_new_channel_count;
2348 int i_old_stream_count;
2349 int i_new_stream_count;
2350 int i_old_coupled_count;
2351 int i_new_coupled_count;
2352 p_old_head = (unsigned char *)pp_old_data[0];
2353 i_old_channel_count = i_old_stream_count = i_old_coupled_count = 0;
2354 p_old_map = default_map;
2355 if( pi_old_size[0] >= 19 && p_old_head[8] <= 15 )
2357 i_old_channel_count = p_old_head[9];
2358 switch( p_old_head[18] )
2360 case 0:
2361 i_old_stream_count = 1;
2362 i_old_coupled_count = i_old_channel_count - 1;
2363 break;
2364 case 1:
2365 if( pi_old_size[0] >= 21U + i_old_channel_count )
2367 i_old_stream_count = p_old_head[19];
2368 i_old_coupled_count = p_old_head[20];
2369 p_old_map = p_old_head + 21;
2371 break;
2374 p_new_head = (unsigned char *)pp_new_data[0];
2375 i_new_channel_count = i_new_stream_count = i_new_coupled_count = 0;
2376 p_new_map = default_map;
2377 if( pi_new_size[0] >= 19 && p_new_head[8] <= 15 )
2379 i_new_channel_count = p_new_head[9];
2380 switch( p_new_head[18] )
2382 case 0:
2383 i_new_stream_count = 1;
2384 i_new_coupled_count = i_new_channel_count - 1;
2385 break;
2386 case 1:
2387 if( pi_new_size[0] >= 21U + i_new_channel_count )
2389 i_new_stream_count = p_new_head[19];
2390 i_new_coupled_count = p_new_head[20];
2391 p_new_map = p_new_head+21;
2393 break;
2396 b_match = i_old_channel_count == i_new_channel_count &&
2397 i_old_stream_count == i_new_stream_count &&
2398 i_old_coupled_count == i_new_coupled_count &&
2399 memcmp(p_old_map, p_new_map,
2400 i_new_channel_count*sizeof(*p_new_map)) == 0;
2403 return b_match;
2406 static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream )
2408 bool b_compatible = false;
2409 if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )
2410 return true;
2412 /* Only Vorbis and Opus are supported. */
2413 if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS )
2414 b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2415 else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
2416 b_compatible = Ogg_IsOpusFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );
2417 else if( p_stream->fmt.i_codec == VLC_CODEC_FLAC )
2418 b_compatible = !p_stream->fmt.b_packetized;
2420 if( !b_compatible )
2421 msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );
2423 return !b_compatible;
2426 static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
2427 const void *p_headers, unsigned i_headers )
2429 demux_sys_t *p_ogg = p_demux->p_sys;
2430 int i_cover_score = 0;
2431 int i_cover_idx = 0;
2432 float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
2433 float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
2434 for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
2436 pf_replay_gain[i] = 0;
2437 pf_replay_peak[i] = 0;
2439 vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
2440 &p_ogg->i_attachments, &p_ogg->attachments,
2441 &i_cover_score, &i_cover_idx,
2442 &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
2443 &pf_replay_gain, &pf_replay_peak );
2444 if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
2446 char psz_url[128];
2447 snprintf( psz_url, sizeof(psz_url), "attachment://%s",
2448 p_ogg->attachments[i_cover_idx]->psz_name );
2449 vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
2452 for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
2454 if ( pf_replay_gain[i] != 0 )
2456 p_fmt->audio_replay_gain.pb_gain[i] = true;
2457 p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
2458 msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
2460 if ( pf_replay_peak[i] != 0 )
2462 p_fmt->audio_replay_gain.pb_peak[i] = true;
2463 p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
2464 msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
2468 if( p_ogg->i_seekpoints > 1 )
2470 p_ogg->updates |= INPUT_UPDATE_TITLE_LIST;
2474 static inline uint32_t GetDW24BE( const uint8_t *p )
2476 uint32_t i = ( p[0] << 16 ) + ( p[1] << 8 ) + ( p[2] );
2477 #ifdef WORDS_BIGENDIAN
2478 i = vlc_bswap32(i);
2479 #endif
2480 return i;
2483 static void Ogg_ExtractFlacComments( demux_t *p_demux, es_format_t *p_fmt,
2484 const uint8_t *p_headers, unsigned i_headers )
2486 /* Skip Streaminfo 42 bytes / 1st page */
2487 if(i_headers <= 46)
2488 return;
2489 p_headers += 42; i_headers -= 42;
2490 /* Block Header 1 + 3 bytes */
2491 uint32_t blocksize = GetDW24BE(&p_headers[1]);
2492 if(p_headers[0] == 0x84 && blocksize <= i_headers - 4)
2494 Ogg_ExtractComments( p_demux, p_fmt, &p_headers[4], i_headers - 4 );
2498 static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
2499 const void *p_headers, unsigned i_headers, unsigned i_skip )
2501 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
2502 void *pp_data[XIPH_MAX_HEADER_COUNT];
2503 unsigned i_count;
2505 if( xiph_SplitHeaders( pi_size, pp_data, &i_count, i_headers, p_headers ) )
2506 return;
2507 /* TODO how to handle multiple comments properly ? */
2508 if( i_count >= 2 && pi_size[1] > i_skip )
2510 Ogg_ExtractComments( p_demux, p_fmt, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip );
2514 static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
2516 demux_sys_t *p_ogg = p_demux->p_sys;
2518 switch( p_fmt->i_codec )
2520 /* 3 headers with the 2° one being the comments */
2521 case VLC_CODEC_VORBIS:
2522 case VLC_CODEC_THEORA:
2523 case VLC_CODEC_DAALA:
2524 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
2525 break;
2526 case VLC_CODEC_OPUS:
2527 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
2528 break;
2529 case VLC_CODEC_SPEEX:
2530 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
2531 break;
2532 case VLC_CODEC_VP8:
2533 Ogg_ExtractComments( p_demux, p_fmt, p_headers, i_headers );
2534 break;
2535 /* N headers with the 2° one being the comments */
2536 case VLC_CODEC_KATE:
2537 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2538 Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
2539 break;
2541 /* TODO */
2542 case VLC_CODEC_FLAC:
2543 Ogg_ExtractFlacComments( p_demux, p_fmt, p_headers, i_headers );
2544 break;
2546 /* No meta data */
2547 case VLC_CODEC_DIRAC:
2548 default:
2549 break;
2551 if( p_ogg->p_meta )
2552 p_ogg->updates |= INPUT_UPDATE_META;
2555 static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
2556 ogg_packet *p_oggpacket )
2558 bs_t bitstream;
2559 unsigned int i_fps_numerator;
2560 unsigned int i_fps_denominator;
2561 int i_keyframe_frequency_force;
2562 int i_major;
2563 int i_minor;
2564 int i_subminor;
2565 int i_version;
2567 /* Signal that we want to keep a backup of the theora
2568 * stream headers. They will be used when switching between
2569 * audio streams. */
2570 p_stream->b_force_backup = true;
2572 /* Cheat and get additionnal info ;) */
2573 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
2574 bs_skip( &bitstream, 56 );
2576 i_major = bs_read( &bitstream, 8 ); /* major version num */
2577 i_minor = bs_read( &bitstream, 8 ); /* minor version num */
2578 i_subminor = bs_read( &bitstream, 8 ); /* subminor version num */
2580 bs_read( &bitstream, 16 ) /*<< 4*/; /* width */
2581 bs_read( &bitstream, 16 ) /*<< 4*/; /* height */
2582 bs_read( &bitstream, 24 ); /* frame width */
2583 bs_read( &bitstream, 24 ); /* frame height */
2584 bs_read( &bitstream, 8 ); /* x offset */
2585 bs_read( &bitstream, 8 ); /* y offset */
2587 i_fps_numerator = bs_read( &bitstream, 32 );
2588 i_fps_denominator = bs_read( &bitstream, 32 );
2589 i_fps_denominator = __MAX( i_fps_denominator, 1 );
2590 bs_read( &bitstream, 24 ); /* aspect_numerator */
2591 bs_read( &bitstream, 24 ); /* aspect_denominator */
2593 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
2594 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
2596 bs_read( &bitstream, 8 ); /* colorspace */
2597 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
2598 bs_read( &bitstream, 6 ); /* quality */
2600 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
2602 /* granule_shift = i_log( frequency_force -1 ) */
2603 p_stream->i_granule_shift = 0;
2604 i_keyframe_frequency_force--;
2605 while( i_keyframe_frequency_force )
2607 p_stream->i_granule_shift++;
2608 i_keyframe_frequency_force >>= 1;
2611 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2612 p_stream->i_first_frame_index = (i_version >= 3002001) ? 1 : 0;
2613 if ( !i_fps_denominator || !i_fps_numerator )
2614 return false;
2615 date_Init( &p_stream->dts, i_fps_numerator, i_fps_denominator );
2617 return true;
2620 static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
2621 ogg_packet *p_oggpacket )
2623 oggpack_buffer opb;
2624 uint32_t i_timebase_numerator;
2625 uint32_t i_timebase_denominator;
2626 int i_keyframe_frequency_force;
2627 uint8_t i_major;
2628 uint8_t i_minor;
2629 uint8_t i_subminor;
2630 int i_version;
2632 /* Signal that we want to keep a backup of the daala
2633 * stream headers. They will be used when switching between
2634 * audio streams. */
2635 p_stream->b_force_backup = true;
2637 /* Cheat and get additionnal info ;) */
2638 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
2639 oggpack_adv( &opb, 48 );
2641 i_major = oggpack_read( &opb, 8 ); /* major version num */
2642 i_minor = oggpack_read( &opb, 8 ); /* minor version num */
2643 i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
2645 oggpack_adv( &opb, 32 ); /* width */
2646 oggpack_adv( &opb, 32 ); /* height */
2648 oggpack_adv( &opb, 32 ); /* aspect numerator */
2649 oggpack_adv( &opb, 32 ); /* aspect denominator */
2650 i_timebase_numerator = oggpack_read( &opb, 32 );
2652 i_timebase_denominator = oggpack_read( &opb, 32 );
2653 i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
2655 p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
2656 p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
2658 oggpack_adv( &opb, 32 ); /* frame duration */
2660 i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
2662 /* granule_shift = i_log( frequency_force -1 ) */
2663 p_stream->i_granule_shift = 0;
2664 i_keyframe_frequency_force--;
2665 while( i_keyframe_frequency_force )
2667 p_stream->i_granule_shift++;
2668 i_keyframe_frequency_force >>= 1;
2671 i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
2672 VLC_UNUSED(i_version);
2673 p_stream->i_first_frame_index = 0;
2674 if ( !i_timebase_numerator || !i_timebase_denominator )
2675 return false;
2676 date_Init( &p_stream->dts, i_timebase_numerator, i_timebase_denominator );
2678 return true;
2681 static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
2682 ogg_packet *p_oggpacket )
2684 oggpack_buffer opb;
2686 /* Signal that we want to keep a backup of the vorbis
2687 * stream headers. They will be used when switching between
2688 * audio streams. */
2689 p_stream->b_force_backup = true;
2691 /* Cheat and get additionnal info ;) */
2692 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2693 oggpack_adv( &opb, 88 );
2694 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2695 fill_channels_info(&p_stream->fmt.audio);
2696 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2697 if( p_stream->fmt.audio.i_rate == 0 )
2698 return false;
2699 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2701 oggpack_adv( &opb, 32 );
2702 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 ); /* is signed 32 */
2703 if( p_stream->fmt.i_bitrate > INT32_MAX ) p_stream->fmt.i_bitrate = 0;
2704 return true;
2706 #ifdef HAVE_LIBVORBIS
2707 static void Ogg_DecodeVorbisHeader( logical_stream_t *p_stream,
2708 ogg_packet *p_oggpacket, int i_number )
2710 switch( i_number )
2712 case VORBIS_HEADER_IDENTIFICATION:
2713 p_stream->special.vorbis.p_info = calloc( 1, sizeof(vorbis_info) );
2714 p_stream->special.vorbis.p_comment = malloc( sizeof(vorbis_comment) );
2715 if ( !p_stream->special.vorbis.p_info || !p_stream->special.vorbis.p_comment )
2717 FREENULL( p_stream->special.vorbis.p_info );
2718 FREENULL( p_stream->special.vorbis.p_comment );
2719 break;
2721 vorbis_info_init( p_stream->special.vorbis.p_info );
2722 vorbis_comment_init( p_stream->special.vorbis.p_comment );
2723 /* fallthrough */
2725 case VORBIS_HEADER_COMMENT:
2726 case VORBIS_HEADER_SETUP:
2727 if ( !p_stream->special.vorbis.p_info ||
2728 vorbis_synthesis_headerin(
2729 p_stream->special.vorbis.p_info,
2730 p_stream->special.vorbis.p_comment, p_oggpacket ) )
2731 break;
2733 p_stream->special.vorbis.i_headers_flags |= VORBIS_HEADER_TO_FLAG(i_number);
2734 /* fallthrough */
2736 default:
2737 break;
2740 #endif
2742 static bool Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
2743 ogg_packet *p_oggpacket )
2745 oggpack_buffer opb;
2747 /* Signal that we want to keep a backup of the speex
2748 * stream headers. They will be used when switching between
2749 * audio streams. */
2750 p_stream->b_force_backup = true;
2752 /* Cheat and get additionnal info ;) */
2753 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2754 oggpack_adv( &opb, 224 );
2755 oggpack_adv( &opb, 32 ); /* speex_version_id */
2756 oggpack_adv( &opb, 32 ); /* header_size */
2757 p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
2758 if ( !p_stream->fmt.audio.i_rate )
2759 return false;
2760 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2761 oggpack_adv( &opb, 32 ); /* mode */
2762 oggpack_adv( &opb, 32 ); /* mode_bitstream_version */
2763 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
2764 fill_channels_info(&p_stream->fmt.audio);
2765 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
2766 p_stream->special.speex.i_framesize =
2767 oggpack_read( &opb, 32 ); /* frame_size */
2768 oggpack_adv( &opb, 32 ); /* vbr */
2769 p_stream->special.speex.i_framesperpacket =
2770 oggpack_read( &opb, 32 ); /* frames_per_packet */
2771 p_stream->i_extra_headers_packets = oggpack_read( &opb, 32 ); /* extra_headers */
2772 return true;
2775 static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
2776 ogg_packet *p_oggpacket )
2778 oggpack_buffer opb;
2780 /* Signal that we want to keep a backup of the opus
2781 * stream headers. They will be used when switching between
2782 * audio streams. */
2783 p_stream->b_force_backup = true;
2785 /* All OggOpus streams are timestamped at 48kHz and
2786 * can be played at 48kHz. */
2787 p_stream->fmt.audio.i_rate = 48000;
2788 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2789 p_stream->fmt.i_bitrate = 0;
2791 /* Cheat and get additional info ;) */
2792 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2793 oggpack_adv( &opb, 64 );
2794 oggpack_adv( &opb, 8 ); /* version_id */
2795 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
2796 fill_channels_info(&p_stream->fmt.audio);
2797 p_stream->i_pre_skip = oggpack_read( &opb, 16 );
2798 /* For Opus, trash the first 80 ms of decoded output as
2799 well, to avoid blowing out speakers if we get unlucky.
2800 Opus predicts content from prior frames, which can go
2801 badly if we seek right where the stream goes from very
2802 quiet to very loud. It will converge after a bit. */
2803 p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
2806 static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
2807 ogg_packet *p_oggpacket )
2809 /* Parse the STREAMINFO metadata */
2810 bs_t s;
2812 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
2814 bs_read( &s, 1 );
2815 if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
2817 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
2818 return false;
2821 if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
2823 bs_skip( &s, 80 );
2824 p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
2825 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
2826 fill_channels_info(&p_stream->fmt.audio);
2828 msg_Dbg( p_demux, "FLAC header, channels: %"PRIu8", rate: %u",
2829 p_stream->fmt.audio.i_channels, p_stream->fmt.audio.i_rate );
2830 if ( p_stream->fmt.audio.i_rate == 0 )
2831 return false;
2832 date_Init( &p_stream->dts, p_stream->fmt.audio.i_rate, 1 );
2834 else
2836 msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
2839 /* Fake this as the last metadata block */
2840 *((uint8_t*)p_oggpacket->packet) |= 0x80;
2841 return true;
2844 static bool Ogg_ReadKateHeader( logical_stream_t *p_stream,
2845 ogg_packet *p_oggpacket )
2847 oggpack_buffer opb;
2848 uint32_t gnum;
2849 uint32_t gden;
2850 int n;
2851 char *psz_desc;
2853 /* Signal that we want to keep a backup of the kate
2854 * stream headers. They will be used when switching between
2855 * kate streams. */
2856 p_stream->b_force_backup = true;
2858 /* Cheat and get additionnal info ;) */
2859 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
2860 oggpack_adv( &opb, 11*8 ); /* packet type, kate magic, version */
2861 p_stream->special.kate.i_num_headers = oggpack_read( &opb, 8 );
2862 oggpack_adv( &opb, 3*8 );
2863 p_stream->i_granule_shift = oggpack_read( &opb, 8 );
2864 oggpack_adv( &opb, 8*8 ); /* reserved */
2865 gnum = oggpack_read( &opb, 32 );
2866 gden = oggpack_read( &opb, 32 );
2867 gden = __MAX( gden, 1 );
2868 if ( !gnum || !gden )
2869 return false;
2870 date_Init( &p_stream->dts, gnum, gden );
2872 p_stream->fmt.psz_language = malloc(16);
2873 if( p_stream->fmt.psz_language )
2875 for( n = 0; n < 16; n++ )
2876 p_stream->fmt.psz_language[n] = oggpack_read(&opb,8);
2877 p_stream->fmt.psz_language[15] = 0; /* just in case */
2879 else
2881 for( n = 0; n < 16; n++ )
2882 oggpack_read(&opb,8);
2884 p_stream->fmt.psz_description = malloc(16);
2885 if( p_stream->fmt.psz_description )
2887 for( n = 0; n < 16; n++ )
2888 p_stream->fmt.psz_description[n] = oggpack_read(&opb,8);
2889 p_stream->fmt.psz_description[15] = 0; /* just in case */
2891 /* Now find a localized user readable description for this category */
2892 psz_desc = strdup(FindKateCategoryName(p_stream->fmt.psz_description));
2893 if( psz_desc )
2895 free( p_stream->fmt.psz_description );
2896 p_stream->fmt.psz_description = psz_desc;
2899 else
2901 for( n = 0; n < 16; n++ )
2902 oggpack_read(&opb,8);
2905 return true;
2908 static bool Ogg_ReadVP8Header( demux_t *p_demux, logical_stream_t *p_stream,
2909 ogg_packet *p_oggpacket )
2911 switch( p_oggpacket->packet[5] )
2913 /* STREAMINFO */
2914 case 0x01:
2915 /* Mapping version */
2916 if ( p_oggpacket->packet[6] != 0x01 || p_oggpacket->packet[7] != 0x00 )
2917 return false;
2918 p_stream->i_granule_shift = 32;
2919 p_stream->fmt.video.i_width = GetWBE( &p_oggpacket->packet[8] );
2920 p_stream->fmt.video.i_height = GetWBE( &p_oggpacket->packet[10] );
2921 p_stream->fmt.video.i_visible_width = p_stream->fmt.video.i_width;
2922 p_stream->fmt.video.i_visible_height = p_stream->fmt.video.i_height;
2923 p_stream->fmt.video.i_sar_num = GetDWBE( &p_oggpacket->packet[12 - 1] ) & 0x0FFF;
2924 p_stream->fmt.video.i_sar_den = GetDWBE( &p_oggpacket->packet[15 - 1] ) & 0x0FFF;
2925 p_stream->fmt.video.i_frame_rate = GetDWBE( &p_oggpacket->packet[18] );
2926 p_stream->fmt.video.i_frame_rate_base = GetDWBE( &p_oggpacket->packet[22] );
2927 if ( !p_stream->fmt.video.i_frame_rate || !p_stream->fmt.video.i_frame_rate_base )
2928 return false;
2929 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
2930 p_stream->fmt.video.i_frame_rate_base );
2931 return true;
2932 /* METADATA */
2933 case 0x02:
2934 Ogg_ExtractMeta( p_demux, & p_stream->fmt,
2935 p_oggpacket->packet + 7, p_oggpacket->bytes - 7 );
2936 return true;
2937 default:
2938 return false;
2942 static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_value,
2943 bool *b_force_backup )
2945 if( p_stream->fmt.i_cat != UNKNOWN_ES )
2946 return;
2948 if( !strncmp(psz_value, "audio/x-wav", 11) )
2950 /* n.b. WAVs are unsupported right now */
2951 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
2952 free( p_stream->fmt.psz_description );
2953 p_stream->fmt.psz_description = strdup("WAV Audio (Unsupported)");
2955 else if( !strncmp(psz_value, "audio/x-vorbis", 14) ||
2956 !strncmp(psz_value, "audio/vorbis", 12) )
2958 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_VORBIS );
2960 *b_force_backup = true;
2962 else if( !strncmp(psz_value, "audio/x-speex", 13) ||
2963 !strncmp(psz_value, "audio/speex", 11) )
2965 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_SPEEX );
2967 *b_force_backup = true;
2969 else if( !strncmp(psz_value, "audio/flac", 10) )
2971 es_format_Change( &p_stream->fmt, AUDIO_ES, VLC_CODEC_FLAC );
2973 *b_force_backup = true;
2975 else if( !strncmp(psz_value, "video/x-theora", 14) ||
2976 !strncmp(psz_value, "video/theora", 12) )
2978 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_THEORA );
2980 *b_force_backup = true;
2982 else if( !strncmp(psz_value, "video/x-daala", 13) ||
2983 !strncmp(psz_value, "video/daala", 11) )
2985 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_DAALA );
2987 *b_force_backup = true;
2989 else if( !strncmp(psz_value, "video/x-xvid", 12) )
2991 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_FOURCC( 'x','v','i','d' ) );
2993 *b_force_backup = true;
2995 else if( !strncmp(psz_value, "video/mpeg", 10) )
2997 /* n.b. MPEG streams are unsupported right now */
2998 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_MPGV );
3000 else if( !strncmp(psz_value, "application/kate", 16) )
3002 /* ??? */
3003 es_format_Change( &p_stream->fmt, UNKNOWN_ES, 0 );
3004 p_stream->fmt.psz_description = strdup("OGG Kate Overlay (Unsupported)");
3006 else if( !strncmp(psz_value, "video/x-vp8", 11) )
3008 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_VP8 );
3012 static void Ogg_ReadAnnodexHeader( demux_t *p_demux,
3013 logical_stream_t *p_stream,
3014 ogg_packet *p_oggpacket )
3016 if( p_oggpacket->bytes >= 28 &&
3017 !memcmp( p_oggpacket->packet, "Annodex", 7 ) )
3019 oggpack_buffer opb;
3021 uint16_t major_version;
3022 uint16_t minor_version;
3023 uint64_t timebase_numerator;
3024 uint64_t timebase_denominator;
3026 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
3028 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
3029 oggpack_adv( &opb, 8*8 ); /* "Annodex\0" header */
3030 major_version = oggpack_read( &opb, 2*8 ); /* major version */
3031 minor_version = oggpack_read( &opb, 2*8 ); /* minor version */
3032 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
3033 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
3035 msg_Dbg( p_demux, "Annodex info: version %"PRIu16".%"PRIu16" "
3036 "Timebase %"PRId64" / %"PRId64,
3037 major_version, minor_version,
3038 timebase_numerator, timebase_denominator );
3040 else if( p_oggpacket->bytes >= 42 &&
3041 !memcmp( p_oggpacket->packet, "AnxData", 7 ) )
3043 uint64_t granule_rate_numerator;
3044 uint64_t granule_rate_denominator;
3045 char content_type_string[1024];
3047 /* Read in Annodex header fields */
3049 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
3050 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
3051 p_stream->i_secondary_header_packets =
3052 GetDWLE( &p_oggpacket->packet[24] );
3054 /* we are guaranteed that the first header field will be
3055 * the content-type (by the Annodex standard) */
3056 content_type_string[0] = '\0';
3057 if( !strncasecmp( (char*)(&p_oggpacket->packet[28]), "Content-Type: ", 14 ) )
3059 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
3060 p_oggpacket->bytes - 1 );
3061 if( p && p[0] == '\r' && p[1] == '\n' )
3062 sscanf( (char*)(&p_oggpacket->packet[42]), "%1023s\r\n",
3063 content_type_string );
3066 msg_Dbg( p_demux, "AnxData packet info: %"PRId64" / %"PRId64", %d, ``%s''",
3067 granule_rate_numerator, granule_rate_denominator,
3068 p_stream->i_secondary_header_packets, content_type_string );
3070 if( granule_rate_numerator && granule_rate_denominator )
3071 date_Init( &p_stream->dts, granule_rate_numerator, granule_rate_denominator );
3073 /* What type of file do we have?
3074 * strcmp is safe to use here because we've extracted
3075 * content_type_string from the stream manually */
3076 Ogg_ApplyContentType( p_stream, content_type_string,
3077 &p_stream->b_force_backup );
3081 static void Ogg_ReadSkeletonHeader( demux_t *p_demux, logical_stream_t *p_stream,
3082 ogg_packet *p_oggpacket )
3084 demux_sys_t *p_sys = p_demux->p_sys;
3086 p_sys->p_skelstream = p_stream;
3087 /* There can be only 1 skeleton for streams */
3088 p_sys->skeleton.major = GetWLE( &p_oggpacket->packet[8] );
3089 p_sys->skeleton.minor = GetWLE( &p_oggpacket->packet[10] );
3090 if ( asprintf( & p_stream->fmt.psz_description,
3091 "OGG Skeleton version %" PRIu16 ".%" PRIu16,
3092 p_sys->skeleton.major, p_sys->skeleton.minor ) < 0 )
3093 p_stream->fmt.psz_description = NULL;
3096 static void Ogg_ReadSkeletonBones( demux_t *p_demux, ogg_packet *p_oggpacket )
3098 demux_sys_t *p_sys = p_demux->p_sys;
3100 if ( p_sys->skeleton.major < 3 || p_oggpacket->bytes < 52 ) return;
3102 /* Find the matching stream for this skeleton data */
3103 ogg_int32_t i_serialno = GetDWLE( &p_oggpacket->packet[12] );
3104 logical_stream_t *p_target_stream = NULL;
3105 for ( int i=0; i< p_sys->i_streams; i++ )
3107 if ( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3109 p_target_stream = p_sys->pp_stream[i];
3110 break;
3113 if ( !p_target_stream ) return;
3115 ogg_skeleton_t *p_skel = p_target_stream->p_skel;
3116 if ( !p_skel )
3118 p_skel = malloc( sizeof( ogg_skeleton_t ) );
3119 if ( !p_skel ) return;
3120 TAB_INIT( p_skel->i_messages, p_skel->ppsz_messages );
3121 p_skel->p_index = NULL;
3122 p_target_stream->p_skel = p_skel;
3125 const unsigned char *p_messages = p_oggpacket->packet + 8 + GetDWLE( &p_oggpacket->packet[8] );
3126 const unsigned char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3127 const unsigned char *p = p_messages;
3128 while ( p <= p_boundary - 1 && p > p_oggpacket->packet )
3130 if ( *p == 0x0D && *(p+1) == 0x0A )
3132 char *psz_message = strndup( (const char *) p_messages,
3133 p - p_messages );
3134 if ( psz_message )
3136 msg_Dbg( p_demux, "stream %" PRId32 " [%s]", i_serialno, psz_message );
3137 TAB_APPEND( p_skel->i_messages, p_skel->ppsz_messages, psz_message );
3139 if ( p < p_boundary - 1 ) p_messages = p + 2;
3141 p++;
3146 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3147 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin,
3148 unsigned const char *p_end,
3149 uint64_t *pi_value )
3151 int i_shift = 0;
3152 int64_t i_read = 0;
3153 *pi_value = 0;
3155 while ( p_begin < p_end )
3157 i_read = *p_begin & 0x7F; /* High bit is start of integer */
3158 *pi_value = *pi_value | ( i_read << i_shift );
3159 i_shift += 7;
3160 if ( (*p_begin++ & 0x80) == 0x80 ) break; /* see prev */
3163 *pi_value = GetQWLE( pi_value );
3164 return p_begin;
3167 static void Ogg_ReadSkeletonIndex( demux_t *p_demux, ogg_packet *p_oggpacket )
3169 demux_sys_t *p_sys = p_demux->p_sys;
3171 if( p_sys->skeleton.major < 4
3172 || p_oggpacket->bytes < 44 /* Need at least 1 index value (42+1+1) */
3173 ) return;
3175 /* Find the matching stream for this skeleton data */
3176 int32_t i_serialno = GetDWLE( &p_oggpacket->packet[6] );
3177 logical_stream_t *p_stream = NULL;
3178 for ( int i=0; i< p_sys->i_streams; i++ )
3180 if( p_sys->pp_stream[i]->i_serial_no == i_serialno )
3182 p_stream = p_sys->pp_stream[i];
3183 break;
3186 if ( !p_stream || !p_stream->p_skel ) return;
3187 uint64_t i_keypoints = GetQWLE( &p_oggpacket->packet[10] );
3188 msg_Dbg( p_demux, "%" PRIi64 " index data for %" PRIi32, i_keypoints, i_serialno );
3189 if ( !i_keypoints ) return;
3191 p_stream->p_skel->i_indexstampden = GetQWLE( &p_oggpacket->packet[18] );
3192 p_stream->p_skel->i_indexfirstnum = GetQWLE( &p_oggpacket->packet[24] );
3193 p_stream->p_skel->i_indexlastnum = GetQWLE( &p_oggpacket->packet[32] );
3194 unsigned const char *p_fwdbyte = &p_oggpacket->packet[42];
3195 unsigned const char *p_boundary = p_oggpacket->packet + p_oggpacket->bytes;
3196 uint64_t i_offset = 0;
3197 uint64_t i_time = 0;
3198 uint64_t i_keypoints_found = 0;
3200 while( p_fwdbyte < p_boundary && i_keypoints_found < i_keypoints )
3202 uint64_t i_val;
3203 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3204 i_offset += i_val;
3205 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte, p_boundary, &i_val );
3206 i_time += i_val * p_stream->p_skel->i_indexstampden;
3207 i_keypoints_found++;
3210 if ( i_keypoints_found != i_keypoints )
3212 msg_Warn( p_demux, "Invalid Index: missing entries" );
3213 return;
3216 p_stream->p_skel->p_index = malloc( p_oggpacket->bytes - 42 );
3217 if ( !p_stream->p_skel->p_index ) return;
3218 memcpy( p_stream->p_skel->p_index, &p_oggpacket->packet[42],
3219 p_oggpacket->bytes - 42 );
3220 p_stream->p_skel->i_index = i_keypoints_found;
3221 p_stream->p_skel->i_index_size = p_oggpacket->bytes - 42;
3224 static void Ogg_FreeSkeleton( ogg_skeleton_t *p_skel )
3226 if ( !p_skel ) return;
3227 for ( int i=0; i< p_skel->i_messages; i++ )
3228 free( p_skel->ppsz_messages[i] );
3229 TAB_CLEAN( p_skel->i_messages, p_skel->ppsz_messages );
3230 free( p_skel->p_index );
3231 free( p_skel );
3234 static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
3236 if ( !p_stream->p_skel ) return;
3237 for ( int i=0; i< p_stream->p_skel->i_messages; i++ )
3239 const char *psz_message = p_stream->p_skel->ppsz_messages[i];
3240 if ( ! strncmp( "Name: ", psz_message, 6 ) )
3242 free( p_stream->fmt.psz_description );
3243 p_stream->fmt.psz_description = strdup( psz_message + 6 );
3245 else if ( ! strncmp("Content-Type: ", psz_message, 14 ) )
3247 bool b_foo;
3248 Ogg_ApplyContentType( p_stream, psz_message + 14, &b_foo );
3253 /* Return true if there's a skeleton exact match */
3254 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, vlc_tick_t i_time,
3255 int64_t *pi_lower, int64_t *pi_upper )
3257 if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index ||
3258 i_time == VLC_TICK_INVALID )
3259 return false;
3261 i_time -= VLC_TICK_0;
3263 /* Validate range */
3264 if ( i_time < p_stream->p_skel->i_indexfirstnum
3265 * p_stream->p_skel->i_indexstampden ||
3266 i_time > p_stream->p_skel->i_indexlastnum
3267 * p_stream->p_skel->i_indexstampden ) return false;
3269 /* Then Lookup its index */
3270 unsigned const char *p_fwdbyte = p_stream->p_skel->p_index;
3271 struct
3273 int64_t i_pos;
3274 vlc_tick_t i_time;
3275 } current = { 0, 0 }, prev = { -1, -1 };
3277 uint64_t i_keypoints_found = 0;
3279 while( p_fwdbyte < p_fwdbyte + p_stream->p_skel->i_index_size
3280 && i_keypoints_found < p_stream->p_skel->i_index )
3282 uint64_t i_val;
3283 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3284 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3285 current.i_pos += i_val;
3286 p_fwdbyte = Read7BitsVariableLE( p_fwdbyte,
3287 p_fwdbyte + p_stream->p_skel->i_index_size, &i_val );
3288 current.i_time += i_val * p_stream->p_skel->i_indexstampden;
3289 if ( current.i_pos < 0 || current.i_time < 0 ) break;
3291 i_keypoints_found++;
3293 if ( i_time <= current.i_time )
3295 *pi_lower = prev.i_pos;
3296 *pi_upper = current.i_pos;
3297 return ( i_time == current.i_time );
3299 prev = current;
3301 return false;
3304 static uint32_t dirac_uint( bs_t *p_bs )
3306 uint32_t u_count = 0, u_value = 0;
3308 while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
3310 u_count++;
3311 u_value <<= 1;
3312 u_value |= bs_read( p_bs, 1 );
3315 return (1<<u_count) - 1 + u_value;
3318 static int dirac_bool( bs_t *p_bs )
3320 return bs_read( p_bs, 1 );
3323 static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
3324 ogg_packet *p_oggpacket )
3326 p_stream->special.dirac.b_old = (p_oggpacket->packet[0] == 'K');
3328 static const struct {
3329 uint32_t u_n /* numerator */, u_d /* denominator */;
3330 } p_dirac_frate_tbl[] = { /* table 10.3 */
3331 {1,1}, /* this first value is never used */
3332 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3333 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3335 static const size_t u_dirac_frate_tbl = sizeof(p_dirac_frate_tbl)/sizeof(*p_dirac_frate_tbl);
3337 static const uint32_t pu_dirac_vidfmt_frate[] = { /* table C.1 */
3338 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3340 static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
3342 bs_t bs;
3344 /* Backing up stream headers is not required -- seqhdrs are repeated
3345 * thoughout the stream at suitable decoding start points */
3346 p_stream->b_force_backup = false;
3348 /* read in useful bits from sequence header */
3349 bs_init( &bs, p_oggpacket->packet, p_oggpacket->bytes );
3350 bs_skip( &bs, 13*8); /* parse_info_header */
3351 dirac_uint( &bs ); /* major_version */
3352 dirac_uint( &bs ); /* minor_version */
3353 dirac_uint( &bs ); /* profile */
3354 dirac_uint( &bs ); /* level */
3356 uint32_t u_video_format = dirac_uint( &bs ); /* index */
3357 if( u_video_format >= u_dirac_vidfmt_frate )
3359 /* don't know how to parse this ogg dirac stream */
3360 return false;
3363 if( dirac_bool( &bs ) )
3365 dirac_uint( &bs ); /* frame_width */
3366 dirac_uint( &bs ); /* frame_height */
3369 if( dirac_bool( &bs ) )
3371 dirac_uint( &bs ); /* chroma_format */
3374 if( dirac_bool( &bs ) )
3376 p_stream->special.dirac.b_interlaced = dirac_uint( &bs ); /* scan_format */
3378 else
3379 p_stream->special.dirac.b_interlaced = false;
3381 uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
3382 uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
3383 u_d = __MAX( u_d, 1 );
3384 if( dirac_bool( &bs ) )
3386 uint32_t u_frame_rate_index = dirac_uint( &bs );
3387 if( u_frame_rate_index >= u_dirac_frate_tbl )
3389 /* something is wrong with this stream */
3390 return false;
3392 u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
3393 u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
3394 if( u_frame_rate_index == 0 )
3396 u_n = dirac_uint( &bs ); /* frame_rate_numerator */
3397 u_d = dirac_uint( &bs ); /* frame_rate_denominator */
3401 if( !u_n || !u_d )
3402 return false;
3405 * NB, OggDirac granulepos values are in units of 2*picturerate
3406 * When picture_coding_mode = 0 (progressive),
3407 * pt increments by two for each picture in display order.
3408 * When picture_coding_mode = 1 (interlace),
3409 * pt increments by one for each field in display order. */
3410 date_Init( &p_stream->dts, 2 * u_n, u_d );
3412 return true;
3415 static bool Ogg_ReadOggSpotsHeader( logical_stream_t *p_stream,
3416 ogg_packet *p_oggpacket )
3418 uint64_t i_granulerate_numerator;
3419 uint64_t i_granulerate_denominator;
3420 int i_major;
3421 int i_minor;
3423 es_format_Change( &p_stream->fmt, VIDEO_ES, VLC_CODEC_OGGSPOTS );
3425 /* Signal that we want to keep a backup of the OggSpots
3426 * stream headers. They will be used when switching between
3427 * audio streams. */
3428 p_stream->b_force_backup = true;
3430 /* Cheat and get additionnal info ;) */
3431 if ( p_oggpacket->bytes != 52 )
3433 /* The OggSpots header is always 52 bytes */
3434 return false;
3437 i_major = GetWLE( &p_oggpacket->packet[ 8] ); /* major version num */
3438 i_minor = GetWLE( &p_oggpacket->packet[10] ); /* minor version num */
3439 if ( i_major != 0 || i_minor != 1 )
3441 return false;
3444 /* Granule rate */
3445 i_granulerate_numerator = GetQWLE( &p_oggpacket->packet[12] );
3446 i_granulerate_denominator = GetQWLE( &p_oggpacket->packet[20] );
3447 if ( i_granulerate_numerator == 0 || i_granulerate_denominator == 0 )
3449 return false;
3452 /* The OggSpots spec contained an error and there are implementations out
3453 * there that used the wrong value. So we detect that case and switch
3454 * numerator and denominator in that case */
3455 if ( i_granulerate_numerator == 1 && i_granulerate_denominator == 30 )
3457 i_granulerate_numerator = 30;
3458 i_granulerate_denominator = 1;
3461 if ( !i_granulerate_numerator || !i_granulerate_denominator )
3462 return false;
3464 /* Normalize granulerate */
3465 vlc_ureduce(&p_stream->fmt.video.i_frame_rate,
3466 &p_stream->fmt.video.i_frame_rate_base,
3467 i_granulerate_numerator, i_granulerate_denominator, 0);
3469 date_Init( &p_stream->dts, p_stream->fmt.video.i_frame_rate,
3470 p_stream->fmt.video.i_frame_rate_base );
3472 p_stream->i_granule_shift = p_oggpacket->packet[28];
3474 return true;