]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_decoder.c
o remise de b_stereo dans les structures audio en attendant que soit
[vlc] / src / ac3_decoder / ac3_decoder.c
1 /*****************************************************************************
2  * ac3_decoder.c: ac3 decoder thread
3  * (c)1999 VideoLAN
4  *****************************************************************************/
5
6 /*
7  * TODO :
8  *
9  * - vérifier l'état de la fifo de sortie avant d'y stocker les samples
10  *   décodés ;
11  * - vlc_cond_signal() / vlc_cond_wait()
12  *
13  */
14
15 /*****************************************************************************
16  * Preamble
17  *****************************************************************************/
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21
22 #include <unistd.h>                                              /* getpid() */
23
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" */
28
29 #include "common.h"
30 #include "config.h"
31 #include "mtime.h"
32 #include "vlc_thread.h"
33 #include "debug.h"                                      /* "input_netlist.h" */
34
35 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
36
37 #include "input.h"                                           /* pes_packet_t */
38 #include "input_netlist.h"                         /* input_NetlistFreePES() */
39 #include "decoder_fifo.h"         /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
40
41 #include "audio_output.h"
42
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"
51
52 /*****************************************************************************
53  * Local prototypes
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 );
59
60 /*****************************************************************************
61  * ac3dec_CreateThread: creates an ac3 decoder thread
62  *****************************************************************************/
63 ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
64 {
65     ac3dec_thread_t *   p_ac3dec;
66
67     intf_DbgMsg("ac3dec debug: creating ac3 decoder thread\n");
68
69     /* Allocate the memory needed to store the thread's structure */
70     if ( (p_ac3dec = (ac3dec_thread_t *)malloc( sizeof(ac3dec_thread_t) )) == NULL )
71     {
72         intf_ErrMsg("ac3dec error: not enough memory for ac3dec_CreateThread() to create the new thread\n");
73         return( NULL );
74     }
75
76     /*
77      * Initialize the thread properties
78      */
79     p_ac3dec->b_die = 0;
80     p_ac3dec->b_error = 0;
81
82     /*
83      * Initialize the input properties
84      */
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;
96
97     /*
98      * Initialize the output properties
99      */
100     p_ac3dec->p_aout = p_input->p_aout;
101     p_ac3dec->p_aout_fifo = NULL;
102
103     imdct_init();
104
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) )
107     {
108         intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread\n" );
109         free( p_ac3dec );
110         return( NULL );
111     }
112
113     intf_DbgMsg( "ac3dec debug: ac3 decoder thread (%p) created\n", p_ac3dec );
114     return( p_ac3dec );
115 }
116
117 /*****************************************************************************
118  * ac3dec_DestroyThread: destroys an ac3 decoder thread
119  *****************************************************************************/
120 void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
121 {
122     intf_DbgMsg( "ac3dec debug: requesting termination of ac3 decoder thread %p\n", p_ac3dec );
123
124     /* Ask thread to kill itself */
125     p_ac3dec->b_die = 1;
126
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) );
131
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 );
135 }
136
137 /* Following functions are local */
138
139 /*****************************************************************************
140  * decode_find_sync()
141  *****************************************************************************/
142 static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
143 {
144     while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
145     {
146         NeedBits( &(p_ac3dec->bit_stream), 16 );
147         if ( (p_ac3dec->bit_stream.fifo.buffer >> (32 - 16)) == 0x0b77 )
148         {
149             DumpBits( &(p_ac3dec->bit_stream), 16 );
150             p_ac3dec->total_bits_read = 16;
151             return( 0 );
152         }
153         DumpBits( &(p_ac3dec->bit_stream), 1 ); /* XXX */
154     }
155     return( -1 );
156 }
157
158 /*****************************************************************************
159  * InitThread : initialize an ac3 decoder thread
160  *****************************************************************************/
161 static int InitThread( ac3dec_thread_t * p_ac3dec )
162 {
163     aout_fifo_t         aout_fifo;
164
165     intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec );
166
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) )
171     {
172         if ( p_ac3dec->b_die )
173         {
174             vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
175             return( -1 );
176         }
177         vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
178     }
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 );
182
183     aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
184     aout_fifo.i_channels = 2;
185     aout_fifo.b_stereo = 1;
186
187     aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE;
188
189     /* Creating the audio output fifo */
190     if ( (p_ac3dec->p_aout_fifo = aout_CreateFifo(p_ac3dec->p_aout, &aout_fifo)) == NULL )
191     {
192         return( -1 );
193     }
194
195     intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p initialized\n", p_ac3dec );
196     return( 0 );
197 }
198
199 /*****************************************************************************
200  * RunThread : ac3 decoder thread
201  *****************************************************************************/
202 static void RunThread( ac3dec_thread_t * p_ac3dec )
203 {
204     intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
205
206     msleep( INPUT_PTS_DELAY );
207
208     /* Initializing the ac3 decoder thread */
209     if ( InitThread(p_ac3dec) ) /* XXX */
210     {
211         p_ac3dec->b_error = 1;
212     }
213
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) )
217     {
218         p_ac3dec->b_invalid = 0;
219
220         decode_find_sync( p_ac3dec );
221
222         if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
223         {
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;
226         }
227         else
228         {
229                 p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
230         }
231
232         parse_syncinfo( p_ac3dec );
233         switch ( p_ac3dec->syncinfo.fscod )
234         {
235                 case 0:
236                         p_ac3dec->p_aout_fifo->l_rate = 48000;
237                         break;
238
239                 case 1:
240                         p_ac3dec->p_aout_fifo->l_rate = 44100;
241                         break;
242
243                 case 2:
244                         p_ac3dec->p_aout_fifo->l_rate = 32000;
245                         break;
246
247                 default: /* XXX */
248                         fprintf( stderr, "ac3dec debug: invalid fscod\n" );
249                         p_ac3dec->b_invalid = 1;
250                         break;
251         }
252         if ( p_ac3dec->b_invalid ) /* XXX */
253         {
254                 continue;
255         }
256
257         parse_bsi( p_ac3dec );
258
259         /* frame 1 */
260         parse_audblk( p_ac3dec );
261         exponent_unpack( p_ac3dec );
262         if ( p_ac3dec->b_invalid )
263         {
264                 continue;
265         }
266         bit_allocate( p_ac3dec );
267         mantissa_unpack( p_ac3dec );
268         if ( p_ac3dec->b_invalid )
269         {
270                 continue;
271         }
272         if ( p_ac3dec->bsi.acmod == 0x2 )
273         {
274                 rematrix( p_ac3dec );
275         }
276         imdct( 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 );
282
283         /* frame 2 */
284         parse_audblk( p_ac3dec );
285         exponent_unpack( p_ac3dec );
286         if ( p_ac3dec->b_invalid )
287         {
288                 continue;
289         }
290         bit_allocate( p_ac3dec );
291         mantissa_unpack( p_ac3dec );
292         if ( p_ac3dec->b_invalid )
293         {
294                 continue;
295         }
296         if ( p_ac3dec->bsi.acmod == 0x2 )
297         {
298                 rematrix( p_ac3dec );
299         }
300         imdct( 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 );
307
308         /* frame 3 */
309         parse_audblk( p_ac3dec );
310         exponent_unpack( p_ac3dec );
311         if ( p_ac3dec->b_invalid )
312         {
313                 continue;
314         }
315         bit_allocate( p_ac3dec );
316         mantissa_unpack( p_ac3dec );
317         if ( p_ac3dec->b_invalid )
318         {
319                 continue;
320         }
321         if ( p_ac3dec->bsi.acmod == 0x2 )
322         {
323                 rematrix( p_ac3dec );
324         }
325         imdct( 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 );
332
333         /* frame 4 */
334         parse_audblk( p_ac3dec );
335         exponent_unpack( p_ac3dec );
336         if ( p_ac3dec->b_invalid )
337         {
338                 continue;
339         }
340         bit_allocate( p_ac3dec );
341         mantissa_unpack( p_ac3dec );
342         if ( p_ac3dec->b_invalid )
343         {
344                 continue;
345         }
346         if ( p_ac3dec->bsi.acmod == 0x2 )
347         {
348                 rematrix( p_ac3dec );
349         }
350         imdct( 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 );
357
358         /* frame 5 */
359         parse_audblk( p_ac3dec );
360         exponent_unpack( p_ac3dec );
361         if ( p_ac3dec->b_invalid )
362         {
363                 continue;
364         }
365         bit_allocate( p_ac3dec );
366         mantissa_unpack( p_ac3dec );
367         if ( p_ac3dec->b_invalid )
368         {
369                 continue;
370         }
371         if ( p_ac3dec->bsi.acmod == 0x2 )
372         {
373                 rematrix( p_ac3dec );
374         }
375         imdct( 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 );
382
383         /* frame 6 */
384         parse_audblk( p_ac3dec );
385         exponent_unpack( p_ac3dec );
386         if ( p_ac3dec->b_invalid )
387         {
388                 continue;
389         }
390         bit_allocate( p_ac3dec );
391         mantissa_unpack( p_ac3dec );
392         if ( p_ac3dec->b_invalid )
393         {
394                 continue;
395         }
396         if ( p_ac3dec->bsi.acmod == 0x2 )
397         {
398                 rematrix( p_ac3dec );
399         }
400         imdct( 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 );
407
408         parse_auxdata( p_ac3dec );
409     }
410
411     /* If b_error is set, the ac3 decoder thread enters the error loop */
412     if ( p_ac3dec->b_error )
413     {
414         ErrorThread( p_ac3dec );
415     }
416
417     /* End of the ac3 decoder thread */
418     EndThread( p_ac3dec );
419 }
420
421 /*****************************************************************************
422  * ErrorThread : ac3 decoder's RunThread() error loop
423  *****************************************************************************/
424 static void ErrorThread( ac3dec_thread_t * p_ac3dec )
425 {
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 );
429
430     /* Wait until a `die' order is sent */
431     while( !p_ac3dec->b_die )
432     {
433         /* Trash all received PES packets */
434         while( !DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) )
435         {
436             input_NetlistFreePES( p_ac3dec->bit_stream.p_input, DECODER_FIFO_START(p_ac3dec->fifo) );
437             DECODER_FIFO_INCSTART( p_ac3dec->fifo );
438         }
439
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 );
442     }
443
444     /* We can release the lock before leaving */
445     vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
446 }
447
448 /*****************************************************************************
449  * EndThread : ac3 decoder thread destruction
450  *****************************************************************************/
451 static void EndThread( ac3dec_thread_t * p_ac3dec )
452 {
453     intf_DbgMsg( "ac3dec debug: destroying ac3 decoder thread %p\n", p_ac3dec );
454
455     /* If the audio output fifo was created, we destroy it */
456     if ( p_ac3dec->p_aout_fifo != NULL )
457     {
458         aout_DestroyFifo( p_ac3dec->p_aout_fifo );
459
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) );
464     }
465
466     /* Destroy descriptor */
467     free( p_ac3dec );
468
469     intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p destroyed\n", p_ac3dec );
470 }