1 /*****************************************************************************
2 * vorbis.c: vorbis decoder module making use of libvorbis.
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: vorbis.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <string.h> /* memcpy(), memset() */
32 #include <vlc/decoder.h>
33 #include <vlc/input.h>
35 #include <input_ext-dec.h>
37 #include <vlc/input.h>
40 #ifdef MODULE_NAME_IS_tremor
41 #include <tremor/ivorbiscodec.h>
43 #include <vorbis/codec.h>
46 /*****************************************************************************
47 * decoder_sys_t : vorbis decoder descriptor
48 *****************************************************************************/
52 vlc_bool_t b_packetizer;
62 vorbis_info vi; /* struct that stores all the static vorbis bitstream
64 vorbis_comment vc; /* struct that stores all the bitstream user
66 vorbis_dsp_state vd; /* central working state for the packet->PCM
68 vorbis_block vb; /* local working space for packet->PCM decode */
73 aout_instance_t *p_aout;
74 aout_input_t *p_aout_input;
75 audio_sample_format_t aout_format;
78 * Packetizer output properties
80 sout_packetizer_input_t *p_sout_input;
81 sout_format_t sout_format;
86 audio_date_t end_date;
87 int i_last_block_size;
91 static int pi_channels_maps[6] =
94 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
95 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
96 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
97 | AOUT_CHAN_REARRIGHT,
98 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
99 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
102 /****************************************************************************
104 ****************************************************************************/
105 static int OpenDecoder ( vlc_object_t * );
106 static int OpenPacketizer( vlc_object_t * );
108 static int InitDecoder ( decoder_t * );
109 static int RunDecoder ( decoder_t *, block_t * );
110 static int EndDecoder ( decoder_t * );
112 static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t );
113 static int DecodePacket ( decoder_t *, ogg_packet * );
114 static int SendPacket ( decoder_t *, ogg_packet * );
116 static void ParseVorbisComments( decoder_t * );
118 #ifdef MODULE_NAME_IS_tremor
119 static void Interleave ( int32_t *, const int32_t **, int, int );
121 static void Interleave ( float *, const float **, int, int );
124 /*****************************************************************************
126 *****************************************************************************/
128 set_description( _("Vorbis audio decoder") );
129 #ifdef MODULE_NAME_IS_tremor
130 set_capability( "decoder", 90 );
132 set_capability( "decoder", 100 );
134 set_callbacks( OpenDecoder, NULL );
137 set_description( _("Vorbis audio packetizer") );
138 set_capability( "packetizer", 100 );
139 set_callbacks( OpenPacketizer, NULL );
142 /*****************************************************************************
143 * OpenDecoder: probe the decoder and return score
144 *****************************************************************************/
145 static int OpenDecoder( vlc_object_t *p_this )
147 decoder_t *p_dec = (decoder_t*)p_this;
149 if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') )
154 p_dec->pf_init = InitDecoder;
155 p_dec->pf_decode = RunDecoder;
156 p_dec->pf_end = EndDecoder;
158 /* Allocate the memory needed to store the decoder's structure */
160 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
162 msg_Err( p_dec, "out of memory" );
165 p_dec->p_sys->b_packetizer = VLC_FALSE;
170 static int OpenPacketizer( vlc_object_t *p_this )
172 decoder_t *p_dec = (decoder_t*)p_this;
174 int i_ret = OpenDecoder( p_this );
176 if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
181 /*****************************************************************************
182 * InitDecoder: Initalize the decoder
183 *****************************************************************************/
184 static int InitDecoder( decoder_t *p_dec )
186 decoder_sys_t *p_sys = p_dec->p_sys;
188 aout_DateSet( &p_sys->end_date, 0 );
190 p_sys->p_aout = NULL;
191 p_sys->p_aout_input = NULL;
192 p_sys->aout_format.i_format = VLC_FOURCC('v','o','r','b');
194 p_sys->p_sout_input = NULL;
195 p_sys->sout_format.i_cat = AUDIO_ES;
196 p_sys->sout_format.i_fourcc = VLC_FOURCC( 'v', 'o', 'r', 'b' );
197 p_sys->sout_format.i_block_align = 0;
198 p_sys->sout_format.i_bitrate = 0;
199 p_sys->sout_format.i_extra_data = 0;
200 p_sys->sout_format.p_extra_data = NULL;
202 /* Take care of vorbis init */
203 vorbis_info_init( &p_sys->vi );
204 vorbis_comment_init( &p_sys->vc );
206 p_sys->i_headers = 0;
211 /****************************************************************************
212 * RunDecoder: the whole thing
213 ****************************************************************************
214 * This function must be fed with ogg packets.
215 ****************************************************************************/
216 static int RunDecoder( decoder_t *p_dec, block_t *p_block )
218 decoder_sys_t *p_sys = p_dec->p_sys;
219 ogg_packet oggpacket;
222 /* Block to Ogg packet */
223 oggpacket.packet = p_block->p_buffer;
224 oggpacket.bytes = p_block->i_buffer;
225 oggpacket.granulepos = p_block->i_dts;
228 oggpacket.packetno = 0;
230 if( p_sys->i_headers == 0 )
232 /* Take care of the initial Vorbis header */
234 oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
235 if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc,
238 msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis "
240 block_Release( p_block );
246 if( p_sys->b_packetizer )
248 /* add a input for the stream ouput */
249 p_sys->sout_format.i_sample_rate = p_sys->vi.rate;
250 p_sys->sout_format.i_channels = p_sys->vi.channels;
251 p_sys->sout_format.i_block_align = 1;
252 p_sys->sout_format.i_bitrate = p_sys->vi.bitrate_nominal;
254 p_sys->p_sout_input =
255 sout_InputNew( p_dec, &p_sys->sout_format );
257 if( !p_sys->p_sout_input )
259 msg_Err( p_dec, "cannot add a new stream" );
260 block_Release( p_block );
266 #ifdef MODULE_NAME_IS_tremor
267 p_sys->aout_format.i_format = VLC_FOURCC('f','i','3','2');
269 p_sys->aout_format.i_format = VLC_FOURCC('f','l','3','2');
271 p_sys->aout_format.i_physical_channels =
272 p_sys->aout_format.i_original_channels =
273 pi_channels_maps[p_sys->vi.channels];
274 p_sys->aout_format.i_rate = p_sys->vi.rate;
276 p_sys->p_aout = NULL;
277 p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
278 &p_sys->aout_format );
280 if( p_sys->p_aout_input == NULL )
282 msg_Err( p_dec, "failed to create aout fifo" );
283 block_Release( p_block );
288 aout_DateInit( &p_sys->end_date, p_sys->vi.rate );
290 msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ld",
291 p_sys->vi.channels, p_sys->vi.rate,
292 p_sys->vi.bitrate_nominal );
294 if( p_sys->b_packetizer )
296 i_ret = SendPacket( p_dec, &oggpacket );
297 block_Release( p_block );
302 block_Release( p_block );
307 if( p_sys->i_headers == 1 )
309 /* The next packet in order is the comments header */
310 if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
313 msg_Err( p_dec, "2nd Vorbis header is corrupted" );
318 ParseVorbisComments( p_dec );
320 if( p_sys->b_packetizer )
322 i_ret = SendPacket( p_dec, &oggpacket );
323 block_Release( p_block );
328 block_Release( p_block );
333 if( p_sys->i_headers == 2 )
335 /* The next packet in order is the codebooks header
336 We need to watch out that this packet is not missing as a
337 missing or corrupted header is fatal. */
338 if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket )
341 msg_Err( p_dec, "3rd Vorbis header is corrupted" );
346 if( !p_sys->b_packetizer )
348 /* Initialize the Vorbis packet->PCM decoder */
349 vorbis_synthesis_init( &p_sys->vd, &p_sys->vi );
350 vorbis_block_init( &p_sys->vd, &p_sys->vb );
353 if( p_sys->b_packetizer )
355 i_ret = SendPacket( p_dec, &oggpacket );
356 block_Release( p_block );
361 block_Release( p_block );
366 i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts );
367 block_Release( p_block );
371 /*****************************************************************************
372 * ProcessPacket: processes a Vorbis packet.
373 *****************************************************************************/
374 static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
377 decoder_sys_t *p_sys = p_dec->p_sys;
379 /* Date management */
380 if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) )
382 aout_DateSet( &p_sys->end_date, i_pts );
385 if( p_sys->b_packetizer )
387 return SendPacket( p_dec, p_oggpacket );
391 return DecodePacket( p_dec, p_oggpacket );
395 /*****************************************************************************
396 * DecodePacket: decodes a Vorbis packet.
397 *****************************************************************************/
398 static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
400 decoder_sys_t *p_sys = p_dec->p_sys;
403 #ifdef MODULE_NAME_IS_tremor
409 if( vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
410 vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );
412 /* **pp_pcm is a multichannel float vector. In stereo, for
413 * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is
414 * the size of each channel. Convert the float values
415 * (-1.<=range<=1.) to whatever PCM format and write it out */
417 while( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
420 aout_buffer_t *p_aout_buffer;
421 p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
425 msg_Err( p_dec, "cannot get aout buffer" );
429 /* Interleave the samples */
430 #ifdef MODULE_NAME_IS_tremor
431 Interleave( (int32_t *)p_aout_buffer->p_buffer,
432 (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples );
434 Interleave( (float *)p_aout_buffer->p_buffer,
435 (const float **)pp_pcm, p_sys->vi.channels, i_samples );
438 /* Tell libvorbis how many samples we actually consumed */
439 vorbis_synthesis_read( &p_sys->vd, i_samples );
441 /* Date management */
442 p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
443 p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
446 aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer );
451 /*****************************************************************************
452 * SendPacket: send an ogg packet to the stream output.
453 *****************************************************************************/
454 static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
456 decoder_sys_t *p_sys = p_dec->p_sys;
457 int i_block_size, i_samples;
459 sout_buffer_t *p_sout_buffer =
460 sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes );
462 if( !p_sout_buffer ) return VLC_EGENERIC;
464 i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
465 if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
466 i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
467 p_sys->i_last_block_size = i_block_size;
469 p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer,
471 p_oggpacket->bytes );
473 p_sout_buffer->i_bitrate = p_sys->vi.bitrate_nominal;
475 /* Date management */
476 p_sout_buffer->i_dts = p_sout_buffer->i_pts =
477 aout_DateGet( &p_sys->end_date );
479 if( p_sys->i_headers >= 3 )
480 p_sout_buffer->i_length =
481 aout_DateIncrement( &p_sys->end_date, i_samples ) -
482 p_sout_buffer->i_pts;
484 p_sout_buffer->i_length = 0;
486 sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer );
491 /*****************************************************************************
492 * ParseVorbisComments: FIXME should be done in demuxer
493 *****************************************************************************/
494 static void ParseVorbisComments( decoder_t *p_dec )
496 input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
497 input_info_category_t *p_cat =
498 input_InfoCategory( p_input, _("Vorbis Comment") );
500 char *psz_name, *psz_value, *psz_comment;
501 while ( i < p_dec->p_sys->vc.comments )
503 psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] );
506 msg_Warn( p_dec, "Out of memory" );
509 psz_name = psz_comment;
510 psz_value = strchr( psz_comment, '=' );
515 input_AddInfo( p_cat, psz_name, psz_value );
522 /*****************************************************************************
523 * Interleave: helper function to interleave channels
524 *****************************************************************************/
525 #ifdef MODULE_NAME_IS_tremor
526 static void Interleave( int32_t *p_out, const int32_t **pp_in,
528 static void Interleave( float *p_out, const float **pp_in,
530 int i_nb_channels, int i_samples )
534 for ( j = 0; j < i_samples; j++ )
536 for ( i = 0; i < i_nb_channels; i++ )
538 p_out[j * i_nb_channels + i] = pp_in[i][j];
543 /*****************************************************************************
544 * EndDecoder: vorbis decoder destruction
545 *****************************************************************************/
546 static int EndDecoder( decoder_t * p_dec )
548 decoder_sys_t *p_sys = p_dec->p_sys;
550 if( p_sys->p_aout_input != NULL )
552 aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
555 if( p_sys->p_sout_input != NULL )
557 sout_InputDelete( p_sys->p_sout_input );
560 if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
562 vorbis_block_clear( &p_sys->vb );
563 vorbis_dsp_clear( &p_sys->vd );
566 vorbis_comment_clear( &p_sys->vc );
567 vorbis_info_clear( &p_sys->vi ); /* must be called last */