]> git.sesse.net Git - vlc/blob - modules/codec/flac.c
Cleaned up a bit spu_t API.
[vlc] / modules / codec / flac.c
1 /*****************************************************************************
2  * flac.c: flac decoder/encoder module making use of libflac
3  *****************************************************************************
4  * Copyright (C) 1999-2001 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *          Sigmund Augdal Helberg <dnumgis@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
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 General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_aout.h>
37
38 #include <stream_decoder.h>
39 #include <stream_encoder.h>
40
41 #include <vlc_block_helper.h>
42 #include <vlc_bits.h>
43
44 #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT >= 8
45 #   define USE_NEW_FLAC_API
46 #endif
47
48 /*****************************************************************************
49  * decoder_sys_t : FLAC decoder descriptor
50  *****************************************************************************/
51 struct decoder_sys_t
52 {
53     /*
54      * Input/Output properties
55      */
56     block_t *p_block;
57     aout_buffer_t *p_aout_buffer;
58     date_t        end_date;
59
60     /*
61      * FLAC properties
62      */
63     FLAC__StreamDecoder *p_flac;
64     FLAC__StreamMetadata_StreamInfo stream_info;
65     bool b_stream_info;
66 };
67
68 static const int pi_channels_maps[9] =
69 {
70     0,
71     AOUT_CHAN_CENTER,
72     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
73     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
74     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
75      | AOUT_CHAN_REARRIGHT,
76     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
77      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
78     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
79      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
80     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
81      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT
82      | AOUT_CHAN_MIDDLERIGHT,
83     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
84      | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
85      | AOUT_CHAN_LFE
86 };
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91 static int  OpenDecoder   ( vlc_object_t * );
92 static void CloseDecoder  ( vlc_object_t * );
93
94 static int OpenEncoder   ( vlc_object_t * );
95 static void CloseEncoder ( vlc_object_t * );
96
97 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
98
99 static FLAC__StreamDecoderReadStatus
100 DecoderReadCallback( const FLAC__StreamDecoder *decoder,
101                      FLAC__byte buffer[], unsigned *bytes, void *client_data );
102
103 static FLAC__StreamDecoderWriteStatus
104 DecoderWriteCallback( const FLAC__StreamDecoder *decoder,
105                       const FLAC__Frame *frame,
106                       const FLAC__int32 *const buffer[], void *client_data );
107
108 static void DecoderMetadataCallback( const FLAC__StreamDecoder *decoder,
109                                      const FLAC__StreamMetadata *metadata,
110                                      void *client_data );
111 static void DecoderErrorCallback( const FLAC__StreamDecoder *decoder,
112                                   FLAC__StreamDecoderErrorStatus status,
113                                   void *client_data);
114
115 static void Interleave32( int32_t *p_out, const int32_t * const *pp_in,
116                           const int *pi_order, int i_nb_channels, int i_samples );
117 static void Interleave24( int8_t *p_out, const int32_t * const *pp_in,
118                           const int *pi_order, int i_nb_channels, int i_samples );
119 static void Interleave16( int16_t *p_out, const int32_t * const *pp_in,
120                           const int *pi_order, int i_nb_channels, int i_samples );
121
122 static void decoder_state_error( decoder_t *p_dec,
123                                  FLAC__StreamDecoderState state );
124
125 /*****************************************************************************
126  * Module descriptor
127  *****************************************************************************/
128 vlc_module_begin ()
129
130     set_category( CAT_INPUT )
131     set_subcategory( SUBCAT_INPUT_ACODEC )
132     add_shortcut( "flac" )
133
134     set_description( N_("Flac audio decoder") )
135     set_capability( "decoder", 100 )
136     set_callbacks( OpenDecoder, CloseDecoder )
137
138     add_submodule ()
139     add_shortcut( "flac" )
140     set_description( N_("Flac audio encoder") )
141     set_capability( "encoder", 100 )
142     set_callbacks( OpenEncoder, CloseEncoder )
143
144 vlc_module_end ()
145
146 /*****************************************************************************
147  * OpenDecoder: probe the decoder and return score
148  *****************************************************************************/
149 static int OpenDecoder( vlc_object_t *p_this )
150 {
151     decoder_t *p_dec = (decoder_t*)p_this;
152     decoder_sys_t *p_sys;
153
154     if( p_dec->fmt_in.i_codec != VLC_CODEC_FLAC )
155     {
156         return VLC_EGENERIC;
157     }
158
159     /* Allocate the memory needed to store the decoder's structure */
160     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
161         return VLC_ENOMEM;
162
163     /* Misc init */
164     p_sys->b_stream_info = false;
165     p_sys->p_block = NULL;
166
167     /* Take care of flac init */
168     if( !(p_sys->p_flac = FLAC__stream_decoder_new()) )
169     {
170         msg_Err( p_dec, "FLAC__stream_decoder_new() failed" );
171         free( p_sys );
172         return VLC_EGENERIC;
173     }
174
175 #ifdef USE_NEW_FLAC_API
176     if( FLAC__stream_decoder_init_stream( p_sys->p_flac,
177                                           DecoderReadCallback,
178                                           NULL,
179                                           NULL,
180                                           NULL,
181                                           NULL,
182                                           DecoderWriteCallback,
183                                           DecoderMetadataCallback,
184                                           DecoderErrorCallback,
185                                           p_dec )
186         != FLAC__STREAM_DECODER_INIT_STATUS_OK )
187     {
188         msg_Err( p_dec, "FLAC__stream_decoder_init_stream() failed" );
189         FLAC__stream_decoder_delete( p_sys->p_flac );
190         free( p_sys );
191         return VLC_EGENERIC;
192     }
193 #else
194     FLAC__stream_decoder_set_read_callback( p_sys->p_flac,
195                                             DecoderReadCallback );
196     FLAC__stream_decoder_set_write_callback( p_sys->p_flac,
197                                              DecoderWriteCallback );
198     FLAC__stream_decoder_set_metadata_callback( p_sys->p_flac,
199                                                 DecoderMetadataCallback );
200     FLAC__stream_decoder_set_error_callback( p_sys->p_flac,
201                                              DecoderErrorCallback );
202     FLAC__stream_decoder_set_client_data( p_sys->p_flac, p_dec );
203
204     FLAC__stream_decoder_init( p_sys->p_flac );
205 #endif
206
207     /* Set output properties */
208     p_dec->fmt_out.i_cat = AUDIO_ES;
209     p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
210
211     /* Set callbacks */
212     p_dec->pf_decode_audio = DecodeBlock;
213
214     /* */
215     p_dec->b_need_packetized = true;
216
217     return VLC_SUCCESS;
218 }
219
220 /*****************************************************************************
221  * CloseDecoder: flac decoder destruction
222  *****************************************************************************/
223 static void CloseDecoder( vlc_object_t *p_this )
224 {
225     decoder_t *p_dec = (decoder_t *)p_this;
226     decoder_sys_t *p_sys = p_dec->p_sys;
227
228     FLAC__stream_decoder_finish( p_sys->p_flac );
229     FLAC__stream_decoder_delete( p_sys->p_flac );
230
231     if( p_sys->p_block )
232         block_Release( p_sys->p_block );
233     free( p_sys );
234 }
235
236 /*****************************************************************************
237  * ProcessHeader: process Flac header.
238  *****************************************************************************/
239 static void ProcessHeader( decoder_t *p_dec )
240 {
241     decoder_sys_t *p_sys = p_dec->p_sys;
242
243     if( !p_dec->fmt_in.i_extra )
244         return;
245
246     /* Decode STREAMINFO */
247     msg_Dbg( p_dec, "decode STREAMINFO" );
248     p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra );
249     memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra,
250             p_dec->fmt_in.i_extra );
251     FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
252     msg_Dbg( p_dec, "STREAMINFO decoded" );
253 }
254
255 /****************************************************************************
256  * DecodeBlock: the whole thing
257  ****************************************************************************/
258 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
259 {
260     decoder_sys_t *p_sys = p_dec->p_sys;
261
262     if( !pp_block || !*pp_block )
263         return NULL;
264     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
265     {
266         block_Release( *pp_block );
267         return NULL;
268     }
269
270     if( !p_sys->b_stream_info )
271         ProcessHeader( p_dec );
272
273     p_sys->p_block = *pp_block;
274     *pp_block = NULL;
275
276     if( p_sys->p_block->i_pts > VLC_TS_INVALID &&
277         p_sys->p_block->i_pts != date_Get( &p_sys->end_date ) )
278         date_Set( &p_sys->end_date, p_sys->p_block->i_pts );
279
280     p_sys->p_aout_buffer = 0;
281
282     if( !FLAC__stream_decoder_process_single( p_sys->p_flac ) )
283     {
284         decoder_state_error( p_dec,
285                              FLAC__stream_decoder_get_state( p_sys->p_flac ) );
286         FLAC__stream_decoder_flush( p_dec->p_sys->p_flac );
287     }
288
289     /* If the decoder is in the "aborted" state,
290      * FLAC__stream_decoder_process_single() won't return an error. */
291     if( FLAC__stream_decoder_get_state(p_dec->p_sys->p_flac)
292         == FLAC__STREAM_DECODER_ABORTED )
293     {
294         FLAC__stream_decoder_flush( p_dec->p_sys->p_flac );
295     }
296
297     block_Release( p_sys->p_block );
298     p_sys->p_block = NULL;
299
300     return p_sys->p_aout_buffer;
301 }
302
303 /*****************************************************************************
304  * DecoderReadCallback: called by libflac when it needs more data
305  *****************************************************************************/
306 static FLAC__StreamDecoderReadStatus
307 DecoderReadCallback( const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
308                      unsigned *bytes, void *client_data )
309 {
310     VLC_UNUSED(decoder);
311     decoder_t *p_dec = (decoder_t *)client_data;
312     decoder_sys_t *p_sys = p_dec->p_sys;
313
314     if( p_sys->p_block && p_sys->p_block->i_buffer )
315     {
316         *bytes = __MIN(*bytes, (unsigned)p_sys->p_block->i_buffer);
317         memcpy( buffer, p_sys->p_block->p_buffer, *bytes );
318         p_sys->p_block->i_buffer -= *bytes;
319         p_sys->p_block->p_buffer += *bytes;
320     }
321     else
322     {
323         *bytes = 0;
324         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
325     }
326
327     return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
328 }
329
330 /*****************************************************************************
331  * DecoderWriteCallback: called by libflac to output decoded samples
332  *****************************************************************************/
333 static FLAC__StreamDecoderWriteStatus
334 DecoderWriteCallback( const FLAC__StreamDecoder *decoder,
335                       const FLAC__Frame *frame,
336                       const FLAC__int32 *const buffer[], void *client_data )
337 {
338     /* XXX it supposes our internal format is WG4 */
339     static const int ppi_reorder[1+8][8] = {
340         {-1},
341         { 0, },
342         { 0, 1 },
343         { 0, 1, 2 },
344         { 0, 1, 2, 3 },
345         { 0, 1, 3, 4, 2 },
346         { 0, 1, 4, 5, 2, 3 },
347
348         { 0, 1, 6, 4, 5, 2, 3 },    /* 7.0 Unspecified by flac, but following SMPTE */
349         { 0, 1, 6, 7, 4, 5, 2, 3 }, /* 7.1 Unspecified by flac, but following SMPTE */
350     };
351
352     VLC_UNUSED(decoder);
353     decoder_t *p_dec = (decoder_t *)client_data;
354     decoder_sys_t *p_sys = p_dec->p_sys;
355
356     if( p_dec->fmt_out.audio.i_channels <= 0 ||
357         p_dec->fmt_out.audio.i_channels > 8 )
358         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
359     if( date_Get( &p_sys->end_date ) <= VLC_TS_INVALID )
360         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
361
362     const int * const pi_reorder = ppi_reorder[p_dec->fmt_out.audio.i_channels];
363
364     p_sys->p_aout_buffer =
365         decoder_NewAudioBuffer( p_dec, frame->header.blocksize );
366
367     if( p_sys->p_aout_buffer == NULL )
368         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
369
370     switch( frame->header.bits_per_sample )
371     {
372     case 16:
373         Interleave16( (int16_t *)p_sys->p_aout_buffer->p_buffer, buffer, pi_reorder,
374                       frame->header.channels, frame->header.blocksize );
375         break;
376     case 24:
377         Interleave24( (int8_t *)p_sys->p_aout_buffer->p_buffer, buffer, pi_reorder,
378                       frame->header.channels, frame->header.blocksize );
379         break;
380     default:
381         Interleave32( (int32_t *)p_sys->p_aout_buffer->p_buffer, buffer, pi_reorder,
382                       frame->header.channels, frame->header.blocksize );
383     }
384
385     /* Date management (already done by packetizer) */
386     p_sys->p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
387     p_sys->p_aout_buffer->i_length =
388         date_Increment( &p_sys->end_date, frame->header.blocksize ) -
389         p_sys->p_aout_buffer->i_pts;
390
391     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
392 }
393
394 /*****************************************************************************
395  * DecoderMetadataCallback: called by libflac to when it encounters metadata
396  *****************************************************************************/
397 static void DecoderMetadataCallback( const FLAC__StreamDecoder *decoder,
398                                      const FLAC__StreamMetadata *metadata,
399                                      void *client_data )
400 {
401     VLC_UNUSED(decoder);
402     decoder_t *p_dec = (decoder_t *)client_data;
403     decoder_sys_t *p_sys = p_dec->p_sys;
404
405     if( p_dec->pf_decode_audio )
406     {
407         switch( metadata->data.stream_info.bits_per_sample )
408         {
409         case 8:
410             p_dec->fmt_out.i_codec = VLC_CODEC_S8;
411             break;
412         case 16:
413             p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
414             break;
415         case 24:
416             p_dec->fmt_out.i_codec = VLC_CODEC_S24N;
417             break;
418         default:
419             msg_Dbg( p_dec, "strange bit/sample value: %d",
420                      metadata->data.stream_info.bits_per_sample );
421             p_dec->fmt_out.i_codec = VLC_CODEC_FI32;
422             break;
423         }
424     }
425
426     /* Setup the format */
427     p_dec->fmt_out.audio.i_rate     = metadata->data.stream_info.sample_rate;
428     p_dec->fmt_out.audio.i_channels = metadata->data.stream_info.channels;
429     p_dec->fmt_out.audio.i_physical_channels =
430         p_dec->fmt_out.audio.i_original_channels =
431             pi_channels_maps[metadata->data.stream_info.channels];
432     p_dec->fmt_out.audio.i_bitspersample =
433         metadata->data.stream_info.bits_per_sample;
434
435     msg_Dbg( p_dec, "channels:%d samplerate:%d bitspersamples:%d",
436              p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_rate,
437              p_dec->fmt_out.audio.i_bitspersample );
438
439     p_sys->b_stream_info = true;
440     p_sys->stream_info = metadata->data.stream_info;
441
442     date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
443     date_Set( &p_sys->end_date, VLC_TS_INVALID );
444 }
445
446 /*****************************************************************************
447  * DecoderErrorCallback: called when the libflac decoder encounters an error
448  *****************************************************************************/
449 static void DecoderErrorCallback( const FLAC__StreamDecoder *decoder,
450                                   FLAC__StreamDecoderErrorStatus status,
451                                   void *client_data )
452 {
453     VLC_UNUSED(decoder);
454     decoder_t *p_dec = (decoder_t *)client_data;
455
456     switch( status )
457     {
458     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
459         msg_Warn( p_dec, "an error in the stream caused the decoder to "
460                  "lose synchronization." );
461         break;
462     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
463         msg_Err( p_dec, "the decoder encountered a corrupted frame header." );
464         break;
465     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
466         msg_Err( p_dec, "frame's data did not match the CRC in the "
467                  "footer." );
468         break;
469     default:
470         msg_Err( p_dec, "got decoder error: %d", status );
471     }
472
473     FLAC__stream_decoder_flush( p_dec->p_sys->p_flac );
474     return;
475 }
476
477 /*****************************************************************************
478  * Interleave: helper function to interleave channels
479  *****************************************************************************/
480 static void Interleave32( int32_t *p_out, const int32_t * const *pp_in,
481                           const int pi_index[],
482                           int i_nb_channels, int i_samples )
483 {
484     int i, j;
485     for ( j = 0; j < i_samples; j++ )
486     {
487         for ( i = 0; i < i_nb_channels; i++ )
488         {
489             p_out[j * i_nb_channels + i] = pp_in[pi_index[i]][j];
490         }
491     }
492 }
493
494 static void Interleave24( int8_t *p_out, const int32_t * const *pp_in,
495                           const int pi_index[],
496                           int i_nb_channels, int i_samples )
497 {
498     int i, j;
499     for ( j = 0; j < i_samples; j++ )
500     {
501         for ( i = 0; i < i_nb_channels; i++ )
502         {
503             const int i_index = pi_index[i];
504 #ifdef WORDS_BIGENDIAN
505             p_out[3*(j * i_nb_channels + i)+0] = (pp_in[i_index][j] >> 16) & 0xff;
506             p_out[3*(j * i_nb_channels + i)+1] = (pp_in[i_index][j] >> 8 ) & 0xff;
507             p_out[3*(j * i_nb_channels + i)+2] = (pp_in[i_index][j] >> 0 ) & 0xff;
508 #else
509             p_out[3*(j * i_nb_channels + i)+2] = (pp_in[i_index][j] >> 16) & 0xff;
510             p_out[3*(j * i_nb_channels + i)+1] = (pp_in[i_index][j] >> 8 ) & 0xff;
511             p_out[3*(j * i_nb_channels + i)+0] = (pp_in[i_index][j] >> 0 ) & 0xff;
512 #endif
513         }
514     }
515 }
516
517 static void Interleave16( int16_t *p_out, const int32_t * const *pp_in,
518                           const int pi_index[],
519                           int i_nb_channels, int i_samples )
520 {
521     int i, j;
522     for ( j = 0; j < i_samples; j++ )
523     {
524         for ( i = 0; i < i_nb_channels; i++ )
525         {
526             p_out[j * i_nb_channels + i] = (int32_t)(pp_in[pi_index[i]][j]);
527         }
528     }
529 }
530
531 /*****************************************************************************
532  * decoder_state_error: print meaningful error messages
533  *****************************************************************************/
534 static void decoder_state_error( decoder_t *p_dec,
535                                  FLAC__StreamDecoderState state )
536 {
537     switch ( state )
538     {
539     case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
540         msg_Dbg( p_dec, "the decoder is ready to search for metadata." );
541         break;
542     case FLAC__STREAM_DECODER_READ_METADATA:
543         msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
544                  "reading metadata." );
545         break;
546     case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
547         msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
548                  "searching for the frame sync code." );
549         break;
550     case FLAC__STREAM_DECODER_READ_FRAME:
551         msg_Dbg( p_dec, "the decoder is ready to or is in the process of "
552                  "reading a frame." );
553         break;
554     case FLAC__STREAM_DECODER_END_OF_STREAM:
555         msg_Dbg( p_dec, "the decoder has reached the end of the stream." );
556         break;
557 #ifdef USE_NEW_FLAC_API
558     case FLAC__STREAM_DECODER_OGG_ERROR:
559         msg_Err( p_dec, "error occurred in the Ogg layer." );
560         break;
561     case FLAC__STREAM_DECODER_SEEK_ERROR:
562         msg_Err( p_dec, "error occurred while seeking." );
563         break;
564 #endif
565     case FLAC__STREAM_DECODER_ABORTED:
566         msg_Warn( p_dec, "the decoder was aborted by the read callback." );
567         break;
568 #ifndef USE_NEW_FLAC_API
569     case FLAC__STREAM_DECODER_UNPARSEABLE_STREAM:
570         msg_Warn( p_dec, "the decoder encountered reserved fields in use "
571                  "in the stream." );
572         break;
573 #endif
574     case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
575         msg_Err( p_dec, "error when allocating memory." );
576         break;
577 #ifndef USE_NEW_FLAC_API
578     case FLAC__STREAM_DECODER_ALREADY_INITIALIZED:
579         msg_Err( p_dec, "FLAC__stream_decoder_init() was called when the "
580                  "decoder was already initialized, usually because "
581                  "FLAC__stream_decoder_finish() was not called." );
582         break;
583     case FLAC__STREAM_DECODER_INVALID_CALLBACK:
584         msg_Err( p_dec, "FLAC__stream_decoder_init() was called without "
585                  "all callbacks being set." );
586         break;
587 #endif
588     case FLAC__STREAM_DECODER_UNINITIALIZED:
589         msg_Err( p_dec, "decoder in uninitialized state." );
590         break;
591     default:
592         msg_Warn(p_dec, "unknown error" );
593     }
594 }
595
596 /*****************************************************************************
597  * encoder_sys_t : flac encoder descriptor
598  *****************************************************************************/
599 struct encoder_sys_t
600 {
601     /*
602      * Input properties
603      */
604     int i_headers;
605
606     int i_samples_delay;
607     int i_channels;
608
609     FLAC__int32 *p_buffer;
610     unsigned int i_buffer;
611
612     block_t *p_chain;
613
614     /*
615      * FLAC properties
616      */
617     FLAC__StreamEncoder *p_flac;
618     FLAC__StreamMetadata_StreamInfo stream_info;
619
620     /*
621      * Common properties
622      */
623     mtime_t i_pts;
624 };
625
626 #define STREAMINFO_SIZE 38
627
628 static block_t *Encode( encoder_t *, aout_buffer_t * );
629
630 static FLAC__StreamEncoderWriteStatus
631 EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
632                       const FLAC__byte buffer[],
633                       unsigned bytes, unsigned samples,
634                       unsigned current_frame, void *client_data );
635
636 static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder,
637                                      const FLAC__StreamMetadata *metadata,
638                                      void *client_data );
639
640 /*****************************************************************************
641  * OpenEncoder: probe the encoder and return score
642  *****************************************************************************/
643 static int OpenEncoder( vlc_object_t *p_this )
644 {
645     encoder_t *p_enc = (encoder_t *)p_this;
646     encoder_sys_t *p_sys;
647
648     if( p_enc->fmt_out.i_codec != VLC_CODEC_FLAC &&
649         !p_enc->b_force )
650     {
651         return VLC_EGENERIC;
652     }
653
654     /* Allocate the memory needed to store the decoder's structure */
655     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
656         return VLC_ENOMEM;
657     p_enc->p_sys = p_sys;
658     p_enc->pf_encode_audio = Encode;
659     p_enc->fmt_out.i_codec = VLC_CODEC_FLAC;
660
661     p_sys->i_headers = 0;
662     p_sys->p_buffer = 0;
663     p_sys->i_buffer = 0;
664     p_sys->i_samples_delay = 0;
665
666     /* Create flac encoder */
667     if( !(p_sys->p_flac = FLAC__stream_encoder_new()) )
668     {
669         msg_Err( p_enc, "FLAC__stream_encoder_new() failed" );
670         free( p_sys );
671         return VLC_EGENERIC;
672     }
673
674     FLAC__stream_encoder_set_streamable_subset( p_sys->p_flac, 1 );
675     FLAC__stream_encoder_set_channels( p_sys->p_flac,
676                                        p_enc->fmt_in.audio.i_channels );
677     FLAC__stream_encoder_set_sample_rate( p_sys->p_flac,
678                                           p_enc->fmt_in.audio.i_rate );
679     FLAC__stream_encoder_set_bits_per_sample( p_sys->p_flac, 16 );
680     p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
681
682     /* Get and store the STREAMINFO metadata block as a p_extra */
683     p_sys->p_chain = 0;
684
685 #ifdef USE_NEW_FLAC_API
686     if( FLAC__stream_encoder_init_stream( p_sys->p_flac,
687                                           EncoderWriteCallback,
688                                           NULL,
689                                           NULL,
690                                           EncoderMetadataCallback,
691                                           p_enc )
692         != FLAC__STREAM_ENCODER_INIT_STATUS_OK )
693     {
694         msg_Err( p_enc, "FLAC__stream_encoder_init_stream() failed" );
695         FLAC__stream_encoder_delete( p_sys->p_flac );
696         free( p_sys );
697         return VLC_EGENERIC;
698     }
699 #else
700     FLAC__stream_encoder_set_write_callback( p_sys->p_flac,
701         EncoderWriteCallback );
702     FLAC__stream_encoder_set_metadata_callback( p_sys->p_flac,
703         EncoderMetadataCallback );
704     FLAC__stream_encoder_set_client_data( p_sys->p_flac, p_enc );
705
706     FLAC__stream_encoder_init( p_sys->p_flac );
707 #endif
708
709     return VLC_SUCCESS;
710 }
711
712 /****************************************************************************
713  * Encode: the whole thing
714  ****************************************************************************
715  * This function spits out ogg packets.
716  ****************************************************************************/
717 static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
718 {
719     encoder_sys_t *p_sys = p_enc->p_sys;
720     block_t *p_chain;
721     unsigned int i;
722
723     p_sys->i_pts = p_aout_buf->i_pts -
724                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
725                 (mtime_t)p_enc->fmt_in.audio.i_rate;
726
727     p_sys->i_samples_delay += p_aout_buf->i_nb_samples;
728
729     /* Convert samples to FLAC__int32 */
730     if( p_sys->i_buffer < p_aout_buf->i_buffer * 2 )
731     {
732         p_sys->p_buffer =
733             xrealloc( p_sys->p_buffer, p_aout_buf->i_buffer * 2 );
734         p_sys->i_buffer = p_aout_buf->i_buffer * 2;
735     }
736
737     for( i = 0 ; i < p_aout_buf->i_buffer / 2 ; i++ )
738     {
739         p_sys->p_buffer[i]= ((int16_t *)p_aout_buf->p_buffer)[i];
740     }
741
742     FLAC__stream_encoder_process_interleaved( p_sys->p_flac, p_sys->p_buffer,
743                                               p_aout_buf->i_nb_samples );
744
745     p_chain = p_sys->p_chain;
746     p_sys->p_chain = 0;
747
748     return p_chain;
749 }
750
751 /*****************************************************************************
752  * CloseEncoder: encoder destruction
753  *****************************************************************************/
754 static void CloseEncoder( vlc_object_t *p_this )
755 {
756     encoder_t *p_enc = (encoder_t *)p_this;
757     encoder_sys_t *p_sys = p_enc->p_sys;
758
759     FLAC__stream_encoder_delete( p_sys->p_flac );
760
761     free( p_sys->p_buffer );
762     free( p_sys );
763 }
764
765 /*****************************************************************************
766  * EncoderMetadataCallback: called by libflac to output metadata
767  *****************************************************************************/
768 static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder,
769                                      const FLAC__StreamMetadata *metadata,
770                                      void *client_data )
771 {
772     VLC_UNUSED(encoder);
773     encoder_t *p_enc = (encoder_t *)client_data;
774
775     msg_Err( p_enc, "MetadataCallback: %i", metadata->type );
776     return;
777 }
778
779 /*****************************************************************************
780  * EncoderWriteCallback: called by libflac to output encoded samples
781  *****************************************************************************/
782 static FLAC__StreamEncoderWriteStatus
783 EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
784                       const FLAC__byte buffer[],
785                       unsigned bytes, unsigned samples,
786                       unsigned current_frame, void *client_data )
787 {
788     VLC_UNUSED(encoder); VLC_UNUSED(current_frame);
789     encoder_t *p_enc = (encoder_t *)client_data;
790     encoder_sys_t *p_sys = p_enc->p_sys;
791     block_t *p_block;
792
793     if( samples == 0 )
794     {
795         if( p_sys->i_headers == 1 )
796         {
797             msg_Dbg( p_enc, "Writing STREAMINFO: %i", bytes );
798
799             /* Backup the STREAMINFO metadata block */
800             p_enc->fmt_out.i_extra = STREAMINFO_SIZE + 4;
801             p_enc->fmt_out.p_extra = xmalloc( STREAMINFO_SIZE + 4 );
802             memcpy( p_enc->fmt_out.p_extra, "fLaC", 4 );
803             memcpy( ((uint8_t *)p_enc->fmt_out.p_extra) + 4, buffer,
804                     STREAMINFO_SIZE );
805
806             /* Fake this as the last metadata block */
807             ((uint8_t*)p_enc->fmt_out.p_extra)[4] |= 0x80;
808         }
809         p_sys->i_headers++;
810         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
811     }
812
813     p_block = block_New( p_enc, bytes );
814     memcpy( p_block->p_buffer, buffer, bytes );
815
816     p_block->i_dts = p_block->i_pts = p_sys->i_pts;
817
818     p_sys->i_samples_delay -= samples;
819
820     p_block->i_length = (mtime_t)1000000 *
821         (mtime_t)samples / (mtime_t)p_enc->fmt_in.audio.i_rate;
822
823     /* Update pts */
824     p_sys->i_pts += p_block->i_length;
825
826     block_ChainAppend( &p_sys->p_chain, p_block );
827
828     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
829 }
830