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.8 2002/08/30 22:22:24 massiot Exp $
9 * Authors: Gildas Bazin <gbazin@netcourrier.com>
10 * Christophe Massiot <massiot@via.ecp.fr>
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.
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.
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 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
32 #include <vlc/decoder.h>
34 #include <stdlib.h> /* malloc(), free() */
35 #include <string.h> /* strdup() */
37 # include <stdint.h> /* int16_t .. */
39 # include <inttypes.h> /* int16_t .. */
46 #ifdef USE_A52DEC_TREE /* liba52 header file */
47 # include "include/a52.h"
49 # include "a52dec/a52.h"
52 #define A52_FRAME_NB 1536
54 /*****************************************************************************
55 * a52_thread_t : a52 decoder thread descriptor
56 *****************************************************************************/
57 typedef struct a52_thread_s
62 a52_state_t * p_a52_state;
65 /* The bit stream structure handles the PES stream at the bit level */
66 bit_stream_t bit_stream;
71 decoder_fifo_t * p_fifo; /* stores the PES stream data */
72 data_packet_t * p_data;
77 aout_instance_t * p_aout; /* opaque */
78 aout_input_t * p_aout_input; /* opaque */
79 audio_sample_format_t output_format;
80 audio_date_t end_date;
83 /*****************************************************************************
85 *****************************************************************************/
86 static int OpenDecoder ( vlc_object_t * );
87 static int RunDecoder ( decoder_fifo_t * );
88 static int DecodeFrame ( a52_thread_t *, byte_t * );
89 static int InitThread ( a52_thread_t *, decoder_fifo_t * );
90 static void EndThread ( a52_thread_t * );
92 /*****************************************************************************
94 *****************************************************************************/
95 #define DYNRNG_TEXT N_("A/52 dynamic range compression")
96 #define DYNRNG_LONGTEXT N_( \
97 "Dynamic range compression makes the loud sounds softer, and the soft " \
98 "sounds louder, so you can more easily listen to the stream in a noisy " \
99 "environment without disturbing anyone. If you disable the dynamic range "\
100 "compression the playback will be more adapted to a movie theater or a " \
104 add_category_hint( N_("Miscellaneous"), NULL );
105 add_bool( "a52-dynrng", 1, NULL, DYNRNG_TEXT, DYNRNG_LONGTEXT );
106 set_description( _("a52 ATSC A/52 aka AC-3 audio decoder module") );
107 set_capability( "decoder", 60 );
108 set_callbacks( OpenDecoder, NULL );
111 /*****************************************************************************
112 * OpenDecoder: probe the decoder and return score
113 *****************************************************************************
114 * Tries to launch a decoder and return score so that the interface is able
116 *****************************************************************************/
117 static int OpenDecoder( vlc_object_t *p_this )
119 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
121 if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
122 && p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
127 p_fifo->pf_run = RunDecoder;
131 /*****************************************************************************
132 * RunDecoder: this function is called just after the thread is created
133 *****************************************************************************/
134 static int RunDecoder( decoder_fifo_t *p_fifo )
138 /* Allocate the memory needed to store the thread's structure */
139 p_dec = (a52_thread_t *)malloc( sizeof(a52_thread_t) );
142 msg_Err( p_fifo, "out of memory" );
143 DecoderError( p_fifo );
147 if( InitThread( p_dec, p_fifo ) )
149 msg_Err( p_dec->p_fifo, "could not initialize thread" );
150 DecoderError( p_fifo );
155 /* liba52 decoder thread's main loop */
156 while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
158 int i_frame_size, i_flags, i_rate, i_bit_rate;
160 /* Temporary buffer to store the raw frame to be decoded */
161 byte_t p_frame_buffer[3840];
163 /* Look for sync word - should be 0x0b77 */
164 RealignBits( &p_dec->bit_stream );
165 while( (ShowBits( &p_dec->bit_stream, 16 ) ) != 0x0b77 &&
166 (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error))
168 RemoveBits( &p_dec->bit_stream, 8 );
171 /* Set the Presentation Time Stamp */
172 NextPTS( &p_dec->bit_stream, &pts, NULL );
173 if ( pts != 0 && pts != aout_DateGet( &p_dec->end_date ) )
175 aout_DateSet( &p_dec->end_date, pts );
178 /* Get A/52 frame header */
179 GetChunk( &p_dec->bit_stream, p_frame_buffer, 7 );
180 if( p_dec->p_fifo->b_die ) break;
182 /* Check if frame is valid and get frame info */
183 i_frame_size = a52_syncinfo( p_frame_buffer, &i_flags, &i_rate,
188 msg_Warn( p_dec->p_fifo, "a52_syncinfo failed" );
192 if( (p_dec->p_aout_input != NULL) &&
193 ( (p_dec->output_format.i_rate != i_rate)
194 /* || (p_dec->output_format.i_channels != i_channels) */ ) )
196 /* Parameters changed - this should not happen. */
197 aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
198 p_dec->p_aout_input = NULL;
201 /* Creating the audio input if not created yet. */
202 if( p_dec->p_aout_input == NULL )
204 p_dec->output_format.i_rate = i_rate;
205 /* p_dec->output_format.i_channels = i_channels; */
206 aout_DateInit( &p_dec->end_date, i_rate );
207 p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
209 &p_dec->output_format );
211 if ( p_dec->p_aout_input == NULL )
213 p_dec->p_fifo->b_error = 1;
218 /* Get the complete frame */
219 GetChunk( &p_dec->bit_stream, p_frame_buffer + 7,
221 if( p_dec->p_fifo->b_die ) break;
223 if( DecodeFrame( p_dec, p_frame_buffer ) )
225 p_dec->p_fifo->b_error = 1;
230 /* If b_error is set, the decoder thread enters the error loop */
231 if( p_dec->p_fifo->b_error )
233 DecoderError( p_dec->p_fifo );
236 /* End of the a52 decoder thread */
242 /*****************************************************************************
243 * InitThread: initialize data before entering main loop
244 *****************************************************************************/
245 static int InitThread( a52_thread_t * p_dec, decoder_fifo_t * p_fifo )
247 /* Initialize the thread properties */
248 p_dec->p_aout = NULL;
249 p_dec->p_aout_input = NULL;
250 p_dec->p_fifo = p_fifo;
251 p_dec->output_format.i_format = AOUT_FMT_FLOAT32;
252 p_dec->output_format.i_channels = 2; /* FIXME ! */
254 /* Initialize liba52 */
255 p_dec->p_a52_state = a52_init( 0 );
256 if( p_dec->p_a52_state == NULL )
258 msg_Err( p_dec->p_fifo, "unable to initialize liba52" );
262 p_dec->b_dynrng = config_GetInt( p_dec->p_fifo, "a52-dynrng" );
264 /* Init the Bitstream */
265 InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
271 /*****************************************************************************
272 * Interleave: helper function to interleave channels
273 *****************************************************************************/
274 static void Interleave( float * p_out, const float * p_in, int i_channels )
278 for ( j = 0; j < i_channels; j++ )
280 for ( i = 0; i < 256; i++ )
282 p_out[i * i_channels + j] = p_in[j * 256 + i];
287 /*****************************************************************************
288 * DecodeFrame: decode an ATSC A/52 frame.
289 *****************************************************************************/
290 static int DecodeFrame( a52_thread_t * p_dec, byte_t * p_frame_buffer )
292 sample_t i_sample_level = 1;
293 aout_buffer_t * p_buffer;
295 int i_bytes_per_block = 256 * p_dec->output_format.i_channels
298 if( !aout_DateGet( &p_dec->end_date ) )
300 /* We've just started the stream, wait for the first PTS. */
304 p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input,
306 if ( p_buffer == NULL ) return -1;
307 p_buffer->start_date = aout_DateGet( &p_dec->end_date );
308 p_buffer->end_date = aout_DateIncrement( &p_dec->end_date,
312 i_flags = A52_STEREO | A52_ADJUST_LEVEL;
314 /* Do the actual decoding now */
315 a52_frame( p_dec->p_a52_state, p_frame_buffer,
316 &i_flags, &i_sample_level, 0 );
318 if( !p_dec->b_dynrng )
320 a52_dynrng( p_dec->p_a52_state, NULL, NULL );
323 for ( i = 0; i < 6; i++ )
325 sample_t * p_samples;
327 if( a52_block( p_dec->p_a52_state ) )
329 msg_Warn( p_dec->p_fifo, "a52_block failed for block %i", i );
332 p_samples = a52_samples( p_dec->p_a52_state );
334 /* Interleave the *$£%ù samples */
335 Interleave( (float *)(p_buffer->p_buffer + i * i_bytes_per_block),
336 p_samples, p_dec->output_format.i_channels );
339 aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
344 /*****************************************************************************
345 * EndThread : liba52 decoder thread destruction
346 *****************************************************************************/
347 static void EndThread( a52_thread_t * p_dec )
349 if ( p_dec->p_aout_input != NULL )
351 aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
354 a52_free( p_dec->p_a52_state );