1 /*****************************************************************************
2 * ac3_decoder.c: ac3 decoder thread
4 *****************************************************************************/
9 * - vérifier l'état de la fifo de sortie avant d'y stocker les samples
11 * - vlc_cond_signal() / vlc_cond_wait()
15 /*****************************************************************************
17 *****************************************************************************/
18 #include <sys/types.h>
22 #include <unistd.h> /* getpid() */
24 #include <stdio.h> /* "intf_msg.h" */
25 #include <stdlib.h> /* malloc(), free() */
26 #include <sys/soundcard.h> /* "audio_output.h" */
27 #include <sys/uio.h> /* "input.h" */
32 #include "vlc_thread.h"
33 #include "debug.h" /* "input_netlist.h" */
35 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
37 #include "input.h" /* pes_packet_t */
38 #include "input_netlist.h" /* input_NetlistFreePES() */
39 #include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
41 #include "audio_output.h"
43 #include "ac3_decoder.h"
44 #include "ac3_parse.h"
45 #include "ac3_exponent.h"
46 #include "ac3_bit_allocate.h"
47 #include "ac3_mantissa.h"
48 #include "ac3_rematrix.h"
49 #include "ac3_imdct.h"
50 #include "ac3_downmix.h"
52 /*****************************************************************************
54 *****************************************************************************/
55 static int InitThread ( ac3dec_thread_t * p_adec );
56 static void RunThread ( ac3dec_thread_t * p_adec );
57 static void ErrorThread ( ac3dec_thread_t * p_adec );
58 static void EndThread ( ac3dec_thread_t * p_adec );
60 /*****************************************************************************
61 * ac3dec_CreateThread: creates an ac3 decoder thread
62 *****************************************************************************/
63 ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
65 ac3dec_thread_t * p_ac3dec;
67 intf_DbgMsg("ac3dec debug: creating ac3 decoder thread\n");
69 /* Allocate the memory needed to store the thread's structure */
70 if ( (p_ac3dec = (ac3dec_thread_t *)malloc( sizeof(ac3dec_thread_t) )) == NULL )
72 intf_ErrMsg("ac3dec error: not enough memory for ac3dec_CreateThread() to create the new thread\n");
77 * Initialize the thread properties
80 p_ac3dec->b_error = 0;
83 * Initialize the input properties
85 /* Initialize the decoder fifo's data lock and conditional variable and set
86 * its buffer as empty */
87 vlc_mutex_init( &p_ac3dec->fifo.data_lock );
88 vlc_cond_init( &p_ac3dec->fifo.data_wait );
89 p_ac3dec->fifo.i_start = 0;
90 p_ac3dec->fifo.i_end = 0;
91 /* Initialize the bit stream structure */
92 p_ac3dec->bit_stream.p_input = p_input;
93 p_ac3dec->bit_stream.p_decoder_fifo = &p_ac3dec->fifo;
94 p_ac3dec->bit_stream.fifo.buffer = 0;
95 p_ac3dec->bit_stream.fifo.i_available = 0;
98 * Initialize the output properties
100 p_ac3dec->p_aout = p_input->p_aout;
101 p_ac3dec->p_aout_fifo = NULL;
105 /* Spawn the ac3 decoder thread */
106 if ( vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) )
108 intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread\n" );
113 intf_DbgMsg( "ac3dec debug: ac3 decoder thread (%p) created\n", p_ac3dec );
117 /*****************************************************************************
118 * ac3dec_DestroyThread: destroys an ac3 decoder thread
119 *****************************************************************************/
120 void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
122 intf_DbgMsg( "ac3dec debug: requesting termination of ac3 decoder thread %p\n", p_ac3dec );
124 /* Ask thread to kill itself */
127 /* Make sure the decoder thread leaves the GetByte() function */
128 vlc_mutex_lock( &(p_ac3dec->fifo.data_lock) );
129 vlc_cond_signal( &(p_ac3dec->fifo.data_wait) );
130 vlc_mutex_unlock( &(p_ac3dec->fifo.data_lock) );
132 /* Waiting for the decoder thread to exit */
133 /* Remove this as soon as the "status" flag is implemented */
134 vlc_thread_join( p_ac3dec->thread_id );
137 /* Following functions are local */
139 /*****************************************************************************
141 *****************************************************************************/
142 static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
144 while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
146 NeedBits( &(p_ac3dec->bit_stream), 16 );
147 if ( (p_ac3dec->bit_stream.fifo.buffer >> (32 - 16)) == 0x0b77 )
149 DumpBits( &(p_ac3dec->bit_stream), 16 );
150 p_ac3dec->total_bits_read = 16;
153 DumpBits( &(p_ac3dec->bit_stream), 1 ); /* XXX */
158 /*****************************************************************************
159 * InitThread : initialize an ac3 decoder thread
160 *****************************************************************************/
161 static int InitThread( ac3dec_thread_t * p_ac3dec )
163 aout_fifo_t aout_fifo;
165 intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec );
167 /* Our first job is to initialize the bit stream structure with the
168 * beginning of the input stream */
169 vlc_mutex_lock( &p_ac3dec->fifo.data_lock );
170 while ( DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) )
172 if ( p_ac3dec->b_die )
174 vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
177 vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
179 p_ac3dec->bit_stream.p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts;
180 p_ac3dec->bit_stream.i_byte = p_ac3dec->bit_stream.p_ts->i_payload_start;
181 vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
183 aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
184 aout_fifo.i_channels = 2;
185 aout_fifo.b_stereo = 1;
187 aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE;
189 /* Creating the audio output fifo */
190 if ( (p_ac3dec->p_aout_fifo = aout_CreateFifo(p_ac3dec->p_aout, &aout_fifo)) == NULL )
195 intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p initialized\n", p_ac3dec );
199 /*****************************************************************************
200 * RunThread : ac3 decoder thread
201 *****************************************************************************/
202 static void RunThread( ac3dec_thread_t * p_ac3dec )
204 intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
206 msleep( INPUT_PTS_DELAY );
208 /* Initializing the ac3 decoder thread */
209 if ( InitThread(p_ac3dec) ) /* XXX */
211 p_ac3dec->b_error = 1;
214 /* ac3 decoder thread's main loop */
215 /* FIXME : do we have enough room to store the decoded frames ? */
216 while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
218 p_ac3dec->b_invalid = 0;
220 decode_find_sync( p_ac3dec );
222 if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
224 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts;
225 DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts = 0;
229 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
232 parse_syncinfo( p_ac3dec );
233 switch ( p_ac3dec->syncinfo.fscod )
236 p_ac3dec->p_aout_fifo->l_rate = 48000;
240 p_ac3dec->p_aout_fifo->l_rate = 44100;
244 p_ac3dec->p_aout_fifo->l_rate = 32000;
248 fprintf( stderr, "ac3dec debug: invalid fscod\n" );
249 p_ac3dec->b_invalid = 1;
252 if ( p_ac3dec->b_invalid ) /* XXX */
257 parse_bsi( p_ac3dec );
260 parse_audblk( p_ac3dec );
261 exponent_unpack( p_ac3dec );
262 if ( p_ac3dec->b_invalid )
266 bit_allocate( p_ac3dec );
267 mantissa_unpack( p_ac3dec );
268 if ( p_ac3dec->b_invalid )
272 if ( p_ac3dec->bsi.acmod == 0x2 )
274 rematrix( p_ac3dec );
277 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
278 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
279 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
280 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
281 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
284 parse_audblk( p_ac3dec );
285 exponent_unpack( p_ac3dec );
286 if ( p_ac3dec->b_invalid )
290 bit_allocate( p_ac3dec );
291 mantissa_unpack( p_ac3dec );
292 if ( p_ac3dec->b_invalid )
296 if ( p_ac3dec->bsi.acmod == 0x2 )
298 rematrix( p_ac3dec );
301 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
302 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
303 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
304 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
305 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
306 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
309 parse_audblk( p_ac3dec );
310 exponent_unpack( p_ac3dec );
311 if ( p_ac3dec->b_invalid )
315 bit_allocate( p_ac3dec );
316 mantissa_unpack( p_ac3dec );
317 if ( p_ac3dec->b_invalid )
321 if ( p_ac3dec->bsi.acmod == 0x2 )
323 rematrix( p_ac3dec );
326 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
327 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
328 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
329 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
330 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
331 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
334 parse_audblk( p_ac3dec );
335 exponent_unpack( p_ac3dec );
336 if ( p_ac3dec->b_invalid )
340 bit_allocate( p_ac3dec );
341 mantissa_unpack( p_ac3dec );
342 if ( p_ac3dec->b_invalid )
346 if ( p_ac3dec->bsi.acmod == 0x2 )
348 rematrix( p_ac3dec );
351 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
352 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
353 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
354 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
355 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
356 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
359 parse_audblk( p_ac3dec );
360 exponent_unpack( p_ac3dec );
361 if ( p_ac3dec->b_invalid )
365 bit_allocate( p_ac3dec );
366 mantissa_unpack( p_ac3dec );
367 if ( p_ac3dec->b_invalid )
371 if ( p_ac3dec->bsi.acmod == 0x2 )
373 rematrix( p_ac3dec );
376 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
377 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
378 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
379 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
380 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
381 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
384 parse_audblk( p_ac3dec );
385 exponent_unpack( p_ac3dec );
386 if ( p_ac3dec->b_invalid )
390 bit_allocate( p_ac3dec );
391 mantissa_unpack( p_ac3dec );
392 if ( p_ac3dec->b_invalid )
396 if ( p_ac3dec->bsi.acmod == 0x2 )
398 rematrix( p_ac3dec );
401 downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
402 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
403 vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
404 p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
405 vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
406 vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
408 parse_auxdata( p_ac3dec );
411 /* If b_error is set, the ac3 decoder thread enters the error loop */
412 if ( p_ac3dec->b_error )
414 ErrorThread( p_ac3dec );
417 /* End of the ac3 decoder thread */
418 EndThread( p_ac3dec );
421 /*****************************************************************************
422 * ErrorThread : ac3 decoder's RunThread() error loop
423 *****************************************************************************/
424 static void ErrorThread( ac3dec_thread_t * p_ac3dec )
426 /* We take the lock, because we are going to read/write the start/end
427 * indexes of the decoder fifo */
428 vlc_mutex_lock( &p_ac3dec->fifo.data_lock );
430 /* Wait until a `die' order is sent */
431 while( !p_ac3dec->b_die )
433 /* Trash all received PES packets */
434 while( !DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) )
436 input_NetlistFreePES( p_ac3dec->bit_stream.p_input, DECODER_FIFO_START(p_ac3dec->fifo) );
437 DECODER_FIFO_INCSTART( p_ac3dec->fifo );
440 /* Waiting for the input thread to put new PES packets in the fifo */
441 vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
444 /* We can release the lock before leaving */
445 vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
448 /*****************************************************************************
449 * EndThread : ac3 decoder thread destruction
450 *****************************************************************************/
451 static void EndThread( ac3dec_thread_t * p_ac3dec )
453 intf_DbgMsg( "ac3dec debug: destroying ac3 decoder thread %p\n", p_ac3dec );
455 /* If the audio output fifo was created, we destroy it */
456 if ( p_ac3dec->p_aout_fifo != NULL )
458 aout_DestroyFifo( p_ac3dec->p_aout_fifo );
460 /* Make sure the output thread leaves the NextFrame() function */
461 vlc_mutex_lock( &(p_ac3dec->p_aout_fifo->data_lock) );
462 vlc_cond_signal( &(p_ac3dec->p_aout_fifo->data_wait) );
463 vlc_mutex_unlock( &(p_ac3dec->p_aout_fifo->data_lock) );
466 /* Destroy descriptor */
469 intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p destroyed\n", p_ac3dec );