]> git.sesse.net Git - vlc/blob - modules/codec/a52/a52.c
Imported 0.4.4 Changelog.
[vlc] / modules / codec / a52 / a52.c
1 /*****************************************************************************
2  * a52.c: ATSC A/52 aka AC-3 decoder plugin for vlc.
3  *   This plugin makes use of liba52 to decode A/52 audio
4  *   (http://liba52.sf.net/).
5  *****************************************************************************
6  * Copyright (C) 2001, 2002 VideoLAN
7  * $Id: a52.c,v 1.2 2002/08/07 21:36:56 massiot Exp $
8  *
9  * Authors: Gildas Bazin <gbazin@netcourrier.com>
10  *          Christophe Massiot <massiot@via.ecp.fr>
11  *      
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include <vlc/vlc.h>
31 #include <vlc/aout.h>
32 #include <vlc/decoder.h>
33
34 #include <stdlib.h>                                      /* malloc(), free() */
35 #include <string.h>                                              /* strdup() */
36 #ifdef HAVE_STDINT_H
37 #   include <stdint.h>                                         /* int16_t .. */
38 #elif HAVE_INTTYPES_H
39 #   include <inttypes.h>                                       /* int16_t .. */
40 #endif
41
42 #ifdef USE_A52DEC_TREE                                 /* liba52 header file */
43 #   include "include/a52.h"
44 #else
45 #   include "a52dec/a52.h"
46 #endif
47
48 #include "a52.h"
49
50 #define A52DEC_FRAME_SIZE 1536 
51
52
53 /*****************************************************************************
54  * Local prototypes
55  *****************************************************************************/
56 static int  OpenDecoder    ( vlc_object_t * );
57 static int  RunDecoder     ( decoder_fifo_t * );
58 static int  DecodeFrame    ( a52_thread_t *, u8 * );
59 static int  InitThread     ( a52_thread_t *, decoder_fifo_t * );
60 static void EndThread      ( a52_thread_t * );
61
62 /*****************************************************************************
63  * Module descriptor
64  *****************************************************************************/
65 #define DYNRNG_TEXT N_("A/52 dynamic range compression")
66 #define DYNRNG_LONGTEXT N_( \
67     "Dynamic range compression makes the loud sounds softer, and the soft " \
68     "sounds louder, so you can more easily listen to the stream in a noisy " \
69     "environment without disturbing anyone. If you disable the dynamic range "\
70     "compression the playback will be more adapted to a movie theater or a " \
71     "listening room.")
72
73 vlc_module_begin();
74     add_category_hint( N_("Miscellaneous"), NULL );
75     add_bool( "a52-dynrng", 1, NULL, DYNRNG_TEXT, DYNRNG_LONGTEXT );
76     set_description( _("a52 ATSC A/52 aka AC-3 audio decoder module") );
77     set_capability( "decoder", 60 );
78     set_callbacks( OpenDecoder, NULL );
79 vlc_module_end();
80
81 /*****************************************************************************
82  * OpenDecoder: probe the decoder and return score
83  *****************************************************************************
84  * Tries to launch a decoder and return score so that the interface is able
85  * to choose.
86  *****************************************************************************/
87 static int OpenDecoder( vlc_object_t *p_this )
88 {
89     decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
90     
91     if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') )
92     {   
93         return VLC_EGENERIC;
94     }
95
96     p_fifo->pf_run = RunDecoder;
97     return VLC_SUCCESS;
98 }
99
100 /*****************************************************************************
101  * RunDecoder: this function is called just after the thread is created
102  *****************************************************************************/
103 static int RunDecoder( decoder_fifo_t *p_fifo )
104 {
105     a52_thread_t *p_a52;
106
107     /* Allocate the memory needed to store the thread's structure */
108     p_a52 = (a52_thread_t *)malloc( sizeof(a52_thread_t) );
109     if( p_a52 == NULL )
110     {
111         msg_Err( p_fifo, "out of memory" );
112         DecoderError( p_fifo );
113         return -1;
114     }
115
116     if( InitThread( p_a52, p_fifo ) )
117     {
118         msg_Err( p_a52->p_fifo, "could not initialize thread" );
119         DecoderError( p_fifo );
120         free( p_a52 );
121         return -1;
122     }
123
124     /* liba52 decoder thread's main loop */
125     while( !p_a52->p_fifo->b_die && !p_a52->p_fifo->b_error )
126     {
127         int i_frame_size, i_flags, i_rate, i_bit_rate;
128         mtime_t pts;
129         /* Temporary buffer to store the raw frame to be decoded */
130         u8  p_frame_buffer[3840];
131
132         /* Look for sync word - should be 0x0b77 */
133         RealignBits(&p_a52->bit_stream);
134         while( (ShowBits( &p_a52->bit_stream, 16 ) ) != 0x0b77 && 
135                (!p_a52->p_fifo->b_die) && (!p_a52->p_fifo->b_error))
136         {
137             RemoveBits( &p_a52->bit_stream, 8 );
138         }
139
140         /* Get A/52 frame header */
141         GetChunk( &p_a52->bit_stream, p_frame_buffer, 7 );
142         if( p_a52->p_fifo->b_die ) break;
143
144         /* Check if frame is valid and get frame info */
145         i_frame_size = a52_syncinfo( p_frame_buffer, &i_flags, &i_rate,
146                                      &i_bit_rate );
147
148         if( !i_frame_size )
149         {
150             msg_Warn( p_a52->p_fifo, "a52_syncinfo failed" );
151             continue;
152         }
153
154         if( (p_a52->p_aout_input != NULL) &&
155             ( (p_a52->output_format.i_rate != i_rate)
156                /* || (p_a52->output_format.i_channels != i_channels) */ ) )
157         {
158             /* Parameters changed - this should not happen. */
159             aout_InputDelete( p_a52->p_aout, p_a52->p_aout_input );
160             p_a52->p_aout_input = NULL;
161         }
162
163         /* Creating the audio input if not created yet. */
164         if( p_a52->p_aout_input == NULL )
165         {
166             p_a52->output_format.i_rate = i_rate;
167             /* p_a52->output_format.i_channels = i_channels; */
168             p_a52->p_aout_input = aout_InputNew( p_a52->p_fifo,
169                                                  &p_a52->p_aout,
170                                                  &p_a52->output_format );
171
172             if ( p_a52->p_aout_input == NULL )
173             {
174                 p_a52->p_fifo->b_error = 1;
175                 break;
176             }
177         }
178
179         /* Set the Presentation Time Stamp */
180         CurrentPTS( &p_a52->bit_stream, &pts, NULL );
181         if ( pts != 0 )
182         {
183             p_a52->last_date = pts;
184         }
185
186         /* Get the complete frame */
187         GetChunk( &p_a52->bit_stream, p_frame_buffer + 7,
188                   i_frame_size - 7 );
189         if( p_a52->p_fifo->b_die ) break;
190
191         if( DecodeFrame( p_a52, p_frame_buffer ) )
192         {
193             p_a52->p_fifo->b_error = 1;
194             break;
195         }
196     }
197
198     /* If b_error is set, the decoder thread enters the error loop */
199     if( p_a52->p_fifo->b_error )
200     {
201         DecoderError( p_a52->p_fifo );
202     }
203
204     /* End of the liba52 decoder thread */
205     EndThread( p_a52 );
206
207     return 0;
208 }
209
210 /*****************************************************************************
211  * InitThread: initialize data before entering main loop
212  *****************************************************************************/
213 static int InitThread( a52_thread_t * p_a52, decoder_fifo_t * p_fifo )
214 {
215     /* Initialize the thread properties */
216     p_a52->p_aout = NULL;
217     p_a52->p_aout_input = NULL;
218     p_a52->p_fifo = p_fifo;
219     p_a52->output_format.i_format = AOUT_FMT_FLOAT32;
220     p_a52->output_format.i_channels = 2; /* FIXME ! */
221     p_a52->last_date = 0;
222
223     /* Initialize liba52 */
224     p_a52->p_a52_state = a52_init( 0 );
225     if( p_a52->p_a52_state == NULL )
226     {
227         msg_Err( p_a52->p_fifo, "unable to initialize liba52" );
228         return -1;
229     }
230
231     p_a52->b_dynrng = config_GetInt( p_a52->p_fifo, "a52-dynrng" );
232
233     /* Init the BitStream */
234     InitBitstream( &p_a52->bit_stream, p_a52->p_fifo,
235                    NULL, NULL );
236
237     return 0;
238 }
239
240 /*****************************************************************************
241  * Interleave: helper function to interleave channels
242  *****************************************************************************/
243 static void Interleave( float * p_out, float * p_in, int i_channels )
244 {
245     int i, j;
246
247     for ( j = 0; j < i_channels; j++ )
248     {
249         for ( i = 0; i < 256; i++ )
250         {
251             p_out[i * i_channels + j] = p_in[j * 256 + i];
252         }
253     }
254 }
255
256 /*****************************************************************************
257  * DecodeFrame: decode an ATSC A/52 frame.
258  *****************************************************************************/
259 static int DecodeFrame( a52_thread_t * p_a52, u8 * p_frame_buffer )
260 {
261     sample_t        i_sample_level = 1;
262     aout_buffer_t * p_buffer;
263     int             i, i_flags;
264     int             i_bytes_per_block = 256 * p_a52->output_format.i_channels
265                       * sizeof(float);
266
267     if( !p_a52->last_date )
268     {
269         /* We've just started the stream, wait for the first PTS. */
270         return 0;
271     }
272
273     p_buffer = aout_BufferNew( p_a52->p_aout, p_a52->p_aout_input,
274                                A52DEC_FRAME_SIZE );
275     if ( p_buffer == NULL ) return -1;
276     p_buffer->start_date = p_a52->last_date;
277     p_a52->last_date += (mtime_t)(A52DEC_FRAME_SIZE * 1000000)
278                           / p_a52->output_format.i_rate;
279     p_buffer->end_date = p_a52->last_date;
280
281     /* FIXME */
282     i_flags = A52_STEREO | A52_ADJUST_LEVEL;
283
284     /* Do the actual decoding now */
285     a52_frame( p_a52->p_a52_state, p_frame_buffer,
286                &i_flags, &i_sample_level, 0 );
287
288     if( !p_a52->b_dynrng )
289     {
290         a52_dynrng( p_a52->p_a52_state, NULL, NULL );
291     }
292
293     for ( i = 0; i < 6; i++ )
294     {
295         sample_t * p_samples;
296
297         if( a52_block( p_a52->p_a52_state ) )
298         {
299             msg_Warn( p_a52->p_fifo, "a52_block failed for block %i", i );
300         }
301
302         p_samples = a52_samples( p_a52->p_a52_state );
303
304         /* Interleave the *$£%ù samples */
305         Interleave( (float *)(p_buffer->p_buffer + i * i_bytes_per_block),
306                     p_samples, p_a52->output_format.i_channels );
307     }
308
309     aout_BufferPlay( p_a52->p_aout, p_a52->p_aout_input, p_buffer );
310
311     return 0;
312 }
313
314 /*****************************************************************************
315  * EndThread : liba52 decoder thread destruction
316  *****************************************************************************/
317 static void EndThread (a52_thread_t *p_a52)
318 {
319     if ( p_a52->p_aout_input != NULL )
320     {
321         aout_InputDelete( p_a52->p_aout, p_a52->p_aout_input );
322     }
323
324     a52_free( p_a52->p_a52_state );
325     free( p_a52 );
326 }
327