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 /*****************************************************************************
26 *****************************************************************************/
32 #include <vorbis/codec.h>
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_demux.h>
40 #include <vlc_input.h>
44 #include <vlc_codecs.h>
47 #include "xiph_metadata.h"
50 #include "ogg_granule.h"
53 /*****************************************************************************
55 *****************************************************************************/
56 static int Open ( vlc_object_t
* );
57 static void Close( vlc_object_t
* );
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
)
70 /*****************************************************************************
71 * Definitions of structures and functions used by this plugins
72 *****************************************************************************/
74 /* OggDS headers for the new header format (used in ogm files) */
79 } stream_header_video_t
;
85 ogg_int16_t blockalign
;
86 ogg_int32_t avgbytespersec
;
87 } stream_header_audio_t
;
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
;
107 stream_header_video_t video
;
109 stream_header_audio_t audio
;
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 /*****************************************************************************
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
, bool );
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
);
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
);
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
* );
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 );
178 static void fill_channels_info(audio_format_t
*audio
)
180 static const int pi_channels_map
[9] =
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
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
;
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
);
223 else if ( strcmp( psz_mime
, "application/ogg" ) &&
224 strcmp( psz_mime
, "video/ogg" ) &&
225 strcmp( psz_mime
, "audio/ogg" ) )
234 p_demux
->p_sys
= p_sys
= calloc( 1, sizeof( demux_sys_t
) );
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
);
249 TAB_INIT( p_sys
->i_seekpoints
, p_sys
->pp_seekpoints
);
251 /* Enforce exclusive mode, only one track can be selected at once. */
252 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_CAT_POLICY
, AUDIO_ES
,
253 ES_OUT_ES_POLICY_EXCLUSIVE
);
255 while ( !p_sys
->b_preparsing_done
&& p_demux
->pf_demux( p_demux
) > 0 )
257 if ( p_sys
->b_preparsing_done
&& p_demux
->b_preparsing
)
258 Ogg_CreateES( p_demux
, true );
263 /*****************************************************************************
264 * Close: frees unused data
265 *****************************************************************************/
266 static void Close( vlc_object_t
*p_this
)
268 demux_t
*p_demux
= (demux_t
*)p_this
;
269 demux_sys_t
*p_sys
= p_demux
->p_sys
;
271 /* Cleanup the bitstream parser */
272 ogg_sync_clear( &p_sys
->oy
);
274 Ogg_EndOfStream( p_demux
);
276 if( p_sys
->p_old_stream
)
277 Ogg_LogicalStreamDelete( p_demux
, p_sys
->p_old_stream
);
282 static vlc_tick_t
Ogg_GetLastDTS( demux_t
* p_demux
)
284 demux_sys_t
*p_sys
= p_demux
->p_sys
;
286 vlc_tick_t i_dts
= VLC_TICK_INVALID
;
287 for( int i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
289 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
290 if ( p_stream
->b_initializing
)
292 if( p_stream
->i_pcr
> i_dts
)
293 i_dts
= p_stream
->i_pcr
;
299 static vlc_tick_t
Ogg_GeneratePCR( demux_t
* p_demux
, bool b_drain
)
301 demux_sys_t
*p_sys
= p_demux
->p_sys
;
302 /* We will consider the lowest PCR among tracks, because the audio core badly
303 * handles PCR rewind (mute)
305 vlc_tick_t i_pcr_candidate
= VLC_TICK_INVALID
;
306 for( int i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
308 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
309 if( p_stream
->fmt
.i_cat
== SPU_ES
)
311 if( p_stream
->fmt
.i_codec
== VLC_CODEC_OGGSPOTS
)
313 if( p_stream
->i_pcr
== VLC_TICK_INVALID
)
315 if ( (!b_drain
&& p_stream
->b_finished
) || p_stream
->b_initializing
)
317 if( i_pcr_candidate
== VLC_TICK_INVALID
||
318 p_stream
->i_pcr
< i_pcr_candidate
)
320 i_pcr_candidate
= p_stream
->i_pcr
;
324 return i_pcr_candidate
;
327 static void Ogg_OutputQueues( demux_t
*p_demux
, bool b_drain
)
329 demux_sys_t
*p_sys
= p_demux
->p_sys
;
332 /* Generate First PCR */
333 if( p_sys
->i_pcr
== VLC_TICK_INVALID
)
335 i_pcr
= Ogg_GeneratePCR( p_demux
, b_drain
);
336 if( i_pcr
!= VLC_TICK_INVALID
&& i_pcr
!= p_sys
->i_pcr
)
338 p_sys
->i_pcr
= i_pcr
;
339 if( likely( !p_sys
->b_slave
) )
340 es_out_SetPCR( p_demux
->out
, p_sys
->i_pcr
);
344 if( p_sys
->i_pcr
!= VLC_TICK_INVALID
)
350 for( int i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
352 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
353 if( Ogg_HasQueuedBlocks( p_stream
) )
354 Ogg_SendQueuedBlock( p_demux
, p_stream
);
355 b_continue
|= Ogg_HasQueuedBlocks( p_stream
);
358 /* Generate Current PCR */
359 i_pcr
= Ogg_GeneratePCR( p_demux
, b_drain
);
360 if( i_pcr
!= VLC_TICK_INVALID
&& i_pcr
!= p_sys
->i_pcr
)
362 p_sys
->i_pcr
= i_pcr
;
363 if( likely( !p_sys
->b_slave
) )
364 es_out_SetPCR( p_demux
->out
, p_sys
->i_pcr
);
366 } while ( b_continue
);
371 /*****************************************************************************
372 * Demux: reads and demuxes data packets
373 *****************************************************************************
374 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
375 *****************************************************************************/
376 static int Demux( demux_t
* p_demux
)
378 demux_sys_t
*p_sys
= p_demux
->p_sys
;
379 ogg_packet oggpacket
;
383 int i_active_streams
= p_sys
->i_streams
;
384 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
386 if ( p_sys
->pp_stream
[i
]->b_finished
)
390 if ( i_active_streams
== 0 )
392 if ( p_sys
->i_streams
) /* All finished */
394 msg_Dbg( p_demux
, "end of a group of %d logical streams", p_sys
->i_streams
);
396 Ogg_OutputQueues( p_demux
, true );
398 vlc_tick_t i_lastdts
= Ogg_GetLastDTS( p_demux
);
400 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
401 * only 1 ES is supported (common case for ogg web radio) */
402 if( p_sys
->i_streams
== 1 && p_sys
->pp_stream
[0]->p_es
)
404 if( p_sys
->p_old_stream
) /* if no setupEs has reused */
405 Ogg_LogicalStreamDelete( p_demux
, p_sys
->p_old_stream
);
406 p_sys
->p_old_stream
= p_sys
->pp_stream
[0];
407 TAB_CLEAN( p_sys
->i_streams
, p_sys
->pp_stream
);
410 Ogg_EndOfStream( p_demux
);
411 p_sys
->b_chained_boundary
= true;
413 if( i_lastdts
!= VLC_TICK_INVALID
)
415 p_sys
->i_nzpcr_offset
= i_lastdts
- VLC_TICK_0
;
416 if( likely( !p_sys
->b_slave
) )
417 es_out_SetPCR( p_demux
->out
, i_lastdts
);
419 p_sys
->i_pcr
= VLC_TICK_INVALID
;
422 if( Ogg_BeginningOfStream( p_demux
) != VLC_SUCCESS
)
423 return VLC_DEMUXER_EOF
;
425 msg_Dbg( p_demux
, "beginning of a group of logical streams" );
427 if ( !p_sys
->b_chained_boundary
)
429 /* Find the real duration */
430 vlc_stream_Control( p_demux
->s
, STREAM_CAN_SEEK
, &b_canseek
);
432 Oggseek_ProbeEnd( p_demux
);
436 p_sys
->b_chained_boundary
= false;
440 if ( p_sys
->b_preparsing_done
&& !p_sys
->b_es_created
)
441 Ogg_CreateES( p_demux
, false );
444 * The first data page of a physical stream is stored in the relevant logical stream
445 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
446 * stream it belongs to if we haven't processed this first page yet. If we do, we
447 * will only process that first page whenever we find the second page for this stream.
448 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
449 * the second page will arrive real quick, this is not fine for Kate, whose second
450 * data page will typically arrive much later.
451 * This means it is now possible to seek right at the start of a stream where the last
452 * logical stream is Kate, without having to wait for the second data page to unblock
453 * the first one, which is the one that triggers the 'no more headers to backup' code.
454 * And, as we all know, seeking without having backed up all headers is bad, since the
455 * codec will fail to initialize if it's missing its headers.
457 if( !p_sys
->b_page_waiting
)
460 * Demux an ogg page from the stream
462 if( Ogg_ReadPage( p_demux
, &p_sys
->current_page
) != VLC_SUCCESS
)
463 return VLC_DEMUXER_EOF
; /* EOF */
464 /* Test for End of Stream */
465 if( ogg_page_eos( &p_sys
->current_page
) )
467 /* If we delayed restarting encoders/SET_ES_FMT for more
468 * skeleton provided configuration */
469 if ( p_sys
->p_skelstream
)
471 if ( p_sys
->p_skelstream
->i_serial_no
== ogg_page_serialno(&p_sys
->current_page
) )
473 msg_Dbg( p_demux
, "End of Skeleton" );
474 p_sys
->b_preparsing_done
= true;
475 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
477 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
478 Ogg_ApplySkeleton( p_stream
);
483 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
485 if ( p_sys
->pp_stream
[i_stream
]->i_serial_no
== ogg_page_serialno( &p_sys
->current_page
) )
487 p_sys
->pp_stream
[i_stream
]->b_finished
= true;
494 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
496 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
498 /* if we've just pulled page, look for the right logical stream */
499 if( !p_sys
->b_page_waiting
)
501 if( p_sys
->i_streams
== 1 &&
502 ogg_page_serialno( &p_sys
->current_page
) != p_stream
->os
.serialno
)
504 msg_Err( p_demux
, "Broken Ogg stream (serialno) mismatch" );
505 Ogg_ResetStream( p_stream
);
506 if( p_stream
->i_pcr
!= VLC_TICK_INVALID
)
507 p_sys
->i_nzpcr_offset
= p_stream
->i_pcr
- VLC_TICK_0
;
508 ogg_stream_reset_serialno( &p_stream
->os
, ogg_page_serialno( &p_sys
->current_page
) );
511 /* Does fail if serialno differs */
512 if( ogg_stream_pagein( &p_stream
->os
, &p_sys
->current_page
) != 0 )
518 /* clear the finished flag if pages after eos (ex: after a seek) */
519 if ( ! ogg_page_eos( &p_sys
->current_page
) && p_sys
->p_skelstream
!= p_stream
)
520 p_stream
->b_finished
= false;
523 if ( p_stream
->fmt
.i_cat
== VIDEO_ES
)
524 msg_Dbg(p_demux
, "DEMUX READ pageno %ld g%"PRId64
" (%d packets) cont %d %ld bytes",
525 ogg_page_pageno( &p_sys
->current_page
),
526 ogg_page_granulepos( &p_sys
->current_page
),
527 ogg_page_packets( &p_sys
->current_page
),
528 ogg_page_continued(&p_sys
->current_page
),
529 p_sys
->current_page
.body_len
)
532 while( ogg_stream_packetout( &p_stream
->os
, &oggpacket
) > 0 )
534 /* Read info from any secondary header packets, if there are any */
535 if( p_stream
->i_secondary_header_packets
> 0 )
537 if( p_stream
->fmt
.i_codec
== VLC_CODEC_THEORA
&&
538 oggpacket
.bytes
>= 7 &&
539 ! memcmp( oggpacket
.packet
, "\x80theora", 7 ) )
541 Ogg_ReadTheoraHeader( p_stream
, &oggpacket
);
542 p_stream
->i_secondary_header_packets
= 0;
544 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_DAALA
&&
545 oggpacket
.bytes
>= 6 &&
546 ! memcmp( oggpacket
.packet
, "\x80""daala", 6 ) )
548 Ogg_ReadDaalaHeader( p_stream
, &oggpacket
);
549 p_stream
->i_secondary_header_packets
= 0;
551 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
&&
552 oggpacket
.bytes
>= 7 &&
553 ! memcmp( oggpacket
.packet
, "\x01vorbis", 7 ) )
555 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_VORBIS
);
556 Ogg_ReadVorbisHeader( p_stream
, &oggpacket
);
557 p_stream
->i_secondary_header_packets
= 0;
560 /* update start of data pointer */
561 p_stream
->i_data_start
= vlc_stream_Tell( p_demux
->s
);
564 if( p_stream
->b_reinit
)
566 p_stream
->b_reinit
= false;
567 if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
569 p_stream
->i_skip_frames
= p_stream
->i_pre_skip
;
573 Ogg_DecodePacket( p_demux
, p_stream
, &oggpacket
);
577 if( !p_sys
->b_page_waiting
)
581 /* if a page was waiting, it's now processed */
582 p_sys
->b_page_waiting
= false;
584 if ( p_sys
->p_skelstream
&& !p_sys
->p_skelstream
->b_finished
)
585 p_sys
->b_preparsing_done
= false;
587 p_sys
->b_preparsing_done
= true;
589 if( p_sys
->b_preparsing_done
)
591 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
593 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
594 if ( p_stream
->b_initializing
)
596 /* We have 1 or more streams needing more than 1 page for preparsing */
597 p_sys
->b_preparsing_done
= false;
603 if( p_sys
->b_preparsing_done
)
604 Ogg_OutputQueues( p_demux
, false );
606 return VLC_DEMUXER_SUCCESS
;
609 static void Ogg_ResetStream( logical_stream_t
*p_stream
)
611 #ifdef HAVE_LIBVORBIS
612 if ( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
)
614 p_stream
->special
.vorbis
.i_prev_blocksize
= 0;
617 /* we'll trash all the data until we find the next pcr */
618 p_stream
->b_reinit
= true;
619 p_stream
->i_pcr
= VLC_TICK_INVALID
;
620 p_stream
->i_next_block_flags
= 0;
621 p_stream
->b_interpolation_failed
= false;
622 date_Set( &p_stream
->dts
, VLC_TICK_INVALID
);
623 ogg_stream_reset( &p_stream
->os
);
624 block_ChainRelease( p_stream
->queue
.p_blocks
);
625 p_stream
->queue
.p_blocks
= NULL
;
626 p_stream
->queue
.pp_append
= &p_stream
->queue
.p_blocks
;
629 static void Ogg_PreparePostSeek( demux_sys_t
*p_sys
)
631 for( int i
= 0; i
< p_sys
->i_streams
; i
++ )
633 Ogg_ResetStream( p_sys
->pp_stream
[i
] );
634 p_sys
->pp_stream
[i
]->i_next_block_flags
= BLOCK_FLAG_DISCONTINUITY
;
637 ogg_sync_reset( &p_sys
->oy
);
638 p_sys
->i_pcr
= VLC_TICK_INVALID
;
641 static logical_stream_t
* Ogg_GetSelectedStream( demux_t
*p_demux
)
643 demux_sys_t
*p_sys
= p_demux
->p_sys
;
644 logical_stream_t
*p_stream
= NULL
;
645 for( int i
=0; i
<p_sys
->i_streams
; i
++ )
647 logical_stream_t
*p_candidate
= p_sys
->pp_stream
[i
];
648 if ( !p_candidate
->p_es
) continue;
650 bool b_selected
= false;
651 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
,
652 p_candidate
->p_es
, &b_selected
);
653 if ( !b_selected
) continue;
655 if ( !p_stream
&& p_candidate
->fmt
.i_cat
== AUDIO_ES
)
657 p_stream
= p_candidate
;
658 continue; /* Try to find video anyway */
661 if ( p_candidate
->fmt
.i_cat
== VIDEO_ES
)
663 p_stream
= p_candidate
;
670 /*****************************************************************************
672 *****************************************************************************/
673 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
675 demux_sys_t
*p_sys
= p_demux
->p_sys
;
679 bool *pb_bool
, b
, acc
;
680 logical_stream_t
*p_stream
;
685 return vlc_stream_vaControl( p_demux
->s
, i_query
, args
);
688 p_meta
= va_arg( args
, vlc_meta_t
* );
690 vlc_meta_Merge( p_meta
, p_sys
->p_meta
);
693 case DEMUX_HAS_UNSUPPORTED_META
:
694 pb_bool
= va_arg( args
, bool* );
698 case DEMUX_SET_NEXT_DEMUX_TIME
:
699 p_sys
->b_slave
= true;
703 if( p_sys
->i_pcr
!= VLC_TICK_INVALID
|| p_sys
->b_slave
)
705 *va_arg( args
, vlc_tick_t
* ) = p_sys
->i_pcr
;
712 i64
= va_arg( args
, vlc_tick_t
);
713 acc
= va_arg( args
, int );
714 p_stream
= Ogg_GetSelectedStream( p_demux
);
717 msg_Err( p_demux
, "No selected seekable stream found" );
720 vlc_stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
721 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux
, p_stream
, VLC_TICK_0
+ i64
, b
) )
723 Ogg_PreparePostSeek( p_sys
);
725 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
733 case DEMUX_GET_ATTACHMENTS
:
735 input_attachment_t
***ppp_attach
=
736 va_arg( args
, input_attachment_t
*** );
737 int *pi_int
= va_arg( args
, int * );
739 if( p_sys
->i_attachments
<= 0 )
742 *ppp_attach
= vlc_alloc( p_sys
->i_attachments
, sizeof(input_attachment_t
*) );
745 *pi_int
= p_sys
->i_attachments
;
746 for( int i
= 0; i
< p_sys
->i_attachments
; i
++ )
747 (*ppp_attach
)[i
] = vlc_input_attachment_Duplicate( p_sys
->attachments
[i
] );
751 case DEMUX_GET_POSITION
: {
755 if( p_sys
->i_length
> 0 && p_sys
->i_pcr
!= VLC_TICK_INVALID
)
757 vlc_tick_t duration
= vlc_tick_from_sec( p_sys
->i_length
);
758 pos
= (double) p_sys
->i_pcr
/ (double) duration
;
760 else if( vlc_stream_GetSize( p_demux
->s
, &size
) == 0 && size
> 0 )
762 uint64_t offset
= vlc_stream_Tell( p_demux
->s
);
763 pos
= (double) offset
/ (double) size
;
766 *va_arg( args
, double * ) = pos
;
770 case DEMUX_SET_POSITION
:
771 /* forbid seeking if we haven't initialized all logical bitstreams yet;
772 if we allowed, some headers would not get backed up and decoder init
773 would fail, making that logical stream unusable */
774 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
776 if ( p_sys
->pp_stream
[i
]->b_initializing
)
780 p_stream
= Ogg_GetSelectedStream( p_demux
);
783 msg_Err( p_demux
, "No selected seekable stream found" );
787 vlc_stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
789 f
= va_arg( args
, double );
790 acc
= va_arg( args
, int );
791 if ( p_sys
->i_length
<= 0 || !b
/* || ! STREAM_CAN_FASTSEEK */ )
793 Ogg_PreparePostSeek( p_sys
);
794 return Oggseek_BlindSeektoPosition( p_demux
, p_stream
, f
, b
);
797 assert( p_sys
->i_length
> 0 );
798 i64
= vlc_tick_from_sec( f
* p_sys
->i_length
);
799 Ogg_PreparePostSeek( p_sys
);
800 if ( Oggseek_SeektoAbsolutetime( p_demux
, p_stream
, VLC_TICK_0
+ i64
) >= 0 )
803 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
810 case DEMUX_GET_LENGTH
:
811 if ( p_sys
->i_length
< 0 )
812 return demux_vaControlHelper( p_demux
->s
, 0, -1, p_sys
->i_bitrate
,
814 *va_arg( args
, vlc_tick_t
* ) = vlc_tick_from_sec(p_sys
->i_length
);
817 case DEMUX_GET_TITLE_INFO
:
819 input_title_t
***ppp_title
= va_arg( args
, input_title_t
*** );
820 int *pi_int
= va_arg( args
, int* );
821 int *pi_title_offset
= va_arg( args
, int* );
822 int *pi_seekpoint_offset
= va_arg( args
, int* );
824 if( p_sys
->i_seekpoints
> 0 )
827 *ppp_title
= malloc( sizeof( input_title_t
* ) );
828 input_title_t
*p_title
= (*ppp_title
)[0] = vlc_input_title_New();
829 for( int i
= 0; i
< p_sys
->i_seekpoints
; i
++ )
831 seekpoint_t
*p_seekpoint_copy
= vlc_seekpoint_Duplicate( p_sys
->pp_seekpoints
[i
] );
832 if ( likely( p_seekpoint_copy
) )
833 TAB_APPEND( p_title
->i_seekpoint
, p_title
->seekpoint
, p_seekpoint_copy
);
835 *pi_title_offset
= 0;
836 *pi_seekpoint_offset
= 0;
841 case DEMUX_SET_TITLE
:
843 const int i_title
= va_arg( args
, int );
848 case DEMUX_SET_SEEKPOINT
:
850 const int i_seekpoint
= va_arg( args
, int );
851 if( i_seekpoint
> p_sys
->i_seekpoints
)
854 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
856 if ( p_sys
->pp_stream
[i
]->b_initializing
)
860 i64
= p_sys
->pp_seekpoints
[i_seekpoint
]->i_time_offset
;
862 p_stream
= Ogg_GetSelectedStream( p_demux
);
865 msg_Err( p_demux
, "No selected seekable stream found" );
869 vlc_stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
870 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux
, p_stream
, VLC_TICK_0
+ i64
, b
) )
872 Ogg_PreparePostSeek( p_sys
);
873 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
875 p_sys
->updates
|= INPUT_UPDATE_SEEKPOINT
;
876 p_sys
->cur_seekpoint
= i_seekpoint
;
882 case DEMUX_TEST_AND_CLEAR_FLAGS
:
884 unsigned *restrict flags
= va_arg( args
, unsigned * );
885 *flags
&= p_sys
->updates
;
886 p_sys
->updates
&= ~*flags
;
889 case DEMUX_GET_TITLE
:
890 *va_arg( args
, int * ) = 0;
892 case DEMUX_GET_SEEKPOINT
:
893 *va_arg( args
, int * ) = p_sys
->cur_seekpoint
;
897 return demux_vaControlHelper( p_demux
->s
, 0, -1, p_sys
->i_bitrate
,
902 /****************************************************************************
903 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
904 ****************************************************************************
905 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
906 * are at the end of stream.
907 ****************************************************************************/
908 static int Ogg_ReadPage( demux_t
*p_demux
, ogg_page
*p_oggpage
)
910 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
914 while( ogg_sync_pageout( &p_ogg
->oy
, p_oggpage
) != 1 )
916 p_buffer
= ogg_sync_buffer( &p_ogg
->oy
, OGGSEEK_BYTES_TO_READ
);
918 i_read
= vlc_stream_Read( p_demux
->s
, p_buffer
, OGGSEEK_BYTES_TO_READ
);
922 ogg_sync_wrote( &p_ogg
->oy
, i_read
);
928 static void Ogg_SetNextFrame( demux_t
*p_demux
, logical_stream_t
*p_stream
,
929 ogg_packet
*p_oggpacket
)
932 ogg_int64_t i_granule
= p_oggpacket
->granulepos
;
934 if( Ogg_GranuleIsValid( p_stream
, i_granule
) )
936 vlc_tick_t i_endtime
= Ogg_GranuleToTime( p_stream
, i_granule
, false, false );
937 assert( !p_stream
->b_contiguous
|| i_endtime
!= VLC_TICK_INVALID
);
938 if( i_endtime
!= VLC_TICK_INVALID
)
940 date_Set( &p_stream
->dts
, i_endtime
);
945 /* Do Interpolation if can't compute directly from granule */
946 if( date_Get( &p_stream
->dts
) != VLC_TICK_INVALID
)
948 if( p_stream
->fmt
.i_cat
== VIDEO_ES
)
950 date_Increment( &p_stream
->dts
, 1 );
952 else if( p_stream
->fmt
.i_cat
== AUDIO_ES
)
954 int64_t i_samples
= 0;
955 switch( p_stream
->fmt
.i_codec
)
958 i_samples
= Ogg_OpusPacketDuration( p_oggpacket
);
960 case VLC_CODEC_SPEEX
:
961 i_samples
= p_stream
->special
.speex
.i_framesize
*
962 p_stream
->special
.speex
.i_framesperpacket
;
964 #ifdef HAVE_LIBVORBIS
965 case VLC_CODEC_VORBIS
:
966 if( p_stream
->special
.vorbis
.p_info
&&
967 VORBIS_HEADERS_VALID(p_stream
) )
969 long i_blocksize
= vorbis_packet_blocksize(
970 p_stream
->special
.vorbis
.p_info
, p_oggpacket
);
971 /* duration in samples per channel */
972 if ( p_stream
->special
.vorbis
.i_prev_blocksize
)
973 i_samples
= ( i_blocksize
+ p_stream
->special
.vorbis
.i_prev_blocksize
) / 4;
975 i_samples
= i_blocksize
/ 2;
976 p_stream
->special
.vorbis
.i_prev_blocksize
= i_blocksize
;
981 if( p_stream
->fmt
.i_bitrate
)
983 i_samples
= 8 * p_oggpacket
->bytes
* p_stream
->dts
.i_divider_num
;
984 i_samples
/= p_stream
->fmt
.i_bitrate
/ p_stream
->dts
.i_divider_den
;
989 p_stream
->b_interpolation_failed
= true;
991 date_Increment( &p_stream
->dts
, i_samples
);
996 static vlc_tick_t
Ogg_FixupOutputQueue( demux_t
*p_demux
, logical_stream_t
*p_stream
)
998 vlc_tick_t i_enddts
= VLC_TICK_INVALID
;
1000 #ifdef HAVE_LIBVORBIS
1001 long i_prev_blocksize
= 0;
1003 VLC_UNUSED(p_demux
);
1005 // PASS 1, set number of samples
1006 unsigned i_total_samples
= 0;
1007 for( block_t
*p_block
= p_stream
->queue
.p_blocks
; p_block
; p_block
= p_block
->p_next
)
1009 if( p_block
->i_dts
!= VLC_TICK_INVALID
)
1011 i_enddts
= p_block
->i_dts
;
1015 if( p_block
->i_flags
& BLOCK_FLAG_HEADER
)
1018 ogg_packet dumb_packet
;
1019 dumb_packet
.bytes
= p_block
->i_buffer
;
1020 dumb_packet
.packet
= p_block
->p_buffer
;
1022 switch( p_stream
->fmt
.i_codec
)
1024 case VLC_CODEC_SPEEX
:
1025 p_block
->i_nb_samples
= p_stream
->special
.speex
.i_framesize
*
1026 p_stream
->special
.speex
.i_framesperpacket
;
1028 case VLC_CODEC_OPUS
:
1029 p_block
->i_nb_samples
= Ogg_OpusPacketDuration( &dumb_packet
);
1031 #ifdef HAVE_LIBVORBIS
1032 case VLC_CODEC_VORBIS
:
1034 if( !VORBIS_HEADERS_VALID(p_stream
) )
1036 msg_Err( p_demux
, "missing vorbis headers, can't compute block size" );
1039 long i_blocksize
= vorbis_packet_blocksize( p_stream
->special
.vorbis
.p_info
,
1041 if ( i_prev_blocksize
)
1042 p_block
->i_nb_samples
= ( i_blocksize
+ i_prev_blocksize
) / 4;
1044 p_block
->i_nb_samples
= i_blocksize
/ 2;
1045 i_prev_blocksize
= i_blocksize
;
1050 if( p_stream
->fmt
.i_cat
== VIDEO_ES
)
1051 p_block
->i_nb_samples
= 1;
1054 i_total_samples
+= p_block
->i_nb_samples
;
1058 if( i_enddts
!= VLC_TICK_INVALID
)
1060 date_t d
= p_stream
->dts
;
1061 date_Set( &d
, i_enddts
);
1062 i_enddts
= date_Decrement( &d
, i_total_samples
);
1063 for( block_t
*p_block
= p_stream
->queue
.p_blocks
; p_block
; p_block
= p_block
->p_next
)
1065 if( p_block
->i_dts
!= VLC_TICK_INVALID
)
1067 if( p_block
->i_flags
& BLOCK_FLAG_HEADER
)
1069 p_block
->i_dts
= date_Get( &d
);
1070 date_Increment( &d
, p_block
->i_nb_samples
);
1072 } /* else can't do anything, no timestamped blocks in stream */
1077 static void Ogg_QueueBlocks( demux_t
*p_demux
, logical_stream_t
*p_stream
, block_t
*p_block
)
1079 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1082 if( p_block
== NULL
)
1084 assert( p_block
!= NULL
);
1088 block_ChainLastAppend( &p_stream
->queue
.pp_append
, p_block
);
1090 if( p_stream
->i_pcr
== VLC_TICK_INVALID
&& p_block
->i_dts
!= VLC_TICK_INVALID
)
1093 p_stream
->i_pcr
= Ogg_FixupOutputQueue( p_demux
, p_stream
);
1096 DemuxDebug( msg_Dbg( p_demux
, "%4.4s block queued > dts %"PRId64
" spcr %"PRId64
" pcr %"PRId64
,
1097 (char*)&p_stream
->fmt
.i_codec
, p_block
->i_dts
, p_stream
->i_pcr
, p_sys
->i_pcr
); )
1100 static void Ogg_SendQueuedBlock( demux_t
*p_demux
, logical_stream_t
*p_stream
)
1102 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1104 if( Ogg_HasQueuedBlocks( p_stream
) )
1106 block_t
*p_queued
= p_stream
->queue
.p_blocks
;
1107 p_stream
->queue
.p_blocks
= p_queued
->p_next
;
1108 p_queued
->p_next
= NULL
;
1110 if( p_queued
->i_dts
== VLC_TICK_INVALID
)
1111 p_queued
->i_dts
= p_queued
->i_pts
;
1113 if( p_queued
->i_flags
& BLOCK_FLAG_HEADER
)
1115 if( p_sys
->i_nzpcr_offset
> 0 || /* Don't send metadata from chained streams */
1116 p_stream
->fmt
.i_extra
> 0 ) /* Don't send metadata if configured by extradata */
1118 block_Release( p_queued
);
1121 p_queued
->i_flags
&= ~BLOCK_FLAG_HEADER
;
1124 unsigned i_toskip
= 0;
1125 if( p_stream
->i_skip_frames
> 0 )
1127 if( p_sys
->i_nzpcr_offset
> 0 )
1129 /* not preskip handling on chained streams */
1130 p_stream
->i_skip_frames
= 0;
1134 i_toskip
= __MIN( p_stream
->i_skip_frames
, p_queued
->i_nb_samples
);
1135 p_stream
->i_skip_frames
-= i_toskip
;
1136 p_queued
->i_nb_samples
-= i_toskip
;
1137 if( p_queued
->i_nb_samples
== 0 )
1138 p_queued
->i_flags
|= BLOCK_FLAG_PREROLL
;
1142 p_queued
->i_flags
|= p_stream
->i_next_block_flags
;
1143 p_stream
->i_next_block_flags
= 0;
1144 p_stream
->i_pcr
= p_queued
->i_dts
;
1146 DemuxDebug( msg_Dbg( p_demux
, "%4.4s block sent > dts %"PRId64
" pts %"PRId64
" spcr %"PRId64
" pcr %"PRId64
1148 (char*)&p_stream
->fmt
.i_codec
, p_queued
->i_dts
,
1149 p_queued
->i_pts
, p_stream
->i_pcr
, p_sys
->i_pcr
,
1150 p_queued
->i_nb_samples
, i_toskip
); );
1152 assert( p_sys
->i_pcr
!= VLC_TICK_INVALID
);
1154 if( p_stream
->p_es
)
1155 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_queued
);
1157 block_Release( p_queued
);
1161 if( p_stream
->queue
.p_blocks
== NULL
)
1162 p_stream
->queue
.pp_append
= &p_stream
->queue
.p_blocks
;
1165 static bool Ogg_IsHeaderPacket( const logical_stream_t
*p_stream
,
1166 const ogg_packet
*p_oggpacket
)
1168 if ( p_stream
->b_oggds
)
1170 return p_oggpacket
->bytes
> 0 &&
1171 (p_oggpacket
->packet
[0] & PACKET_TYPE_HEADER
);
1173 else return ( p_oggpacket
->granulepos
== 0 && p_stream
->i_first_frame_index
> 0 );
1176 /****************************************************************************
1177 * Ogg_DecodePacket: Decode an Ogg packet.
1178 ****************************************************************************/
1179 static void Ogg_DecodePacket( demux_t
*p_demux
,
1180 logical_stream_t
*p_stream
,
1181 ogg_packet
*p_oggpacket
)
1183 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1186 long i_header_len
= 0;
1188 if( p_oggpacket
->bytes
>= 7 &&
1189 ! memcmp ( p_oggpacket
->packet
, "Annodex", 7 ) )
1191 /* it's an Annodex packet -- skip it (do nothing) */
1194 else if( p_oggpacket
->bytes
>= 7 &&
1195 ! memcmp ( p_oggpacket
->packet
, "AnxData", 7 ) )
1197 /* it's an AnxData packet -- skip it (do nothing) */
1200 else if( p_oggpacket
->bytes
>= 8 &&
1201 ! memcmp ( p_oggpacket
->packet
, "fisbone", 8 ) )
1203 Ogg_ReadSkeletonBones( p_demux
, p_oggpacket
);
1206 else if( p_oggpacket
->bytes
>= 6 &&
1207 ! memcmp ( p_oggpacket
->packet
, "index", 6 ) )
1209 Ogg_ReadSkeletonIndex( p_demux
, p_oggpacket
);
1212 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
&&
1213 p_oggpacket
->bytes
>= 7 &&
1214 !memcmp( p_oggpacket
->packet
, "OVP80\x02\x20", 7 ) )
1216 Ogg_ReadVP8Header( p_demux
, p_stream
, p_oggpacket
);
1220 if( p_stream
->fmt
.i_codec
== VLC_CODEC_SUBT
&& p_oggpacket
->bytes
> 0 &&
1221 p_oggpacket
->packet
[0] & PACKET_TYPE_BITS
) return;
1223 /* Check the ES is selected */
1224 if ( !p_stream
->p_es
)
1227 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
,
1228 p_stream
->p_es
, &b_selected
);
1230 if( p_stream
->b_force_backup
)
1233 p_stream
->i_packets_backup
++;
1234 switch( p_stream
->fmt
.i_codec
)
1236 case VLC_CODEC_VORBIS
:
1237 #ifdef HAVE_LIBVORBIS
1238 Ogg_DecodeVorbisHeader( p_stream
, p_oggpacket
, p_stream
->i_packets_backup
);
1241 case VLC_CODEC_THEORA
:
1242 if( p_stream
->i_packets_backup
== 3 )
1243 p_stream
->b_force_backup
= false;
1247 case VLC_CODEC_DAALA
:
1248 if( p_stream
->i_packets_backup
== 3 )
1249 p_stream
->b_force_backup
= false;
1253 case VLC_CODEC_SPEEX
:
1254 if( p_stream
->i_packets_backup
== 2 + p_stream
->i_extra_headers_packets
)
1255 p_stream
->b_force_backup
= false;
1259 case VLC_CODEC_OPUS
:
1260 if( p_stream
->i_packets_backup
== 2 )
1261 p_stream
->b_force_backup
= false;
1265 case VLC_CODEC_FLAC
:
1266 if( p_stream
->i_packets_backup
== 1 + p_stream
->i_extra_headers_packets
)
1268 p_stream
->b_force_backup
= false;
1270 if( p_stream
->special
.flac
.b_old
)
1272 Ogg_ReadFlacStreamInfo( p_demux
, p_stream
, p_oggpacket
);
1274 else if( p_stream
->i_packets_backup
== 1 )
1276 if( p_oggpacket
->bytes
>= 9 ) /* Point to Flac for extradata */
1278 p_oggpacket
->packet
+= 9;
1279 p_oggpacket
->bytes
-= 9;
1285 case VLC_CODEC_KATE
:
1286 if( p_stream
->i_packets_backup
== p_stream
->special
.kate
.i_num_headers
)
1287 p_stream
->b_force_backup
= false;
1292 p_stream
->b_force_backup
= false;
1297 /* Backup the ogg packet (likely an header packet) */
1300 uint8_t *p_realloc
= realloc( p_stream
->p_headers
, p_stream
->i_headers
+ p_oggpacket
->bytes
);
1303 memcpy( &p_realloc
[p_stream
->i_headers
], p_oggpacket
->packet
, p_oggpacket
->bytes
);
1304 p_stream
->i_headers
+= p_oggpacket
->bytes
;
1305 p_stream
->p_headers
= p_realloc
;
1309 free( p_stream
->p_headers
);
1310 p_stream
->i_headers
= 0;
1311 p_stream
->p_headers
= NULL
;
1314 else if( xiph_AppendHeaders( &p_stream
->i_headers
, &p_stream
->p_headers
,
1315 p_oggpacket
->bytes
, p_oggpacket
->packet
) )
1317 p_stream
->i_headers
= 0;
1318 p_stream
->p_headers
= NULL
;
1320 if( p_stream
->i_headers
> 0 )
1322 if( !p_stream
->b_force_backup
)
1324 /* Last header received, commit changes */
1325 free( p_stream
->fmt
.p_extra
);
1327 p_stream
->fmt
.i_extra
= p_stream
->i_headers
;
1328 p_stream
->fmt
.p_extra
= malloc( p_stream
->i_headers
);
1329 if( p_stream
->fmt
.p_extra
)
1330 memcpy( p_stream
->fmt
.p_extra
, p_stream
->p_headers
,
1331 p_stream
->i_headers
);
1333 p_stream
->fmt
.i_extra
= 0;
1335 if( p_stream
->i_headers
> 0 )
1336 Ogg_ExtractMeta( p_demux
, & p_stream
->fmt
,
1337 p_stream
->p_headers
, p_stream
->i_headers
);
1339 /* we're not at BOS anymore for this logical stream */
1340 p_stream
->b_initializing
= false;
1344 b_selected
= false; /* Discard the header packet */
1348 p_stream
->b_initializing
= false;
1351 vlc_tick_t i_dts
= Ogg_GranuleToTime( p_stream
, p_oggpacket
->granulepos
, true, false );
1352 vlc_tick_t i_expected_dts
= p_stream
->b_interpolation_failed
? VLC_TICK_INVALID
:
1353 date_Get( &p_stream
->dts
); /* Interpolated or previous end time */
1354 if( i_dts
== VLC_TICK_INVALID
)
1355 i_dts
= i_expected_dts
;
1357 date_Set( &p_stream
->dts
, i_dts
);
1359 /* Write end granule as next start, or do interpolation */
1360 bool b_header
= Ogg_IsHeaderPacket( p_stream
, p_oggpacket
);
1362 Ogg_SetNextFrame( p_demux
, p_stream
, p_oggpacket
);
1366 /* This stream isn't currently selected so we don't need to decode it,
1367 * but we did need to store its pcr as it might be selected later on */
1368 if( !b_header
&& !p_stream
->b_initializing
)
1370 vlc_tick_t i_pcr
= date_Get( &p_stream
->dts
);
1371 if( i_pcr
!= VLC_TICK_INVALID
)
1372 p_stream
->i_pcr
= p_sys
->i_nzpcr_offset
+ i_pcr
;
1377 if( !( p_block
= block_Alloc( p_oggpacket
->bytes
) ) )
1380 /* Set effective timestamp */
1381 if( i_dts
!= VLC_TICK_INVALID
)
1382 p_block
->i_dts
= p_sys
->i_nzpcr_offset
+ i_dts
;
1384 /* Vorbis and Opus can trim the end of a stream using granule positions. */
1385 if( p_oggpacket
->e_o_s
)
1387 vlc_tick_t i_endtime
= Ogg_GranuleToTime( p_stream
, p_oggpacket
->granulepos
, false, false );
1388 if( i_endtime
!= VLC_TICK_INVALID
&& i_expected_dts
!= VLC_TICK_INVALID
)
1390 p_block
->i_length
= i_endtime
- i_expected_dts
;
1391 p_block
->i_flags
|= BLOCK_FLAG_END_OF_SEQUENCE
;
1395 if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
) /* also required for trimming */
1396 p_block
->i_nb_samples
= Ogg_OpusPacketDuration( p_oggpacket
);
1398 DemuxDebug( msg_Dbg(p_demux
, "%4.4s block set from granule %"PRId64
" to pts/pcr %"PRId64
" skip %d",
1399 (char *) &p_stream
->fmt
.i_codec
, p_oggpacket
->granulepos
,
1400 p_block
->i_dts
, p_stream
->i_skip_frames
); )
1402 /* may need to preroll after a seek or in case of preskip */
1404 /* Conditional block fixes */
1405 if ( p_stream
->fmt
.i_cat
== VIDEO_ES
)
1407 if( Ogg_IsKeyFrame( p_stream
, p_oggpacket
) )
1408 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
1410 if( p_stream
->fmt
.i_codec
== VLC_CODEC_DIRAC
)
1412 if( p_oggpacket
->granulepos
> 0 )
1413 p_block
->i_pts
= Ogg_GranuleToTime( p_stream
, p_oggpacket
->granulepos
, true, true );
1415 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_THEORA
)
1417 p_block
->i_pts
= p_block
->i_dts
;
1420 else if( p_stream
->fmt
.i_cat
== AUDIO_ES
)
1422 if( p_stream
->b_interpolation_failed
&& p_oggpacket
->granulepos
< 0 )
1423 p_block
->i_pts
= VLC_TICK_INVALID
;
1425 p_block
->i_pts
= p_block
->i_dts
;
1427 else if( p_stream
->fmt
.i_cat
== SPU_ES
)
1429 p_block
->i_length
= 0;
1430 p_block
->i_pts
= p_block
->i_dts
;
1433 p_stream
->b_interpolation_failed
= false;
1435 if( p_stream
->b_oggds
)
1437 if( p_oggpacket
->bytes
<= 0 )
1439 msg_Dbg( p_demux
, "discarding 0 sized packet" );
1440 block_Release( p_block
);
1443 /* We remove the header from the packet */
1444 i_header_len
= (*p_oggpacket
->packet
& PACKET_LEN_BITS01
) >> 6;
1445 i_header_len
|= (*p_oggpacket
->packet
& PACKET_LEN_BITS2
) << 1;
1447 if( i_header_len
>= p_oggpacket
->bytes
)
1449 msg_Dbg( p_demux
, "discarding invalid packet" );
1450 block_Release( p_block
);
1454 if( p_stream
->fmt
.i_codec
== VLC_CODEC_SUBT
)
1456 /* But with subtitles we need to retrieve the duration first */
1457 int i
, lenbytes
= 0;
1459 if( i_header_len
> 0 && p_oggpacket
->bytes
>= i_header_len
+ 1 )
1461 for( i
= 0, lenbytes
= 0; i
< i_header_len
; i
++ )
1463 lenbytes
= lenbytes
<< 8;
1464 lenbytes
+= *(p_oggpacket
->packet
+ i_header_len
- i
);
1467 if( p_oggpacket
->bytes
- 1 - i_header_len
> 2 ||
1468 ( p_oggpacket
->packet
[i_header_len
+ 1] != ' ' &&
1469 p_oggpacket
->packet
[i_header_len
+ 1] != 0 &&
1470 p_oggpacket
->packet
[i_header_len
+ 1] != '\n' &&
1471 p_oggpacket
->packet
[i_header_len
+ 1] != '\r' ) )
1473 p_block
->i_length
= (vlc_tick_t
)lenbytes
* 1000;
1478 if( p_block
->i_buffer
>= (unsigned int)i_header_len
)
1479 p_block
->i_buffer
-= i_header_len
;
1481 p_block
->i_buffer
= 0;
1485 p_block
->i_flags
|= BLOCK_FLAG_HEADER
;
1487 memcpy( p_block
->p_buffer
, p_oggpacket
->packet
+ i_header_len
,
1488 p_oggpacket
->bytes
- i_header_len
);
1490 Ogg_QueueBlocks( p_demux
, p_stream
, p_block
);
1493 static unsigned Ogg_OpusPacketDuration( ogg_packet
*p_oggpacket
)
1495 return opus_frame_duration(p_oggpacket
->packet
, p_oggpacket
->bytes
);
1498 /****************************************************************************
1499 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1500 * stream and fill p_ogg.
1501 *****************************************************************************
1502 * The initial page of a logical stream is marked as a 'bos' page.
1503 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1504 * together and all of the initial pages must appear before any data pages.
1506 * On success this function returns VLC_SUCCESS.
1507 ****************************************************************************/
1508 static int Ogg_FindLogicalStreams( demux_t
*p_demux
)
1510 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
1511 ogg_packet oggpacket
;
1513 p_ogg
->i_total_length
= stream_Size ( p_demux
->s
);
1514 msg_Dbg( p_demux
, "File length is %"PRId64
" bytes", p_ogg
->i_total_length
);
1517 while( Ogg_ReadPage( p_demux
, &p_ogg
->current_page
) == VLC_SUCCESS
)
1520 if( ogg_page_bos( &p_ogg
->current_page
) )
1523 /* All is wonderful in our fine fine little world.
1524 * We found the beginning of our first logical stream. */
1525 while( ogg_page_bos( &p_ogg
->current_page
) )
1527 logical_stream_t
*p_stream
= malloc( sizeof(logical_stream_t
) );
1528 if( unlikely( !p_stream
) )
1531 Ogg_LogicalStreamInit( p_stream
);
1533 /* Setup the logical stream */
1534 p_stream
->i_serial_no
= ogg_page_serialno( &p_ogg
->current_page
);
1535 ogg_stream_init( &p_stream
->os
, p_stream
->i_serial_no
);
1537 TAB_APPEND( p_ogg
->i_streams
, p_ogg
->pp_stream
, p_stream
);
1539 /* Extract the initial header from the first page and verify
1540 * the codec type of this Ogg bitstream */
1541 if( ogg_stream_pagein( &p_stream
->os
, &p_ogg
->current_page
) < 0 )
1543 /* error. stream version mismatch perhaps */
1544 msg_Err( p_demux
, "error reading first page of "
1545 "Ogg bitstream data" );
1546 return VLC_EGENERIC
;
1549 if ( ogg_stream_packetpeek( &p_stream
->os
, &oggpacket
) != 1 )
1551 msg_Err( p_demux
, "error in ogg_stream_packetpeek" );
1552 return VLC_EGENERIC
;
1555 /* Check for Vorbis header */
1556 if( oggpacket
.bytes
>= 7 &&
1557 ! memcmp( oggpacket
.packet
, "\x01vorbis", 7 ) )
1559 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_VORBIS
);
1560 if ( Ogg_ReadVorbisHeader( p_stream
, &oggpacket
) )
1561 msg_Dbg( p_demux
, "found vorbis header" );
1564 msg_Dbg( p_demux
, "found invalid vorbis header" );
1565 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1567 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1568 p_ogg
->i_streams
- 1 );
1571 /* Check for Speex header */
1572 else if( oggpacket
.bytes
>= 5 &&
1573 ! memcmp( oggpacket
.packet
, "Speex", 5 ) )
1575 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_SPEEX
);
1576 if ( Ogg_ReadSpeexHeader( p_stream
, &oggpacket
) )
1577 msg_Dbg( p_demux
, "found speex header, channels: %i, "
1578 "rate: %"PRIu32
"/%"PRIu32
", bitrate: %i, frames: %i group %i",
1579 p_stream
->fmt
.audio
.i_channels
,
1580 p_stream
->dts
.i_divider_num
, p_stream
->dts
.i_divider_den
,
1581 p_stream
->fmt
.i_bitrate
,
1582 p_stream
->special
.speex
.i_framesize
,
1583 p_stream
->special
.speex
.i_framesperpacket
);
1586 msg_Dbg( p_demux
, "found invalid Speex header" );
1587 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1589 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1590 p_ogg
->i_streams
- 1 );
1593 /* Check for Opus header */
1594 else if( oggpacket
.bytes
>= 8 &&
1595 ! memcmp( oggpacket
.packet
, "OpusHead", 8 ) )
1597 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_OPUS
);
1598 Ogg_ReadOpusHeader( p_stream
, &oggpacket
);
1599 msg_Dbg( p_demux
, "found opus header, channels: %i, "
1601 p_stream
->fmt
.audio
.i_channels
,
1602 (int)p_stream
->i_pre_skip
);
1603 p_stream
->i_skip_frames
= p_stream
->i_pre_skip
;
1605 /* Check for OLD Flac header */
1606 else if( oggpacket
.bytes
>= 4 &&
1607 ! memcmp( oggpacket
.packet
, "fLaC", 4 ) )
1609 msg_Dbg( p_demux
, "found FLAC header" );
1611 /* Grrrr!!!! Did they really have to put all the
1612 * important info in the second header packet!!!
1613 * (STREAMINFO metadata is in the following packet) */
1614 p_stream
->b_force_backup
= true;
1615 p_stream
->i_extra_headers_packets
= 1;
1616 p_stream
->special
.flac
.b_old
= true;
1617 date_Init( &p_stream
->dts
, 48000, 1 ); /* better be safe since that's delayed */
1618 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_FLAC
);
1620 /* Check for Flac header (>= version 1.0.0) */
1621 else if( oggpacket
.bytes
>= 13 && oggpacket
.packet
[0] ==0x7F &&
1622 ! memcmp( &oggpacket
.packet
[1], "FLAC", 4 ) &&
1623 ! memcmp( &oggpacket
.packet
[9], "fLaC", 4 ) )
1625 int i_packets
= ((int)oggpacket
.packet
[7]) << 8 |
1626 oggpacket
.packet
[8];
1627 msg_Dbg( p_demux
, "found FLAC header version %i.%i "
1628 "(%i header packets)",
1629 oggpacket
.packet
[5], oggpacket
.packet
[6],
1631 /* STREAMINFO is in current packet, and then
1632 followed by 0 or more metadata, blockheader prefixed, and first being a vorbis comment */
1633 p_stream
->b_force_backup
= true;
1634 p_stream
->i_extra_headers_packets
= i_packets
;
1635 p_stream
->special
.flac
.b_old
= false;
1637 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_FLAC
);
1638 oggpacket
.packet
+= 13; oggpacket
.bytes
-= 13; /* Point to the streaminfo */
1639 if ( !Ogg_ReadFlacStreamInfo( p_demux
, p_stream
, &oggpacket
) )
1641 msg_Dbg( p_demux
, "found invalid Flac header" );
1642 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1644 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1645 p_ogg
->i_streams
- 1 );
1647 p_stream
->fmt
.b_packetized
= false;
1649 /* Check for Theora header */
1650 else if( oggpacket
.bytes
>= 7 &&
1651 ! memcmp( oggpacket
.packet
, "\x80theora", 7 ) )
1653 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_THEORA
);
1654 if ( Ogg_ReadTheoraHeader( p_stream
, &oggpacket
) )
1656 "found theora header, bitrate: %i, rate: %"PRIu32
"/%"PRIu32
,
1657 p_stream
->fmt
.i_bitrate
,
1658 p_stream
->dts
.i_divider_num
, p_stream
->dts
.i_divider_den
);
1661 msg_Dbg( p_demux
, "found invalid Theora header" );
1662 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1664 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1665 p_ogg
->i_streams
- 1 );
1668 /* Check for Daala header */
1669 else if( oggpacket
.bytes
>= 6 &&
1670 ! memcmp( oggpacket
.packet
, "\x80""daala", 6 ) )
1672 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_DAALA
);
1673 if ( Ogg_ReadDaalaHeader( p_stream
, &oggpacket
) )
1675 "found daala header, bitrate: %i, rate: %"PRIu32
"/%"PRIu32
,
1676 p_stream
->fmt
.i_bitrate
,
1677 p_stream
->dts
.i_divider_num
, p_stream
->dts
.i_divider_den
);
1680 msg_Dbg( p_demux
, "found invalid Daala header" );
1681 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1683 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1684 p_ogg
->i_streams
- 1 );
1687 /* Check for Dirac header */
1688 else if( ( oggpacket
.bytes
>= 5 &&
1689 ! memcmp( oggpacket
.packet
, "BBCD\x00", 5 ) ) ||
1690 ( oggpacket
.bytes
>= 9 &&
1691 ! memcmp( oggpacket
.packet
, "KW-DIRAC\x00", 9 ) ) )
1693 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_DIRAC
);
1694 if( Ogg_ReadDiracHeader( p_stream
, &oggpacket
) )
1695 msg_Dbg( p_demux
, "found dirac header" );
1698 msg_Warn( p_demux
, "found dirac header isn't decodable" );
1699 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1701 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1702 p_ogg
->i_streams
- 1 );
1705 /* Check for VP8 header */
1706 else if( oggpacket
.bytes
>= 26 &&
1707 ! memcmp( oggpacket
.packet
, "OVP80", 5 ) )
1709 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_VP8
);
1710 if ( Ogg_ReadVP8Header( p_demux
, p_stream
, &oggpacket
) )
1711 msg_Dbg( p_demux
, "found VP8 header "
1712 "fps: %"PRIu32
"/%"PRIu32
", width:%i; height:%i",
1713 p_stream
->dts
.i_divider_num
, p_stream
->dts
.i_divider_den
,
1714 p_stream
->fmt
.video
.i_width
,
1715 p_stream
->fmt
.video
.i_height
);
1718 msg_Dbg( p_demux
, "invalid VP8 header found");
1719 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1721 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1722 p_ogg
->i_streams
- 1 );
1725 /* Check for Annodex header */
1726 else if( oggpacket
.bytes
>= 7 &&
1727 ! memcmp( oggpacket
.packet
, "Annodex", 7 ) )
1729 Ogg_ReadAnnodexHeader( p_demux
, p_stream
, &oggpacket
);
1730 /* kill annodex track */
1731 FREENULL( p_stream
);
1732 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1733 p_ogg
->i_streams
- 1 );
1735 /* Check for Annodex header */
1736 else if( oggpacket
.bytes
>= 7 &&
1737 ! memcmp( oggpacket
.packet
, "AnxData", 7 ) )
1739 Ogg_ReadAnnodexHeader( p_demux
, p_stream
, &oggpacket
);
1741 /* Check for Kate header */
1742 else if( oggpacket
.bytes
>= 8 &&
1743 ! memcmp( &oggpacket
.packet
[1], "kate\0\0\0", 7 ) )
1745 es_format_Change( &p_stream
->fmt
, SPU_ES
, VLC_CODEC_KATE
);
1746 if ( Ogg_ReadKateHeader( p_stream
, &oggpacket
) )
1747 msg_Dbg( p_demux
, "found kate header" );
1750 msg_Dbg( p_demux
, "invalid kate header found");
1751 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1753 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1754 p_ogg
->i_streams
- 1 );
1757 /* Check for OggDS */
1758 else if( oggpacket
.bytes
>= 142 &&
1759 !memcmp( &oggpacket
.packet
[1],
1760 "Direct Show Samples embedded in Ogg", 35 ))
1762 /* Old header type */
1763 p_stream
->b_oggds
= true;
1764 p_stream
->b_contiguous
= false;
1765 /* Check for video header (old format) */
1766 if( GetDWLE((oggpacket
.packet
+96)) == 0x05589f80 &&
1767 oggpacket
.bytes
>= 184 )
1769 es_format_Change( &p_stream
->fmt
, VIDEO_ES
,
1770 VLC_FOURCC( oggpacket
.packet
[68],
1771 oggpacket
.packet
[69],
1772 oggpacket
.packet
[70],
1773 oggpacket
.packet
[71] ) );
1774 msg_Dbg( p_demux
, "found video header of type: %.4s",
1775 (char *)&p_stream
->fmt
.i_codec
);
1777 unsigned num
= OGGDS_RESOLUTION
;
1778 unsigned den
= GetQWLE(oggpacket
.packet
+164);
1779 vlc_ureduce( &num
, &den
, num
, den
> 0 ? den
: 1, OGGDS_RESOLUTION
);
1780 p_stream
->fmt
.video
.i_frame_rate
= num
;
1781 p_stream
->fmt
.video
.i_frame_rate_base
= den
;
1782 date_Init( &p_stream
->dts
, num
, den
);
1783 p_stream
->fmt
.video
.i_bits_per_pixel
=
1784 GetWLE((oggpacket
.packet
+182));
1785 if( !p_stream
->fmt
.video
.i_bits_per_pixel
)
1787 p_stream
->fmt
.video
.i_bits_per_pixel
= 24;
1788 p_stream
->fmt
.video
.i_width
=
1789 GetDWLE((oggpacket
.packet
+176));
1790 p_stream
->fmt
.video
.i_height
=
1791 GetDWLE((oggpacket
.packet
+180));
1792 p_stream
->fmt
.video
.i_visible_width
=
1793 p_stream
->fmt
.video
.i_width
;
1794 p_stream
->fmt
.video
.i_visible_height
=
1795 p_stream
->fmt
.video
.i_height
;
1798 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1799 p_stream
->fmt
.video
.i_frame_rate
,
1800 p_stream
->fmt
.video
.i_frame_rate_base
,
1801 p_stream
->fmt
.video
.i_width
,
1802 p_stream
->fmt
.video
.i_height
,
1803 p_stream
->fmt
.video
.i_bits_per_pixel
);
1805 if ( !p_stream
->fmt
.video
.i_frame_rate
||
1806 !p_stream
->fmt
.video
.i_frame_rate_base
)
1808 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1810 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1811 p_ogg
->i_streams
- 1 );
1814 /* Check for audio header (old format) */
1815 else if( GetDWLE((oggpacket
.packet
+96)) == 0x05589F81 )
1818 unsigned int i_format_tag
;
1820 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, 0 );
1822 i_extra_size
= GetWLE((oggpacket
.packet
+140));
1823 if( i_extra_size
> 0 && i_extra_size
< oggpacket
.bytes
- 142 )
1825 p_stream
->fmt
.i_extra
= i_extra_size
;
1826 p_stream
->fmt
.p_extra
= malloc( i_extra_size
);
1827 if( p_stream
->fmt
.p_extra
)
1828 memcpy( p_stream
->fmt
.p_extra
,
1829 oggpacket
.packet
+ 142, i_extra_size
);
1831 p_stream
->fmt
.i_extra
= 0;
1834 i_format_tag
= GetWLE((oggpacket
.packet
+124));
1835 p_stream
->fmt
.audio
.i_channels
=
1836 GetWLE((oggpacket
.packet
+126));
1837 fill_channels_info(&p_stream
->fmt
.audio
);
1838 p_stream
->fmt
.audio
.i_rate
=
1839 GetDWLE((oggpacket
.packet
+128));
1840 p_stream
->fmt
.i_bitrate
=
1841 GetDWLE((oggpacket
.packet
+132)) * 8;
1842 p_stream
->fmt
.audio
.i_blockalign
=
1843 GetWLE((oggpacket
.packet
+136));
1844 p_stream
->fmt
.audio
.i_bitspersample
=
1845 GetWLE((oggpacket
.packet
+138));
1847 date_Init( &p_stream
->dts
, p_stream
->fmt
.audio
.i_rate
, 1 );
1849 wf_tag_to_fourcc( i_format_tag
,
1850 &p_stream
->fmt
.i_codec
, 0 );
1852 if( p_stream
->fmt
.i_codec
== VLC_CODEC_UNKNOWN
)
1854 p_stream
->fmt
.i_codec
= VLC_FOURCC( 'm', 's',
1855 ( i_format_tag
>> 8 ) & 0xff,
1856 i_format_tag
& 0xff );
1859 msg_Dbg( p_demux
, "found audio header of type: %.4s",
1860 (char *)&p_stream
->fmt
.i_codec
);
1861 msg_Dbg( p_demux
, "audio:0x%4.4x channels:%d %dHz "
1862 "%dbits/sample %dkb/s",
1864 p_stream
->fmt
.audio
.i_channels
,
1865 p_stream
->fmt
.audio
.i_rate
,
1866 p_stream
->fmt
.audio
.i_bitspersample
,
1867 p_stream
->fmt
.i_bitrate
/ 1024 );
1869 if ( p_stream
->fmt
.audio
.i_rate
== 0 )
1871 msg_Dbg( p_demux
, "invalid oggds audio header" );
1872 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
1874 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1875 p_ogg
->i_streams
- 1 );
1880 msg_Dbg( p_demux
, "stream %d has an old header "
1881 "but is of an unknown type", p_ogg
->i_streams
-1 );
1882 FREENULL( p_stream
);
1883 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
1884 p_ogg
->i_streams
- 1 );
1887 /* Check for OggDS */
1888 else if( oggpacket
.bytes
>= 44+1 &&
1889 (*oggpacket
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
)
1891 stream_header_t tmp
;
1892 stream_header_t
*st
= &tmp
;
1894 p_stream
->b_oggds
= true;
1895 p_stream
->b_contiguous
= false;
1897 memcpy( st
->streamtype
, &oggpacket
.packet
[1+0], 8 );
1898 memcpy( st
->subtype
, &oggpacket
.packet
[1+8], 4 );
1899 st
->size
= GetDWLE( &oggpacket
.packet
[1+12] );
1900 st
->time_unit
= GetQWLE( &oggpacket
.packet
[1+16] );
1901 st
->samples_per_unit
= GetQWLE( &oggpacket
.packet
[1+24] );
1902 st
->default_len
= GetDWLE( &oggpacket
.packet
[1+32] );
1903 st
->buffersize
= GetDWLE( &oggpacket
.packet
[1+36] );
1904 st
->bits_per_sample
= GetWLE( &oggpacket
.packet
[1+40] ); // (padding 2)
1906 /* Check for video header (new format) */
1907 if( !strncmp( st
->streamtype
, "video", 5 ) &&
1908 oggpacket
.bytes
>= 52+1 )
1910 st
->sh
.video
.width
= GetDWLE( &oggpacket
.packet
[1+44] );
1911 st
->sh
.video
.height
= GetDWLE( &oggpacket
.packet
[1+48] );
1913 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, 0 );
1915 /* We need to get rid of the header packet */
1916 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
1918 p_stream
->fmt
.i_codec
=
1919 VLC_FOURCC( st
->subtype
[0], st
->subtype
[1],
1920 st
->subtype
[2], st
->subtype
[3] );
1921 msg_Dbg( p_demux
, "found video header of type: %.4s",
1922 (char *)&p_stream
->fmt
.i_codec
);
1924 /* FIXME: no clue where it's from */
1925 if( st
->time_unit
<= 0 )
1926 st
->time_unit
= 400000;
1928 vlc_ureduce( &num
, &den
,
1929 st
->samples_per_unit
* OGGDS_RESOLUTION
,
1930 st
->time_unit
> 0 ? st
->time_unit
: OGGDS_RESOLUTION
,
1932 date_Init( &p_stream
->dts
, num
, den
);
1933 p_stream
->fmt
.video
.i_frame_rate
= num
;
1934 p_stream
->fmt
.video
.i_frame_rate_base
= den
;
1935 p_stream
->fmt
.video
.i_bits_per_pixel
= st
->bits_per_sample
;
1936 p_stream
->fmt
.video
.i_width
= st
->sh
.video
.width
;
1937 p_stream
->fmt
.video
.i_height
= st
->sh
.video
.height
;
1938 p_stream
->fmt
.video
.i_visible_width
=
1939 p_stream
->fmt
.video
.i_width
;
1940 p_stream
->fmt
.video
.i_visible_height
=
1941 p_stream
->fmt
.video
.i_height
;
1944 "fps: %u/%u, width:%i; height:%i, bitcount:%i",
1945 p_stream
->fmt
.video
.i_frame_rate
,
1946 p_stream
->fmt
.video
.i_frame_rate_base
,
1947 p_stream
->fmt
.video
.i_width
,
1948 p_stream
->fmt
.video
.i_height
,
1949 p_stream
->fmt
.video
.i_bits_per_pixel
);
1951 /* Check for audio header (new format) */
1952 else if( !strncmp( st
->streamtype
, "audio", 5 ) &&
1953 oggpacket
.bytes
>= 56+1 )
1959 st
->sh
.audio
.channels
= GetWLE( &oggpacket
.packet
[1+44] );
1960 st
->sh
.audio
.blockalign
= GetWLE( &oggpacket
.packet
[1+48] );
1961 st
->sh
.audio
.avgbytespersec
= GetDWLE( &oggpacket
.packet
[1+52] );
1963 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, 0 );
1965 /* We need to get rid of the header packet */
1966 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
1968 i_extra_size
= st
->size
- 56;
1970 if( i_extra_size
> 0 &&
1971 i_extra_size
< oggpacket
.bytes
- 1 - 56 )
1973 p_stream
->fmt
.i_extra
= i_extra_size
;
1974 p_stream
->fmt
.p_extra
= malloc( p_stream
->fmt
.i_extra
);
1975 if( p_stream
->fmt
.p_extra
)
1976 memcpy( p_stream
->fmt
.p_extra
, oggpacket
.packet
+ 57,
1977 p_stream
->fmt
.i_extra
);
1979 p_stream
->fmt
.i_extra
= 0;
1982 memcpy( p_buffer
, st
->subtype
, 4 );
1984 i_format_tag
= strtol(p_buffer
,NULL
,16);
1985 p_stream
->fmt
.audio
.i_channels
= st
->sh
.audio
.channels
;
1986 fill_channels_info(&p_stream
->fmt
.audio
);
1989 vlc_ureduce( &num
, &den
,
1990 st
->samples_per_unit
* OGGDS_RESOLUTION
,
1991 st
->time_unit
> 0 ? st
->time_unit
: OGGDS_RESOLUTION
,
1993 date_Init( &p_stream
->dts
, num
, den
);
1994 p_stream
->fmt
.audio
.i_rate
= num
/ den
;
1995 p_stream
->fmt
.i_bitrate
= st
->sh
.audio
.avgbytespersec
* 8;
1996 p_stream
->fmt
.audio
.i_blockalign
= st
->sh
.audio
.blockalign
;
1997 p_stream
->fmt
.audio
.i_bitspersample
= st
->bits_per_sample
;
1999 wf_tag_to_fourcc( i_format_tag
,
2000 &p_stream
->fmt
.i_codec
, 0 );
2002 if( p_stream
->fmt
.i_codec
== VLC_CODEC_UNKNOWN
)
2004 p_stream
->fmt
.i_codec
= VLC_FOURCC( 'm', 's',
2005 ( i_format_tag
>> 8 ) & 0xff,
2006 i_format_tag
& 0xff );
2009 msg_Dbg( p_demux
, "found audio header of type: %.4s",
2010 (char *)&p_stream
->fmt
.i_codec
);
2011 msg_Dbg( p_demux
, "audio:0x%4.4x channels:%d %dHz "
2012 "%dbits/sample %dkb/s",
2014 p_stream
->fmt
.audio
.i_channels
,
2015 p_stream
->fmt
.audio
.i_rate
,
2016 p_stream
->fmt
.audio
.i_bitspersample
,
2017 p_stream
->fmt
.i_bitrate
/ 1024 );
2018 if ( p_stream
->fmt
.audio
.i_rate
== 0 )
2020 msg_Dbg( p_demux
, "invalid oggds audio header" );
2021 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
2023 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
2024 p_ogg
->i_streams
- 1 );
2027 /* Check for text (subtitles) header */
2028 else if( !strncmp(st
->streamtype
, "text", 4) )
2030 /* We need to get rid of the header packet */
2031 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
2033 msg_Dbg( p_demux
, "found text subtitle header" );
2034 es_format_Change( &p_stream
->fmt
, SPU_ES
, VLC_CODEC_SUBT
);
2035 date_Init( &p_stream
->dts
, 1000, 1 ); /* granulepos is in millisec */
2039 msg_Dbg( p_demux
, "stream %d has a header marker "
2040 "but is of an unknown type", p_ogg
->i_streams
-1 );
2041 FREENULL( p_stream
);
2042 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
2043 p_ogg
->i_streams
- 1 );
2046 else if( oggpacket
.bytes
>= 8 &&
2047 ! memcmp( oggpacket
.packet
, "fishead\0", 8 ) )
2051 msg_Dbg( p_demux
, "stream %d is a skeleton",
2052 p_ogg
->i_streams
-1 );
2053 Ogg_ReadSkeletonHeader( p_demux
, p_stream
, &oggpacket
);
2055 /* Check for OggSpots header */
2056 else if( oggpacket
.bytes
>= 8 &&
2057 ! memcmp( oggpacket
.packet
, "SPOTS\0\0", 8 ) )
2059 if ( Ogg_ReadOggSpotsHeader( p_stream
, &oggpacket
) )
2061 "found OggSpots header, time resolution: %u/%u",
2062 p_stream
->fmt
.video
.i_frame_rate
,
2063 p_stream
->fmt
.video
.i_frame_rate_base
);
2066 msg_Err( p_demux
, "found invalid OggSpots header" );
2067 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
2069 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
2070 p_ogg
->i_streams
- 1 );
2075 Ogg_LogicalStreamDelete( p_demux
, p_stream
);
2077 TAB_ERASE( p_ogg
->i_streams
, p_ogg
->pp_stream
,
2078 p_ogg
->i_streams
- 1 );
2079 msg_Dbg( p_demux
, "stream %d is of unknown type",
2083 /* we'll need to get all headers */
2085 p_stream
->b_initializing
&= p_stream
->b_force_backup
;
2087 if( Ogg_ReadPage( p_demux
, &p_ogg
->current_page
) != VLC_SUCCESS
)
2088 return VLC_EGENERIC
;
2091 /* This is the first data page, which means we are now finished
2092 * with the initial pages. We just need to store it in the relevant
2094 for( int i_stream
= 0; i_stream
< p_ogg
->i_streams
; i_stream
++ )
2096 if( ogg_stream_pagein( &p_ogg
->pp_stream
[i_stream
]->os
,
2097 &p_ogg
->current_page
) == 0 )
2099 p_ogg
->b_page_waiting
= true;
2108 return VLC_EGENERIC
;
2111 /****************************************************************************
2112 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
2113 ****************************************************************************/
2114 static void Ogg_CreateES( demux_t
*p_demux
, bool stable_id
)
2116 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2117 logical_stream_t
*p_old_stream
= p_ogg
->p_old_stream
;
2120 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
2122 logical_stream_t
*p_stream
= p_ogg
->pp_stream
[i_stream
];
2124 if ( p_stream
->p_es
== NULL
&& !p_stream
->b_finished
)
2126 /* Better be safe than sorry when possible with ogm */
2127 if( p_stream
->fmt
.i_codec
== VLC_CODEC_MPGA
||
2128 p_stream
->fmt
.i_codec
== VLC_CODEC_A52
)
2129 p_stream
->fmt
.b_packetized
= false;
2131 /* Try first to reuse an old ES */
2133 p_old_stream
->fmt
.i_cat
== p_stream
->fmt
.i_cat
&&
2134 p_old_stream
->fmt
.i_codec
== p_stream
->fmt
.i_codec
&&
2135 p_old_stream
->p_es
!= NULL
&& p_stream
->p_es
!= NULL
)
2137 msg_Dbg( p_demux
, "will reuse old stream to avoid glitch" );
2139 p_stream
->p_es
= p_old_stream
->p_es
;
2140 p_stream
->b_finished
= false;
2141 p_stream
->b_reinit
= false;
2142 p_stream
->b_initializing
= false;
2143 p_stream
->i_pre_skip
= 0;
2144 es_format_Clean( &p_stream
->fmt_old
);
2145 es_format_Copy( &p_stream
->fmt_old
, &p_old_stream
->fmt
);
2146 bool b_resetdecoder
= Ogg_LogicalStreamResetEsFormat( p_demux
, p_stream
);
2148 p_old_stream
->p_es
= NULL
;
2149 p_old_stream
= NULL
;
2150 if ( b_resetdecoder
)
2152 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_FMT
,
2153 p_stream
->p_es
, &p_stream
->fmt
);
2160 /* IDs are stable when ES tracks are created from the Open
2161 * function. Don't specify ids when tracks are added
2163 p_stream
->fmt
.i_id
= i_stream
;
2165 p_stream
->p_es
= es_out_Add( p_demux
->out
, &p_stream
->fmt
);
2170 if( p_ogg
->p_old_stream
)
2172 if( p_ogg
->p_old_stream
->p_es
)
2173 msg_Dbg( p_demux
, "old stream not reused" );
2174 Ogg_LogicalStreamDelete( p_demux
, p_ogg
->p_old_stream
);
2175 p_ogg
->p_old_stream
= NULL
;
2177 p_ogg
->b_es_created
= true;
2180 /****************************************************************************
2181 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
2182 * Elementary streams.
2183 ****************************************************************************/
2184 static int Ogg_BeginningOfStream( demux_t
*p_demux
)
2186 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2189 /* Find the logical streams embedded in the physical stream and
2190 * initialize our p_ogg structure. */
2191 if( Ogg_FindLogicalStreams( p_demux
) != VLC_SUCCESS
)
2193 msg_Warn( p_demux
, "couldn't find any ogg logical stream" );
2194 return VLC_EGENERIC
;
2197 p_ogg
->i_bitrate
= 0;
2199 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
2201 logical_stream_t
*p_stream
= p_ogg
->pp_stream
[i_stream
];
2203 p_stream
->p_es
= NULL
;
2205 /* initialise kframe index */
2208 if ( p_stream
->fmt
.i_bitrate
== 0 &&
2209 ( p_stream
->fmt
.i_cat
== VIDEO_ES
||
2210 p_stream
->fmt
.i_cat
== AUDIO_ES
) )
2211 p_ogg
->b_partial_bitrate
= true;
2213 p_ogg
->i_bitrate
+= p_stream
->fmt
.i_bitrate
;
2215 p_stream
->i_pcr
= VLC_TICK_INVALID
;
2216 p_stream
->b_reinit
= false;
2219 /* get total frame count for video stream; we will need this for seeking */
2220 p_ogg
->i_total_frames
= 0;
2225 /****************************************************************************
2226 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
2227 ****************************************************************************/
2228 static void Ogg_EndOfStream( demux_t
*p_demux
)
2230 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2233 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
2234 Ogg_LogicalStreamDelete( p_demux
, p_ogg
->pp_stream
[i_stream
] );
2235 free( p_ogg
->pp_stream
);
2238 p_ogg
->i_bitrate
= 0;
2239 p_ogg
->i_streams
= 0;
2240 p_ogg
->pp_stream
= NULL
;
2241 p_ogg
->skeleton
.major
= 0;
2242 p_ogg
->skeleton
.minor
= 0;
2243 p_ogg
->b_preparsing_done
= false;
2244 p_ogg
->b_es_created
= false;
2248 vlc_meta_Delete( p_ogg
->p_meta
);
2249 p_ogg
->p_meta
= NULL
;
2251 for(int i
=0; i
<p_ogg
->i_attachments
; i
++)
2252 vlc_input_attachment_Delete( p_ogg
->attachments
[i
] );
2253 TAB_CLEAN(p_ogg
->i_attachments
, p_ogg
->attachments
);
2255 for ( int i
=0; i
< p_ogg
->i_seekpoints
; i
++ )
2257 if ( p_ogg
->pp_seekpoints
[i
] )
2258 vlc_seekpoint_Delete( p_ogg
->pp_seekpoints
[i
] );
2260 TAB_CLEAN( p_ogg
->i_seekpoints
, p_ogg
->pp_seekpoints
);
2263 static void Ogg_CleanSpecificData( logical_stream_t
*p_stream
)
2265 #ifdef HAVE_LIBVORBIS
2266 if ( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
)
2268 if( p_stream
->special
.vorbis
.p_info
)
2269 vorbis_info_clear( p_stream
->special
.vorbis
.p_info
);
2270 FREENULL( p_stream
->special
.vorbis
.p_info
);
2271 if( p_stream
->special
.vorbis
.p_comment
)
2272 vorbis_comment_clear( p_stream
->special
.vorbis
.p_comment
);
2273 FREENULL( p_stream
->special
.vorbis
.p_comment
);
2274 p_stream
->special
.vorbis
.i_headers_flags
= 0;
2277 VLC_UNUSED( p_stream
);
2281 static void Ogg_LogicalStreamInit( logical_stream_t
*p_stream
)
2283 memset( p_stream
, 0, sizeof(logical_stream_t
) );
2284 es_format_Init( &p_stream
->fmt
, UNKNOWN_ES
, 0 );
2285 es_format_Init( &p_stream
->fmt_old
, UNKNOWN_ES
, 0 );
2286 p_stream
->i_pcr
= VLC_TICK_INVALID
;
2287 p_stream
->i_first_frame_index
= 1;
2288 date_Set( &p_stream
->dts
, VLC_TICK_INVALID
);
2289 p_stream
->b_initializing
= true;
2290 p_stream
->b_contiguous
= true; /* default */
2291 p_stream
->queue
.pp_append
= &p_stream
->queue
.p_blocks
;
2295 * This function delete and release all data associated to a logical_stream_t
2297 static void Ogg_LogicalStreamDelete( demux_t
*p_demux
, logical_stream_t
*p_stream
)
2299 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2301 if( p_stream
->p_es
)
2302 es_out_Del( p_demux
->out
, p_stream
->p_es
);
2304 ogg_stream_clear( &p_stream
->os
);
2305 free( p_stream
->p_headers
);
2307 Ogg_CleanSpecificData( p_stream
);
2309 es_format_Clean( &p_stream
->fmt_old
);
2310 es_format_Clean( &p_stream
->fmt
);
2312 if ( p_stream
->idx
!= NULL
)
2314 oggseek_index_entries_free( p_stream
->idx
);
2317 Ogg_FreeSkeleton( p_stream
->p_skel
);
2318 p_stream
->p_skel
= NULL
;
2319 if( p_sys
->p_skelstream
== p_stream
)
2320 p_sys
->p_skelstream
= NULL
;
2322 /* Shouldn't happen */
2323 block_ChainRelease( p_stream
->queue
.p_blocks
);
2328 * This function check if a we need to reset a decoder in case we are
2331 static bool Ogg_IsVorbisFormatCompatible( const es_format_t
*p_new
, const es_format_t
*p_old
)
2333 unsigned pi_new_size
[XIPH_MAX_HEADER_COUNT
];
2334 const void *pp_new_data
[XIPH_MAX_HEADER_COUNT
];
2335 unsigned i_new_count
;
2337 if( xiph_SplitHeaders(pi_new_size
, pp_new_data
, &i_new_count
, p_new
->i_extra
, p_new
->p_extra
) )
2340 unsigned pi_old_size
[XIPH_MAX_HEADER_COUNT
];
2341 const void *pp_old_data
[XIPH_MAX_HEADER_COUNT
];
2342 unsigned i_old_count
;
2344 if( xiph_SplitHeaders(pi_old_size
, pp_old_data
, &i_old_count
, p_old
->i_extra
, p_old
->p_extra
) )
2347 bool b_match
= i_new_count
== i_old_count
;
2348 for( unsigned i
= 0; i
< i_new_count
&& b_match
; i
++ )
2350 /* Ignore vorbis comment */
2353 if( pi_new_size
[i
] != pi_old_size
[i
] ||
2354 memcmp( pp_new_data
[i
], pp_old_data
[i
], pi_new_size
[i
] ) )
2361 static bool Ogg_IsOpusFormatCompatible( const es_format_t
*p_new
,
2362 const es_format_t
*p_old
)
2364 unsigned pi_new_size
[XIPH_MAX_HEADER_COUNT
];
2365 const void *pp_new_data
[XIPH_MAX_HEADER_COUNT
];
2366 unsigned i_new_count
;
2368 if( xiph_SplitHeaders(pi_new_size
, pp_new_data
, &i_new_count
, p_new
->i_extra
, p_new
->p_extra
) )
2371 unsigned pi_old_size
[XIPH_MAX_HEADER_COUNT
];
2372 const void *pp_old_data
[XIPH_MAX_HEADER_COUNT
];
2373 unsigned i_old_count
;
2375 if( xiph_SplitHeaders(pi_old_size
, pp_old_data
, &i_old_count
, p_old
->i_extra
, p_old
->p_extra
) )
2377 bool b_match
= false;
2378 if( i_new_count
== i_old_count
&& i_new_count
> 0 )
2380 static const unsigned char default_map
[2] = { 0, 1 };
2381 const unsigned char *p_old_head
;
2382 unsigned char *p_new_head
;
2383 const unsigned char *p_old_map
;
2384 const unsigned char *p_new_map
;
2385 int i_old_channel_count
;
2386 int i_new_channel_count
;
2387 int i_old_stream_count
;
2388 int i_new_stream_count
;
2389 int i_old_coupled_count
;
2390 int i_new_coupled_count
;
2391 p_old_head
= pp_old_data
[0];
2392 i_old_channel_count
= i_old_stream_count
= i_old_coupled_count
= 0;
2393 p_old_map
= default_map
;
2394 if( pi_old_size
[0] >= 19 && p_old_head
[8] <= 15 )
2396 i_old_channel_count
= p_old_head
[9];
2397 switch( p_old_head
[18] )
2400 i_old_stream_count
= 1;
2401 i_old_coupled_count
= i_old_channel_count
- 1;
2404 if( pi_old_size
[0] >= 21U + i_old_channel_count
)
2406 i_old_stream_count
= p_old_head
[19];
2407 i_old_coupled_count
= p_old_head
[20];
2408 p_old_map
= p_old_head
+ 21;
2413 p_new_head
= (unsigned char *)pp_new_data
[0];
2414 i_new_channel_count
= i_new_stream_count
= i_new_coupled_count
= 0;
2415 p_new_map
= default_map
;
2416 if( pi_new_size
[0] >= 19 && p_new_head
[8] <= 15 )
2418 i_new_channel_count
= p_new_head
[9];
2419 switch( p_new_head
[18] )
2422 i_new_stream_count
= 1;
2423 i_new_coupled_count
= i_new_channel_count
- 1;
2426 if( pi_new_size
[0] >= 21U + i_new_channel_count
)
2428 i_new_stream_count
= p_new_head
[19];
2429 i_new_coupled_count
= p_new_head
[20];
2430 p_new_map
= p_new_head
+21;
2435 b_match
= i_old_channel_count
== i_new_channel_count
&&
2436 i_old_stream_count
== i_new_stream_count
&&
2437 i_old_coupled_count
== i_new_coupled_count
&&
2438 memcmp(p_old_map
, p_new_map
,
2439 i_new_channel_count
*sizeof(*p_new_map
)) == 0;
2445 static bool Ogg_LogicalStreamResetEsFormat( demux_t
*p_demux
, logical_stream_t
*p_stream
)
2447 bool b_compatible
= false;
2448 if( !p_stream
->fmt_old
.i_cat
|| !p_stream
->fmt_old
.i_codec
)
2451 /* Only Vorbis and Opus are supported. */
2452 if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
)
2453 b_compatible
= Ogg_IsVorbisFormatCompatible( &p_stream
->fmt
, &p_stream
->fmt_old
);
2454 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
2455 b_compatible
= Ogg_IsOpusFormatCompatible( &p_stream
->fmt
, &p_stream
->fmt_old
);
2456 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_FLAC
)
2457 b_compatible
= !p_stream
->fmt
.b_packetized
;
2460 msg_Warn( p_demux
, "cannot reuse old stream, resetting the decoder" );
2462 return !b_compatible
;
2465 static void Ogg_ExtractComments( demux_t
*p_demux
, es_format_t
*p_fmt
,
2466 const void *p_headers
, unsigned i_headers
)
2468 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2469 int i_cover_score
= 0;
2470 int i_cover_idx
= 0;
2471 float pf_replay_gain
[AUDIO_REPLAY_GAIN_MAX
];
2472 float pf_replay_peak
[AUDIO_REPLAY_GAIN_MAX
];
2473 for(int i
=0; i
< AUDIO_REPLAY_GAIN_MAX
; i
++ )
2475 pf_replay_gain
[i
] = 0;
2476 pf_replay_peak
[i
] = 0;
2478 vorbis_ParseComment( p_fmt
, &p_ogg
->p_meta
, p_headers
, i_headers
,
2479 &p_ogg
->i_attachments
, &p_ogg
->attachments
,
2480 &i_cover_score
, &i_cover_idx
,
2481 &p_ogg
->i_seekpoints
, &p_ogg
->pp_seekpoints
,
2482 &pf_replay_gain
, &pf_replay_peak
);
2483 if( p_ogg
->p_meta
!= NULL
&& i_cover_idx
< p_ogg
->i_attachments
)
2486 snprintf( psz_url
, sizeof(psz_url
), "attachment://%s",
2487 p_ogg
->attachments
[i_cover_idx
]->psz_name
);
2488 vlc_meta_Set( p_ogg
->p_meta
, vlc_meta_ArtworkURL
, psz_url
);
2491 for ( int i
=0; i
<AUDIO_REPLAY_GAIN_MAX
;i
++ )
2493 if ( pf_replay_gain
[i
] != 0 )
2495 p_fmt
->audio_replay_gain
.pb_gain
[i
] = true;
2496 p_fmt
->audio_replay_gain
.pf_gain
[i
] = pf_replay_gain
[i
];
2497 msg_Dbg( p_demux
, "setting replay gain %d to %f", i
, pf_replay_gain
[i
] );
2499 if ( pf_replay_peak
[i
] != 0 )
2501 p_fmt
->audio_replay_gain
.pb_peak
[i
] = true;
2502 p_fmt
->audio_replay_gain
.pf_peak
[i
] = pf_replay_peak
[i
];
2503 msg_Dbg( p_demux
, "setting replay peak %d to %f", i
, pf_replay_gain
[i
] );
2507 if( p_ogg
->i_seekpoints
> 1 )
2509 p_ogg
->updates
|= INPUT_UPDATE_TITLE_LIST
;
2513 static inline uint32_t GetDW24BE( const uint8_t *p
)
2515 uint32_t i
= ( p
[0] << 16 ) + ( p
[1] << 8 ) + ( p
[2] );
2516 #ifdef WORDS_BIGENDIAN
2522 static void Ogg_ExtractFlacComments( demux_t
*p_demux
, es_format_t
*p_fmt
,
2523 const uint8_t *p_headers
, unsigned i_headers
)
2525 /* Skip Streaminfo 42 bytes / 1st page */
2528 p_headers
+= 42; i_headers
-= 42;
2529 /* Block Header 1 + 3 bytes */
2530 uint32_t blocksize
= GetDW24BE(&p_headers
[1]);
2531 if(p_headers
[0] == 0x84 && blocksize
<= i_headers
- 4)
2533 Ogg_ExtractComments( p_demux
, p_fmt
, &p_headers
[4], i_headers
- 4 );
2537 static void Ogg_ExtractXiphMeta( demux_t
*p_demux
, es_format_t
*p_fmt
,
2538 const void *p_headers
, unsigned i_headers
, unsigned i_skip
)
2540 unsigned pi_size
[XIPH_MAX_HEADER_COUNT
];
2541 const void *pp_data
[XIPH_MAX_HEADER_COUNT
];
2544 if( xiph_SplitHeaders( pi_size
, pp_data
, &i_count
, i_headers
, p_headers
) )
2546 /* TODO how to handle multiple comments properly ? */
2547 if( i_count
>= 2 && pi_size
[1] > i_skip
)
2549 Ogg_ExtractComments( p_demux
, p_fmt
,
2550 (const uint8_t *)pp_data
[1] + i_skip
,
2551 pi_size
[1] - i_skip
);
2555 static void Ogg_ExtractMeta( demux_t
*p_demux
, es_format_t
*p_fmt
, const uint8_t *p_headers
, int i_headers
)
2557 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2559 switch( p_fmt
->i_codec
)
2561 /* 3 headers with the 2° one being the comments */
2562 case VLC_CODEC_VORBIS
:
2563 case VLC_CODEC_THEORA
:
2564 case VLC_CODEC_DAALA
:
2565 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 1+6 );
2567 case VLC_CODEC_OPUS
:
2568 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 8 );
2570 case VLC_CODEC_SPEEX
:
2571 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 0 );
2574 Ogg_ExtractComments( p_demux
, p_fmt
, p_headers
, i_headers
);
2576 /* N headers with the 2° one being the comments */
2577 case VLC_CODEC_KATE
:
2578 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2579 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 1+7+1 );
2583 case VLC_CODEC_FLAC
:
2584 Ogg_ExtractFlacComments( p_demux
, p_fmt
, p_headers
, i_headers
);
2588 case VLC_CODEC_DIRAC
:
2593 p_ogg
->updates
|= INPUT_UPDATE_META
;
2596 static bool Ogg_ReadTheoraHeader( logical_stream_t
*p_stream
,
2597 ogg_packet
*p_oggpacket
)
2600 unsigned int i_fps_numerator
;
2601 unsigned int i_fps_denominator
;
2602 int i_keyframe_frequency_force
;
2608 /* Signal that we want to keep a backup of the theora
2609 * stream headers. They will be used when switching between
2611 p_stream
->b_force_backup
= true;
2613 /* Cheat and get additionnal info ;) */
2614 bs_init( &bitstream
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2615 bs_skip( &bitstream
, 56 );
2617 i_major
= bs_read( &bitstream
, 8 ); /* major version num */
2618 i_minor
= bs_read( &bitstream
, 8 ); /* minor version num */
2619 i_subminor
= bs_read( &bitstream
, 8 ); /* subminor version num */
2621 bs_read( &bitstream
, 16 ) /*<< 4*/; /* width */
2622 bs_read( &bitstream
, 16 ) /*<< 4*/; /* height */
2623 bs_read( &bitstream
, 24 ); /* frame width */
2624 bs_read( &bitstream
, 24 ); /* frame height */
2625 bs_read( &bitstream
, 8 ); /* x offset */
2626 bs_read( &bitstream
, 8 ); /* y offset */
2628 i_fps_numerator
= bs_read( &bitstream
, 32 );
2629 i_fps_denominator
= bs_read( &bitstream
, 32 );
2630 i_fps_denominator
= __MAX( i_fps_denominator
, 1 );
2631 bs_read( &bitstream
, 24 ); /* aspect_numerator */
2632 bs_read( &bitstream
, 24 ); /* aspect_denominator */
2634 p_stream
->fmt
.video
.i_frame_rate
= i_fps_numerator
;
2635 p_stream
->fmt
.video
.i_frame_rate_base
= i_fps_denominator
;
2637 bs_read( &bitstream
, 8 ); /* colorspace */
2638 p_stream
->fmt
.i_bitrate
= bs_read( &bitstream
, 24 );
2639 bs_read( &bitstream
, 6 ); /* quality */
2641 i_keyframe_frequency_force
= 1 << bs_read( &bitstream
, 5 );
2643 /* granule_shift = i_log( frequency_force -1 ) */
2644 p_stream
->i_granule_shift
= 0;
2645 i_keyframe_frequency_force
--;
2646 while( i_keyframe_frequency_force
)
2648 p_stream
->i_granule_shift
++;
2649 i_keyframe_frequency_force
>>= 1;
2652 i_version
= i_major
* 1000000 + i_minor
* 1000 + i_subminor
;
2653 p_stream
->i_first_frame_index
= (i_version
>= 3002001) ? 1 : 0;
2654 if ( !i_fps_denominator
|| !i_fps_numerator
)
2656 date_Init( &p_stream
->dts
, i_fps_numerator
, i_fps_denominator
);
2661 static bool Ogg_ReadDaalaHeader( logical_stream_t
*p_stream
,
2662 ogg_packet
*p_oggpacket
)
2665 uint32_t i_timebase_numerator
;
2666 uint32_t i_timebase_denominator
;
2667 int keyframe_granule_shift
;
2668 unsigned int i_keyframe_frequency_force
;
2674 /* Signal that we want to keep a backup of the daala
2675 * stream headers. They will be used when switching between
2677 p_stream
->b_force_backup
= true;
2679 /* Cheat and get additionnal info ;) */
2680 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2681 oggpack_adv( &opb
, 48 );
2683 i_major
= oggpack_read( &opb
, 8 ); /* major version num */
2684 i_minor
= oggpack_read( &opb
, 8 ); /* minor version num */
2685 i_subminor
= oggpack_read( &opb
, 8 ); /* subminor version num */
2687 oggpack_adv( &opb
, 32 ); /* width */
2688 oggpack_adv( &opb
, 32 ); /* height */
2690 oggpack_adv( &opb
, 32 ); /* aspect numerator */
2691 oggpack_adv( &opb
, 32 ); /* aspect denominator */
2692 i_timebase_numerator
= oggpack_read( &opb
, 32 );
2694 i_timebase_denominator
= oggpack_read( &opb
, 32 );
2695 i_timebase_denominator
= __MAX( i_timebase_denominator
, 1 );
2697 p_stream
->fmt
.video
.i_frame_rate
= i_timebase_numerator
;
2698 p_stream
->fmt
.video
.i_frame_rate_base
= i_timebase_denominator
;
2700 oggpack_adv( &opb
, 32 ); /* frame duration */
2702 keyframe_granule_shift
= oggpack_read( &opb
, 8 );
2703 keyframe_granule_shift
= __MIN(keyframe_granule_shift
, 31);
2704 i_keyframe_frequency_force
= 1u << keyframe_granule_shift
;
2706 /* granule_shift = i_log( frequency_force -1 ) */
2707 p_stream
->i_granule_shift
= 0;
2708 i_keyframe_frequency_force
--;
2709 while( i_keyframe_frequency_force
)
2711 p_stream
->i_granule_shift
++;
2712 i_keyframe_frequency_force
>>= 1;
2715 i_version
= i_major
* 1000000 + i_minor
* 1000 + i_subminor
;
2716 VLC_UNUSED(i_version
);
2717 p_stream
->i_first_frame_index
= 0;
2718 if ( !i_timebase_numerator
|| !i_timebase_denominator
)
2720 date_Init( &p_stream
->dts
, i_timebase_numerator
, i_timebase_denominator
);
2725 static bool Ogg_ReadVorbisHeader( logical_stream_t
*p_stream
,
2726 ogg_packet
*p_oggpacket
)
2730 /* Signal that we want to keep a backup of the vorbis
2731 * stream headers. They will be used when switching between
2733 p_stream
->b_force_backup
= true;
2735 /* Cheat and get additionnal info ;) */
2736 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2737 oggpack_adv( &opb
, 88 );
2738 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 8 );
2739 fill_channels_info(&p_stream
->fmt
.audio
);
2740 p_stream
->fmt
.audio
.i_rate
= oggpack_read( &opb
, 32 );
2741 if( p_stream
->fmt
.audio
.i_rate
== 0 )
2743 date_Init( &p_stream
->dts
, p_stream
->fmt
.audio
.i_rate
, 1 );
2745 oggpack_adv( &opb
, 32 );
2746 p_stream
->fmt
.i_bitrate
= oggpack_read( &opb
, 32 ); /* is signed 32 */
2747 if( p_stream
->fmt
.i_bitrate
> INT32_MAX
) p_stream
->fmt
.i_bitrate
= 0;
2750 #ifdef HAVE_LIBVORBIS
2751 static void Ogg_DecodeVorbisHeader( logical_stream_t
*p_stream
,
2752 ogg_packet
*p_oggpacket
, int i_number
)
2756 case VORBIS_HEADER_IDENTIFICATION
:
2757 p_stream
->special
.vorbis
.p_info
= calloc( 1, sizeof(vorbis_info
) );
2758 p_stream
->special
.vorbis
.p_comment
= malloc( sizeof(vorbis_comment
) );
2759 if ( !p_stream
->special
.vorbis
.p_info
|| !p_stream
->special
.vorbis
.p_comment
)
2761 FREENULL( p_stream
->special
.vorbis
.p_info
);
2762 FREENULL( p_stream
->special
.vorbis
.p_comment
);
2765 vorbis_info_init( p_stream
->special
.vorbis
.p_info
);
2766 vorbis_comment_init( p_stream
->special
.vorbis
.p_comment
);
2769 case VORBIS_HEADER_COMMENT
:
2770 case VORBIS_HEADER_SETUP
:
2771 if ( !p_stream
->special
.vorbis
.p_info
||
2772 vorbis_synthesis_headerin(
2773 p_stream
->special
.vorbis
.p_info
,
2774 p_stream
->special
.vorbis
.p_comment
, p_oggpacket
) )
2777 p_stream
->special
.vorbis
.i_headers_flags
|= VORBIS_HEADER_TO_FLAG(i_number
);
2786 static bool Ogg_ReadSpeexHeader( logical_stream_t
*p_stream
,
2787 ogg_packet
*p_oggpacket
)
2791 /* Signal that we want to keep a backup of the speex
2792 * stream headers. They will be used when switching between
2794 p_stream
->b_force_backup
= true;
2796 /* Cheat and get additionnal info ;) */
2797 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2798 oggpack_adv( &opb
, 224 );
2799 oggpack_adv( &opb
, 32 ); /* speex_version_id */
2800 oggpack_adv( &opb
, 32 ); /* header_size */
2801 p_stream
->fmt
.audio
.i_rate
= oggpack_read( &opb
, 32 );
2802 if ( !p_stream
->fmt
.audio
.i_rate
)
2804 date_Init( &p_stream
->dts
, p_stream
->fmt
.audio
.i_rate
, 1 );
2805 oggpack_adv( &opb
, 32 ); /* mode */
2806 oggpack_adv( &opb
, 32 ); /* mode_bitstream_version */
2807 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 32 );
2808 fill_channels_info(&p_stream
->fmt
.audio
);
2809 p_stream
->fmt
.i_bitrate
= oggpack_read( &opb
, 32 );
2810 p_stream
->special
.speex
.i_framesize
=
2811 oggpack_read( &opb
, 32 ); /* frame_size */
2812 oggpack_adv( &opb
, 32 ); /* vbr */
2813 p_stream
->special
.speex
.i_framesperpacket
=
2814 oggpack_read( &opb
, 32 ); /* frames_per_packet */
2815 p_stream
->i_extra_headers_packets
= oggpack_read( &opb
, 32 ); /* extra_headers */
2819 static void Ogg_ReadOpusHeader( logical_stream_t
*p_stream
,
2820 ogg_packet
*p_oggpacket
)
2824 /* Signal that we want to keep a backup of the opus
2825 * stream headers. They will be used when switching between
2827 p_stream
->b_force_backup
= true;
2829 /* All OggOpus streams are timestamped at 48kHz and
2830 * can be played at 48kHz. */
2831 p_stream
->fmt
.audio
.i_rate
= 48000;
2832 date_Init( &p_stream
->dts
, p_stream
->fmt
.audio
.i_rate
, 1 );
2833 p_stream
->fmt
.i_bitrate
= 0;
2835 /* Cheat and get additional info ;) */
2836 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2837 oggpack_adv( &opb
, 64 );
2838 oggpack_adv( &opb
, 8 ); /* version_id */
2839 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 8 );
2840 fill_channels_info(&p_stream
->fmt
.audio
);
2841 p_stream
->i_pre_skip
= oggpack_read( &opb
, 16 );
2842 /* For Opus, trash the first 80 ms of decoded output as
2843 well, to avoid blowing out speakers if we get unlucky.
2844 Opus predicts content from prior frames, which can go
2845 badly if we seek right where the stream goes from very
2846 quiet to very loud. It will converge after a bit. */
2847 p_stream
->i_pre_skip
= __MAX( 80*48, p_stream
->i_pre_skip
);
2850 static bool Ogg_ReadFlacStreamInfo( demux_t
*p_demux
, logical_stream_t
*p_stream
,
2851 ogg_packet
*p_oggpacket
)
2853 /* Parse the STREAMINFO metadata */
2856 bs_init( &s
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2859 if( p_oggpacket
->bytes
> 0 && bs_read( &s
, 7 ) != 0 )
2861 msg_Dbg( p_demux
, "Invalid FLAC STREAMINFO metadata" );
2865 if( bs_read( &s
, 24 ) >= 34 /*size STREAMINFO*/ )
2868 p_stream
->fmt
.audio
.i_rate
= bs_read( &s
, 20 );
2869 p_stream
->fmt
.audio
.i_channels
= bs_read( &s
, 3 ) + 1;
2870 fill_channels_info(&p_stream
->fmt
.audio
);
2872 msg_Dbg( p_demux
, "FLAC header, channels: %"PRIu8
", rate: %u",
2873 p_stream
->fmt
.audio
.i_channels
, p_stream
->fmt
.audio
.i_rate
);
2874 if ( p_stream
->fmt
.audio
.i_rate
== 0 )
2876 date_Init( &p_stream
->dts
, p_stream
->fmt
.audio
.i_rate
, 1 );
2880 msg_Dbg( p_demux
, "FLAC STREAMINFO metadata too short" );
2883 /* Fake this as the last metadata block */
2884 *((uint8_t*)p_oggpacket
->packet
) |= 0x80;
2888 static bool Ogg_ReadKateHeader( logical_stream_t
*p_stream
,
2889 ogg_packet
*p_oggpacket
)
2897 /* Signal that we want to keep a backup of the kate
2898 * stream headers. They will be used when switching between
2900 p_stream
->b_force_backup
= true;
2902 /* Cheat and get additionnal info ;) */
2903 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2904 oggpack_adv( &opb
, 11*8 ); /* packet type, kate magic, version */
2905 p_stream
->special
.kate
.i_num_headers
= oggpack_read( &opb
, 8 );
2906 oggpack_adv( &opb
, 3*8 );
2907 p_stream
->i_granule_shift
= oggpack_read( &opb
, 8 );
2908 oggpack_adv( &opb
, 8*8 ); /* reserved */
2909 gnum
= oggpack_read( &opb
, 32 );
2910 gden
= oggpack_read( &opb
, 32 );
2911 gden
= __MAX( gden
, 1 );
2912 if ( !gnum
|| !gden
)
2914 date_Init( &p_stream
->dts
, gnum
, gden
);
2916 p_stream
->fmt
.psz_language
= malloc(16);
2917 if( p_stream
->fmt
.psz_language
)
2919 for( n
= 0; n
< 16; n
++ )
2920 p_stream
->fmt
.psz_language
[n
] = oggpack_read(&opb
,8);
2921 p_stream
->fmt
.psz_language
[15] = 0; /* just in case */
2925 for( n
= 0; n
< 16; n
++ )
2926 oggpack_read(&opb
,8);
2928 p_stream
->fmt
.psz_description
= malloc(16);
2929 if( p_stream
->fmt
.psz_description
)
2931 for( n
= 0; n
< 16; n
++ )
2932 p_stream
->fmt
.psz_description
[n
] = oggpack_read(&opb
,8);
2933 p_stream
->fmt
.psz_description
[15] = 0; /* just in case */
2935 /* Now find a localized user readable description for this category */
2936 psz_desc
= strdup(FindKateCategoryName(p_stream
->fmt
.psz_description
));
2939 free( p_stream
->fmt
.psz_description
);
2940 p_stream
->fmt
.psz_description
= psz_desc
;
2945 for( n
= 0; n
< 16; n
++ )
2946 oggpack_read(&opb
,8);
2952 static bool Ogg_ReadVP8Header( demux_t
*p_demux
, logical_stream_t
*p_stream
,
2953 ogg_packet
*p_oggpacket
)
2955 switch( p_oggpacket
->packet
[5] )
2959 /* Mapping version */
2960 if ( p_oggpacket
->packet
[6] != 0x01 || p_oggpacket
->packet
[7] != 0x00 )
2962 p_stream
->i_granule_shift
= 32;
2963 p_stream
->fmt
.video
.i_width
= GetWBE( &p_oggpacket
->packet
[8] );
2964 p_stream
->fmt
.video
.i_height
= GetWBE( &p_oggpacket
->packet
[10] );
2965 p_stream
->fmt
.video
.i_visible_width
= p_stream
->fmt
.video
.i_width
;
2966 p_stream
->fmt
.video
.i_visible_height
= p_stream
->fmt
.video
.i_height
;
2967 p_stream
->fmt
.video
.i_sar_num
= GetDWBE( &p_oggpacket
->packet
[12 - 1] ) & 0x0FFF;
2968 p_stream
->fmt
.video
.i_sar_den
= GetDWBE( &p_oggpacket
->packet
[15 - 1] ) & 0x0FFF;
2969 p_stream
->fmt
.video
.i_frame_rate
= GetDWBE( &p_oggpacket
->packet
[18] );
2970 p_stream
->fmt
.video
.i_frame_rate_base
= GetDWBE( &p_oggpacket
->packet
[22] );
2971 if ( !p_stream
->fmt
.video
.i_frame_rate
|| !p_stream
->fmt
.video
.i_frame_rate_base
)
2973 date_Init( &p_stream
->dts
, p_stream
->fmt
.video
.i_frame_rate
,
2974 p_stream
->fmt
.video
.i_frame_rate_base
);
2978 Ogg_ExtractMeta( p_demux
, & p_stream
->fmt
,
2979 p_oggpacket
->packet
+ 7, p_oggpacket
->bytes
- 7 );
2986 static void Ogg_ApplyContentType( logical_stream_t
*p_stream
, const char* psz_value
,
2987 bool *b_force_backup
)
2989 if( p_stream
->fmt
.i_cat
!= UNKNOWN_ES
)
2992 if( !strncmp(psz_value
, "audio/x-wav", 11) )
2994 /* n.b. WAVs are unsupported right now */
2995 es_format_Change( &p_stream
->fmt
, UNKNOWN_ES
, 0 );
2996 free( p_stream
->fmt
.psz_description
);
2997 p_stream
->fmt
.psz_description
= strdup("WAV Audio (Unsupported)");
2999 else if( !strncmp(psz_value
, "audio/x-vorbis", 14) ||
3000 !strncmp(psz_value
, "audio/vorbis", 12) )
3002 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_VORBIS
);
3004 *b_force_backup
= true;
3006 else if( !strncmp(psz_value
, "audio/x-speex", 13) ||
3007 !strncmp(psz_value
, "audio/speex", 11) )
3009 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_SPEEX
);
3011 *b_force_backup
= true;
3013 else if( !strncmp(psz_value
, "audio/flac", 10) )
3015 es_format_Change( &p_stream
->fmt
, AUDIO_ES
, VLC_CODEC_FLAC
);
3017 *b_force_backup
= true;
3019 else if( !strncmp(psz_value
, "video/x-theora", 14) ||
3020 !strncmp(psz_value
, "video/theora", 12) )
3022 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_THEORA
);
3024 *b_force_backup
= true;
3026 else if( !strncmp(psz_value
, "video/x-daala", 13) ||
3027 !strncmp(psz_value
, "video/daala", 11) )
3029 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_DAALA
);
3031 *b_force_backup
= true;
3033 else if( !strncmp(psz_value
, "video/x-xvid", 12) )
3035 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_FOURCC( 'x','v','i','d' ) );
3037 *b_force_backup
= true;
3039 else if( !strncmp(psz_value
, "video/mpeg", 10) )
3041 /* n.b. MPEG streams are unsupported right now */
3042 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_MPGV
);
3044 else if( !strncmp(psz_value
, "application/kate", 16) )
3047 es_format_Change( &p_stream
->fmt
, UNKNOWN_ES
, 0 );
3048 p_stream
->fmt
.psz_description
= strdup("OGG Kate Overlay (Unsupported)");
3050 else if( !strncmp(psz_value
, "video/x-vp8", 11) )
3052 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_VP8
);
3056 static void Ogg_ReadAnnodexHeader( demux_t
*p_demux
,
3057 logical_stream_t
*p_stream
,
3058 ogg_packet
*p_oggpacket
)
3060 if( p_oggpacket
->bytes
>= 28 &&
3061 !memcmp( p_oggpacket
->packet
, "Annodex", 7 ) )
3065 uint16_t major_version
;
3066 uint16_t minor_version
;
3067 uint64_t timebase_numerator
;
3068 uint64_t timebase_denominator
;
3070 Ogg_ReadTheoraHeader( p_stream
, p_oggpacket
);
3072 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
3073 oggpack_adv( &opb
, 8*8 ); /* "Annodex\0" header */
3074 major_version
= oggpack_read( &opb
, 2*8 ); /* major version */
3075 minor_version
= oggpack_read( &opb
, 2*8 ); /* minor version */
3076 timebase_numerator
= GetQWLE( &p_oggpacket
->packet
[16] );
3077 timebase_denominator
= GetQWLE( &p_oggpacket
->packet
[24] );
3079 msg_Dbg( p_demux
, "Annodex info: version %"PRIu16
".%"PRIu16
" "
3080 "Timebase %"PRId64
" / %"PRId64
,
3081 major_version
, minor_version
,
3082 timebase_numerator
, timebase_denominator
);
3084 else if( p_oggpacket
->bytes
>= 42 &&
3085 !memcmp( p_oggpacket
->packet
, "AnxData", 7 ) )
3087 uint64_t granule_rate_numerator
;
3088 uint64_t granule_rate_denominator
;
3089 char content_type_string
[1024];
3091 /* Read in Annodex header fields */
3093 granule_rate_numerator
= GetQWLE( &p_oggpacket
->packet
[8] );
3094 granule_rate_denominator
= GetQWLE( &p_oggpacket
->packet
[16] );
3095 p_stream
->i_secondary_header_packets
=
3096 GetDWLE( &p_oggpacket
->packet
[24] );
3098 /* we are guaranteed that the first header field will be
3099 * the content-type (by the Annodex standard) */
3100 content_type_string
[0] = '\0';
3101 if( !strncasecmp( (char*)(&p_oggpacket
->packet
[28]), "Content-Type: ", 14 ) )
3103 uint8_t *p
= memchr( &p_oggpacket
->packet
[42], '\r',
3104 p_oggpacket
->bytes
- 1 );
3105 if( p
&& p
[0] == '\r' && p
[1] == '\n' )
3106 sscanf( (char*)(&p_oggpacket
->packet
[42]), "%1023s\r\n",
3107 content_type_string
);
3110 msg_Dbg( p_demux
, "AnxData packet info: %"PRId64
" / %"PRId64
", %d, ``%s''",
3111 granule_rate_numerator
, granule_rate_denominator
,
3112 p_stream
->i_secondary_header_packets
, content_type_string
);
3114 if( granule_rate_numerator
&& granule_rate_denominator
)
3115 date_Init( &p_stream
->dts
, granule_rate_numerator
, granule_rate_denominator
);
3117 /* What type of file do we have?
3118 * strcmp is safe to use here because we've extracted
3119 * content_type_string from the stream manually */
3120 Ogg_ApplyContentType( p_stream
, content_type_string
,
3121 &p_stream
->b_force_backup
);
3125 static void Ogg_ReadSkeletonHeader( demux_t
*p_demux
, logical_stream_t
*p_stream
,
3126 ogg_packet
*p_oggpacket
)
3128 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3129 if( p_oggpacket
->bytes
< 12 )
3132 p_sys
->p_skelstream
= p_stream
;
3133 /* There can be only 1 skeleton for streams */
3134 p_sys
->skeleton
.major
= GetWLE( &p_oggpacket
->packet
[8] );
3135 p_sys
->skeleton
.minor
= GetWLE( &p_oggpacket
->packet
[10] );
3136 if ( asprintf( & p_stream
->fmt
.psz_description
,
3137 "OGG Skeleton version %" PRIu16
".%" PRIu16
,
3138 p_sys
->skeleton
.major
, p_sys
->skeleton
.minor
) < 0 )
3139 p_stream
->fmt
.psz_description
= NULL
;
3142 static void Ogg_ReadSkeletonBones( demux_t
*p_demux
, ogg_packet
*p_oggpacket
)
3144 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3146 if ( p_sys
->skeleton
.major
< 3 || p_oggpacket
->bytes
< 52 ) return;
3148 /* Find the matching stream for this skeleton data */
3149 ogg_int32_t i_serialno
= GetDWLE( &p_oggpacket
->packet
[12] );
3150 logical_stream_t
*p_target_stream
= NULL
;
3151 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
3153 if ( p_sys
->pp_stream
[i
]->i_serial_no
== i_serialno
)
3155 p_target_stream
= p_sys
->pp_stream
[i
];
3159 if ( !p_target_stream
) return;
3161 ogg_skeleton_t
*p_skel
= p_target_stream
->p_skel
;
3164 p_skel
= malloc( sizeof( ogg_skeleton_t
) );
3165 if ( !p_skel
) return;
3166 TAB_INIT( p_skel
->i_messages
, p_skel
->ppsz_messages
);
3167 p_skel
->p_index
= NULL
;
3168 p_target_stream
->p_skel
= p_skel
;
3171 const unsigned char *p_messages
= p_oggpacket
->packet
+ 8 + GetDWLE( &p_oggpacket
->packet
[8] );
3172 const unsigned char *p_boundary
= p_oggpacket
->packet
+ p_oggpacket
->bytes
;
3173 const unsigned char *p
= p_messages
;
3174 while ( p
<= p_boundary
- 1 && p
> p_oggpacket
->packet
)
3176 if ( *p
== 0x0D && *(p
+1) == 0x0A )
3178 char *psz_message
= strndup( (const char *) p_messages
,
3182 msg_Dbg( p_demux
, "stream %" PRId32
" [%s]", i_serialno
, psz_message
);
3183 TAB_APPEND( p_skel
->i_messages
, p_skel
->ppsz_messages
, psz_message
);
3185 if ( p
< p_boundary
- 1 ) p_messages
= p
+ 2;
3192 /* Unpacks the 7bit variable encoding used in skeleton indexes */
3193 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin
,
3194 unsigned const char *p_end
,
3195 uint64_t *pi_value
)
3201 while ( p_begin
< p_end
)
3203 i_read
= *p_begin
& 0x7F; /* High bit is start of integer */
3204 *pi_value
= *pi_value
| ( i_read
<< i_shift
);
3206 if ( (*p_begin
++ & 0x80) == 0x80 ) break; /* see prev */
3209 *pi_value
= GetQWLE( pi_value
);
3213 static void Ogg_ReadSkeletonIndex( demux_t
*p_demux
, ogg_packet
*p_oggpacket
)
3215 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3217 if( p_sys
->skeleton
.major
< 4
3218 || p_oggpacket
->bytes
< 44 /* Need at least 1 index value (42+1+1) */
3221 /* Find the matching stream for this skeleton data */
3222 int32_t i_serialno
= GetDWLE( &p_oggpacket
->packet
[6] );
3223 logical_stream_t
*p_stream
= NULL
;
3224 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
3226 if( p_sys
->pp_stream
[i
]->i_serial_no
== i_serialno
)
3228 p_stream
= p_sys
->pp_stream
[i
];
3232 if ( !p_stream
|| !p_stream
->p_skel
) return;
3233 uint64_t i_keypoints
= GetQWLE( &p_oggpacket
->packet
[10] );
3234 msg_Dbg( p_demux
, "%" PRIi64
" index data for %" PRIi32
, i_keypoints
, i_serialno
);
3235 if ( !i_keypoints
) return;
3237 p_stream
->p_skel
->i_indexstampden
= GetQWLE( &p_oggpacket
->packet
[18] );
3238 p_stream
->p_skel
->i_indexfirstnum
= GetQWLE( &p_oggpacket
->packet
[24] );
3239 p_stream
->p_skel
->i_indexlastnum
= GetQWLE( &p_oggpacket
->packet
[32] );
3240 unsigned const char *p_fwdbyte
= &p_oggpacket
->packet
[42];
3241 unsigned const char *p_boundary
= p_oggpacket
->packet
+ p_oggpacket
->bytes
;
3242 uint64_t i_offset
= 0;
3243 uint64_t i_time
= 0;
3244 uint64_t i_keypoints_found
= 0;
3246 while( p_fwdbyte
< p_boundary
&& i_keypoints_found
< i_keypoints
)
3249 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
, p_boundary
, &i_val
);
3251 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
, p_boundary
, &i_val
);
3252 i_time
+= i_val
* p_stream
->p_skel
->i_indexstampden
;
3253 i_keypoints_found
++;
3256 if ( i_keypoints_found
!= i_keypoints
)
3258 msg_Warn( p_demux
, "Invalid Index: missing entries" );
3262 p_stream
->p_skel
->p_index
= malloc( p_oggpacket
->bytes
- 42 );
3263 if ( !p_stream
->p_skel
->p_index
) return;
3264 memcpy( p_stream
->p_skel
->p_index
, &p_oggpacket
->packet
[42],
3265 p_oggpacket
->bytes
- 42 );
3266 p_stream
->p_skel
->i_index
= i_keypoints_found
;
3267 p_stream
->p_skel
->i_index_size
= p_oggpacket
->bytes
- 42;
3270 static void Ogg_FreeSkeleton( ogg_skeleton_t
*p_skel
)
3272 if ( !p_skel
) return;
3273 for ( int i
=0; i
< p_skel
->i_messages
; i
++ )
3274 free( p_skel
->ppsz_messages
[i
] );
3275 TAB_CLEAN( p_skel
->i_messages
, p_skel
->ppsz_messages
);
3276 free( p_skel
->p_index
);
3280 static void Ogg_ApplySkeleton( logical_stream_t
*p_stream
)
3282 if ( !p_stream
->p_skel
) return;
3283 for ( int i
=0; i
< p_stream
->p_skel
->i_messages
; i
++ )
3285 const char *psz_message
= p_stream
->p_skel
->ppsz_messages
[i
];
3286 if ( ! strncmp( "Name: ", psz_message
, 6 ) )
3288 free( p_stream
->fmt
.psz_description
);
3289 p_stream
->fmt
.psz_description
= strdup( psz_message
+ 6 );
3291 else if ( ! strncmp("Content-Type: ", psz_message
, 14 ) )
3294 Ogg_ApplyContentType( p_stream
, psz_message
+ 14, &b_foo
);
3299 /* Return true if there's a skeleton exact match */
3300 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t
*p_stream
, vlc_tick_t i_time
,
3301 int64_t *pi_lower
, int64_t *pi_upper
)
3303 if ( !p_stream
|| !p_stream
->p_skel
|| !p_stream
->p_skel
->p_index
||
3304 i_time
== VLC_TICK_INVALID
)
3307 i_time
-= VLC_TICK_0
;
3309 /* Validate range */
3310 if ( i_time
< p_stream
->p_skel
->i_indexfirstnum
3311 * p_stream
->p_skel
->i_indexstampden
||
3312 i_time
> p_stream
->p_skel
->i_indexlastnum
3313 * p_stream
->p_skel
->i_indexstampden
) return false;
3315 /* Then Lookup its index */
3316 unsigned const char *p_fwdbyte
= p_stream
->p_skel
->p_index
;
3321 } current
= { 0, 0 }, prev
= { -1, -1 };
3323 uint64_t i_keypoints_found
= 0;
3325 while( p_fwdbyte
< p_fwdbyte
+ p_stream
->p_skel
->i_index_size
3326 && i_keypoints_found
< p_stream
->p_skel
->i_index
)
3329 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
,
3330 p_fwdbyte
+ p_stream
->p_skel
->i_index_size
, &i_val
);
3331 current
.i_pos
+= i_val
;
3332 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
,
3333 p_fwdbyte
+ p_stream
->p_skel
->i_index_size
, &i_val
);
3334 current
.i_time
+= i_val
* p_stream
->p_skel
->i_indexstampden
;
3335 if ( current
.i_pos
< 0 || current
.i_time
< 0 ) break;
3337 i_keypoints_found
++;
3339 if ( i_time
<= current
.i_time
)
3341 *pi_lower
= prev
.i_pos
;
3342 *pi_upper
= current
.i_pos
;
3343 return ( i_time
== current
.i_time
);
3350 static uint32_t dirac_uint( bs_t
*p_bs
)
3352 uint32_t u_count
= 0, u_value
= 0;
3354 while( !bs_eof( p_bs
) && !bs_read( p_bs
, 1 ) )
3358 u_value
|= bs_read( p_bs
, 1 );
3361 return (1<<u_count
) - 1 + u_value
;
3364 static int dirac_bool( bs_t
*p_bs
)
3366 return bs_read( p_bs
, 1 );
3369 static bool Ogg_ReadDiracHeader( logical_stream_t
*p_stream
,
3370 ogg_packet
*p_oggpacket
)
3372 p_stream
->special
.dirac
.b_old
= (p_oggpacket
->packet
[0] == 'K');
3374 static const struct {
3375 uint32_t u_n
/* numerator */, u_d
/* denominator */;
3376 } p_dirac_frate_tbl
[] = { /* table 10.3 */
3377 {1,1}, /* this first value is never used */
3378 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
3379 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
3381 static const size_t u_dirac_frate_tbl
= sizeof(p_dirac_frate_tbl
)/sizeof(*p_dirac_frate_tbl
);
3383 static const uint32_t pu_dirac_vidfmt_frate
[] = { /* table C.1 */
3384 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
3386 static const size_t u_dirac_vidfmt_frate
= sizeof(pu_dirac_vidfmt_frate
)/sizeof(*pu_dirac_vidfmt_frate
);
3390 /* Backing up stream headers is not required -- seqhdrs are repeated
3391 * thoughout the stream at suitable decoding start points */
3392 p_stream
->b_force_backup
= false;
3394 /* read in useful bits from sequence header */
3395 bs_init( &bs
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
3396 bs_skip( &bs
, 13*8); /* parse_info_header */
3397 dirac_uint( &bs
); /* major_version */
3398 dirac_uint( &bs
); /* minor_version */
3399 dirac_uint( &bs
); /* profile */
3400 dirac_uint( &bs
); /* level */
3402 uint32_t u_video_format
= dirac_uint( &bs
); /* index */
3403 if( u_video_format
>= u_dirac_vidfmt_frate
)
3405 /* don't know how to parse this ogg dirac stream */
3409 if( dirac_bool( &bs
) )
3411 dirac_uint( &bs
); /* frame_width */
3412 dirac_uint( &bs
); /* frame_height */
3415 if( dirac_bool( &bs
) )
3417 dirac_uint( &bs
); /* chroma_format */
3420 if( dirac_bool( &bs
) )
3422 p_stream
->special
.dirac
.b_interlaced
= dirac_uint( &bs
); /* scan_format */
3425 p_stream
->special
.dirac
.b_interlaced
= false;
3427 uint32_t u_n
= p_dirac_frate_tbl
[pu_dirac_vidfmt_frate
[u_video_format
]].u_n
;
3428 uint32_t u_d
= p_dirac_frate_tbl
[pu_dirac_vidfmt_frate
[u_video_format
]].u_d
;
3429 u_d
= __MAX( u_d
, 1 );
3430 if( dirac_bool( &bs
) )
3432 uint32_t u_frame_rate_index
= dirac_uint( &bs
);
3433 if( u_frame_rate_index
>= u_dirac_frate_tbl
)
3435 /* something is wrong with this stream */
3438 u_n
= p_dirac_frate_tbl
[u_frame_rate_index
].u_n
;
3439 u_d
= p_dirac_frate_tbl
[u_frame_rate_index
].u_d
;
3440 if( u_frame_rate_index
== 0 )
3442 u_n
= dirac_uint( &bs
); /* frame_rate_numerator */
3443 u_d
= dirac_uint( &bs
); /* frame_rate_denominator */
3451 * NB, OggDirac granulepos values are in units of 2*picturerate
3452 * When picture_coding_mode = 0 (progressive),
3453 * pt increments by two for each picture in display order.
3454 * When picture_coding_mode = 1 (interlace),
3455 * pt increments by one for each field in display order. */
3456 date_Init( &p_stream
->dts
, 2 * u_n
, u_d
);
3461 static bool Ogg_ReadOggSpotsHeader( logical_stream_t
*p_stream
,
3462 ogg_packet
*p_oggpacket
)
3464 uint64_t i_granulerate_numerator
;
3465 uint64_t i_granulerate_denominator
;
3469 es_format_Change( &p_stream
->fmt
, VIDEO_ES
, VLC_CODEC_OGGSPOTS
);
3471 /* Signal that we want to keep a backup of the OggSpots
3472 * stream headers. They will be used when switching between
3474 p_stream
->b_force_backup
= true;
3476 /* Cheat and get additionnal info ;) */
3477 if ( p_oggpacket
->bytes
!= 52 )
3479 /* The OggSpots header is always 52 bytes */
3483 i_major
= GetWLE( &p_oggpacket
->packet
[ 8] ); /* major version num */
3484 i_minor
= GetWLE( &p_oggpacket
->packet
[10] ); /* minor version num */
3485 if ( i_major
!= 0 || i_minor
!= 1 )
3491 i_granulerate_numerator
= GetQWLE( &p_oggpacket
->packet
[12] );
3492 i_granulerate_denominator
= GetQWLE( &p_oggpacket
->packet
[20] );
3493 if ( i_granulerate_numerator
== 0 || i_granulerate_denominator
== 0 )
3498 /* The OggSpots spec contained an error and there are implementations out
3499 * there that used the wrong value. So we detect that case and switch
3500 * numerator and denominator in that case */
3501 if ( i_granulerate_numerator
== 1 && i_granulerate_denominator
== 30 )
3503 i_granulerate_numerator
= 30;
3504 i_granulerate_denominator
= 1;
3507 if ( !i_granulerate_numerator
|| !i_granulerate_denominator
)
3510 /* Normalize granulerate */
3511 vlc_ureduce(&p_stream
->fmt
.video
.i_frame_rate
,
3512 &p_stream
->fmt
.video
.i_frame_rate_base
,
3513 i_granulerate_numerator
, i_granulerate_denominator
, 0);
3515 date_Init( &p_stream
->dts
, p_stream
->fmt
.video
.i_frame_rate
,
3516 p_stream
->fmt
.video
.i_frame_rate_base
);
3518 p_stream
->i_granule_shift
= p_oggpacket
->packet
[28];