qt: playlist: use item title if available
[vlc.git] / modules / codec / flac.c
blob850ea002c9b7ed24d745a800f1b0d3a548977d26
1 /*****************************************************************************
2 * flac.c: flac decoder/encoder module making use of libflac
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@videolan.org>
7 * Sigmund Augdal Helberg <dnumgis@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 /* workaround libflac overriding assert.h system header */
29 #define assert(x) do {} while(0)
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
38 #include <vlc_codecs.h>
39 #include <vlc_aout.h>
41 #ifdef _WIN32
42 # define FLAC__NO_DLL
43 #endif
45 #include <FLAC/stream_decoder.h>
46 #include <FLAC/stream_encoder.h>
48 #include <vlc_block_helper.h>
49 #include <vlc_bits.h>
51 #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT >= 8
52 # define USE_NEW_FLAC_API
53 #endif
55 /*****************************************************************************
56 * decoder_sys_t : FLAC decoder descriptor
57 *****************************************************************************/
58 typedef struct
61 * Input/Output properties
63 block_t *p_block;
64 block_t *p_aout_buffer;
65 date_t end_date;
68 * FLAC properties
70 FLAC__StreamDecoder *p_flac;
71 FLAC__StreamMetadata_StreamInfo stream_info;
73 uint8_t rgi_channels_reorder[AOUT_CHAN_MAX];
74 bool b_stream_info;
75 } decoder_sys_t;
77 static const int pi_channels_maps[FLAC__MAX_CHANNELS + 1] =
80 AOUT_CHAN_CENTER,
81 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
82 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
83 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
84 | AOUT_CHAN_REARRIGHT,
85 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
86 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
87 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
88 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
89 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
90 | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT| AOUT_CHAN_MIDDLERIGHT
91 | AOUT_CHAN_LFE,
92 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
93 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
94 | AOUT_CHAN_LFE
97 /* XXX it supposes our internal format is WG4 */
98 static const uint8_t ppi_reorder[1+FLAC__MAX_CHANNELS][FLAC__MAX_CHANNELS] =
100 { 0 },
101 { 0, },
102 { 0, 1 },
103 { 0, 1, 2 },
104 { 0, 1, 2, 3 },
105 { 0, 1, 3, 4, 2 },
106 { 0, 1, 4, 5, 2, 3 },
107 { 0, 1, 5, 6, 4, 2, 3 },
108 { 0, 1, 6, 7, 4, 5, 2, 3 },
111 /* Flac uses same order as waveformatex */
112 #define MAPPED_WFX_CHANNELS 9
113 static const uint32_t wfx_remapping[MAPPED_WFX_CHANNELS][2] =
115 { WAVE_SPEAKER_FRONT_LEFT, AOUT_CHAN_LEFT },
116 { WAVE_SPEAKER_FRONT_RIGHT, AOUT_CHAN_RIGHT },
117 { WAVE_SPEAKER_FRONT_CENTER, AOUT_CHAN_CENTER },
118 { WAVE_SPEAKER_LOW_FREQUENCY, AOUT_CHAN_LFE },
119 { WAVE_SPEAKER_BACK_LEFT, AOUT_CHAN_REARLEFT },
120 { WAVE_SPEAKER_BACK_RIGHT, AOUT_CHAN_REARRIGHT },
121 { WAVE_SPEAKER_BACK_CENTER, AOUT_CHAN_REARCENTER },
122 { WAVE_SPEAKER_SIDE_LEFT, AOUT_CHAN_MIDDLELEFT },
123 { WAVE_SPEAKER_SIDE_RIGHT, AOUT_CHAN_MIDDLERIGHT },
126 static const uint32_t wfx_chans_order[MAPPED_WFX_CHANNELS + 1] =
128 AOUT_CHAN_LEFT,
129 AOUT_CHAN_RIGHT,
130 AOUT_CHAN_CENTER,
131 AOUT_CHAN_LFE,
132 AOUT_CHAN_REARLEFT,
133 AOUT_CHAN_REARRIGHT,
134 AOUT_CHAN_REARCENTER,
135 AOUT_CHAN_MIDDLELEFT,
136 AOUT_CHAN_MIDDLERIGHT,
140 /*****************************************************************************
141 * Local prototypes
142 *****************************************************************************/
143 static int OpenDecoder ( vlc_object_t * );
144 static void CloseDecoder ( vlc_object_t * );
146 #ifdef ENABLE_SOUT
147 static int OpenEncoder ( vlc_object_t * );
148 static void CloseEncoder ( vlc_object_t * );
149 #endif
151 static int DecodeBlock( decoder_t *, block_t * );
152 static void Flush( decoder_t * );
154 /*****************************************************************************
155 * Module descriptor
156 *****************************************************************************/
157 vlc_module_begin ()
159 set_category( CAT_INPUT )
160 set_subcategory( SUBCAT_INPUT_ACODEC )
161 add_shortcut( "flac" )
163 set_description( N_("Flac audio decoder") )
164 set_capability( "audio decoder", 100 )
165 set_callbacks( OpenDecoder, CloseDecoder )
167 #ifdef ENABLE_SOUT
168 add_submodule ()
169 add_shortcut( "flac" )
170 set_description( N_("Flac audio encoder") )
171 set_capability( "encoder", 100 )
172 set_callbacks( OpenEncoder, CloseEncoder )
173 #endif
175 vlc_module_end ()
177 /*****************************************************************************
178 * Interleave: helper function to interleave channels
179 *****************************************************************************/
180 static void Interleave( int32_t *p_out, const int32_t * const *pp_in,
181 const uint8_t *restrict pi_index, unsigned i_nb_channels,
182 unsigned i_samples, unsigned bits )
184 unsigned shift = 32 - bits;
186 for( unsigned j = 0; j < i_samples; j++ )
187 for( unsigned i = 0; i < i_nb_channels; i++ )
189 union { int32_t i; uint32_t u; } spl;
191 spl.u = ((uint32_t)pp_in[pi_index[i]][j]) << shift;
192 p_out[j * i_nb_channels + i] = spl.i;
196 /*****************************************************************************
197 * DecoderSetOutputFormat: helper function to convert and check frame format
198 *****************************************************************************/
199 static int DecoderSetOutputFormat( unsigned i_channels, unsigned i_rate,
200 unsigned i_streaminfo_rate,
201 unsigned i_bitspersample,
202 audio_format_t *fmt,
203 uint8_t *pi_channels_reorder )
205 if( i_channels == 0 || i_channels > FLAC__MAX_CHANNELS ||
206 i_bitspersample == 0 || (i_rate == 0 && i_streaminfo_rate == 0) )
207 return VLC_EGENERIC;
209 fmt->i_channels = i_channels;
210 fmt->i_rate = (i_rate > 0 ) ? i_rate : i_streaminfo_rate;
211 fmt->i_physical_channels = pi_channels_maps[i_channels];
212 memcpy( pi_channels_reorder, ppi_reorder[i_channels], i_channels );
213 fmt->i_bitspersample = i_bitspersample;
215 return VLC_SUCCESS;
218 /*****************************************************************************
219 * DecoderWriteCallback: called by libflac to output decoded samples
220 *****************************************************************************/
221 static FLAC__StreamDecoderWriteStatus
222 DecoderWriteCallback( const FLAC__StreamDecoder *decoder,
223 const FLAC__Frame *frame,
224 const FLAC__int32 *const buffer[], void *client_data )
226 VLC_UNUSED(decoder);
227 decoder_t *p_dec = (decoder_t *)client_data;
228 decoder_sys_t *p_sys = p_dec->p_sys;
230 if( DecoderSetOutputFormat( frame->header.channels,
231 frame->header.sample_rate,
232 p_sys->b_stream_info ? p_sys->stream_info.sample_rate : 0,
233 frame->header.bits_per_sample,
234 &p_dec->fmt_out.audio,
235 p_sys->rgi_channels_reorder ) )
236 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
238 if( p_sys->end_date.i_divider_num != p_dec->fmt_out.audio.i_rate )
240 if( p_sys->end_date.i_divider_num > 0 )
241 date_Change( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
242 else
243 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
246 if( decoder_UpdateAudioFormat( p_dec ) )
247 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
249 if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID )
250 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
252 p_sys->p_aout_buffer =
253 decoder_NewAudioBuffer( p_dec, frame->header.blocksize );
255 if( p_sys->p_aout_buffer == NULL )
256 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
258 Interleave( (int32_t *)p_sys->p_aout_buffer->p_buffer, buffer,
259 p_sys->rgi_channels_reorder,
260 frame->header.channels, frame->header.blocksize,
261 frame->header.bits_per_sample );
263 /* Date management (already done by packetizer) */
264 p_sys->p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
265 p_sys->p_aout_buffer->i_length =
266 date_Increment( &p_sys->end_date, frame->header.blocksize ) -
267 p_sys->p_aout_buffer->i_pts;
269 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
272 /*****************************************************************************
273 * DecoderReadCallback: called by libflac when it needs more data
274 *****************************************************************************/
275 static FLAC__StreamDecoderReadStatus
276 DecoderReadCallback( const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
277 size_t *bytes, void *client_data )
279 VLC_UNUSED(decoder);
280 decoder_t *p_dec = (decoder_t *)client_data;
281 decoder_sys_t *p_sys = p_dec->p_sys;
283 if( p_sys->p_block && p_sys->p_block->i_buffer )
285 *bytes = __MIN(*bytes, p_sys->p_block->i_buffer);
286 memcpy( buffer, p_sys->p_block->p_buffer, *bytes );
287 p_sys->p_block->i_buffer -= *bytes;
288 p_sys->p_block->p_buffer += *bytes;
290 else
292 *bytes = 0;
293 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
296 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
299 /*****************************************************************************
300 * DecoderMetadataCallback: called by libflac to when it encounters metadata
301 *****************************************************************************/
302 static void DecoderMetadataCallback( const FLAC__StreamDecoder *decoder,
303 const FLAC__StreamMetadata *metadata,
304 void *client_data )
306 VLC_UNUSED(decoder);
307 decoder_t *p_dec = (decoder_t *)client_data;
308 decoder_sys_t *p_sys = p_dec->p_sys;
310 switch(metadata->type)
312 case FLAC__METADATA_TYPE_STREAMINFO:
313 /* Setup the format */
314 DecoderSetOutputFormat( metadata->data.stream_info.channels,
315 metadata->data.stream_info.sample_rate,
316 metadata->data.stream_info.sample_rate,
317 metadata->data.stream_info.bits_per_sample,
318 &p_dec->fmt_out.audio, p_sys->rgi_channels_reorder );
320 msg_Dbg( p_dec, "channels:%d samplerate:%d bitspersamples:%d",
321 p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_rate,
322 p_dec->fmt_out.audio.i_bitspersample );
324 p_sys->b_stream_info = true;
325 p_sys->stream_info = metadata->data.stream_info;
327 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
328 break;
330 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
331 for( FLAC__uint32 i=0; i<metadata->data.vorbis_comment.num_comments; i++ )
333 const FLAC__StreamMetadata_VorbisComment_Entry *comment =
334 &metadata->data.vorbis_comment.comments[i];
335 /* Check for custom WAVEFORMATEX channel ordering */
336 if( comment->length > 34 &&
337 !strncmp( "WAVEFORMATEXTENSIBLE_CHANNEL_MASK=", (char *) comment->entry, 34 ) )
339 char *endptr = (char *) &comment->entry[34] + comment->length;
340 const uint32_t i_wfxmask = strtoul( (char *) &comment->entry[34], &endptr, 16 );
341 const unsigned i_wfxchannels = vlc_popcount( i_wfxmask );
342 if( i_wfxchannels > 0 && i_wfxchannels <= AOUT_CHAN_MAX )
344 /* Create the vlc bitmap from wfx channels */
345 uint32_t i_vlcmask = 0;
346 for( uint32_t i_chan = 1; i_chan && i_chan <= i_wfxmask; i_chan <<= 1 )
348 if( (i_chan & i_wfxmask) == 0 )
349 continue;
350 for( size_t j=0; j<MAPPED_WFX_CHANNELS; j++ )
352 if( wfx_remapping[j][0] == i_chan )
353 i_vlcmask |= wfx_remapping[j][1];
356 /* Check if we have the 1 to 1 mapping */
357 if( (unsigned) vlc_popcount(i_vlcmask) != i_wfxchannels )
359 msg_Warn( p_dec, "Unsupported channel mask %x", i_wfxmask );
360 return;
363 /* Compute the remapping */
364 uint8_t neworder[AOUT_CHAN_MAX] = {0};
365 aout_CheckChannelReorder( wfx_chans_order, NULL,
366 i_vlcmask, neworder );
368 /* /!\ Invert our source/dest reordering,
369 * as Interleave() here works source indexes */
370 for( unsigned j=0; j<i_wfxchannels; j++ )
371 p_sys->rgi_channels_reorder[neworder[j]] = j;
373 p_dec->fmt_out.audio.i_physical_channels = i_vlcmask;
374 p_dec->fmt_out.audio.i_channels = i_wfxchannels;
377 break;
381 default:
382 break;
386 /*****************************************************************************
387 * DecoderErrorCallback: called when the libflac decoder encounters an error
388 *****************************************************************************/
389 static void DecoderErrorCallback( const FLAC__StreamDecoder *decoder,
390 FLAC__StreamDecoderErrorStatus status,
391 void *client_data )
393 VLC_UNUSED(decoder);
394 decoder_t *p_dec = (decoder_t *)client_data;
395 decoder_sys_t *p_sys = p_dec->p_sys;
397 switch( status )
399 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
400 msg_Warn( p_dec, "an error in the stream caused the decoder to "
401 "lose synchronization." );
402 break;
403 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
404 msg_Err( p_dec, "the decoder encountered a corrupted frame header." );
405 break;
406 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
407 msg_Err( p_dec, "frame's data did not match the CRC in the "
408 "footer." );
409 break;
410 case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
411 msg_Err( p_dec, "The decoder encountered reserved fields in use in "
412 "the stream." );
413 break;
414 default:
415 msg_Err( p_dec, "got decoder error: %d", status );
418 FLAC__stream_decoder_flush( p_sys->p_flac );
419 return;
421 /*****************************************************************************
422 * OpenDecoder: probe the decoder and return score
423 *****************************************************************************/
424 static int OpenDecoder( vlc_object_t *p_this )
426 decoder_t *p_dec = (decoder_t*)p_this;
427 decoder_sys_t *p_sys;
429 if( p_dec->fmt_in.i_codec != VLC_CODEC_FLAC )
431 return VLC_EGENERIC;
434 /* Allocate the memory needed to store the decoder's structure */
435 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
436 return VLC_ENOMEM;
438 /* Misc init */
439 p_sys->b_stream_info = false;
440 memset(p_sys->rgi_channels_reorder, 0, AOUT_CHAN_MAX);
441 p_sys->p_block = NULL;
443 /* Take care of flac init */
444 if( !(p_sys->p_flac = FLAC__stream_decoder_new()) )
446 msg_Err( p_dec, "FLAC__stream_decoder_new() failed" );
447 free( p_sys );
448 return VLC_EGENERIC;
451 /* Enable STREAMINFO + COMMENTS */
452 FLAC__stream_decoder_set_metadata_respond( p_sys->p_flac,
453 FLAC__METADATA_TYPE_VORBIS_COMMENT );
455 #ifdef USE_NEW_FLAC_API
456 if( FLAC__stream_decoder_init_stream( p_sys->p_flac,
457 DecoderReadCallback,
458 NULL,
459 NULL,
460 NULL,
461 NULL,
462 DecoderWriteCallback,
463 DecoderMetadataCallback,
464 DecoderErrorCallback,
465 p_dec )
466 != FLAC__STREAM_DECODER_INIT_STATUS_OK )
468 msg_Err( p_dec, "FLAC__stream_decoder_init_stream() failed" );
469 FLAC__stream_decoder_delete( p_sys->p_flac );
470 free( p_sys );
471 return VLC_EGENERIC;
473 #else
474 FLAC__stream_decoder_set_read_callback( p_sys->p_flac,
475 DecoderReadCallback );
476 FLAC__stream_decoder_set_write_callback( p_sys->p_flac,
477 DecoderWriteCallback );
478 FLAC__stream_decoder_set_metadata_callback( p_sys->p_flac,
479 DecoderMetadataCallback );
480 FLAC__stream_decoder_set_error_callback( p_sys->p_flac,
481 DecoderErrorCallback );
482 FLAC__stream_decoder_set_client_data( p_sys->p_flac, p_dec );
484 FLAC__stream_decoder_init( p_sys->p_flac );
485 #endif
487 /* Set output properties */
488 p_dec->fmt_out.i_codec = VLC_CODEC_S32N;
490 /* Set callbacks */
491 p_dec->pf_decode = DecodeBlock;
492 p_dec->pf_flush = Flush;
494 return VLC_SUCCESS;
497 /*****************************************************************************
498 * CloseDecoder: flac decoder destruction
499 *****************************************************************************/
500 static void CloseDecoder( vlc_object_t *p_this )
502 decoder_t *p_dec = (decoder_t *)p_this;
503 decoder_sys_t *p_sys = p_dec->p_sys;
505 FLAC__stream_decoder_finish( p_sys->p_flac );
506 FLAC__stream_decoder_delete( p_sys->p_flac );
508 if( p_sys->p_block )
509 block_Release( p_sys->p_block );
510 free( p_sys );
513 /*****************************************************************************
514 * ProcessHeader: process Flac header.
515 *****************************************************************************/
516 static void ProcessHeader( decoder_t *p_dec )
518 decoder_sys_t *p_sys = p_dec->p_sys;
520 if( !p_dec->fmt_in.i_extra )
521 return;
523 /* Decode STREAMINFO */
524 msg_Dbg( p_dec, "decode STREAMINFO" );
525 int i_extra = p_dec->fmt_in.i_extra;
527 static const char header[4] = { 'f', 'L', 'a', 'C' };
529 if( memcmp( p_dec->fmt_in.p_extra, header, 4 ) )
530 i_extra += 8;
532 p_sys->p_block = block_Alloc( i_extra );
533 if( p_sys->p_block == NULL )
534 return;
536 uint8_t *p_data = p_sys->p_block->p_buffer;
537 if( i_extra != p_dec->fmt_in.i_extra )
539 memcpy( p_data, header, 4);
540 p_data[4] = 0x80 | 0; /* STREAMINFO faked as last block */
541 p_data[5] = 0;
542 p_data[6] = 0;
543 p_data[7] = 34; /* block size */
544 p_data += 8;
546 memcpy( p_data, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
548 FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
549 msg_Dbg( p_dec, "STREAMINFO decoded" );
551 block_Release( p_sys->p_block );
552 p_sys->p_block = NULL;
555 /*****************************************************************************
556 * decoder_state_error: print meaningful error messages
557 *****************************************************************************/
558 static void decoder_state_error( decoder_t *p_dec,
559 FLAC__StreamDecoderState state )
561 switch ( state )
563 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
564 msg_Dbg( p_dec, "the decoder is ready to search for metadata." );
565 break;
566 case FLAC__STREAM_DECODER_READ_METADATA:
567 msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
568 "reading metadata." );
569 break;
570 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
571 msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
572 "searching for the frame sync code." );
573 break;
574 case FLAC__STREAM_DECODER_READ_FRAME:
575 msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
576 "reading a frame." );
577 break;
578 case FLAC__STREAM_DECODER_END_OF_STREAM:
579 msg_Dbg( p_dec, "the decoder has reached the end of the stream." );
580 break;
581 #ifdef USE_NEW_FLAC_API
582 case FLAC__STREAM_DECODER_OGG_ERROR:
583 msg_Err( p_dec, "error occurred in the Ogg layer." );
584 break;
585 case FLAC__STREAM_DECODER_SEEK_ERROR:
586 msg_Err( p_dec, "error occurred while seeking." );
587 break;
588 #endif
589 case FLAC__STREAM_DECODER_ABORTED:
590 msg_Warn( p_dec, "the decoder was aborted by the read callback." );
591 break;
592 #ifndef USE_NEW_FLAC_API
593 case FLAC__STREAM_DECODER_UNPARSEABLE_STREAM:
594 msg_Warn( p_dec, "the decoder encountered reserved fields in use "
595 "in the stream." );
596 break;
597 #endif
598 case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
599 msg_Err( p_dec, "error when allocating memory." );
600 break;
601 #ifndef USE_NEW_FLAC_API
602 case FLAC__STREAM_DECODER_ALREADY_INITIALIZED:
603 msg_Err( p_dec, "FLAC__stream_decoder_init() was called when the "
604 "decoder was already initialized, usually because "
605 "FLAC__stream_decoder_finish() was not called." );
606 break;
607 case FLAC__STREAM_DECODER_INVALID_CALLBACK:
608 msg_Err( p_dec, "FLAC__stream_decoder_init() was called without "
609 "all callbacks being set." );
610 break;
611 #endif
612 case FLAC__STREAM_DECODER_UNINITIALIZED:
613 msg_Err( p_dec, "decoder in uninitialized state." );
614 break;
615 default:
616 msg_Warn(p_dec, "unknown error" );
620 /*****************************************************************************
621 * Flush:
622 *****************************************************************************/
623 static void Flush( decoder_t *p_dec )
625 decoder_sys_t *p_sys = p_dec->p_sys;
627 if( p_sys->b_stream_info )
628 FLAC__stream_decoder_flush( p_sys->p_flac );
629 date_Set( &p_sys->end_date, VLC_TICK_INVALID );
632 /****************************************************************************
633 * DecodeBlock: the whole thing
634 ****************************************************************************/
635 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
637 decoder_sys_t *p_sys = p_dec->p_sys;
639 if( p_block == NULL ) /* No Drain */
640 return VLCDEC_SUCCESS;
641 if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
643 Flush( p_dec );
644 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
646 block_Release( p_block );
647 return VLCDEC_SUCCESS;
651 if( !p_sys->b_stream_info )
653 ProcessHeader( p_dec );
654 if( !p_sys->b_stream_info )
656 block_Release( p_block );
657 return VLCDEC_ECRITICAL;
661 p_sys->p_block = p_block;
663 if( p_sys->p_block->i_pts != VLC_TICK_INVALID &&
664 p_sys->p_block->i_pts != date_Get( &p_sys->end_date ) )
665 date_Set( &p_sys->end_date, p_sys->p_block->i_pts );
667 p_sys->p_aout_buffer = 0;
669 if( !FLAC__stream_decoder_process_single( p_sys->p_flac ) )
671 decoder_state_error( p_dec,
672 FLAC__stream_decoder_get_state( p_sys->p_flac ) );
673 FLAC__stream_decoder_flush( p_sys->p_flac );
676 /* If the decoder is in the "aborted" state,
677 * FLAC__stream_decoder_process_single() won't return an error. */
678 switch ( FLAC__stream_decoder_get_state(p_sys->p_flac) )
680 case FLAC__STREAM_DECODER_ABORTED:
681 FLAC__stream_decoder_flush( p_sys->p_flac );
682 break;
683 case FLAC__STREAM_DECODER_END_OF_STREAM:
684 FLAC__stream_decoder_reset( p_sys->p_flac );
685 break;
686 default:
687 break;
690 block_Release( p_sys->p_block );
691 p_sys->p_block = NULL;
693 if( p_sys->p_aout_buffer != NULL )
694 decoder_QueueAudio( p_dec, p_sys->p_aout_buffer );
695 return VLCDEC_SUCCESS;
698 #ifdef ENABLE_SOUT
700 /*****************************************************************************
701 * encoder_sys_t : flac encoder descriptor
702 *****************************************************************************/
703 typedef struct
706 * Input properties
708 int i_headers;
710 int i_samples_delay;
712 FLAC__int32 *p_buffer;
713 unsigned int i_buffer;
715 block_t *p_chain;
718 * FLAC properties
720 FLAC__StreamEncoder *p_flac;
721 FLAC__StreamMetadata_StreamInfo stream_info;
724 * Common properties
726 vlc_tick_t i_pts;
727 } encoder_sys_t;
729 #define STREAMINFO_SIZE 34
731 static block_t *Encode( encoder_t *, block_t * );
733 /*****************************************************************************
734 * EncoderWriteCallback: called by libflac to output encoded samples
735 *****************************************************************************/
736 static FLAC__StreamEncoderWriteStatus
737 EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
738 const FLAC__byte buffer[],
739 size_t bytes, unsigned samples,
740 unsigned current_frame, void *client_data )
742 VLC_UNUSED(encoder); VLC_UNUSED(current_frame);
743 encoder_t *p_enc = (encoder_t *)client_data;
744 encoder_sys_t *p_sys = p_enc->p_sys;
745 block_t *p_block;
747 if( samples == 0 )
749 if( p_sys->i_headers == 1 )
751 msg_Dbg( p_enc, "Writing STREAMINFO: %zu", bytes );
753 /* Backup the STREAMINFO metadata block */
754 p_enc->fmt_out.i_extra = STREAMINFO_SIZE + 8;
755 p_enc->fmt_out.p_extra = xmalloc( STREAMINFO_SIZE + 8);
756 memcpy(p_enc->fmt_out.p_extra, "fLaC", 4);
757 memcpy((uint8_t*)p_enc->fmt_out.p_extra + 4, buffer, STREAMINFO_SIZE );
758 /* Fake this as the last metadata block */
759 ((uint8_t*)p_enc->fmt_out.p_extra)[4] |= 0x80;
761 p_sys->i_headers++;
762 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
765 p_block = block_Alloc( bytes );
766 memcpy( p_block->p_buffer, buffer, bytes );
768 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
770 p_sys->i_samples_delay -= samples;
772 p_block->i_length = vlc_tick_from_samples(samples, p_enc->fmt_in.audio.i_rate);
774 /* Update pts */
775 p_sys->i_pts += p_block->i_length;
777 block_ChainAppend( &p_sys->p_chain, p_block );
779 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
781 /*****************************************************************************
782 * EncoderMetadataCallback: called by libflac to output metadata
783 *****************************************************************************/
784 static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder,
785 const FLAC__StreamMetadata *metadata,
786 void *client_data )
788 VLC_UNUSED(encoder);
789 encoder_t *p_enc = (encoder_t *)client_data;
791 msg_Err( p_enc, "MetadataCallback: %i", metadata->type );
792 return;
795 /*****************************************************************************
796 * OpenEncoder: probe the encoder and return score
797 *****************************************************************************/
798 static int OpenEncoder( vlc_object_t *p_this )
800 encoder_t *p_enc = (encoder_t *)p_this;
801 encoder_sys_t *p_sys;
803 if( p_enc->fmt_out.i_codec != VLC_CODEC_FLAC &&
804 !p_enc->obj.force )
806 return VLC_EGENERIC;
809 /* Allocate the memory needed to store the decoder's structure */
810 if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
811 return VLC_ENOMEM;
812 p_enc->p_sys = p_sys;
813 p_enc->pf_encode_audio = Encode;
814 p_enc->fmt_out.i_codec = VLC_CODEC_FLAC;
816 p_sys->i_headers = 0;
817 p_sys->p_buffer = 0;
818 p_sys->i_buffer = 0;
819 p_sys->i_samples_delay = 0;
821 /* Create flac encoder */
822 if( !(p_sys->p_flac = FLAC__stream_encoder_new()) )
824 msg_Err( p_enc, "FLAC__stream_encoder_new() failed" );
825 free( p_sys );
826 return VLC_EGENERIC;
829 FLAC__stream_encoder_set_streamable_subset( p_sys->p_flac, 1 );
830 FLAC__stream_encoder_set_channels( p_sys->p_flac,
831 p_enc->fmt_in.audio.i_channels );
832 FLAC__stream_encoder_set_sample_rate( p_sys->p_flac,
833 p_enc->fmt_in.audio.i_rate );
834 FLAC__stream_encoder_set_bits_per_sample( p_sys->p_flac, 16 );
835 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
837 /* Get and store the STREAMINFO metadata block as a p_extra */
838 p_sys->p_chain = 0;
840 #ifdef USE_NEW_FLAC_API
841 if( FLAC__stream_encoder_init_stream( p_sys->p_flac,
842 EncoderWriteCallback,
843 NULL,
844 NULL,
845 EncoderMetadataCallback,
846 p_enc )
847 != FLAC__STREAM_ENCODER_INIT_STATUS_OK )
849 msg_Err( p_enc, "FLAC__stream_encoder_init_stream() failed" );
850 FLAC__stream_encoder_delete( p_sys->p_flac );
851 free( p_sys );
852 return VLC_EGENERIC;
854 #else
855 FLAC__stream_encoder_set_write_callback( p_sys->p_flac,
856 EncoderWriteCallback );
857 FLAC__stream_encoder_set_metadata_callback( p_sys->p_flac,
858 EncoderMetadataCallback );
859 FLAC__stream_encoder_set_client_data( p_sys->p_flac, p_enc );
861 FLAC__stream_encoder_init( p_sys->p_flac );
862 #endif
864 return VLC_SUCCESS;
867 /****************************************************************************
868 * Encode: the whole thing
869 ****************************************************************************
870 * This function spits out ogg packets.
871 ****************************************************************************/
872 static block_t *Encode( encoder_t *p_enc, block_t *p_aout_buf )
874 encoder_sys_t *p_sys = p_enc->p_sys;
875 block_t *p_chain;
877 /* FIXME: p_aout_buf is NULL when it's time to flush*/
878 if( unlikely( !p_aout_buf ) ) return NULL;
880 p_sys->i_pts = p_aout_buf->i_pts -
881 vlc_tick_from_samples( p_sys->i_samples_delay,
882 p_enc->fmt_in.audio.i_rate );
884 p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
886 /* Convert samples to FLAC__int32 */
887 if( p_sys->i_buffer < p_aout_buf->i_buffer * sizeof(FLAC__int32) )
889 p_sys->p_buffer =
890 xrealloc( p_sys->p_buffer, p_aout_buf->i_buffer * sizeof(FLAC__int32) );
891 p_sys->i_buffer = p_aout_buf->i_buffer * 2;
894 for( unsigned i = 0 ; i < p_aout_buf->i_buffer / 2 ; i++ )
896 p_sys->p_buffer[i]= ((int16_t *)p_aout_buf->p_buffer)[i];
899 FLAC__stream_encoder_process_interleaved( p_sys->p_flac, p_sys->p_buffer,
900 p_aout_buf->i_nb_samples );
902 p_chain = p_sys->p_chain;
903 p_sys->p_chain = 0;
905 return p_chain;
908 /*****************************************************************************
909 * CloseEncoder: encoder destruction
910 *****************************************************************************/
911 static void CloseEncoder( vlc_object_t *p_this )
913 encoder_t *p_enc = (encoder_t *)p_this;
914 encoder_sys_t *p_sys = p_enc->p_sys;
916 FLAC__stream_encoder_delete( p_sys->p_flac );
918 free( p_sys->p_buffer );
919 free( p_sys );
921 #endif