]> git.sesse.net Git - vlc/blob - plugins/lpcm_adec/lpcm_adec.c
* Closing Debian bug #119369 which was fixed a while ago.
[vlc] / plugins / lpcm_adec / lpcm_adec.c
1 /*****************************************************************************
2  * lpcm_decoder_thread.c: lpcm decoder thread
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: lpcm_adec.c,v 1.1 2001/11/13 12:09:18 henri Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Henri Fallon <henri@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #define MODULE_NAME lpcm_adec
26 #include "modules_inner.h"
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include "defs.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>                                              /* getpid() */
35 #endif
36
37 #include <stdio.h>                                           /* "intf_msg.h" */
38 #include <string.h>                                    /* memcpy(), memset() */
39 #include <stdlib.h>                                      /* malloc(), free() */
40
41 #include "config.h"
42 #include "common.h"
43 #include "threads.h"
44 #include "mtime.h"
45 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
46
47 #include "audio_output.h"
48
49 #include "modules.h"
50 #include "modules_export.h"
51
52 #include "stream_control.h"
53 #include "input_ext-dec.h"
54
55 #include "lpcm_adec.h"
56
57 /*****************************************************************************
58  * Local prototypes
59  *****************************************************************************/
60 static int      lpcm_adec_Probe         ( probedata_t * );
61 static int      lpcm_adec_Run           ( decoder_config_t * );
62 void            lpcm_adec_DecodeFrame   ( lpcmdec_thread_t * );
63 static int      lpcm_adec_Init          ( lpcmdec_thread_t * );
64 static void     lpcm_adec_ErrorThread   ( lpcmdec_thread_t * );
65 static void     lpcm_adec_EndThread     ( lpcmdec_thread_t * );
66
67
68 /*****************************************************************************
69  * Capabilities
70  *****************************************************************************/
71 void _M( adec_getfunctions )( function_list_t * p_function_list )
72 {
73     p_function_list->pf_probe = lpcm_adec_Probe;
74     p_function_list->functions.dec.pf_RunThread = lpcm_adec_Run;
75 }
76
77 /*****************************************************************************
78  * Build configuration tree.
79  *****************************************************************************/
80 MODULE_CONFIG_START
81 ADD_WINDOW( "Configuration for lpcm audio decoder module" )
82     ADD_COMMENT( "Nothing to configure" )
83 MODULE_CONFIG_STOP
84
85 MODULE_INIT_START
86     p_module->i_capabilities = MODULE_CAPABILITY_DEC;
87     p_module->psz_longname = "Linear PCM audio decoder";
88 MODULE_INIT_STOP
89
90 MODULE_ACTIVATE_START
91     _M( adec_getfunctions )( &p_module->p_functions->dec );
92 MODULE_ACTIVATE_STOP
93
94 MODULE_DEACTIVATE_START
95 MODULE_DEACTIVATE_STOP
96
97 /*****************************************************************************
98  * lpcm_adec_Probe: probe the decoder and return score
99  *****************************************************************************/
100 static int lpcm_adec_Probe( probedata_t *p_data )
101 {
102     if( p_data->i_type == LPCM_AUDIO_ES )
103         return( 100 );
104     else
105         return( 0 );
106 }
107
108 /*****************************************************************************
109  * lpcm_adec_Run: the lpcm decoder
110  *****************************************************************************/
111 static int lpcm_adec_Run( decoder_config_t * p_config )
112 {
113     lpcmdec_thread_t *   p_lpcmdec;
114
115     intf_DbgMsg("lpcm_adec debug: thread launched, initializing.");
116     
117     /* Allocate the memory needed to store the thread's structure */
118     if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
119             == NULL) 
120     {
121         intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" );
122         return( -1 );
123     }
124
125     /*
126      * Initialize the thread properties
127      */
128     p_lpcmdec->p_config = p_config;
129     p_lpcmdec->p_fifo = p_config->p_decoder_fifo;
130
131     if( lpcm_adec_Init( p_lpcmdec ) )
132     {
133         return( -1 );
134     }
135
136     intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n", 
137                  p_lpcmdec );
138     
139     /* lpcm decoder thread's main loop */
140     while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
141     {
142         lpcm_adec_DecodeFrame(p_lpcmdec);
143     }
144
145     /* If b_error is set, the lpcm decoder thread enters the error loop */
146     if (p_lpcmdec->p_fifo->b_error)
147     {
148         lpcm_adec_ErrorThread (p_lpcmdec);
149     }
150
151     /* End of the lpcm decoder thread */
152     lpcm_adec_EndThread (p_lpcmdec);
153
154     return( 0 );
155 }
156
157 /*****************************************************************************
158  * lpcm_adec_Init : initialize an lpcm decoder thread
159  *****************************************************************************/
160 static int lpcm_adec_Init (lpcmdec_thread_t * p_lpcmdec)
161 {
162
163     /* Init the BitStream */
164     p_lpcmdec->p_config->pf_init_bit_stream(
165             &p_lpcmdec->bit_stream,
166             p_lpcmdec->p_config->p_decoder_fifo,
167             NULL, NULL);
168
169     /* Creating the audio output fifo */
170     p_lpcmdec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 48000,
171                                             0, LPCMDEC_FRAME_SIZE/2, NULL  );
172     if ( p_lpcmdec->p_aout_fifo == NULL )
173     {
174         return( -1 );
175     }
176     return( 0 );
177 }
178
179 /*****************************************************************************
180  * lpcm_adec_DecodeFrame: decodes a frame.
181  *****************************************************************************/
182 void lpcm_adec_DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
183 {
184     byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
185     int i_loop;
186     byte_t byte1, byte2;
187
188     if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
189     {
190         p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
191             DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
192         DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
193     }
194     else
195     { 
196         p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
197             LAST_MDATE;
198     }
199
200     buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) + 
201               (p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
202
203     RemoveBits32(&p_lpcmdec->bit_stream);
204     byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
205     byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
206     
207     /* I only have 2 test streams. As far as I understand
208      * after the RemoveBits and the 2 GetBits, we should be exactly 
209      * where we whant : the sync word : 0x0180.
210      * If not, we got and find it. */
211     while( ( byte1 != 0x01 || byte2 != 0x80 ) && (!p_lpcmdec->p_fifo->b_die)
212                                        && (!p_lpcmdec->p_fifo->b_error) )
213     {
214         byte1 = byte2;
215         byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
216     }
217     
218     GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
219     
220     for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
221     {
222         buffer[2*i_loop]=p_temp[2*i_loop+1];
223         buffer[2*i_loop+1]=p_temp[2*i_loop];
224     }
225     
226     vlc_mutex_lock (&p_lpcmdec->p_aout_fifo->data_lock);
227     p_lpcmdec->p_aout_fifo->l_end_frame = 
228         (p_lpcmdec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
229     vlc_cond_signal (&p_lpcmdec->p_aout_fifo->data_wait);
230     vlc_mutex_unlock (&p_lpcmdec->p_aout_fifo->data_lock);
231     
232     intf_DbgMsg( "LPCM Debug: %x", *buffer );
233
234 }
235
236
237 /*****************************************************************************
238  * lpcm_adec_ErrorThread : lpcm decoder's RunThread() error loop
239  *****************************************************************************/
240 static void lpcm_adec_ErrorThread( lpcmdec_thread_t * p_lpcmdec )
241 {
242     /* We take the lock, because we are going to read/write the start/end
243      * indexes of the decoder fifo */
244     vlc_mutex_lock( &p_lpcmdec->p_fifo->data_lock );
245
246     /* Wait until a `die' order is sent */
247     while( !p_lpcmdec->p_fifo->b_die ) 
248     {
249         /* Trash all received PES packets */
250         while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) ) 
251         {
252             p_lpcmdec->p_fifo->pf_delete_pes( p_lpcmdec->p_fifo->p_packets_mgt,
253                     DECODER_FIFO_START(*p_lpcmdec->p_fifo ));
254             DECODER_FIFO_INCSTART( *p_lpcmdec->p_fifo );
255         }
256
257         /* Waiting for the input thread to put new PES packets in the fifo */
258         vlc_cond_wait ( &p_lpcmdec->p_fifo->data_wait, 
259                         &p_lpcmdec->p_fifo->data_lock );
260     }
261
262     /* We can release the lock before leaving */
263     vlc_mutex_unlock( &p_lpcmdec->p_fifo->data_lock );
264 }
265
266 /*****************************************************************************
267  * lpcm_adec_EndThread : lpcm decoder thread destruction
268  *****************************************************************************/
269 static void lpcm_adec_EndThread( lpcmdec_thread_t * p_lpcmdec )
270 {
271     intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", p_lpcmdec );
272
273     /* If the audio output fifo was created, we destroy it */
274     if( p_lpcmdec->p_aout_fifo != NULL ) 
275     {
276         aout_DestroyFifo( p_lpcmdec->p_aout_fifo );
277
278         /* Make sure the output thread leaves the NextFrame() function */
279         vlc_mutex_lock( &(p_lpcmdec->p_aout_fifo->data_lock) );
280         vlc_cond_signal( &(p_lpcmdec->p_aout_fifo->data_wait) );
281         vlc_mutex_unlock( &(p_lpcmdec->p_aout_fifo->data_lock) );
282     }
283
284     /* Destroy descriptor */
285     free( p_lpcmdec );
286
287     intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p destroyed", p_lpcmdec );
288 }