]> git.sesse.net Git - vlc/blob - plugins/ac3_adec/ac3_adec.c
* ALL: the first libvlc commit.
[vlc] / plugins / ac3_adec / ac3_adec.c
1 /*****************************************************************************
2  * ac3_adec.c: ac3 decoder module main file
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: ac3_adec.c,v 1.32 2002/06/01 12:31:58 sam Exp $
6  *
7  * Authors: Michel Lespinasse <walken@zoy.org>
8  *
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <string.h>                                              /* memset() */
29
30 #include <vlc/vlc.h>
31 #include <vlc/aout.h>
32 #include <vlc/decoder.h>
33
34 #ifdef HAVE_UNISTD_H
35 #   include <unistd.h>                                           /* getpid() */
36 #endif
37
38 #include "ac3_imdct.h"
39 #include "ac3_downmix.h"
40 #include "ac3_adec.h"
41
42 #define AC3DEC_FRAME_SIZE (2*1536) 
43
44 /*****************************************************************************
45  * Local prototypes
46  *****************************************************************************/
47 static int  decoder_Probe     ( u8 * );
48 static int  decoder_Run       ( decoder_fifo_t * );
49 static int  InitThread        ( ac3dec_t * p_adec );
50 static void EndThread         ( ac3dec_t * p_adec );
51 static void BitstreamCallback ( bit_stream_t *p_bit_stream,
52                                 vlc_bool_t b_new_pes );
53
54 /*****************************************************************************
55  * Capabilities
56  *****************************************************************************/
57 void _M( adec_getfunctions )( function_list_t * p_function_list )
58 {
59     p_function_list->functions.dec.pf_probe = decoder_Probe;
60     p_function_list->functions.dec.pf_run   = decoder_Run;
61 }
62
63 /*****************************************************************************
64  * Build configuration tree.
65  *****************************************************************************/
66 /* Variable containing the AC3 downmix method */
67 #define DOWNMIX_METHOD_VAR              "ac3-downmix"
68 /* Variable containing the AC3 IMDCT method */
69 #define IMDCT_METHOD_VAR                "ac3-imdct"
70
71 MODULE_CONFIG_START
72 ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL)
73 ADD_MODULE  ( DOWNMIX_METHOD_VAR, MODULE_CAPABILITY_DOWNMIX, NULL, NULL,
74               N_("AC3 downmix module"), NULL )
75 ADD_MODULE  ( IMDCT_METHOD_VAR, MODULE_CAPABILITY_IMDCT, NULL, NULL,
76               N_("AC3 IMDCT module"), NULL )
77 MODULE_CONFIG_STOP
78
79 MODULE_INIT_START
80     SET_DESCRIPTION( _("software AC3 decoder") )
81     ADD_CAPABILITY( DECODER, 50 )
82     ADD_SHORTCUT( "ac3" )
83 MODULE_INIT_STOP
84
85 MODULE_ACTIVATE_START
86     _M( adec_getfunctions )( &p_module->p_functions->dec );
87 MODULE_ACTIVATE_STOP
88
89 MODULE_DEACTIVATE_START
90 MODULE_DEACTIVATE_STOP
91
92
93 /*****************************************************************************
94  * decoder_Probe: probe the decoder and return score
95  *****************************************************************************
96  * Tries to launch a decoder and return score so that the interface is able 
97  * to chose.
98  *****************************************************************************/
99 static int decoder_Probe( u8 *pi_type )
100 {
101     return ( *pi_type == AC3_AUDIO_ES ) ? 0 : -1;
102 }
103
104 /*****************************************************************************
105  * decoder_Run: this function is called just after the thread is created
106  *****************************************************************************/
107 static int decoder_Run ( decoder_fifo_t * p_fifo )
108 {
109     ac3dec_t *   p_ac3dec;
110     void *       p_orig;                          /* pointer before memalign */
111     vlc_bool_t   b_sync = 0;
112
113     /* Allocate the memory needed to store the thread's structure */
114     p_ac3dec = (ac3dec_t *)vlc_memalign( &p_orig, 16, sizeof(ac3dec_t) );
115     memset( p_ac3dec, 0, sizeof( ac3dec_t ) );
116
117     if( p_ac3dec == NULL )
118     {
119         msg_Err( p_fifo, "out of memory" );
120         DecoderError( p_fifo );
121         return( -1 );
122     }
123
124     /*
125      * Initialize the thread properties
126      */
127     p_ac3dec->p_fifo = p_fifo;
128     if( InitThread( p_ac3dec ) )
129     {
130         msg_Err( p_fifo, "could not initialize thread" );
131         DecoderError( p_fifo );
132         free( p_orig );
133         return( -1 );
134     }
135
136     /* ac3 decoder thread's main loop */
137     /* FIXME : do we have enough room to store the decoded frames ?? */
138     while ((!p_ac3dec->p_fifo->b_die) && (!p_ac3dec->p_fifo->b_error))
139     {
140         s16 * buffer;
141         ac3_sync_info_t sync_info;
142
143         if( !b_sync )
144         {
145              int i_sync_ptr;
146 #define p_bit_stream (&p_ac3dec->bit_stream)
147
148              /* Go to the next PES packet and jump to sync_ptr */
149              do {
150                 BitstreamNextDataPacket( p_bit_stream );
151              } while( !p_bit_stream->p_decoder_fifo->b_die
152                        && !p_bit_stream->p_decoder_fifo->b_error
153                        && p_bit_stream->p_data !=
154                           p_bit_stream->p_decoder_fifo->p_first->p_first );
155              i_sync_ptr = *(p_bit_stream->p_byte - 2) << 8
156                             | *(p_bit_stream->p_byte - 1);
157              p_bit_stream->p_byte += i_sync_ptr;
158
159              /* Empty the bit FIFO and realign the bit stream */
160              p_bit_stream->fifo.buffer = 0;
161              p_bit_stream->fifo.i_available = 0;
162              AlignWord( p_bit_stream );
163              b_sync = 1;
164 #undef p_bit_stream
165         }
166
167         if (ac3_sync_frame (p_ac3dec, &sync_info))
168         {
169             b_sync = 0;
170             continue;
171         }
172
173         if( ( p_ac3dec->p_aout_fifo != NULL ) &&
174             ( p_ac3dec->p_aout_fifo->i_rate != sync_info.sample_rate ) )
175         {
176             /* Make sure the output thread leaves the NextFrame() function */
177             vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock));
178             aout_DestroyFifo (p_ac3dec->p_aout_fifo);
179             vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait));
180             vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock));
181
182             p_ac3dec->p_aout_fifo = NULL;
183         }
184
185         /* Creating the audio output fifo if not created yet */
186         if (p_ac3dec->p_aout_fifo == NULL ) {
187             p_ac3dec->p_aout_fifo =
188                 aout_CreateFifo( p_ac3dec->p_fifo->p_this, AOUT_FIFO_PCM, 2,
189                          sync_info.sample_rate, AC3DEC_FRAME_SIZE, NULL  );
190             if ( p_ac3dec->p_aout_fifo == NULL )
191             {
192                 p_ac3dec->p_fifo->b_error = 1;
193                 break;
194             }
195         }
196
197         CurrentPTS( &p_ac3dec->bit_stream,
198             &p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->i_end_frame],
199             NULL );
200         if( !p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->i_end_frame] )
201         {
202             p_ac3dec->p_aout_fifo->date[
203                 p_ac3dec->p_aout_fifo->i_end_frame] =
204                 LAST_MDATE;
205         }
206     
207         buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) + 
208             (p_ac3dec->p_aout_fifo->i_end_frame * AC3DEC_FRAME_SIZE);
209
210         if (ac3_decode_frame (p_ac3dec, buffer))
211         {
212             b_sync = 0;
213             continue;
214         }
215         
216         vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock);
217         p_ac3dec->p_aout_fifo->i_end_frame = 
218             (p_ac3dec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
219         vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait);
220         vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock);
221
222         RealignBits(&p_ac3dec->bit_stream);
223     }
224
225     /* If b_error is set, the ac3 decoder thread enters the error loop */
226     if (p_ac3dec->p_fifo->b_error)
227     {
228         DecoderError( p_ac3dec->p_fifo );
229     }
230
231     /* End of the ac3 decoder thread */
232     EndThread (p_ac3dec);
233
234     free( p_orig );
235
236     return( 0 );
237 }
238
239 /*****************************************************************************
240  * InitThread: initialize data before entering main loop
241  *****************************************************************************/
242 static int InitThread( ac3dec_t * p_ac3dec )
243 {
244     char *psz_name;
245
246     /*
247      * Choose the best downmix module
248      */
249 #define DOWNMIX p_ac3dec->downmix
250     psz_name = config_GetPsz( p_ac3dec->p_fifo, DOWNMIX_METHOD_VAR );
251     DOWNMIX.p_module = module_Need( p_ac3dec->p_fifo,
252                                     MODULE_CAPABILITY_DOWNMIX, psz_name, NULL );
253     if( psz_name ) free( psz_name );
254
255     if( DOWNMIX.p_module == NULL )
256     {
257         msg_Err( p_ac3dec->p_fifo, "no suitable downmix module" );
258         return( -1 );
259     }
260
261 #define F DOWNMIX.p_module->p_functions->downmix.functions.downmix
262     DOWNMIX.pf_downmix_3f_2r_to_2ch     = F.pf_downmix_3f_2r_to_2ch;
263     DOWNMIX.pf_downmix_2f_2r_to_2ch     = F.pf_downmix_2f_2r_to_2ch;
264     DOWNMIX.pf_downmix_3f_1r_to_2ch     = F.pf_downmix_3f_1r_to_2ch;
265     DOWNMIX.pf_downmix_2f_1r_to_2ch     = F.pf_downmix_2f_1r_to_2ch;
266     DOWNMIX.pf_downmix_3f_0r_to_2ch     = F.pf_downmix_3f_0r_to_2ch;
267     DOWNMIX.pf_stream_sample_2ch_to_s16 = F.pf_stream_sample_2ch_to_s16;
268     DOWNMIX.pf_stream_sample_1ch_to_s16 = F.pf_stream_sample_1ch_to_s16;
269 #undef F
270 #undef DOWNMIX
271
272     /*
273      * Choose the best IMDCT module
274      */
275     p_ac3dec->imdct = vlc_memalign( &p_ac3dec->imdct_orig,
276                                     16, sizeof(imdct_t) );
277     
278 #define IMDCT p_ac3dec->imdct
279     psz_name = config_GetPsz( p_ac3dec->p_fifo, IMDCT_METHOD_VAR );
280     IMDCT->p_module = module_Need( p_ac3dec->p_fifo,
281                                    MODULE_CAPABILITY_IMDCT, psz_name, NULL );
282     if( psz_name ) free( psz_name );
283
284     if( IMDCT->p_module == NULL )
285     {
286         msg_Err( p_ac3dec->p_fifo, "no suitable IMDCT module" );
287         module_Unneed( p_ac3dec->downmix.p_module );
288         free( p_ac3dec->imdct_orig );
289         return( -1 );
290     }
291
292 #define F IMDCT->p_module->p_functions->imdct.functions.imdct
293     IMDCT->pf_imdct_init    = F.pf_imdct_init;
294     IMDCT->pf_imdct_256     = F.pf_imdct_256;
295     IMDCT->pf_imdct_256_nol = F.pf_imdct_256_nol;
296     IMDCT->pf_imdct_512     = F.pf_imdct_512;
297     IMDCT->pf_imdct_512_nol = F.pf_imdct_512_nol;
298 #undef F
299
300     /* Initialize the ac3 decoder structures */
301     p_ac3dec->samples = vlc_memalign( &p_ac3dec->samples_orig,
302                                       16, 6 * 256 * sizeof(float) );
303
304     IMDCT->buf    = vlc_memalign( &IMDCT->buf_orig,
305                                   16, N/4 * sizeof(complex_t) );
306     IMDCT->delay  = vlc_memalign( &IMDCT->delay_orig,
307                                   16, 6 * 256 * sizeof(float) );
308     IMDCT->delay1 = vlc_memalign( &IMDCT->delay1_orig,
309                                   16, 6 * 256 * sizeof(float) );
310     IMDCT->xcos1  = vlc_memalign( &IMDCT->xcos1_orig,
311                                   16, N/4 * sizeof(float) );
312     IMDCT->xsin1  = vlc_memalign( &IMDCT->xsin1_orig,
313                                   16, N/4 * sizeof(float) );
314     IMDCT->xcos2  = vlc_memalign( &IMDCT->xcos2_orig,
315                                   16, N/8 * sizeof(float) );
316     IMDCT->xsin2  = vlc_memalign( &IMDCT->xsin2_orig,
317                                   16, N/8 * sizeof(float) );
318     IMDCT->xcos_sin_sse = vlc_memalign( &IMDCT->xcos_sin_sse_orig,
319                                         16, 128 * 4 * sizeof(float) );
320     IMDCT->w_1    = vlc_memalign( &IMDCT->w_1_orig,
321                                   16, 1  * sizeof(complex_t) );
322     IMDCT->w_2    = vlc_memalign( &IMDCT->w_2_orig,
323                                   16, 2  * sizeof(complex_t) );
324     IMDCT->w_4    = vlc_memalign( &IMDCT->w_4_orig,
325                                   16, 4  * sizeof(complex_t) );
326     IMDCT->w_8    = vlc_memalign( &IMDCT->w_8_orig,
327                                   16, 8  * sizeof(complex_t) );
328     IMDCT->w_16   = vlc_memalign( &IMDCT->w_16_orig,
329                                   16, 16 * sizeof(complex_t) );
330     IMDCT->w_32   = vlc_memalign( &IMDCT->w_32_orig,
331                                   16, 32 * sizeof(complex_t) );
332     IMDCT->w_64   = vlc_memalign( &IMDCT->w_64_orig,
333                                   16, 64 * sizeof(complex_t) );
334 #undef IMDCT
335
336     _M( ac3_init )( p_ac3dec );
337
338     /*
339      * Initialize the output properties
340      */
341     p_ac3dec->p_aout_fifo = NULL;
342
343     /*
344      * Bit stream
345      */
346     InitBitstream( &p_ac3dec->bit_stream, p_ac3dec->p_fifo,
347                    BitstreamCallback, (void *) p_ac3dec );
348     
349     return( 0 );
350 }
351
352 /*****************************************************************************
353  * EndThread : ac3 decoder thread destruction
354  *****************************************************************************/
355 static void EndThread (ac3dec_t * p_ac3dec)
356 {
357     /* If the audio output fifo was created, we destroy it */
358     if (p_ac3dec->p_aout_fifo != NULL)
359     {
360         aout_DestroyFifo (p_ac3dec->p_aout_fifo);
361
362         /* Make sure the output thread leaves the NextFrame() function */
363         vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock));
364         vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait));
365         vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock));
366     }
367
368     /* Free allocated structures */
369 #define IMDCT p_ac3dec->imdct
370     free( IMDCT->w_1_orig );
371     free( IMDCT->w_64_orig );
372     free( IMDCT->w_32_orig );
373     free( IMDCT->w_16_orig );
374     free( IMDCT->w_8_orig );
375     free( IMDCT->w_4_orig );
376     free( IMDCT->w_2_orig );
377     free( IMDCT->xcos_sin_sse_orig );
378     free( IMDCT->xsin2_orig );
379     free( IMDCT->xcos2_orig );
380     free( IMDCT->xsin1_orig );
381     free( IMDCT->xcos1_orig );
382     free( IMDCT->delay1_orig );
383     free( IMDCT->delay_orig );
384     free( IMDCT->buf_orig );
385 #undef IMDCT
386
387     free( p_ac3dec->samples_orig );
388
389     /* Unlock the modules */
390     module_Unneed( p_ac3dec->downmix.p_module );
391     module_Unneed( p_ac3dec->imdct->p_module );
392
393     /* Free what's left of the decoder */
394     free( p_ac3dec->imdct_orig );
395 }
396
397 /*****************************************************************************
398  * BitstreamCallback: Import parameters from the new data/PES packet
399  *****************************************************************************
400  * This function is called by input's NextDataPacket.
401  *****************************************************************************/
402 static void BitstreamCallback ( bit_stream_t * p_bit_stream,
403                                 vlc_bool_t b_new_pes )
404 {
405     if( b_new_pes )
406     {
407         /* Drop special AC3 header */
408 /*        p_bit_stream->p_byte += 3; */
409     }
410 }
411