1 /*****************************************************************************
2 * ogg.c : ogg stream demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Andre Pang <Andre.Pang@csiro.au> (Annodex support)
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_demux.h>
37 #include <vlc_input.h>
41 #include <vlc_codecs.h>
44 #include "xiph_metadata.h"
48 /*****************************************************************************
50 *****************************************************************************/
51 static int Open ( vlc_object_t
* );
52 static void Close( vlc_object_t
* );
55 set_shortname ( "OGG" )
56 set_description( N_("OGG demuxer" ) )
57 set_category( CAT_INPUT
)
58 set_subcategory( SUBCAT_INPUT_DEMUX
)
59 set_capability( "demux", 50 )
60 set_callbacks( Open
, Close
)
65 /*****************************************************************************
66 * Definitions of structures and functions used by this plugins
67 *****************************************************************************/
69 /* OggDS headers for the new header format (used in ogm files) */
74 } stream_header_video_t
;
80 ogg_int16_t blockalign
;
81 ogg_int32_t avgbytespersec
;
82 } stream_header_audio_t
;
89 ogg_int32_t size
; /* size of the structure */
91 ogg_int64_t time_unit
; /* in reference time */
92 ogg_int64_t samples_per_unit
;
93 ogg_int32_t default_len
; /* in media time */
95 ogg_int32_t buffersize
;
96 ogg_int16_t bits_per_sample
;
102 stream_header_video_t video
;
104 stream_header_audio_t audio
;
108 /*****************************************************************************
110 *****************************************************************************/
111 static int Demux ( demux_t
* );
112 static int Control( demux_t
*, int, va_list );
114 /* Bitstream manipulation */
115 static int Ogg_ReadPage ( demux_t
*, ogg_page
* );
116 static void Ogg_UpdatePCR ( demux_t
*, logical_stream_t
*, ogg_packet
* );
117 static void Ogg_DecodePacket ( demux_t
*, logical_stream_t
*, ogg_packet
* );
118 static int Ogg_OpusPacketDuration( logical_stream_t
*, ogg_packet
* );
120 static void Ogg_CreateES( demux_t
*p_demux
);
121 static int Ogg_BeginningOfStream( demux_t
*p_demux
);
122 static int Ogg_FindLogicalStreams( demux_t
*p_demux
);
123 static void Ogg_EndOfStream( demux_t
*p_demux
);
126 static void Ogg_LogicalStreamDelete( demux_t
*p_demux
, logical_stream_t
*p_stream
);
127 static bool Ogg_LogicalStreamResetEsFormat( demux_t
*p_demux
, logical_stream_t
*p_stream
);
130 static void Ogg_ExtractMeta( demux_t
*p_demux
, es_format_t
*p_fmt
, const uint8_t *p_headers
, int i_headers
);
132 /* Logical bitstream headers */
133 static void Ogg_ReadTheoraHeader( logical_stream_t
*, ogg_packet
* );
134 static void Ogg_ReadVorbisHeader( logical_stream_t
*, ogg_packet
* );
135 static void Ogg_ReadSpeexHeader( logical_stream_t
*, ogg_packet
* );
136 static void Ogg_ReadOpusHeader( logical_stream_t
*, ogg_packet
* );
137 static void Ogg_ReadKateHeader( logical_stream_t
*, ogg_packet
* );
138 static void Ogg_ReadFlacHeader( demux_t
*, logical_stream_t
*, ogg_packet
* );
139 static void Ogg_ReadAnnodexHeader( demux_t
*, logical_stream_t
*, ogg_packet
* );
140 static bool Ogg_ReadDiracHeader( logical_stream_t
*, ogg_packet
* );
141 static bool Ogg_ReadVP8Header( demux_t
*, logical_stream_t
*, ogg_packet
* );
142 static void Ogg_ReadSkeletonHeader( demux_t
*, logical_stream_t
*, ogg_packet
* );
145 static void Ogg_ReadSkeletonBones( demux_t
*, ogg_packet
* );
146 static void Ogg_ReadSkeletonIndex( demux_t
*, ogg_packet
* );
147 static void Ogg_FreeSkeleton( ogg_skeleton_t
* );
148 static void Ogg_ApplySkeleton( logical_stream_t
* );
150 static void fill_channels_info(audio_format_t
*audio
)
152 static const int pi_channels_map
[9] =
156 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
157 AOUT_CHAN_CENTER
| AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
158 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT
159 | AOUT_CHAN_REARRIGHT
,
160 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
161 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
,
162 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
163 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
| AOUT_CHAN_LFE
,
164 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
165 | AOUT_CHAN_REARCENTER
| AOUT_CHAN_MIDDLELEFT
166 | AOUT_CHAN_MIDDLERIGHT
| AOUT_CHAN_LFE
,
167 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT
168 | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_MIDDLELEFT
| AOUT_CHAN_MIDDLERIGHT
172 unsigned chans
= audio
->i_channels
;
173 if (chans
< sizeof(pi_channels_map
) / sizeof(pi_channels_map
[0]))
174 audio
->i_physical_channels
=
175 audio
->i_original_channels
= pi_channels_map
[chans
];
178 /* Special TS value: don't send or derive any pts/pcr from it.
179 Represents TS state prior first known valid timestamp */
180 #define VLC_TS_UNKNOWN (VLC_TS_INVALID - 1)
182 /*****************************************************************************
183 * Open: initializes ogg demux structures
184 *****************************************************************************/
185 static int Open( vlc_object_t
* p_this
)
187 demux_t
*p_demux
= (demux_t
*)p_this
;
189 const uint8_t *p_peek
;
191 /* Check if we are dealing with an ogg stream */
192 if( stream_Peek( p_demux
->s
, &p_peek
, 4 ) < 4 ) return VLC_EGENERIC
;
193 if( !p_demux
->b_force
&& memcmp( p_peek
, "OggS", 4 ) )
199 p_demux
->p_sys
= p_sys
= calloc( 1, sizeof( demux_sys_t
) );
203 p_sys
->i_length
= -1;
204 p_sys
->b_preparsing_done
= false;
206 stream_Control( p_demux
->s
, ACCESS_GET_PTS_DELAY
, & p_sys
->i_access_delay
);
208 /* Set exported functions */
209 p_demux
->pf_demux
= Demux
;
210 p_demux
->pf_control
= Control
;
212 /* Initialize the Ogg physical bitstream parser */
213 ogg_sync_init( &p_sys
->oy
);
216 TAB_INIT( p_sys
->i_seekpoints
, p_sys
->pp_seekpoints
);
219 while ( !p_sys
->b_preparsing_done
&& p_demux
->pf_demux( p_demux
) > 0 )
225 /*****************************************************************************
226 * Close: frees unused data
227 *****************************************************************************/
228 static void Close( vlc_object_t
*p_this
)
230 demux_t
*p_demux
= (demux_t
*)p_this
;
231 demux_sys_t
*p_sys
= p_demux
->p_sys
;
233 /* Cleanup the bitstream parser */
234 ogg_sync_clear( &p_sys
->oy
);
236 Ogg_EndOfStream( p_demux
);
238 if( p_sys
->p_old_stream
)
239 Ogg_LogicalStreamDelete( p_demux
, p_sys
->p_old_stream
);
244 /*****************************************************************************
245 * Demux: reads and demuxes data packets
246 *****************************************************************************
247 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
248 *****************************************************************************/
249 static int Demux( demux_t
* p_demux
)
251 demux_sys_t
*p_sys
= p_demux
->p_sys
;
252 ogg_packet oggpacket
;
254 bool b_skipping
= false;
257 int i_active_streams
= p_sys
->i_streams
;
258 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
260 if ( p_sys
->pp_stream
[i
]->b_finished
)
264 if ( i_active_streams
== 0 )
266 if ( p_sys
->i_streams
) /* All finished */
268 msg_Dbg( p_demux
, "end of a group of logical streams" );
269 /* We keep the ES to try reusing it in Ogg_BeginningOfStream
270 * only 1 ES is supported (common case for ogg web radio) */
271 if( p_sys
->i_streams
== 1 )
273 p_sys
->p_old_stream
= p_sys
->pp_stream
[0];
274 TAB_CLEAN( p_sys
->i_streams
, p_sys
->pp_stream
);
276 Ogg_EndOfStream( p_demux
);
277 p_sys
->b_chained_boundary
= true;
280 if( Ogg_BeginningOfStream( p_demux
) != VLC_SUCCESS
)
283 msg_Dbg( p_demux
, "beginning of a group of logical streams" );
285 if ( !p_sys
->b_chained_boundary
)
287 /* Find the real duration */
288 stream_Control( p_demux
->s
, STREAM_CAN_SEEK
, &b_canseek
);
290 Oggseek_ProbeEnd( p_demux
);
294 p_sys
->b_chained_boundary
= false;
298 if ( p_sys
->b_preparsing_done
&& !p_sys
->b_es_created
)
300 Ogg_CreateES( p_demux
);
301 p_sys
->b_es_created
= true;
305 * The first data page of a physical stream is stored in the relevant logical stream
306 * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
307 * stream it belongs to if we haven't processed this first page yet. If we do, we
308 * will only process that first page whenever we find the second page for this stream.
309 * While this is fine for Vorbis and Theora, which are continuous codecs, which means
310 * the second page will arrive real quick, this is not fine for Kate, whose second
311 * data page will typically arrive much later.
312 * This means it is now possible to seek right at the start of a stream where the last
313 * logical stream is Kate, without having to wait for the second data page to unblock
314 * the first one, which is the one that triggers the 'no more headers to backup' code.
315 * And, as we all know, seeking without having backed up all headers is bad, since the
316 * codec will fail to initialize if it's missing its headers.
318 if( !p_sys
->b_page_waiting
)
321 * Demux an ogg page from the stream
323 if( Ogg_ReadPage( p_demux
, &p_sys
->current_page
) != VLC_SUCCESS
)
325 /* Test for End of Stream */
326 if( ogg_page_eos( &p_sys
->current_page
) )
328 /* If we delayed restarting encoders/SET_ES_FMT for more
329 * skeleton provided configuration */
330 if ( p_sys
->p_skelstream
)
332 if ( p_sys
->p_skelstream
->i_serial_no
== ogg_page_serialno(&p_sys
->current_page
) )
334 msg_Dbg( p_demux
, "End of Skeleton" );
335 p_sys
->b_preparsing_done
= true;
336 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
338 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
339 Ogg_ApplySkeleton( p_stream
);
344 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
346 if ( p_sys
->pp_stream
[i_stream
]->i_serial_no
== ogg_page_serialno( &p_sys
->current_page
) )
348 p_sys
->pp_stream
[i_stream
]->b_finished
= true;
356 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
358 b_skipping
|= p_sys
->pp_stream
[i_stream
]->i_skip_frames
;
361 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
363 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
365 /* if we've just pulled page, look for the right logical stream */
366 if( !p_sys
->b_page_waiting
)
368 if( p_sys
->i_streams
== 1 &&
369 ogg_page_serialno( &p_sys
->current_page
) != p_stream
->os
.serialno
)
371 msg_Err( p_demux
, "Broken Ogg stream (serialno) mismatch" );
372 ogg_stream_reset_serialno( &p_stream
->os
, ogg_page_serialno( &p_sys
->current_page
) );
374 p_stream
->b_reinit
= true;
375 p_stream
->i_pcr
= VLC_TS_UNKNOWN
;
376 p_stream
->i_interpolated_pcr
= VLC_TS_UNKNOWN
;
377 p_stream
->i_previous_granulepos
= -1;
378 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, VLC_TS_0
);
381 /* Does fail if serialno differs */
382 if( ogg_stream_pagein( &p_stream
->os
, &p_sys
->current_page
) != 0 )
389 /* clear the finished flag if pages after eos (ex: after a seek) */
390 if ( ! ogg_page_eos( &p_sys
->current_page
) ) p_stream
->b_finished
= false;
393 if ( p_stream
->fmt
.i_cat
== VIDEO_ES
)
394 msg_Dbg(p_demux
, "DEMUX READ pageno %ld g%"PRId64
" (%d packets) cont %d %ld bytes",
395 ogg_page_pageno( &p_sys
->current_page
),
396 ogg_page_granulepos( &p_sys
->current_page
),
397 ogg_page_packets( &p_sys
->current_page
),
398 ogg_page_continued(&p_sys
->current_page
),
399 p_sys
->current_page
.body_len
)
402 while( ogg_stream_packetout( &p_stream
->os
, &oggpacket
) > 0 )
404 /* Read info from any secondary header packets, if there are any */
405 if( p_stream
->i_secondary_header_packets
> 0 )
407 if( p_stream
->fmt
.i_codec
== VLC_CODEC_THEORA
&&
408 oggpacket
.bytes
>= 7 &&
409 ! memcmp( oggpacket
.packet
, "\x80theora", 7 ) )
411 Ogg_ReadTheoraHeader( p_stream
, &oggpacket
);
412 p_stream
->i_secondary_header_packets
= 0;
414 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
&&
415 oggpacket
.bytes
>= 7 &&
416 ! memcmp( oggpacket
.packet
, "\x01vorbis", 7 ) )
418 Ogg_ReadVorbisHeader( p_stream
, &oggpacket
);
419 p_stream
->i_secondary_header_packets
= 0;
421 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_CMML
)
423 p_stream
->i_secondary_header_packets
= 0;
426 /* update start of data pointer */
427 p_stream
->i_data_start
= stream_Tell( p_demux
->s
);
430 /* If any streams have i_skip_frames, only decode (pre-roll)
431 * for those streams, but don't skip headers */
432 if ( b_skipping
&& p_stream
->i_skip_frames
== 0
433 && p_stream
->i_secondary_header_packets
) continue;
435 if( p_stream
->b_reinit
)
437 if ( Oggseek_PacketPCRFixup( p_stream
, &p_sys
->current_page
,
440 DemuxDebug( msg_Dbg( p_demux
, "PCR fixup for %"PRId64
,
441 ogg_page_granulepos( &p_sys
->current_page
) ) );
445 /* If synchro is re-initialized we need to drop all the packets
446 * until we find a new dated one. */
447 Ogg_UpdatePCR( p_demux
, p_stream
, &oggpacket
);
450 if( p_stream
->i_pcr
>= 0 )
452 p_stream
->b_reinit
= false;
453 /* For Opus, trash the first 80 ms of decoded output as
454 well, to avoid blowing out speakers if we get unlucky.
455 Opus predicts content from prior frames, which can go
456 badly if we seek right where the stream goes from very
457 quiet to very loud. It will converge after a bit. */
458 if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
460 ogg_int64_t start_time
;
462 p_stream
->i_skip_frames
= 80*48;
463 /* Make sure we never play audio from within the
464 pre-skip at the beginning of the stream. */
466 Ogg_OpusPacketDuration( p_stream
, &oggpacket
);
467 start_time
= p_stream
->i_previous_granulepos
;
470 start_time
= start_time
> duration
?
471 start_time
- duration
: 0;
473 if( p_stream
->i_pre_skip
> start_time
)
475 p_stream
->i_skip_frames
+=
476 p_stream
->i_pre_skip
- start_time
;
483 msg_Dbg(p_demux
, "DEMUX DROPS PACKET (? / %d) pageno %ld granule %"PRId64
,
484 ogg_page_packets( &p_sys
->current_page
),
485 ogg_page_pageno( &p_sys
->current_page
), oggpacket
.granulepos
);
488 p_stream
->i_interpolated_pcr
= -1;
489 p_stream
->i_previous_granulepos
= -1;
493 /* An Ogg/vorbis packet contains an end date granulepos */
494 if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
||
495 p_stream
->fmt
.i_codec
== VLC_CODEC_SPEEX
||
496 p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
||
497 p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
||
498 p_stream
->fmt
.i_codec
== VLC_CODEC_FLAC
)
500 if( ogg_stream_packetout( &p_stream
->os
, &oggpacket
) > 0 )
502 Ogg_DecodePacket( p_demux
, p_stream
, &oggpacket
);
506 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
,
507 VLC_TS_0
+ p_stream
->i_pcr
);
513 DemuxDebug( if ( p_sys
->b_seeked
)
515 if ( Ogg_IsKeyFrame( p_stream
, &oggpacket
) )
516 msg_Dbg(p_demux
, "** DEMUX ON KEYFRAME **" );
518 ogg_int64_t iframe
= ogg_page_granulepos( &p_sys
->current_page
) >> p_stream
->i_granule_shift
;
519 ogg_int64_t pframe
= ogg_page_granulepos( &p_sys
->current_page
) - ( iframe
<< p_stream
->i_granule_shift
);
521 msg_Dbg(p_demux
, "DEMUX PACKET (size %d) IS at iframe %"PRId64
" pageno %ld pframe %"PRId64
" OFFSET %"PRId64
" PACKET NO %"PRId64
" skipleft=%d",
522 ogg_page_packets( &p_sys
->current_page
),
523 iframe
, ogg_page_pageno( &p_sys
->current_page
), pframe
, p_sys
->i_input_position
, oggpacket
.packetno
, p_stream
->i_skip_frames
);
526 Ogg_DecodePacket( p_demux
, p_stream
, &oggpacket
);
529 DemuxDebug( p_sys
->b_seeked
= false; )
531 if( !p_sys
->b_page_waiting
)
535 /* if a page was waiting, it's now processed */
536 p_sys
->b_page_waiting
= false;
538 if ( p_sys
->p_skelstream
&& !p_sys
->p_skelstream
->b_finished
)
539 p_sys
->b_preparsing_done
= false;
541 p_sys
->b_preparsing_done
= true;
543 /* We will consider the lowest PCR among tracks, because the audio core badly
544 * handles PCR rewind (mute)
546 mtime_t i_pcr_candidate
= VLC_TS_INVALID
;
547 for( i_stream
= 0; i_stream
< p_sys
->i_streams
; i_stream
++ )
549 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i_stream
];
551 if ( p_sys
->b_preparsing_done
&& p_stream
->b_initializing
)
553 /* We have 1 or more streams needing more than 1 page for preparsing */
554 p_sys
->b_preparsing_done
= false;
557 if( p_stream
->fmt
.i_cat
== SPU_ES
)
559 if( p_stream
->i_interpolated_pcr
< VLC_TS_0
)
561 if ( p_stream
->b_finished
|| p_stream
->b_initializing
)
564 if( i_pcr_candidate
< VLC_TS_0
565 || p_stream
->i_interpolated_pcr
<= i_pcr_candidate
)
567 i_pcr_candidate
= p_stream
->i_interpolated_pcr
;
571 if ( i_pcr_candidate
> VLC_TS_INVALID
&& p_sys
->i_pcr
!= i_pcr_candidate
)
573 if ( p_sys
->i_streams
== 1 && p_sys
->i_access_delay
)
575 int64_t i_pcr_jitter
= i_pcr_candidate
- p_sys
->i_pcr
;
576 if ( i_pcr_jitter
> p_sys
->i_pcr_jitter
)
578 p_sys
->i_pcr_jitter
= i_pcr_jitter
;
579 if ( p_sys
->i_access_delay
< i_pcr_jitter
)
580 msg_Warn( p_demux
, "Consider increasing access caching variable from %"PRId64
" to >%"PRId64
,
581 p_sys
->i_access_delay
/ 1000, i_pcr_jitter
/ 1000 );
584 p_sys
->i_pcr
= i_pcr_candidate
;
586 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_pcr
);
592 static void Ogg_ResetStreamHelper( demux_sys_t
*p_sys
)
594 for( int i
= 0; i
< p_sys
->i_streams
; i
++ )
596 logical_stream_t
*p_stream
= p_sys
->pp_stream
[i
];
598 /* we'll trash all the data until we find the next pcr */
599 p_stream
->b_reinit
= true;
600 p_stream
->i_pcr
= VLC_TS_UNKNOWN
;
601 p_stream
->i_interpolated_pcr
= VLC_TS_UNKNOWN
;
602 p_stream
->i_previous_granulepos
= -1;
603 ogg_stream_reset( &p_stream
->os
);
605 ogg_sync_reset( &p_sys
->oy
);
608 static logical_stream_t
* Ogg_GetSelectedStream( demux_t
*p_demux
)
610 demux_sys_t
*p_sys
= p_demux
->p_sys
;
611 logical_stream_t
*p_stream
= NULL
;
612 for( int i
=0; i
<p_sys
->i_streams
; i
++ )
614 logical_stream_t
*p_candidate
= p_sys
->pp_stream
[i
];
615 if ( !p_candidate
->p_es
) continue;
617 bool b_selected
= false;
618 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
,
619 p_candidate
->p_es
, &b_selected
);
620 if ( !b_selected
) continue;
622 if ( !p_stream
&& p_candidate
->fmt
.i_cat
== AUDIO_ES
)
624 p_stream
= p_candidate
;
625 continue; /* Try to find video anyway */
628 if ( p_candidate
->fmt
.i_cat
== VIDEO_ES
)
630 p_stream
= p_candidate
;
637 /*****************************************************************************
639 *****************************************************************************/
640 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
642 demux_sys_t
*p_sys
= p_demux
->p_sys
;
651 p_meta
= (vlc_meta_t
*)va_arg( args
, vlc_meta_t
* );
653 vlc_meta_Merge( p_meta
, p_sys
->p_meta
);
656 case DEMUX_HAS_UNSUPPORTED_META
:
657 pb_bool
= (bool*)va_arg( args
, bool* );
662 pi64
= (int64_t*)va_arg( args
, int64_t * );
663 *pi64
= p_sys
->i_pcr
;
667 i64
= (int64_t)va_arg( args
, int64_t );
668 logical_stream_t
*p_stream
= Ogg_GetSelectedStream( p_demux
);
671 msg_Err( p_demux
, "No selected seekable stream found" );
674 stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
675 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux
, p_stream
, i64
, b
) )
677 Ogg_ResetStreamHelper( p_sys
);
678 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
685 case DEMUX_GET_ATTACHMENTS
:
687 input_attachment_t
***ppp_attach
=
688 (input_attachment_t
***)va_arg( args
, input_attachment_t
*** );
689 int *pi_int
= (int*)va_arg( args
, int * );
691 if( p_sys
->i_attachments
<= 0 )
694 *pi_int
= p_sys
->i_attachments
;
695 *ppp_attach
= xmalloc( sizeof(input_attachment_t
*) * p_sys
->i_attachments
);
696 for( int i
= 0; i
< p_sys
->i_attachments
; i
++ )
697 (*ppp_attach
)[i
] = vlc_input_attachment_Duplicate( p_sys
->attachments
[i
] );
701 case DEMUX_GET_POSITION
:
702 pf
= (double*)va_arg( args
, double * );
703 if( p_sys
->i_length
> 0 )
705 *pf
= (double) p_sys
->i_pcr
/
706 (double) ( p_sys
->i_length
* (mtime_t
)1000000 );
708 else if( stream_Size( p_demux
->s
) > 0 )
710 i64
= stream_Tell( p_demux
->s
);
711 *pf
= (double) i64
/ stream_Size( p_demux
->s
);
716 case DEMUX_SET_POSITION
:
717 /* forbid seeking if we haven't initialized all logical bitstreams yet;
718 if we allowed, some headers would not get backed up and decoder init
719 would fail, making that logical stream unusable */
720 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
722 if ( p_sys
->pp_stream
[i
]->b_initializing
)
726 p_stream
= Ogg_GetSelectedStream( p_demux
);
729 msg_Err( p_demux
, "No selected seekable stream found" );
733 stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
735 f
= (double)va_arg( args
, double );
736 if ( p_sys
->i_length
<= 0 || !b
/* || ! ACCESS_CAN_FASTSEEK */ )
738 Ogg_ResetStreamHelper( p_sys
);
739 Oggseek_BlindSeektoPosition( p_demux
, p_stream
, f
, b
);
743 assert( p_sys
->i_length
> 0 );
744 i64
= CLOCK_FREQ
* p_sys
->i_length
* f
;
745 Ogg_ResetStreamHelper( p_sys
);
746 if ( Oggseek_SeektoAbsolutetime( p_demux
, p_stream
, i64
) >= 0 )
748 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
755 case DEMUX_GET_LENGTH
:
756 if ( p_sys
->i_length
< 0 )
757 return demux_vaControlHelper( p_demux
->s
, 0, -1, p_sys
->i_bitrate
,
759 pi64
= (int64_t*)va_arg( args
, int64_t * );
760 *pi64
= p_sys
->i_length
* 1000000;
763 case DEMUX_GET_TITLE_INFO
:
765 input_title_t
***ppp_title
= (input_title_t
***)va_arg( args
, input_title_t
*** );
766 int *pi_int
= (int*)va_arg( args
, int* );
767 int *pi_title_offset
= (int*)va_arg( args
, int* );
768 int *pi_seekpoint_offset
= (int*)va_arg( args
, int* );
770 if( p_sys
->i_seekpoints
> 0 )
773 *ppp_title
= malloc( sizeof( input_title_t
* ) );
774 input_title_t
*p_title
= (*ppp_title
)[0] = vlc_input_title_New();
775 for( int i
= 0; i
< p_sys
->i_seekpoints
; i
++ )
777 seekpoint_t
*p_seekpoint_copy
= vlc_seekpoint_Duplicate( p_sys
->pp_seekpoints
[i
] );
778 if ( likely( p_seekpoint_copy
) )
779 TAB_APPEND( p_title
->i_seekpoint
, p_title
->seekpoint
, p_seekpoint_copy
);
781 *pi_title_offset
= 0;
782 *pi_seekpoint_offset
= 0;
786 case DEMUX_SET_TITLE
:
788 const int i_title
= (int)va_arg( args
, int );
793 case DEMUX_SET_SEEKPOINT
:
795 const int i_seekpoint
= (int)va_arg( args
, int );
796 if( i_seekpoint
> p_sys
->i_seekpoints
)
799 for ( int i
=0; i
< p_sys
->i_streams
; i
++ )
801 if ( p_sys
->pp_stream
[i
]->b_initializing
)
805 i64
= p_sys
->pp_seekpoints
[i_seekpoint
]->i_time_offset
;
807 p_stream
= Ogg_GetSelectedStream( p_demux
);
810 msg_Err( p_demux
, "No selected seekable stream found" );
814 stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &b
);
815 if ( Oggseek_BlindSeektoAbsoluteTime( p_demux
, p_stream
, i64
, b
) )
817 Ogg_ResetStreamHelper( p_sys
);
818 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
,
820 p_demux
->info
.i_update
|= INPUT_UPDATE_SEEKPOINT
;
821 p_demux
->info
.i_seekpoint
= i_seekpoint
;
829 return demux_vaControlHelper( p_demux
->s
, 0, -1, p_sys
->i_bitrate
,
834 /****************************************************************************
835 * Ogg_ReadPage: Read a full Ogg page from the physical bitstream.
836 ****************************************************************************
837 * Returns VLC_SUCCESS if a page has been read. An error might happen if we
838 * are at the end of stream.
839 ****************************************************************************/
840 static int Ogg_ReadPage( demux_t
*p_demux
, ogg_page
*p_oggpage
)
842 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
846 while( ogg_sync_pageout( &p_ogg
->oy
, p_oggpage
) != 1 )
848 p_buffer
= ogg_sync_buffer( &p_ogg
->oy
, OGGSEEK_BYTES_TO_READ
);
850 i_read
= stream_Read( p_demux
->s
, p_buffer
, OGGSEEK_BYTES_TO_READ
);
854 ogg_sync_wrote( &p_ogg
->oy
, i_read
);
860 /****************************************************************************
861 * Ogg_UpdatePCR: update the PCR (90kHz program clock reference) for the
863 ****************************************************************************/
864 static void Ogg_UpdatePCR( demux_t
*p_demux
, logical_stream_t
*p_stream
,
865 ogg_packet
*p_oggpacket
)
867 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
868 p_stream
->i_end_trim
= 0;
870 /* Convert the granulepos into a pcr */
871 if ( p_oggpacket
->granulepos
== 0 )
873 /* We're in headers, and we haven't parsed 1st data packet yet */
874 p_stream
->i_pcr
= VLC_TS_UNKNOWN
;
875 p_stream
->i_interpolated_pcr
= VLC_TS_UNKNOWN
;
877 else if( p_oggpacket
->granulepos
> 0 )
879 if( p_stream
->fmt
.i_codec
== VLC_CODEC_THEORA
||
880 p_stream
->fmt
.i_codec
== VLC_CODEC_KATE
||
881 p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
||
882 p_stream
->fmt
.i_codec
== VLC_CODEC_DIRAC
)
884 p_stream
->i_pcr
= Oggseek_GranuleToAbsTimestamp( p_stream
,
885 p_oggpacket
->granulepos
, true );
890 sample
= p_oggpacket
->granulepos
;
891 if( p_oggpacket
->e_o_s
&&
892 p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
&&
893 p_stream
->i_previous_granulepos
>= 0 )
896 duration
= Ogg_OpusPacketDuration( p_stream
, p_oggpacket
);
899 ogg_int64_t end_sample
;
900 end_sample
= p_stream
->i_previous_granulepos
+ duration
;
901 if( end_sample
> sample
)
902 p_stream
->i_end_trim
= (int)(end_sample
- sample
);
905 if (sample
>= p_stream
->i_pre_skip
)
906 sample
-= p_stream
->i_pre_skip
;
909 p_stream
->i_pcr
= sample
* CLOCK_FREQ
/ p_stream
->f_rate
;
912 if ( !p_ogg
->i_pcr_offset
)
913 p_stream
->i_pcr
+= VLC_TS_0
;
915 p_stream
->i_pcr
+= p_ogg
->i_pcr_offset
;
916 p_stream
->i_interpolated_pcr
= p_stream
->i_pcr
;
921 p_stream
->i_pcr
= VLC_TS_INVALID
;
923 /* no granulepos available, try to interpolate the pcr.
924 * If we can't then don't touch the old value. */
925 if( p_stream
->fmt
.i_cat
== VIDEO_ES
)
926 /* 1 frame per packet */
927 p_stream
->i_interpolated_pcr
+= (CLOCK_FREQ
/ p_stream
->f_rate
);
928 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
&&
929 p_stream
->i_previous_granulepos
> 0 &&
931 Ogg_OpusPacketDuration( p_stream
, p_oggpacket
) ) > 0 )
934 p_oggpacket
->granulepos
=
935 p_stream
->i_previous_granulepos
+ duration
;
936 sample
= p_oggpacket
->granulepos
;
937 if (sample
>= p_stream
->i_pre_skip
)
938 sample
-= p_stream
->i_pre_skip
;
941 p_stream
->i_interpolated_pcr
=
942 VLC_TS_0
+ sample
* CLOCK_FREQ
/ p_stream
->f_rate
;
943 p_stream
->i_interpolated_pcr
+= p_ogg
->i_pcr_offset
;
945 else if( p_stream
->fmt
.i_bitrate
&& p_stream
->i_pcr
> VLC_TS_UNKNOWN
)
947 p_stream
->i_interpolated_pcr
+=
948 ( p_oggpacket
->bytes
* CLOCK_FREQ
/
949 p_stream
->fmt
.i_bitrate
/ 8 );
950 p_stream
->i_interpolated_pcr
+= p_ogg
->i_pcr_offset
;
953 p_stream
->i_previous_granulepos
= p_oggpacket
->granulepos
;
956 /****************************************************************************
957 * Ogg_DecodePacket: Decode an Ogg packet.
958 ****************************************************************************/
959 static void Ogg_DecodePacket( demux_t
*p_demux
,
960 logical_stream_t
*p_stream
,
961 ogg_packet
*p_oggpacket
)
965 int i_header_len
= 0;
966 mtime_t i_pts
= VLC_TS_UNKNOWN
;
967 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
969 if( p_oggpacket
->bytes
>= 7 &&
970 ! memcmp ( p_oggpacket
->packet
, "Annodex", 7 ) )
972 /* it's an Annodex packet -- skip it (do nothing) */
975 else if( p_oggpacket
->bytes
>= 7 &&
976 ! memcmp ( p_oggpacket
->packet
, "AnxData", 7 ) )
978 /* it's an AnxData packet -- skip it (do nothing) */
981 else if( p_oggpacket
->bytes
>= 8 &&
982 ! memcmp ( p_oggpacket
->packet
, "fisbone", 8 ) )
984 Ogg_ReadSkeletonBones( p_demux
, p_oggpacket
);
987 else if( p_oggpacket
->bytes
>= 6 &&
988 ! memcmp ( p_oggpacket
->packet
, "index", 6 ) )
990 Ogg_ReadSkeletonIndex( p_demux
, p_oggpacket
);
993 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
&&
994 p_oggpacket
->bytes
>= 7 &&
995 !memcmp( p_oggpacket
->packet
, "OVP80\x02\x20", 7 ) )
997 Ogg_ReadVP8Header( p_demux
, p_stream
, p_oggpacket
);
1001 if( p_stream
->fmt
.i_codec
== VLC_CODEC_SUBT
&& p_oggpacket
->bytes
> 0 &&
1002 p_oggpacket
->packet
[0] & PACKET_TYPE_BITS
) return;
1004 /* Check the ES is selected */
1005 if ( !p_stream
->p_es
)
1008 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
,
1009 p_stream
->p_es
, &b_selected
);
1011 if( p_stream
->b_force_backup
)
1014 p_stream
->i_packets_backup
++;
1015 switch( p_stream
->fmt
.i_codec
)
1017 case VLC_CODEC_VORBIS
:
1018 case VLC_CODEC_THEORA
:
1019 if( p_stream
->i_packets_backup
== 3 )
1020 p_stream
->b_force_backup
= false;
1024 case VLC_CODEC_SPEEX
:
1025 if( p_stream
->i_packets_backup
== 2 + p_stream
->i_extra_headers_packets
)
1026 p_stream
->b_force_backup
= false;
1030 case VLC_CODEC_OPUS
:
1031 if( p_stream
->i_packets_backup
== 2 )
1032 p_stream
->b_force_backup
= false;
1036 case VLC_CODEC_FLAC
:
1037 if( !p_stream
->fmt
.audio
.i_rate
&& p_stream
->i_packets_backup
== 2 )
1039 Ogg_ReadFlacHeader( p_demux
, p_stream
, p_oggpacket
);
1040 p_stream
->b_force_backup
= false;
1042 else if( p_stream
->fmt
.audio
.i_rate
)
1044 p_stream
->b_force_backup
= false;
1045 if( p_oggpacket
->bytes
>= 9 )
1047 p_oggpacket
->packet
+= 9;
1048 p_oggpacket
->bytes
-= 9;
1054 case VLC_CODEC_KATE
:
1055 if( p_stream
->i_packets_backup
== p_stream
->i_kate_num_headers
)
1056 p_stream
->b_force_backup
= false;
1061 p_stream
->b_force_backup
= false;
1066 /* Backup the ogg packet (likely an header packet) */
1069 void *p_org
= p_stream
->p_headers
;
1070 p_stream
->i_headers
+= p_oggpacket
->bytes
;
1071 p_stream
->p_headers
= realloc( p_stream
->p_headers
, p_stream
->i_headers
);
1072 if( p_stream
->p_headers
)
1074 memcpy( (unsigned char *)p_stream
->p_headers
+ p_stream
->i_headers
- p_oggpacket
->bytes
,
1075 p_oggpacket
->packet
, p_oggpacket
->bytes
);
1079 #warning Memory leak
1080 p_stream
->i_headers
= 0;
1081 p_stream
->p_headers
= NULL
;
1085 else if( xiph_AppendHeaders( &p_stream
->i_headers
, &p_stream
->p_headers
,
1086 p_oggpacket
->bytes
, p_oggpacket
->packet
) )
1088 p_stream
->i_headers
= 0;
1089 p_stream
->p_headers
= NULL
;
1091 if( p_stream
->i_headers
> 0 )
1093 if( !p_stream
->b_force_backup
)
1095 /* Last header received, commit changes */
1096 free( p_stream
->fmt
.p_extra
);
1098 p_stream
->fmt
.i_extra
= p_stream
->i_headers
;
1099 p_stream
->fmt
.p_extra
= malloc( p_stream
->i_headers
);
1100 if( p_stream
->fmt
.p_extra
)
1101 memcpy( p_stream
->fmt
.p_extra
, p_stream
->p_headers
,
1102 p_stream
->i_headers
);
1104 p_stream
->fmt
.i_extra
= 0;
1106 if( p_stream
->i_headers
> 0 )
1107 Ogg_ExtractMeta( p_demux
, & p_stream
->fmt
,
1108 p_stream
->p_headers
, p_stream
->i_headers
);
1110 /* we're not at BOS anymore for this logical stream */
1111 p_stream
->b_initializing
= false;
1115 b_selected
= false; /* Discard the header packet */
1118 p_stream
->b_initializing
= false;
1120 /* Convert the pcr into a pts */
1121 if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
||
1122 p_stream
->fmt
.i_codec
== VLC_CODEC_SPEEX
||
1123 p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
||
1124 p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
||
1125 p_stream
->fmt
.i_codec
== VLC_CODEC_FLAC
)
1127 if( p_stream
->i_pcr
> VLC_TS_INVALID
)
1129 p_stream
->i_previous_pcr
= p_stream
->i_pcr
;
1130 /* The granulepos is the end date of the sample */
1131 i_pts
= p_stream
->i_pcr
;
1135 /* Convert the granulepos into the next pcr */
1136 Ogg_UpdatePCR( p_demux
, p_stream
, p_oggpacket
);
1138 if( p_stream
->fmt
.i_codec
!= VLC_CODEC_VORBIS
&&
1139 p_stream
->fmt
.i_codec
!= VLC_CODEC_SPEEX
&&
1140 p_stream
->fmt
.i_codec
!= VLC_CODEC_OPUS
&&
1141 p_stream
->fmt
.i_codec
!= VLC_CODEC_VP8
&&
1142 p_stream
->fmt
.i_codec
!= VLC_CODEC_FLAC
&&
1143 p_stream
->i_pcr
>= 0 )
1145 p_stream
->i_previous_pcr
= p_stream
->i_pcr
;
1147 /* The granulepos is the start date of the sample */
1148 i_pts
= p_stream
->i_pcr
;
1153 /* This stream isn't currently selected so we don't need to decode it,
1154 * but we did need to store its pcr as it might be selected later on */
1158 if( !( p_block
= block_Alloc( p_oggpacket
->bytes
) ) ) return;
1161 /* may need to preroll after a seek */
1162 if ( p_stream
->i_skip_frames
> 0 )
1164 if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
1167 duration
= Ogg_OpusPacketDuration( p_stream
, p_oggpacket
);
1168 if( p_stream
->i_skip_frames
> duration
)
1170 p_block
->i_flags
|= BLOCK_FLAG_PREROLL
;
1171 p_block
->i_nb_samples
= 0;
1172 p_stream
->i_skip_frames
-= duration
;
1176 p_block
->i_nb_samples
= duration
- p_stream
->i_skip_frames
;
1177 if( p_stream
->i_previous_granulepos
>=
1178 p_block
->i_nb_samples
+ p_stream
->i_pre_skip
)
1180 i_pts
= VLC_TS_0
+ (p_stream
->i_previous_granulepos
1181 - p_block
->i_nb_samples
- p_stream
->i_pre_skip
) *
1182 CLOCK_FREQ
/ p_stream
->f_rate
;
1184 p_stream
->i_skip_frames
= 0;
1189 p_block
->i_flags
|= BLOCK_FLAG_PREROLL
;
1190 p_stream
->i_skip_frames
--;
1193 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
1194 p_block
->i_nb_samples
= Ogg_OpusPacketDuration( p_stream
, p_oggpacket
);
1197 if( i_pts
== VLC_TS_UNKNOWN
)
1198 i_pts
= VLC_TS_INVALID
;
1200 if( p_stream
->fmt
.i_cat
== AUDIO_ES
)
1202 p_block
->i_dts
= p_block
->i_pts
= i_pts
;
1203 /* Blatant abuse of the i_length field. */
1204 p_block
->i_length
= p_stream
->i_end_trim
;
1206 else if( p_stream
->fmt
.i_cat
== SPU_ES
)
1208 p_block
->i_dts
= p_block
->i_pts
= i_pts
;
1209 p_block
->i_length
= 0;
1211 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_THEORA
)
1213 p_block
->i_dts
= p_block
->i_pts
= i_pts
;
1214 if( (p_oggpacket
->granulepos
& ((1<<p_stream
->i_granule_shift
)-1)) == 0 )
1216 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
1219 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_DIRAC
)
1221 ogg_int64_t dts
= p_oggpacket
->granulepos
>> 31;
1222 ogg_int64_t delay
= (p_oggpacket
->granulepos
>> 9) & 0x1fff;
1224 uint64_t u_pnum
= dts
+ delay
;
1226 p_block
->i_dts
= p_stream
->i_pcr
;
1227 p_block
->i_pts
= VLC_TS_INVALID
;
1228 /* NB, OggDirac granulepos values are in units of 2*picturerate */
1230 /* granulepos for dirac is possibly broken, this value should be ignored */
1231 if( -1 != p_oggpacket
->granulepos
)
1232 p_block
->i_pts
= u_pnum
* CLOCK_FREQ
/ p_stream
->f_rate
/ 2;
1234 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_VP8
)
1236 p_block
->i_pts
= p_stream
->i_interpolated_pcr
;
1237 p_block
->i_dts
= p_block
->i_pts
;
1238 if( p_oggpacket
->granulepos
> 0 && Ogg_IsKeyFrame( p_stream
, p_oggpacket
) )
1240 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
1245 p_block
->i_dts
= i_pts
;
1246 p_block
->i_pts
= VLC_TS_INVALID
;
1249 if( p_stream
->fmt
.i_codec
!= VLC_CODEC_VORBIS
&&
1250 p_stream
->fmt
.i_codec
!= VLC_CODEC_SPEEX
&&
1251 p_stream
->fmt
.i_codec
!= VLC_CODEC_OPUS
&&
1252 p_stream
->fmt
.i_codec
!= VLC_CODEC_VP8
&&
1253 p_stream
->fmt
.i_codec
!= VLC_CODEC_FLAC
&&
1254 p_stream
->fmt
.i_codec
!= VLC_CODEC_TARKIN
&&
1255 p_stream
->fmt
.i_codec
!= VLC_CODEC_THEORA
&&
1256 p_stream
->fmt
.i_codec
!= VLC_CODEC_CMML
&&
1257 p_stream
->fmt
.i_codec
!= VLC_CODEC_DIRAC
&&
1258 p_stream
->fmt
.i_codec
!= VLC_CODEC_KATE
)
1260 if( p_oggpacket
->bytes
<= 0 )
1262 msg_Dbg( p_demux
, "discarding 0 sized packet" );
1263 block_Release( p_block
);
1266 /* We remove the header from the packet */
1267 i_header_len
= (*p_oggpacket
->packet
& PACKET_LEN_BITS01
) >> 6;
1268 i_header_len
|= (*p_oggpacket
->packet
& PACKET_LEN_BITS2
) << 1;
1270 if( p_stream
->fmt
.i_codec
== VLC_CODEC_SUBT
)
1272 /* But with subtitles we need to retrieve the duration first */
1273 int i
, lenbytes
= 0;
1275 if( i_header_len
> 0 && p_oggpacket
->bytes
>= i_header_len
+ 1 )
1277 for( i
= 0, lenbytes
= 0; i
< i_header_len
; i
++ )
1279 lenbytes
= lenbytes
<< 8;
1280 lenbytes
+= *(p_oggpacket
->packet
+ i_header_len
- i
);
1283 if( p_oggpacket
->bytes
- 1 - i_header_len
> 2 ||
1284 ( p_oggpacket
->packet
[i_header_len
+ 1] != ' ' &&
1285 p_oggpacket
->packet
[i_header_len
+ 1] != 0 &&
1286 p_oggpacket
->packet
[i_header_len
+ 1] != '\n' &&
1287 p_oggpacket
->packet
[i_header_len
+ 1] != '\r' ) )
1289 p_block
->i_length
= (mtime_t
)lenbytes
* 1000;
1294 if( p_block
->i_buffer
>= (unsigned int)i_header_len
)
1295 p_block
->i_buffer
-= i_header_len
;
1297 p_block
->i_buffer
= 0;
1301 if( p_stream
->fmt
.i_codec
== VLC_CODEC_TARKIN
)
1303 /* FIXME: the biggest hack I've ever done */
1304 msg_Warn( p_demux
, "tarkin pts: %"PRId64
", granule: %"PRId64
,
1305 p_block
->i_pts
, p_block
->i_dts
);
1309 memcpy( p_block
->p_buffer
, p_oggpacket
->packet
+ i_header_len
,
1310 p_oggpacket
->bytes
- i_header_len
);
1312 if ( p_ogg
->i_streams
== 1 && p_block
->i_pts
> VLC_TS_INVALID
&& p_ogg
->i_pcr
< VLC_TS_0
)
1314 p_ogg
->i_pcr
= p_block
->i_pts
;
1315 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_ogg
->i_pcr
);
1318 if ( p_stream
->p_es
)
1320 /* Because ES creation is delayed for preparsing */
1321 if ( p_stream
->p_preparse_block
)
1323 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_stream
->p_preparse_block
);
1324 p_stream
->p_preparse_block
= NULL
;
1326 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_block
);
1329 block_ChainAppend( & p_stream
->p_preparse_block
, p_block
);
1332 /* Re-implemented to avoid linking against libopus from the demuxer. */
1333 static int Ogg_OpusPacketDuration( logical_stream_t
*p_stream
,
1334 ogg_packet
*p_oggpacket
)
1336 static const int silk_fs_div
[4] = { 6000, 3000, 1500, 1000 };
1342 if( p_oggpacket
->bytes
< 1 )
1343 return VLC_EGENERIC
;
1344 toc
= p_oggpacket
->packet
[0];
1355 if( p_oggpacket
->bytes
< 2 )
1356 return VLC_EGENERIC
;
1357 nframes
= p_oggpacket
->packet
[1]&0x3F;
1360 i_rate
= (int)p_stream
->fmt
.audio
.i_rate
;
1362 frame_size
= (i_rate
<< (toc
>> 3 & 3)) / 400;
1363 else if( ( toc
&0x60 ) == 0x60 )
1364 frame_size
= i_rate
/(100 >> (toc
>> 3 & 1));
1366 frame_size
= i_rate
*60 / silk_fs_div
[toc
>> 3 & 3];
1367 nsamples
= nframes
*frame_size
;
1368 if( nsamples
*25 > i_rate
*3 )
1369 return VLC_EGENERIC
;
1373 /****************************************************************************
1374 * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical
1375 * stream and fill p_ogg.
1376 *****************************************************************************
1377 * The initial page of a logical stream is marked as a 'bos' page.
1378 * Furthermore, the Ogg specification mandates that grouped bitstreams begin
1379 * together and all of the initial pages must appear before any data pages.
1381 * On success this function returns VLC_SUCCESS.
1382 ****************************************************************************/
1383 static int Ogg_FindLogicalStreams( demux_t
*p_demux
)
1385 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
1386 ogg_packet oggpacket
;
1389 p_ogg
->i_total_length
= stream_Size ( p_demux
->s
);
1390 msg_Dbg( p_demux
, "File length is %"PRId64
" bytes", p_ogg
->i_total_length
);
1393 while( Ogg_ReadPage( p_demux
, &p_ogg
->current_page
) == VLC_SUCCESS
)
1396 if( ogg_page_bos( &p_ogg
->current_page
) )
1399 /* All is wonderful in our fine fine little world.
1400 * We found the beginning of our first logical stream. */
1401 while( ogg_page_bos( &p_ogg
->current_page
) )
1403 logical_stream_t
*p_stream
;
1405 p_stream
= malloc( sizeof(logical_stream_t
) );
1406 if( unlikely( !p_stream
) )
1409 TAB_APPEND( p_ogg
->i_streams
, p_ogg
->pp_stream
, p_stream
);
1411 memset( p_stream
, 0, sizeof(logical_stream_t
) );
1413 es_format_Init( &p_stream
->fmt
, 0, 0 );
1414 es_format_Init( &p_stream
->fmt_old
, 0, 0 );
1415 p_stream
->b_initializing
= true;
1417 /* Setup the logical stream */
1418 p_stream
->i_serial_no
= ogg_page_serialno( &p_ogg
->current_page
);
1419 ogg_stream_init( &p_stream
->os
, p_stream
->i_serial_no
);
1421 /* Extract the initial header from the first page and verify
1422 * the codec type of this Ogg bitstream */
1423 if( ogg_stream_pagein( &p_stream
->os
, &p_ogg
->current_page
) < 0 )
1425 /* error. stream version mismatch perhaps */
1426 msg_Err( p_demux
, "error reading first page of "
1427 "Ogg bitstream data" );
1428 return VLC_EGENERIC
;
1431 /* FIXME: check return value */
1432 ogg_stream_packetpeek( &p_stream
->os
, &oggpacket
);
1434 /* Check for Vorbis header */
1435 if( oggpacket
.bytes
>= 7 &&
1436 ! memcmp( oggpacket
.packet
, "\x01vorbis", 7 ) )
1438 Ogg_ReadVorbisHeader( p_stream
, &oggpacket
);
1439 msg_Dbg( p_demux
, "found vorbis header" );
1441 /* Check for Speex header */
1442 else if( oggpacket
.bytes
>= 5 &&
1443 ! memcmp( oggpacket
.packet
, "Speex", 5 ) )
1445 Ogg_ReadSpeexHeader( p_stream
, &oggpacket
);
1446 msg_Dbg( p_demux
, "found speex header, channels: %i, "
1447 "rate: %i, bitrate: %i",
1448 p_stream
->fmt
.audio
.i_channels
,
1449 (int)p_stream
->f_rate
, p_stream
->fmt
.i_bitrate
);
1451 /* Check for Opus header */
1452 else if( oggpacket
.bytes
>= 8 &&
1453 ! memcmp( oggpacket
.packet
, "OpusHead", 8 ) )
1455 Ogg_ReadOpusHeader( p_stream
, &oggpacket
);
1456 msg_Dbg( p_demux
, "found opus header, channels: %i, "
1458 p_stream
->fmt
.audio
.i_channels
,
1459 (int)p_stream
->i_pre_skip
);
1460 p_stream
->i_skip_frames
= p_stream
->i_pre_skip
;
1462 /* Check for Flac header (< version 1.1.1) */
1463 else if( oggpacket
.bytes
>= 4 &&
1464 ! memcmp( oggpacket
.packet
, "fLaC", 4 ) )
1466 msg_Dbg( p_demux
, "found FLAC header" );
1468 /* Grrrr!!!! Did they really have to put all the
1469 * important info in the second header packet!!!
1470 * (STREAMINFO metadata is in the following packet) */
1471 p_stream
->b_force_backup
= true;
1473 p_stream
->fmt
.i_cat
= AUDIO_ES
;
1474 p_stream
->fmt
.i_codec
= VLC_CODEC_FLAC
;
1476 /* Check for Flac header (>= version 1.1.1) */
1477 else if( oggpacket
.bytes
>= 13 && oggpacket
.packet
[0] ==0x7F &&
1478 ! memcmp( &oggpacket
.packet
[1], "FLAC", 4 ) &&
1479 ! memcmp( &oggpacket
.packet
[9], "fLaC", 4 ) )
1481 int i_packets
= ((int)oggpacket
.packet
[7]) << 8 |
1482 oggpacket
.packet
[8];
1483 msg_Dbg( p_demux
, "found FLAC header version %i.%i "
1484 "(%i header packets)",
1485 oggpacket
.packet
[5], oggpacket
.packet
[6],
1488 p_stream
->b_force_backup
= true;
1490 p_stream
->fmt
.i_cat
= AUDIO_ES
;
1491 p_stream
->fmt
.i_codec
= VLC_CODEC_FLAC
;
1492 oggpacket
.packet
+= 13; oggpacket
.bytes
-= 13;
1493 Ogg_ReadFlacHeader( p_demux
, p_stream
, &oggpacket
);
1495 /* Check for Theora header */
1496 else if( oggpacket
.bytes
>= 7 &&
1497 ! memcmp( oggpacket
.packet
, "\x80theora", 7 ) )
1499 Ogg_ReadTheoraHeader( p_stream
, &oggpacket
);
1502 "found theora header, bitrate: %i, rate: %f",
1503 p_stream
->fmt
.i_bitrate
, p_stream
->f_rate
);
1505 /* Check for Dirac header */
1506 else if( ( oggpacket
.bytes
>= 5 &&
1507 ! memcmp( oggpacket
.packet
, "BBCD\x00", 5 ) ) ||
1508 ( oggpacket
.bytes
>= 9 &&
1509 ! memcmp( oggpacket
.packet
, "KW-DIRAC\x00", 9 ) ) )
1511 if( Ogg_ReadDiracHeader( p_stream
, &oggpacket
) )
1512 msg_Dbg( p_demux
, "found dirac header" );
1515 msg_Warn( p_demux
, "found dirac header isn't decodable" );
1520 /* Check for Tarkin header */
1521 else if( oggpacket
.bytes
>= 7 &&
1522 ! memcmp( &oggpacket
.packet
[1], "tarkin", 6 ) )
1526 msg_Dbg( p_demux
, "found tarkin header" );
1527 p_stream
->fmt
.i_cat
= VIDEO_ES
;
1528 p_stream
->fmt
.i_codec
= VLC_CODEC_TARKIN
;
1530 /* Cheat and get additionnal info ;) */
1531 oggpack_readinit( &opb
, oggpacket
.packet
, oggpacket
.bytes
);
1532 oggpack_adv( &opb
, 88 );
1533 oggpack_adv( &opb
, 104 );
1534 p_stream
->fmt
.i_bitrate
= oggpack_read( &opb
, 32 );
1535 p_stream
->f_rate
= 2; /* FIXME */
1537 "found tarkin header, bitrate: %i, rate: %f",
1538 p_stream
->fmt
.i_bitrate
, p_stream
->f_rate
);
1540 /* Check for VP8 header */
1541 else if( oggpacket
.bytes
>= 26 &&
1542 ! memcmp( oggpacket
.packet
, "OVP80", 5 ) )
1544 if ( Ogg_ReadVP8Header( p_demux
, p_stream
, &oggpacket
) )
1545 msg_Dbg( p_demux
, "found VP8 header "
1546 "fps: %f, width:%i; height:%i",
1548 p_stream
->fmt
.video
.i_width
,
1549 p_stream
->fmt
.video
.i_height
);
1551 p_stream
->fmt
.i_cat
= UNKNOWN_ES
;
1553 /* Check for Annodex header */
1554 else if( oggpacket
.bytes
>= 7 &&
1555 ! memcmp( oggpacket
.packet
, "Annodex", 7 ) )
1557 Ogg_ReadAnnodexHeader( p_demux
, p_stream
, &oggpacket
);
1558 /* kill annodex track */
1562 /* Check for Annodex header */
1563 else if( oggpacket
.bytes
>= 7 &&
1564 ! memcmp( oggpacket
.packet
, "AnxData", 7 ) )
1566 Ogg_ReadAnnodexHeader( p_demux
, p_stream
, &oggpacket
);
1568 /* Check for Kate header */
1569 else if( oggpacket
.bytes
>= 8 &&
1570 ! memcmp( &oggpacket
.packet
[1], "kate\0\0\0", 7 ) )
1572 Ogg_ReadKateHeader( p_stream
, &oggpacket
);
1573 msg_Dbg( p_demux
, "found kate header" );
1575 /* Check for OggDS */
1576 else if( oggpacket
.bytes
>= 142 &&
1577 !memcmp( &oggpacket
.packet
[1],
1578 "Direct Show Samples embedded in Ogg", 35 ))
1580 /* Old header type */
1581 p_stream
->b_oggds
= true;
1582 /* Check for video header (old format) */
1583 if( GetDWLE((oggpacket
.packet
+96)) == 0x05589f80 &&
1584 oggpacket
.bytes
>= 184 )
1586 p_stream
->fmt
.i_cat
= VIDEO_ES
;
1587 p_stream
->fmt
.i_codec
=
1588 VLC_FOURCC( oggpacket
.packet
[68],
1589 oggpacket
.packet
[69],
1590 oggpacket
.packet
[70],
1591 oggpacket
.packet
[71] );
1592 msg_Dbg( p_demux
, "found video header of type: %.4s",
1593 (char *)&p_stream
->fmt
.i_codec
);
1595 p_stream
->fmt
.video
.i_frame_rate
= 10000000;
1596 p_stream
->fmt
.video
.i_frame_rate_base
=
1597 GetQWLE((oggpacket
.packet
+164));
1598 p_stream
->f_rate
= 10000000.0 /
1599 GetQWLE((oggpacket
.packet
+164));
1600 p_stream
->fmt
.video
.i_bits_per_pixel
=
1601 GetWLE((oggpacket
.packet
+182));
1602 if( !p_stream
->fmt
.video
.i_bits_per_pixel
)
1604 p_stream
->fmt
.video
.i_bits_per_pixel
= 24;
1605 p_stream
->fmt
.video
.i_width
=
1606 GetDWLE((oggpacket
.packet
+176));
1607 p_stream
->fmt
.video
.i_height
=
1608 GetDWLE((oggpacket
.packet
+180));
1611 "fps: %f, width:%i; height:%i, bitcount:%i",
1613 p_stream
->fmt
.video
.i_width
,
1614 p_stream
->fmt
.video
.i_height
,
1615 p_stream
->fmt
.video
.i_bits_per_pixel
);
1618 /* Check for audio header (old format) */
1619 else if( GetDWLE((oggpacket
.packet
+96)) == 0x05589F81 )
1622 unsigned int i_format_tag
;
1624 p_stream
->fmt
.i_cat
= AUDIO_ES
;
1626 i_extra_size
= GetWLE((oggpacket
.packet
+140));
1627 if( i_extra_size
> 0 && i_extra_size
< oggpacket
.bytes
- 142 )
1629 p_stream
->fmt
.i_extra
= i_extra_size
;
1630 p_stream
->fmt
.p_extra
= malloc( i_extra_size
);
1631 if( p_stream
->fmt
.p_extra
)
1632 memcpy( p_stream
->fmt
.p_extra
,
1633 oggpacket
.packet
+ 142, i_extra_size
);
1635 p_stream
->fmt
.i_extra
= 0;
1638 i_format_tag
= GetWLE((oggpacket
.packet
+124));
1639 p_stream
->fmt
.audio
.i_channels
=
1640 GetWLE((oggpacket
.packet
+126));
1641 fill_channels_info(&p_stream
->fmt
.audio
);
1642 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
=
1643 GetDWLE((oggpacket
.packet
+128));
1644 p_stream
->fmt
.i_bitrate
=
1645 GetDWLE((oggpacket
.packet
+132)) * 8;
1646 p_stream
->fmt
.audio
.i_blockalign
=
1647 GetWLE((oggpacket
.packet
+136));
1648 p_stream
->fmt
.audio
.i_bitspersample
=
1649 GetWLE((oggpacket
.packet
+138));
1651 wf_tag_to_fourcc( i_format_tag
,
1652 &p_stream
->fmt
.i_codec
, 0 );
1654 if( p_stream
->fmt
.i_codec
==
1655 VLC_FOURCC('u','n','d','f') )
1657 p_stream
->fmt
.i_codec
= VLC_FOURCC( 'm', 's',
1658 ( i_format_tag
>> 8 ) & 0xff,
1659 i_format_tag
& 0xff );
1662 msg_Dbg( p_demux
, "found audio header of type: %.4s",
1663 (char *)&p_stream
->fmt
.i_codec
);
1664 msg_Dbg( p_demux
, "audio:0x%4.4x channels:%d %dHz "
1665 "%dbits/sample %dkb/s",
1667 p_stream
->fmt
.audio
.i_channels
,
1668 p_stream
->fmt
.audio
.i_rate
,
1669 p_stream
->fmt
.audio
.i_bitspersample
,
1670 p_stream
->fmt
.i_bitrate
/ 1024 );
1675 msg_Dbg( p_demux
, "stream %d has an old header "
1676 "but is of an unknown type", p_ogg
->i_streams
-1 );
1681 /* Check for OggDS */
1682 else if( oggpacket
.bytes
>= 44+1 &&
1683 (*oggpacket
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
)
1685 stream_header_t tmp
;
1686 stream_header_t
*st
= &tmp
;
1688 p_stream
->b_oggds
= true;
1690 memcpy( st
->streamtype
, &oggpacket
.packet
[1+0], 8 );
1691 memcpy( st
->subtype
, &oggpacket
.packet
[1+8], 4 );
1692 st
->size
= GetDWLE( &oggpacket
.packet
[1+12] );
1693 st
->time_unit
= GetQWLE( &oggpacket
.packet
[1+16] );
1694 st
->samples_per_unit
= GetQWLE( &oggpacket
.packet
[1+24] );
1695 st
->default_len
= GetDWLE( &oggpacket
.packet
[1+32] );
1696 st
->buffersize
= GetDWLE( &oggpacket
.packet
[1+36] );
1697 st
->bits_per_sample
= GetWLE( &oggpacket
.packet
[1+40] ); // (padding 2)
1699 /* Check for video header (new format) */
1700 if( !strncmp( st
->streamtype
, "video", 5 ) &&
1701 oggpacket
.bytes
>= 52+1 )
1703 st
->sh
.video
.width
= GetDWLE( &oggpacket
.packet
[1+44] );
1704 st
->sh
.video
.height
= GetDWLE( &oggpacket
.packet
[1+48] );
1706 p_stream
->fmt
.i_cat
= VIDEO_ES
;
1708 /* We need to get rid of the header packet */
1709 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
1711 p_stream
->fmt
.i_codec
=
1712 VLC_FOURCC( st
->subtype
[0], st
->subtype
[1],
1713 st
->subtype
[2], st
->subtype
[3] );
1714 msg_Dbg( p_demux
, "found video header of type: %.4s",
1715 (char *)&p_stream
->fmt
.i_codec
);
1717 p_stream
->fmt
.video
.i_frame_rate
= 10000000;
1718 p_stream
->fmt
.video
.i_frame_rate_base
= st
->time_unit
;
1719 if( st
->time_unit
<= 0 )
1720 st
->time_unit
= 400000;
1721 p_stream
->f_rate
= 10000000.0 / st
->time_unit
;
1722 p_stream
->fmt
.video
.i_bits_per_pixel
= st
->bits_per_sample
;
1723 p_stream
->fmt
.video
.i_width
= st
->sh
.video
.width
;
1724 p_stream
->fmt
.video
.i_height
= st
->sh
.video
.height
;
1727 "fps: %f, width:%i; height:%i, bitcount:%i",
1729 p_stream
->fmt
.video
.i_width
,
1730 p_stream
->fmt
.video
.i_height
,
1731 p_stream
->fmt
.video
.i_bits_per_pixel
);
1733 /* Check for audio header (new format) */
1734 else if( !strncmp( st
->streamtype
, "audio", 5 ) &&
1735 oggpacket
.bytes
>= 56+1 )
1741 st
->sh
.audio
.channels
= GetWLE( &oggpacket
.packet
[1+44] );
1742 st
->sh
.audio
.blockalign
= GetWLE( &oggpacket
.packet
[1+48] );
1743 st
->sh
.audio
.avgbytespersec
= GetDWLE( &oggpacket
.packet
[1+52] );
1745 p_stream
->fmt
.i_cat
= AUDIO_ES
;
1747 /* We need to get rid of the header packet */
1748 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
1750 i_extra_size
= st
->size
- 56;
1752 if( i_extra_size
> 0 &&
1753 i_extra_size
< oggpacket
.bytes
- 1 - 56 )
1755 p_stream
->fmt
.i_extra
= i_extra_size
;
1756 p_stream
->fmt
.p_extra
= malloc( p_stream
->fmt
.i_extra
);
1757 if( p_stream
->fmt
.p_extra
)
1758 memcpy( p_stream
->fmt
.p_extra
, oggpacket
.packet
+ 57,
1759 p_stream
->fmt
.i_extra
);
1761 p_stream
->fmt
.i_extra
= 0;
1764 memcpy( p_buffer
, st
->subtype
, 4 );
1766 i_format_tag
= strtol(p_buffer
,NULL
,16);
1767 p_stream
->fmt
.audio
.i_channels
= st
->sh
.audio
.channels
;
1768 fill_channels_info(&p_stream
->fmt
.audio
);
1769 if( st
->time_unit
<= 0 )
1770 st
->time_unit
= 10000000;
1771 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
= st
->samples_per_unit
* 10000000 / st
->time_unit
;
1772 p_stream
->fmt
.i_bitrate
= st
->sh
.audio
.avgbytespersec
* 8;
1773 p_stream
->fmt
.audio
.i_blockalign
= st
->sh
.audio
.blockalign
;
1774 p_stream
->fmt
.audio
.i_bitspersample
= st
->bits_per_sample
;
1776 wf_tag_to_fourcc( i_format_tag
,
1777 &p_stream
->fmt
.i_codec
, 0 );
1779 if( p_stream
->fmt
.i_codec
==
1780 VLC_FOURCC('u','n','d','f') )
1782 p_stream
->fmt
.i_codec
= VLC_FOURCC( 'm', 's',
1783 ( i_format_tag
>> 8 ) & 0xff,
1784 i_format_tag
& 0xff );
1787 msg_Dbg( p_demux
, "found audio header of type: %.4s",
1788 (char *)&p_stream
->fmt
.i_codec
);
1789 msg_Dbg( p_demux
, "audio:0x%4.4x channels:%d %dHz "
1790 "%dbits/sample %dkb/s",
1792 p_stream
->fmt
.audio
.i_channels
,
1793 p_stream
->fmt
.audio
.i_rate
,
1794 p_stream
->fmt
.audio
.i_bitspersample
,
1795 p_stream
->fmt
.i_bitrate
/ 1024 );
1797 /* Check for text (subtitles) header */
1798 else if( !strncmp(st
->streamtype
, "text", 4) )
1800 /* We need to get rid of the header packet */
1801 ogg_stream_packetout( &p_stream
->os
, &oggpacket
);
1803 msg_Dbg( p_demux
, "found text subtitle header" );
1804 p_stream
->fmt
.i_cat
= SPU_ES
;
1805 p_stream
->fmt
.i_codec
= VLC_CODEC_SUBT
;
1806 p_stream
->f_rate
= 1000; /* granulepos is in millisec */
1810 msg_Dbg( p_demux
, "stream %d has a header marker "
1811 "but is of an unknown type", p_ogg
->i_streams
-1 );
1816 else if( oggpacket
.bytes
>= 8 &&
1817 ! memcmp( oggpacket
.packet
, "fishead\0", 8 ) )
1821 msg_Dbg( p_demux
, "stream %d is a skeleton",
1822 p_ogg
->i_streams
-1 );
1823 Ogg_ReadSkeletonHeader( p_demux
, p_stream
, &oggpacket
);
1827 msg_Dbg( p_demux
, "stream %d is of unknown type",
1828 p_ogg
->i_streams
-1 );
1833 /* we'll need to get all headers */
1834 p_ogg
->pp_stream
[i_stream
]->b_initializing
&= p_ogg
->pp_stream
[i_stream
]->b_force_backup
;
1836 if( Ogg_ReadPage( p_demux
, &p_ogg
->current_page
) != VLC_SUCCESS
)
1837 return VLC_EGENERIC
;
1840 /* This is the first data page, which means we are now finished
1841 * with the initial pages. We just need to store it in the relevant
1843 for( i_stream
= 0; i_stream
< p_ogg
->i_streams
; i_stream
++ )
1845 if( ogg_stream_pagein( &p_ogg
->pp_stream
[i_stream
]->os
,
1846 &p_ogg
->current_page
) == 0 )
1848 p_ogg
->b_page_waiting
= true;
1857 return VLC_EGENERIC
;
1860 /****************************************************************************
1861 * Ogg_CreateES: Creates all Elementary streams once headers are parsed
1862 ****************************************************************************/
1863 static void Ogg_CreateES( demux_t
*p_demux
)
1865 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
1866 logical_stream_t
*p_old_stream
= p_ogg
->p_old_stream
;
1869 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
1871 logical_stream_t
*p_stream
= p_ogg
->pp_stream
[i_stream
];
1873 if ( p_stream
->p_es
== NULL
&& !p_stream
->b_finished
)
1875 /* Better be safe than sorry when possible with ogm */
1876 if( p_stream
->fmt
.i_codec
== VLC_CODEC_MPGA
||
1877 p_stream
->fmt
.i_codec
== VLC_CODEC_A52
)
1878 p_stream
->fmt
.b_packetized
= false;
1880 /* Try first to reuse an old ES */
1882 p_old_stream
->fmt
.i_cat
== p_stream
->fmt
.i_cat
&&
1883 p_old_stream
->fmt
.i_codec
== p_stream
->fmt
.i_codec
)
1885 msg_Dbg( p_demux
, "will reuse old stream to avoid glitch" );
1887 p_stream
->p_es
= p_old_stream
->p_es
;
1888 p_stream
->b_finished
= false;
1889 p_stream
->b_reinit
= false;
1890 p_stream
->b_initializing
= false;
1891 bool b_resetdecoder
= Ogg_LogicalStreamResetEsFormat( p_demux
, p_stream
);
1892 es_format_Copy( &p_stream
->fmt_old
, &p_old_stream
->fmt
);
1894 p_old_stream
->p_es
= NULL
;
1895 p_old_stream
= NULL
;
1896 if ( b_resetdecoder
)
1898 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_FMT
,
1899 p_stream
->p_es
, &p_stream
->fmt
);
1904 p_stream
->p_es
= es_out_Add( p_demux
->out
, &p_stream
->fmt
);
1907 // TODO: something to do here ?
1908 if( p_stream
->fmt
.i_codec
== VLC_CODEC_CMML
)
1910 /* Set the CMML stream active */
1911 es_out_Control( p_demux
->out
, ES_OUT_SET_ES
, p_stream
->p_es
);
1916 if( p_ogg
->p_old_stream
)
1918 if( p_ogg
->p_old_stream
->p_es
)
1919 msg_Dbg( p_demux
, "old stream not reused" );
1920 Ogg_LogicalStreamDelete( p_demux
, p_ogg
->p_old_stream
);
1921 p_ogg
->p_old_stream
= NULL
;
1925 /****************************************************************************
1926 * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
1927 * Elementary streams.
1928 ****************************************************************************/
1929 static int Ogg_BeginningOfStream( demux_t
*p_demux
)
1931 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
1934 /* Find the logical streams embedded in the physical stream and
1935 * initialize our p_ogg structure. */
1936 if( Ogg_FindLogicalStreams( p_demux
) != VLC_SUCCESS
)
1938 msg_Warn( p_demux
, "couldn't find any ogg logical stream" );
1939 return VLC_EGENERIC
;
1942 p_ogg
->i_bitrate
= 0;
1944 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
1946 logical_stream_t
*p_stream
= p_ogg
->pp_stream
[i_stream
];
1948 p_stream
->p_es
= NULL
;
1950 /* initialise kframe index */
1953 if ( p_stream
->fmt
.i_bitrate
== 0 &&
1954 ( p_stream
->fmt
.i_cat
== VIDEO_ES
||
1955 p_stream
->fmt
.i_cat
== AUDIO_ES
) )
1956 p_ogg
->b_partial_bitrate
= true;
1958 p_ogg
->i_bitrate
+= p_stream
->fmt
.i_bitrate
;
1960 p_stream
->i_pcr
= p_stream
->i_previous_pcr
=
1961 p_stream
->i_interpolated_pcr
= VLC_TS_UNKNOWN
;
1962 p_stream
->b_reinit
= false;
1965 /* get total frame count for video stream; we will need this for seeking */
1966 p_ogg
->i_total_frames
= 0;
1971 /****************************************************************************
1972 * Ogg_EndOfStream: clean up the ES when an End of Stream is detected.
1973 ****************************************************************************/
1974 static void Ogg_EndOfStream( demux_t
*p_demux
)
1976 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
1979 for( i_stream
= 0 ; i_stream
< p_ogg
->i_streams
; i_stream
++ )
1980 Ogg_LogicalStreamDelete( p_demux
, p_ogg
->pp_stream
[i_stream
] );
1981 free( p_ogg
->pp_stream
);
1984 p_ogg
->i_bitrate
= 0;
1985 p_ogg
->i_streams
= 0;
1986 p_ogg
->pp_stream
= NULL
;
1987 p_ogg
->skeleton
.major
= 0;
1988 p_ogg
->skeleton
.minor
= 0;
1989 p_ogg
->b_preparsing_done
= false;
1990 p_ogg
->b_es_created
= false;
1991 p_ogg
->i_pcr_offset
= p_ogg
->i_pcr
;
1995 vlc_meta_Delete( p_ogg
->p_meta
);
1996 p_ogg
->p_meta
= NULL
;
1998 for ( int i
=0; i
< p_ogg
->i_seekpoints
; i
++ )
2000 if ( p_ogg
->pp_seekpoints
[i
] )
2001 vlc_seekpoint_Delete( p_ogg
->pp_seekpoints
[i
] );
2003 TAB_CLEAN( p_ogg
->i_seekpoints
, p_ogg
->pp_seekpoints
);
2004 p_ogg
->i_seekpoints
= 0;
2008 * This function delete and release all data associated to a logical_stream_t
2010 static void Ogg_LogicalStreamDelete( demux_t
*p_demux
, logical_stream_t
*p_stream
)
2012 if( p_stream
->p_es
)
2013 es_out_Del( p_demux
->out
, p_stream
->p_es
);
2015 ogg_stream_clear( &p_stream
->os
);
2016 free( p_stream
->p_headers
);
2018 es_format_Clean( &p_stream
->fmt_old
);
2019 es_format_Clean( &p_stream
->fmt
);
2021 if ( p_stream
->idx
!= NULL
)
2023 oggseek_index_entries_free( p_stream
->idx
);
2026 Ogg_FreeSkeleton( p_stream
->p_skel
);
2027 p_stream
->p_skel
= NULL
;
2028 if ( p_demux
->p_sys
->p_skelstream
== p_stream
)
2029 p_demux
->p_sys
->p_skelstream
= NULL
;
2031 /* Shouldn't happen */
2032 if ( unlikely( p_stream
->p_preparse_block
) )
2034 block_ChainRelease( p_stream
->p_preparse_block
);
2035 p_stream
->p_preparse_block
= NULL
;
2041 * This function check if a we need to reset a decoder in case we are
2044 static bool Ogg_IsVorbisFormatCompatible( const es_format_t
*p_new
, const es_format_t
*p_old
)
2046 unsigned pi_new_size
[XIPH_MAX_HEADER_COUNT
];
2047 void *pp_new_data
[XIPH_MAX_HEADER_COUNT
];
2048 unsigned i_new_count
;
2049 if( xiph_SplitHeaders(pi_new_size
, pp_new_data
, &i_new_count
, p_new
->i_extra
, p_new
->p_extra
) )
2052 unsigned pi_old_size
[XIPH_MAX_HEADER_COUNT
];
2053 void *pp_old_data
[XIPH_MAX_HEADER_COUNT
];
2054 unsigned i_old_count
;
2055 if( xiph_SplitHeaders(pi_old_size
, pp_old_data
, &i_old_count
, p_old
->i_extra
, p_old
->p_extra
) )
2058 bool b_match
= i_new_count
== i_old_count
;
2059 for( unsigned i
= 0; i
< i_new_count
&& b_match
; i
++ )
2061 /* Ignore vorbis comment */
2064 if( pi_new_size
[i
] != pi_old_size
[i
] ||
2065 memcmp( pp_new_data
[i
], pp_old_data
[i
], pi_new_size
[i
] ) )
2072 static bool Ogg_IsOpusFormatCompatible( const es_format_t
*p_new
,
2073 const es_format_t
*p_old
)
2075 unsigned pi_new_size
[XIPH_MAX_HEADER_COUNT
];
2076 void *pp_new_data
[XIPH_MAX_HEADER_COUNT
];
2077 unsigned i_new_count
;
2078 if( xiph_SplitHeaders(pi_new_size
, pp_new_data
, &i_new_count
, p_new
->i_extra
, p_new
->p_extra
) )
2080 unsigned pi_old_size
[XIPH_MAX_HEADER_COUNT
];
2081 void *pp_old_data
[XIPH_MAX_HEADER_COUNT
];
2082 unsigned i_old_count
;
2083 if( xiph_SplitHeaders(pi_old_size
, pp_old_data
, &i_old_count
, p_old
->i_extra
, p_old
->p_extra
) )
2085 bool b_match
= false;
2086 if( i_new_count
== i_old_count
&& i_new_count
> 0 )
2088 static const unsigned char default_map
[2] = { 0, 1 };
2089 unsigned char *p_old_head
;
2090 unsigned char *p_new_head
;
2091 const unsigned char *p_old_map
;
2092 const unsigned char *p_new_map
;
2093 int i_old_channel_count
;
2094 int i_new_channel_count
;
2095 int i_old_stream_count
;
2096 int i_new_stream_count
;
2097 int i_old_coupled_count
;
2098 int i_new_coupled_count
;
2099 p_old_head
= (unsigned char *)pp_old_data
[0];
2100 i_old_channel_count
= i_old_stream_count
= i_old_coupled_count
= 0;
2101 p_old_map
= default_map
;
2102 if( pi_old_size
[0] >= 19 && p_old_head
[8] <= 15 )
2104 i_old_channel_count
= p_old_head
[9];
2105 switch( p_old_head
[18] )
2108 i_old_stream_count
= 1;
2109 i_old_coupled_count
= i_old_channel_count
- 1;
2112 if( pi_old_size
[0] >= 21U + i_old_channel_count
)
2114 i_old_stream_count
= p_old_head
[19];
2115 i_old_coupled_count
= p_old_head
[20];
2116 p_old_map
= p_old_head
+ 21;
2121 p_new_head
= (unsigned char *)pp_new_data
[0];
2122 i_new_channel_count
= i_new_stream_count
= i_new_coupled_count
= 0;
2123 p_new_map
= default_map
;
2124 if( pi_new_size
[0] >= 19 && p_new_head
[8] <= 15 )
2126 i_new_channel_count
= p_new_head
[9];
2127 switch( p_new_head
[18] )
2130 i_new_stream_count
= 1;
2131 i_new_coupled_count
= i_new_channel_count
- 1;
2134 if( pi_new_size
[0] >= 21U + i_new_channel_count
)
2136 i_new_stream_count
= p_new_head
[19];
2137 i_new_coupled_count
= p_new_head
[20];
2138 p_new_map
= p_new_head
+21;
2143 b_match
= i_old_channel_count
== i_new_channel_count
&&
2144 i_old_stream_count
== i_new_stream_count
&&
2145 i_old_coupled_count
== i_new_coupled_count
&&
2146 memcmp(p_old_map
, p_new_map
,
2147 i_new_channel_count
*sizeof(*p_new_map
)) == 0;
2153 static bool Ogg_LogicalStreamResetEsFormat( demux_t
*p_demux
, logical_stream_t
*p_stream
)
2155 bool b_compatible
= false;
2156 if( !p_stream
->fmt_old
.i_cat
|| !p_stream
->fmt_old
.i_codec
)
2159 /* Only Vorbis and Opus are supported. */
2160 if( p_stream
->fmt
.i_codec
== VLC_CODEC_VORBIS
)
2161 b_compatible
= Ogg_IsVorbisFormatCompatible( &p_stream
->fmt
, &p_stream
->fmt_old
);
2162 else if( p_stream
->fmt
.i_codec
== VLC_CODEC_OPUS
)
2163 b_compatible
= Ogg_IsOpusFormatCompatible( &p_stream
->fmt
, &p_stream
->fmt_old
);
2166 msg_Warn( p_demux
, "cannot reuse old stream, resetting the decoder" );
2168 return !b_compatible
;
2171 static void Ogg_ExtractComments( demux_t
*p_demux
, es_format_t
*p_fmt
,
2172 const void *p_headers
, unsigned i_headers
)
2174 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2175 int i_cover_score
= 0;
2176 int i_cover_idx
= 0;
2177 float pf_replay_gain
[AUDIO_REPLAY_GAIN_MAX
];
2178 float pf_replay_peak
[AUDIO_REPLAY_GAIN_MAX
];
2179 for(int i
=0; i
< AUDIO_REPLAY_GAIN_MAX
; i
++ )
2181 pf_replay_gain
[i
] = 0;
2182 pf_replay_peak
[i
] = 0;
2184 vorbis_ParseComment( &p_ogg
->p_meta
, p_headers
, i_headers
,
2185 &p_ogg
->i_attachments
, &p_ogg
->attachments
,
2186 &i_cover_score
, &i_cover_idx
,
2187 &p_ogg
->i_seekpoints
, &p_ogg
->pp_seekpoints
,
2188 &pf_replay_gain
, &pf_replay_peak
);
2189 if( p_ogg
->p_meta
!= NULL
&& i_cover_idx
< p_ogg
->i_attachments
)
2192 snprintf( psz_url
, sizeof(psz_url
), "attachment://%s",
2193 p_ogg
->attachments
[i_cover_idx
]->psz_name
);
2194 vlc_meta_Set( p_ogg
->p_meta
, vlc_meta_ArtworkURL
, psz_url
);
2197 for ( int i
=0; i
<AUDIO_REPLAY_GAIN_MAX
;i
++ )
2199 if ( pf_replay_gain
[i
] != 0 )
2201 p_fmt
->audio_replay_gain
.pb_gain
[i
] = true;
2202 p_fmt
->audio_replay_gain
.pf_gain
[i
] = pf_replay_gain
[i
];
2203 msg_Dbg( p_demux
, "setting replay gain %d to %f", i
, pf_replay_gain
[i
] );
2205 if ( pf_replay_peak
[i
] != 0 )
2207 p_fmt
->audio_replay_gain
.pb_peak
[i
] = true;
2208 p_fmt
->audio_replay_gain
.pf_peak
[i
] = pf_replay_peak
[i
];
2209 msg_Dbg( p_demux
, "setting replay peak %d to %f", i
, pf_replay_gain
[i
] );
2213 if( p_ogg
->i_seekpoints
> 1 )
2215 p_demux
->info
.i_update
|= INPUT_UPDATE_TITLE_LIST
;
2219 static void Ogg_ExtractXiphMeta( demux_t
*p_demux
, es_format_t
*p_fmt
,
2220 const void *p_headers
, unsigned i_headers
, unsigned i_skip
)
2222 unsigned pi_size
[XIPH_MAX_HEADER_COUNT
];
2223 void *pp_data
[XIPH_MAX_HEADER_COUNT
];
2226 if( xiph_SplitHeaders( pi_size
, pp_data
, &i_count
, i_headers
, p_headers
) )
2228 /* TODO how to handle multiple comments properly ? */
2229 if( i_count
>= 2 && pi_size
[1] > i_skip
)
2231 Ogg_ExtractComments( p_demux
, p_fmt
, (uint8_t*)pp_data
[1] + i_skip
, pi_size
[1] - i_skip
);
2235 static void Ogg_ExtractMeta( demux_t
*p_demux
, es_format_t
*p_fmt
, const uint8_t *p_headers
, int i_headers
)
2237 demux_sys_t
*p_ogg
= p_demux
->p_sys
;
2239 switch( p_fmt
->i_codec
)
2241 /* 3 headers with the 2° one being the comments */
2242 case VLC_CODEC_VORBIS
:
2243 case VLC_CODEC_THEORA
:
2244 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 1+6 );
2246 case VLC_CODEC_OPUS
:
2247 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 8 );
2249 case VLC_CODEC_SPEEX
:
2250 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 0 );
2253 Ogg_ExtractComments( p_demux
, p_fmt
, p_headers
, i_headers
);
2255 /* N headers with the 2° one being the comments */
2256 case VLC_CODEC_KATE
:
2257 /* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
2258 Ogg_ExtractXiphMeta( p_demux
, p_fmt
, p_headers
, i_headers
, 1+7+1 );
2262 case VLC_CODEC_FLAC
:
2263 msg_Warn( p_demux
, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt
->i_codec
);
2267 case VLC_CODEC_CMML
: /* CMML is XML text, doesn't have Vorbis comments */
2268 case VLC_CODEC_DIRAC
:
2273 p_demux
->info
.i_update
|= INPUT_UPDATE_META
;
2276 static void Ogg_ReadTheoraHeader( logical_stream_t
*p_stream
,
2277 ogg_packet
*p_oggpacket
)
2280 int i_fps_numerator
;
2281 int i_fps_denominator
;
2282 int i_keyframe_frequency_force
;
2288 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2289 p_stream
->fmt
.i_codec
= VLC_CODEC_THEORA
;
2291 /* Signal that we want to keep a backup of the theora
2292 * stream headers. They will be used when switching between
2294 p_stream
->b_force_backup
= true;
2296 /* Cheat and get additionnal info ;) */
2297 bs_init( &bitstream
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2298 bs_skip( &bitstream
, 56 );
2300 i_major
= bs_read( &bitstream
, 8 ); /* major version num */
2301 i_minor
= bs_read( &bitstream
, 8 ); /* minor version num */
2302 i_subminor
= bs_read( &bitstream
, 8 ); /* subminor version num */
2304 bs_read( &bitstream
, 16 ) /*<< 4*/; /* width */
2305 bs_read( &bitstream
, 16 ) /*<< 4*/; /* height */
2306 bs_read( &bitstream
, 24 ); /* frame width */
2307 bs_read( &bitstream
, 24 ); /* frame height */
2308 bs_read( &bitstream
, 8 ); /* x offset */
2309 bs_read( &bitstream
, 8 ); /* y offset */
2311 i_fps_numerator
= bs_read( &bitstream
, 32 );
2312 i_fps_denominator
= bs_read( &bitstream
, 32 );
2313 i_fps_denominator
= __MAX( i_fps_denominator
, 1 );
2314 bs_read( &bitstream
, 24 ); /* aspect_numerator */
2315 bs_read( &bitstream
, 24 ); /* aspect_denominator */
2317 p_stream
->fmt
.video
.i_frame_rate
= i_fps_numerator
;
2318 p_stream
->fmt
.video
.i_frame_rate_base
= i_fps_denominator
;
2320 bs_read( &bitstream
, 8 ); /* colorspace */
2321 p_stream
->fmt
.i_bitrate
= bs_read( &bitstream
, 24 );
2322 bs_read( &bitstream
, 6 ); /* quality */
2324 i_keyframe_frequency_force
= 1 << bs_read( &bitstream
, 5 );
2326 /* granule_shift = i_log( frequency_force -1 ) */
2327 p_stream
->i_granule_shift
= 0;
2328 i_keyframe_frequency_force
--;
2329 while( i_keyframe_frequency_force
)
2331 p_stream
->i_granule_shift
++;
2332 i_keyframe_frequency_force
>>= 1;
2335 i_version
= i_major
* 1000000 + i_minor
* 1000 + i_subminor
;
2336 p_stream
->i_keyframe_offset
= 0;
2337 p_stream
->f_rate
= ((float)i_fps_numerator
) / i_fps_denominator
;
2339 if ( i_version
>= 3002001 )
2341 p_stream
->i_keyframe_offset
= 1;
2345 static void Ogg_ReadVorbisHeader( logical_stream_t
*p_stream
,
2346 ogg_packet
*p_oggpacket
)
2350 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2351 p_stream
->fmt
.i_codec
= VLC_CODEC_VORBIS
;
2353 /* Signal that we want to keep a backup of the vorbis
2354 * stream headers. They will be used when switching between
2356 p_stream
->b_force_backup
= true;
2358 /* Cheat and get additionnal info ;) */
2359 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2360 oggpack_adv( &opb
, 88 );
2361 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 8 );
2362 fill_channels_info(&p_stream
->fmt
.audio
);
2363 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
=
2364 oggpack_read( &opb
, 32 );
2365 oggpack_adv( &opb
, 32 );
2366 p_stream
->fmt
.i_bitrate
= oggpack_read( &opb
, 32 ); /* is signed 32 */
2367 if( p_stream
->fmt
.i_bitrate
> INT32_MAX
) p_stream
->fmt
.i_bitrate
= 0;
2370 static void Ogg_ReadSpeexHeader( logical_stream_t
*p_stream
,
2371 ogg_packet
*p_oggpacket
)
2375 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2376 p_stream
->fmt
.i_codec
= VLC_CODEC_SPEEX
;
2378 /* Signal that we want to keep a backup of the speex
2379 * stream headers. They will be used when switching between
2381 p_stream
->b_force_backup
= true;
2383 /* Cheat and get additionnal info ;) */
2384 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2385 oggpack_adv( &opb
, 224 );
2386 oggpack_adv( &opb
, 32 ); /* speex_version_id */
2387 oggpack_adv( &opb
, 32 ); /* header_size */
2388 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
= oggpack_read( &opb
, 32 );
2389 oggpack_adv( &opb
, 32 ); /* mode */
2390 oggpack_adv( &opb
, 32 ); /* mode_bitstream_version */
2391 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 32 );
2392 fill_channels_info(&p_stream
->fmt
.audio
);
2393 p_stream
->fmt
.i_bitrate
= oggpack_read( &opb
, 32 );
2394 oggpack_adv( &opb
, 32 ); /* frame_size */
2395 oggpack_adv( &opb
, 32 ); /* vbr */
2396 oggpack_adv( &opb
, 32 ); /* frames_per_packet */
2397 p_stream
->i_extra_headers_packets
= oggpack_read( &opb
, 32 ); /* extra_headers */
2400 static void Ogg_ReadOpusHeader( logical_stream_t
*p_stream
,
2401 ogg_packet
*p_oggpacket
)
2405 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2406 p_stream
->fmt
.i_codec
= VLC_CODEC_OPUS
;
2408 /* Signal that we want to keep a backup of the opus
2409 * stream headers. They will be used when switching between
2411 p_stream
->b_force_backup
= true;
2413 /* All OggOpus streams are timestamped at 48kHz and
2414 * can be played at 48kHz. */
2415 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
= 48000;
2416 p_stream
->fmt
.i_bitrate
= 0;
2418 /* Cheat and get additional info ;) */
2419 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2420 oggpack_adv( &opb
, 64 );
2421 oggpack_adv( &opb
, 8 ); /* version_id */
2422 p_stream
->fmt
.audio
.i_channels
= oggpack_read( &opb
, 8 );
2423 fill_channels_info(&p_stream
->fmt
.audio
);
2424 p_stream
->i_pre_skip
= oggpack_read( &opb
, 16 );
2427 static void Ogg_ReadFlacHeader( demux_t
*p_demux
, logical_stream_t
*p_stream
,
2428 ogg_packet
*p_oggpacket
)
2430 /* Parse the STREAMINFO metadata */
2433 bs_init( &s
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2436 if( p_oggpacket
->bytes
> 0 && bs_read( &s
, 7 ) != 0 )
2438 msg_Dbg( p_demux
, "Invalid FLAC STREAMINFO metadata" );
2442 if( bs_read( &s
, 24 ) >= 34 /*size STREAMINFO*/ )
2445 p_stream
->f_rate
= p_stream
->fmt
.audio
.i_rate
= bs_read( &s
, 20 );
2446 p_stream
->fmt
.audio
.i_channels
= bs_read( &s
, 3 ) + 1;
2447 fill_channels_info(&p_stream
->fmt
.audio
);
2449 msg_Dbg( p_demux
, "FLAC header, channels: %i, rate: %i",
2450 p_stream
->fmt
.audio
.i_channels
, (int)p_stream
->f_rate
);
2454 msg_Dbg( p_demux
, "FLAC STREAMINFO metadata too short" );
2457 /* Fake this as the last metadata block */
2458 *((uint8_t*)p_oggpacket
->packet
) |= 0x80;
2461 static void Ogg_ReadKateHeader( logical_stream_t
*p_stream
,
2462 ogg_packet
*p_oggpacket
)
2470 p_stream
->fmt
.i_cat
= SPU_ES
;
2471 p_stream
->fmt
.i_codec
= VLC_CODEC_KATE
;
2473 /* Signal that we want to keep a backup of the kate
2474 * stream headers. They will be used when switching between
2476 p_stream
->b_force_backup
= true;
2478 /* Cheat and get additionnal info ;) */
2479 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2480 oggpack_adv( &opb
, 11*8 ); /* packet type, kate magic, version */
2481 p_stream
->i_kate_num_headers
= oggpack_read( &opb
, 8 );
2482 oggpack_adv( &opb
, 3*8 );
2483 p_stream
->i_granule_shift
= oggpack_read( &opb
, 8 );
2484 oggpack_adv( &opb
, 8*8 ); /* reserved */
2485 gnum
= oggpack_read( &opb
, 32 );
2486 gden
= oggpack_read( &opb
, 32 );
2487 p_stream
->f_rate
= (double)gnum
/gden
;
2489 p_stream
->fmt
.psz_language
= malloc(16);
2490 if( p_stream
->fmt
.psz_language
)
2492 for( n
= 0; n
< 16; n
++ )
2493 p_stream
->fmt
.psz_language
[n
] = oggpack_read(&opb
,8);
2494 p_stream
->fmt
.psz_language
[15] = 0; /* just in case */
2498 for( n
= 0; n
< 16; n
++ )
2499 oggpack_read(&opb
,8);
2501 p_stream
->fmt
.psz_description
= malloc(16);
2502 if( p_stream
->fmt
.psz_description
)
2504 for( n
= 0; n
< 16; n
++ )
2505 p_stream
->fmt
.psz_description
[n
] = oggpack_read(&opb
,8);
2506 p_stream
->fmt
.psz_description
[15] = 0; /* just in case */
2508 /* Now find a localized user readable description for this category */
2509 psz_desc
= strdup(FindKateCategoryName(p_stream
->fmt
.psz_description
));
2512 free( p_stream
->fmt
.psz_description
);
2513 p_stream
->fmt
.psz_description
= psz_desc
;
2518 for( n
= 0; n
< 16; n
++ )
2519 oggpack_read(&opb
,8);
2523 static bool Ogg_ReadVP8Header( demux_t
*p_demux
, logical_stream_t
*p_stream
,
2524 ogg_packet
*p_oggpacket
)
2526 switch( p_oggpacket
->packet
[5] )
2530 /* Mapping version */
2531 if ( p_oggpacket
->packet
[6] != 0x01 || p_oggpacket
->packet
[7] != 0x00 )
2533 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2534 p_stream
->fmt
.i_codec
= VLC_CODEC_VP8
;
2535 p_stream
->i_granule_shift
= 32;
2536 p_stream
->fmt
.video
.i_width
= GetWBE( &p_oggpacket
->packet
[8] );
2537 p_stream
->fmt
.video
.i_height
= GetWBE( &p_oggpacket
->packet
[10] );
2538 p_stream
->fmt
.video
.i_sar_num
= GetDWBE( &p_oggpacket
->packet
[12 - 1] ) & 0x0FFF;
2539 p_stream
->fmt
.video
.i_sar_den
= GetDWBE( &p_oggpacket
->packet
[15 - 1] ) & 0x0FFF;
2540 p_stream
->fmt
.video
.i_frame_rate
= GetDWBE( &p_oggpacket
->packet
[18] );
2541 p_stream
->fmt
.video
.i_frame_rate_base
= GetDWBE( &p_oggpacket
->packet
[22] );
2542 p_stream
->f_rate
= (double) p_stream
->fmt
.video
.i_frame_rate
/ p_stream
->fmt
.video
.i_frame_rate_base
;
2546 Ogg_ExtractMeta( p_demux
, & p_stream
->fmt
,
2547 p_oggpacket
->packet
+ 7, p_oggpacket
->bytes
- 7 );
2554 static void Ogg_ApplyContentType( logical_stream_t
*p_stream
, const char* psz_value
,
2555 bool *b_force_backup
, bool *b_packet_out
)
2557 if( !strncmp(psz_value
, "audio/x-wav", 11) )
2559 /* n.b. WAVs are unsupported right now */
2560 p_stream
->fmt
.i_cat
= UNKNOWN_ES
;
2561 free( p_stream
->fmt
.psz_description
);
2562 p_stream
->fmt
.psz_description
= strdup("WAV Audio (Unsupported)");
2564 else if( !strncmp(psz_value
, "audio/x-vorbis", 14) ||
2565 !strncmp(psz_value
, "audio/vorbis", 12) )
2567 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2568 p_stream
->fmt
.i_codec
= VLC_CODEC_VORBIS
;
2570 *b_force_backup
= true;
2572 else if( !strncmp(psz_value
, "audio/x-speex", 13) ||
2573 !strncmp(psz_value
, "audio/speex", 11) )
2575 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2576 p_stream
->fmt
.i_codec
= VLC_CODEC_SPEEX
;
2578 *b_force_backup
= true;
2580 else if( !strncmp(psz_value
, "audio/flac", 10) )
2582 p_stream
->fmt
.i_cat
= AUDIO_ES
;
2583 p_stream
->fmt
.i_codec
= VLC_CODEC_FLAC
;
2585 *b_force_backup
= true;
2587 else if( !strncmp(psz_value
, "video/x-theora", 14) ||
2588 !strncmp(psz_value
, "video/theora", 12) )
2590 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2591 p_stream
->fmt
.i_codec
= VLC_CODEC_THEORA
;
2593 *b_force_backup
= true;
2595 else if( !strncmp(psz_value
, "video/x-xvid", 12) )
2597 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2598 p_stream
->fmt
.i_codec
= VLC_FOURCC( 'x','v','i','d' );
2600 *b_force_backup
= true;
2602 else if( !strncmp(psz_value
, "video/mpeg", 10) )
2604 /* n.b. MPEG streams are unsupported right now */
2605 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2606 p_stream
->fmt
.i_codec
= VLC_CODEC_MPGV
;
2608 else if( !strncmp(psz_value
, "text/x-cmml", 11) ||
2609 !strncmp(psz_value
, "text/cmml", 9) )
2611 p_stream
->fmt
.i_cat
= SPU_ES
;
2612 p_stream
->fmt
.i_codec
= VLC_CODEC_CMML
;
2613 *b_packet_out
= true;
2615 else if( !strncmp(psz_value
, "application/kate", 16) )
2618 p_stream
->fmt
.i_cat
= UNKNOWN_ES
;
2619 free( p_stream
->fmt
.psz_description
);
2620 p_stream
->fmt
.psz_description
= strdup("OGG Kate Overlay (Unsupported)");
2622 else if( !strncmp(psz_value
, "video/x-vp8", 11) )
2624 p_stream
->fmt
.i_cat
= VIDEO_ES
;
2625 p_stream
->fmt
.i_codec
= VLC_CODEC_VP8
;
2629 static void Ogg_ReadAnnodexHeader( demux_t
*p_demux
,
2630 logical_stream_t
*p_stream
,
2631 ogg_packet
*p_oggpacket
)
2633 if( p_oggpacket
->bytes
>= 28 &&
2634 !memcmp( p_oggpacket
->packet
, "Annodex", 7 ) )
2638 uint16_t major_version
;
2639 uint16_t minor_version
;
2640 uint64_t timebase_numerator
;
2641 uint64_t timebase_denominator
;
2643 Ogg_ReadTheoraHeader( p_stream
, p_oggpacket
);
2645 oggpack_readinit( &opb
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2646 oggpack_adv( &opb
, 8*8 ); /* "Annodex\0" header */
2647 major_version
= oggpack_read( &opb
, 2*8 ); /* major version */
2648 minor_version
= oggpack_read( &opb
, 2*8 ); /* minor version */
2649 timebase_numerator
= GetQWLE( &p_oggpacket
->packet
[16] );
2650 timebase_denominator
= GetQWLE( &p_oggpacket
->packet
[24] );
2652 msg_Dbg( p_demux
, "Annodex info: version %"PRIu16
".%"PRIu16
" "
2653 "Timebase %"PRId64
" / %"PRId64
,
2654 major_version
, minor_version
,
2655 timebase_numerator
, timebase_denominator
);
2657 else if( p_oggpacket
->bytes
>= 42 &&
2658 !memcmp( p_oggpacket
->packet
, "AnxData", 7 ) )
2660 uint64_t granule_rate_numerator
;
2661 uint64_t granule_rate_denominator
;
2662 char content_type_string
[1024];
2664 /* Read in Annodex header fields */
2666 granule_rate_numerator
= GetQWLE( &p_oggpacket
->packet
[8] );
2667 granule_rate_denominator
= GetQWLE( &p_oggpacket
->packet
[16] );
2668 p_stream
->i_secondary_header_packets
=
2669 GetDWLE( &p_oggpacket
->packet
[24] );
2671 /* we are guaranteed that the first header field will be
2672 * the content-type (by the Annodex standard) */
2673 content_type_string
[0] = '\0';
2674 if( !strncasecmp( (char*)(&p_oggpacket
->packet
[28]), "Content-Type: ", 14 ) )
2676 uint8_t *p
= memchr( &p_oggpacket
->packet
[42], '\r',
2677 p_oggpacket
->bytes
- 1 );
2678 if( p
&& p
[0] == '\r' && p
[1] == '\n' )
2679 sscanf( (char*)(&p_oggpacket
->packet
[42]), "%1023s\r\n",
2680 content_type_string
);
2683 msg_Dbg( p_demux
, "AnxData packet info: %"PRId64
" / %"PRId64
", %d, ``%s''",
2684 granule_rate_numerator
, granule_rate_denominator
,
2685 p_stream
->i_secondary_header_packets
, content_type_string
);
2687 p_stream
->f_rate
= (float) granule_rate_numerator
/
2688 (float) granule_rate_denominator
;
2690 /* What type of file do we have?
2691 * strcmp is safe to use here because we've extracted
2692 * content_type_string from the stream manually */
2693 bool b_dopacketout
= false;
2694 Ogg_ApplyContentType( p_stream
, content_type_string
,
2695 &p_stream
->b_force_backup
, &b_dopacketout
);
2696 if ( b_dopacketout
) ogg_stream_packetout( &p_stream
->os
, p_oggpacket
);
2700 static void Ogg_ReadSkeletonHeader( demux_t
*p_demux
, logical_stream_t
*p_stream
,
2701 ogg_packet
*p_oggpacket
)
2703 p_demux
->p_sys
->p_skelstream
= p_stream
;
2704 /* There can be only 1 skeleton for streams */
2705 p_demux
->p_sys
->skeleton
.major
= GetWLE( &p_oggpacket
->packet
[8] );
2706 p_demux
->p_sys
->skeleton
.minor
= GetWLE( &p_oggpacket
->packet
[10] );
2707 if ( asprintf( & p_stream
->fmt
.psz_description
,
2708 "OGG Skeleton version %" PRIu16
".%" PRIu16
,
2709 p_demux
->p_sys
->skeleton
.major
,
2710 p_demux
->p_sys
->skeleton
.minor
) < 0 )
2711 p_stream
->fmt
.psz_description
= NULL
;
2714 static void Ogg_ReadSkeletonBones( demux_t
*p_demux
, ogg_packet
*p_oggpacket
)
2716 if ( p_demux
->p_sys
->skeleton
.major
< 3 || p_oggpacket
->bytes
< 52 ) return;
2718 /* Find the matching stream for this skeleton data */
2719 ogg_int32_t i_serialno
= GetDWLE( &p_oggpacket
->packet
[12] );
2720 logical_stream_t
*p_target_stream
= NULL
;
2721 for ( int i
=0; i
< p_demux
->p_sys
->i_streams
; i
++ )
2723 if ( p_demux
->p_sys
->pp_stream
[i
]->i_serial_no
== i_serialno
)
2725 p_target_stream
= p_demux
->p_sys
->pp_stream
[i
];
2729 if ( !p_target_stream
) return;
2731 ogg_skeleton_t
*p_skel
= p_target_stream
->p_skel
;
2734 p_skel
= malloc( sizeof( ogg_skeleton_t
) );
2735 if ( !p_skel
) return;
2736 TAB_INIT( p_skel
->i_messages
, p_skel
->ppsz_messages
);
2737 p_skel
->p_index
= NULL
;
2738 p_target_stream
->p_skel
= p_skel
;
2741 const unsigned char *p_messages
= p_oggpacket
->packet
+ 8 + GetDWLE( &p_oggpacket
->packet
[8] );
2742 const unsigned char *p_boundary
= p_oggpacket
->packet
+ p_oggpacket
->bytes
;
2743 const unsigned char *p
= p_messages
;
2744 while ( p
<= p_boundary
- 1 && p
> p_oggpacket
->packet
)
2746 if ( *p
== 0x0D && *(p
+1) == 0x0A )
2748 char *psz_message
= strndup( (const char *) p_messages
,
2752 msg_Dbg( p_demux
, "stream %" PRId32
" [%s]", i_serialno
, psz_message
);
2753 TAB_APPEND( p_skel
->i_messages
, p_skel
->ppsz_messages
, psz_message
);
2755 if ( p
< p_boundary
- 1 ) p_messages
= p
+ 2;
2762 /* Unpacks the 7bit variable encoding used in skeleton indexes */
2763 unsigned const char * Read7BitsVariableLE( unsigned const char *p_begin
,
2764 unsigned const char *p_end
,
2765 uint64_t *pi_value
)
2771 while ( p_begin
< p_end
)
2773 i_read
= *p_begin
& 0x7F; /* High bit is start of integer */
2774 *pi_value
= *pi_value
| ( i_read
<< i_shift
);
2776 if ( (*p_begin
++ & 0x80) == 0x80 ) break; /* see prev */
2779 *pi_value
= GetQWLE( pi_value
);
2783 static void Ogg_ReadSkeletonIndex( demux_t
*p_demux
, ogg_packet
*p_oggpacket
)
2785 if ( p_demux
->p_sys
->skeleton
.major
< 4
2786 || p_oggpacket
->bytes
< 44 /* Need at least 1 index value (42+1+1) */
2789 /* Find the matching stream for this skeleton data */
2790 int32_t i_serialno
= GetDWLE( &p_oggpacket
->packet
[6] );
2791 logical_stream_t
*p_stream
= NULL
;
2792 for ( int i
=0; i
< p_demux
->p_sys
->i_streams
; i
++ )
2794 if ( p_demux
->p_sys
->pp_stream
[i
]->i_serial_no
== i_serialno
)
2796 p_stream
= p_demux
->p_sys
->pp_stream
[i
];
2800 if ( !p_stream
) return;
2801 uint64_t i_keypoints
= GetQWLE( &p_oggpacket
->packet
[10] );
2802 msg_Dbg( p_demux
, "%" PRIi64
" index data for %" PRIi32
, i_keypoints
, i_serialno
);
2803 if ( !i_keypoints
) return;
2805 p_stream
->p_skel
->i_indexstampden
= GetQWLE( &p_oggpacket
->packet
[18] );
2806 p_stream
->p_skel
->i_indexfirstnum
= GetQWLE( &p_oggpacket
->packet
[24] );
2807 p_stream
->p_skel
->i_indexlastnum
= GetQWLE( &p_oggpacket
->packet
[32] );
2808 unsigned const char *p_fwdbyte
= &p_oggpacket
->packet
[42];
2809 unsigned const char *p_boundary
= p_oggpacket
->packet
+ p_oggpacket
->bytes
;
2810 uint64_t i_offset
= 0;
2811 uint64_t i_time
= 0;
2812 uint64_t i_keypoints_found
= 0;
2814 while( p_fwdbyte
< p_boundary
&& i_keypoints_found
< i_keypoints
)
2817 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
, p_boundary
, &i_val
);
2819 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
, p_boundary
, &i_val
);
2820 i_time
+= i_val
* p_stream
->p_skel
->i_indexstampden
;
2821 i_keypoints_found
++;
2824 if ( i_keypoints_found
!= i_keypoints
)
2826 msg_Warn( p_demux
, "Invalid Index: missing entries" );
2830 p_stream
->p_skel
->p_index
= malloc( p_oggpacket
->bytes
- 42 );
2831 if ( !p_stream
->p_skel
->p_index
) return;
2832 memcpy( p_stream
->p_skel
->p_index
, &p_oggpacket
->packet
[42],
2833 p_oggpacket
->bytes
- 42 );
2834 p_stream
->p_skel
->i_index
= i_keypoints_found
;
2835 p_stream
->p_skel
->i_index_size
= p_oggpacket
->bytes
- 42;
2838 static void Ogg_FreeSkeleton( ogg_skeleton_t
*p_skel
)
2840 if ( !p_skel
) return;
2841 for ( int i
=0; i
< p_skel
->i_messages
; i
++ )
2842 free( p_skel
->ppsz_messages
[i
] );
2843 TAB_CLEAN( p_skel
->i_messages
, p_skel
->ppsz_messages
);
2844 free( p_skel
->p_index
);
2848 static void Ogg_ApplySkeleton( logical_stream_t
*p_stream
)
2850 if ( !p_stream
->p_skel
) return;
2851 for ( int i
=0; i
< p_stream
->p_skel
->i_messages
; i
++ )
2853 const char *psz_message
= p_stream
->p_skel
->ppsz_messages
[i
];
2854 if ( ! strncmp( "Name: ", psz_message
, 6 ) )
2856 free( p_stream
->fmt
.psz_description
);
2857 p_stream
->fmt
.psz_description
= strdup( psz_message
+ 6 );
2859 else if ( ! strncmp("Content-Type: ", psz_message
, 14 ) )
2862 Ogg_ApplyContentType( p_stream
, psz_message
+ 14, &b_foo
, &b_foo
);
2867 /* Return true if there's a skeleton exact match */
2868 bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t
*p_stream
, int64_t i_time
,
2869 int64_t *pi_lower
, int64_t *pi_upper
)
2871 if ( !p_stream
|| !p_stream
->p_skel
|| !p_stream
->p_skel
->p_index
)
2874 /* Validate range */
2875 if ( i_time
< p_stream
->p_skel
->i_indexfirstnum
2876 * p_stream
->p_skel
->i_indexstampden
||
2877 i_time
> p_stream
->p_skel
->i_indexlastnum
2878 * p_stream
->p_skel
->i_indexstampden
) return false;
2880 /* Then Lookup its index */
2881 unsigned const char *p_fwdbyte
= p_stream
->p_skel
->p_index
;
2886 } current
= { 0, 0 }, prev
= { -1, -1 };
2888 uint64_t i_keypoints_found
= 0;
2890 while( p_fwdbyte
< p_fwdbyte
+ p_stream
->p_skel
->i_index_size
2891 && i_keypoints_found
< p_stream
->p_skel
->i_index
)
2894 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
,
2895 p_fwdbyte
+ p_stream
->p_skel
->i_index_size
, &i_val
);
2896 current
.i_pos
+= i_val
;
2897 p_fwdbyte
= Read7BitsVariableLE( p_fwdbyte
,
2898 p_fwdbyte
+ p_stream
->p_skel
->i_index_size
, &i_val
);
2899 current
.i_time
+= i_val
* p_stream
->p_skel
->i_indexstampden
;
2900 if ( current
.i_pos
< 0 || current
.i_time
< 0 ) break;
2902 i_keypoints_found
++;
2904 if ( i_time
<= current
.i_time
)
2906 *pi_lower
= prev
.i_pos
;
2907 *pi_upper
= current
.i_pos
;
2908 return ( i_time
== current
.i_time
);
2915 static uint32_t dirac_uint( bs_t
*p_bs
)
2917 uint32_t u_count
= 0, u_value
= 0;
2919 while( !bs_eof( p_bs
) && !bs_read( p_bs
, 1 ) )
2923 u_value
|= bs_read( p_bs
, 1 );
2926 return (1<<u_count
) - 1 + u_value
;
2929 static int dirac_bool( bs_t
*p_bs
)
2931 return bs_read( p_bs
, 1 );
2934 static bool Ogg_ReadDiracHeader( logical_stream_t
*p_stream
,
2935 ogg_packet
*p_oggpacket
)
2937 static const struct {
2938 uint32_t u_n
/* numerator */, u_d
/* denominator */;
2939 } p_dirac_frate_tbl
[] = { /* table 10.3 */
2940 {1,1}, /* this first value is never used */
2941 {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
2942 {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
2944 static const size_t u_dirac_frate_tbl
= sizeof(p_dirac_frate_tbl
)/sizeof(*p_dirac_frate_tbl
);
2946 static const uint32_t pu_dirac_vidfmt_frate
[] = { /* table C.1 */
2947 1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
2949 static const size_t u_dirac_vidfmt_frate
= sizeof(pu_dirac_vidfmt_frate
)/sizeof(*pu_dirac_vidfmt_frate
);
2953 p_stream
->i_granule_shift
= 22; /* not 32 */
2955 /* Backing up stream headers is not required -- seqhdrs are repeated
2956 * thoughout the stream at suitable decoding start points */
2957 p_stream
->b_force_backup
= false;
2959 /* read in useful bits from sequence header */
2960 bs_init( &bs
, p_oggpacket
->packet
, p_oggpacket
->bytes
);
2961 bs_skip( &bs
, 13*8); /* parse_info_header */
2962 dirac_uint( &bs
); /* major_version */
2963 dirac_uint( &bs
); /* minor_version */
2964 dirac_uint( &bs
); /* profile */
2965 dirac_uint( &bs
); /* level */
2967 uint32_t u_video_format
= dirac_uint( &bs
); /* index */
2968 if( u_video_format
>= u_dirac_vidfmt_frate
)
2970 /* don't know how to parse this ogg dirac stream */
2974 if( dirac_bool( &bs
) )
2976 dirac_uint( &bs
); /* frame_width */
2977 dirac_uint( &bs
); /* frame_height */
2980 if( dirac_bool( &bs
) )
2982 dirac_uint( &bs
); /* chroma_format */
2985 if( dirac_bool( &bs
) )
2987 dirac_uint( &bs
); /* scan_format */
2990 uint32_t u_n
= p_dirac_frate_tbl
[pu_dirac_vidfmt_frate
[u_video_format
]].u_n
;
2991 uint32_t u_d
= p_dirac_frate_tbl
[pu_dirac_vidfmt_frate
[u_video_format
]].u_d
;
2992 if( dirac_bool( &bs
) )
2994 uint32_t u_frame_rate_index
= dirac_uint( &bs
);
2995 if( u_frame_rate_index
>= u_dirac_frate_tbl
)
2997 /* something is wrong with this stream */
3000 u_n
= p_dirac_frate_tbl
[u_frame_rate_index
].u_n
;
3001 u_d
= p_dirac_frate_tbl
[u_frame_rate_index
].u_d
;
3002 if( u_frame_rate_index
== 0 )
3004 u_n
= dirac_uint( &bs
); /* frame_rate_numerator */
3005 u_d
= dirac_uint( &bs
); /* frame_rate_denominator */
3008 p_stream
->f_rate
= (float) u_n
/ u_d
;
3010 /* probably is an ogg dirac es */
3011 p_stream
->fmt
.i_cat
= VIDEO_ES
;
3012 p_stream
->fmt
.i_codec
= VLC_CODEC_DIRAC
;