1 /*****************************************************************************
2 * lpcm_decoder_thread.c: lpcm decoder thread
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: lpcm_adec.c,v 1.2 2001/11/28 15:08:05 massiot Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Henri Fallon <henri@videolan.org>
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.
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.
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 *****************************************************************************/
25 #define MODULE_NAME lpcm_adec
26 #include "modules_inner.h"
28 /*****************************************************************************
30 *****************************************************************************/
34 #include <unistd.h> /* getpid() */
37 #include <stdio.h> /* "intf_msg.h" */
38 #include <string.h> /* memcpy(), memset() */
39 #include <stdlib.h> /* malloc(), free() */
43 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
47 #include "audio_output.h"
50 #include "modules_export.h"
52 #include "stream_control.h"
53 #include "input_ext-dec.h"
55 #include "lpcm_adec.h"
57 /*****************************************************************************
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 * );
68 /*****************************************************************************
70 *****************************************************************************/
71 void _M( adec_getfunctions )( function_list_t * p_function_list )
73 p_function_list->pf_probe = lpcm_adec_Probe;
74 p_function_list->functions.dec.pf_RunThread = lpcm_adec_Run;
77 /*****************************************************************************
78 * Build configuration tree.
79 *****************************************************************************/
81 ADD_WINDOW( "Configuration for lpcm audio decoder module" )
82 ADD_COMMENT( "Nothing to configure" )
86 p_module->i_capabilities = MODULE_CAPABILITY_DEC;
87 p_module->psz_longname = "Linear PCM audio decoder";
91 _M( adec_getfunctions )( &p_module->p_functions->dec );
94 MODULE_DEACTIVATE_START
95 MODULE_DEACTIVATE_STOP
97 /*****************************************************************************
98 * lpcm_adec_Probe: probe the decoder and return score
99 *****************************************************************************/
100 static int lpcm_adec_Probe( probedata_t *p_data )
102 if( p_data->i_type == LPCM_AUDIO_ES )
108 /*****************************************************************************
109 * lpcm_adec_Run: the lpcm decoder
110 *****************************************************************************/
111 static int lpcm_adec_Run( decoder_config_t * p_config )
113 lpcmdec_thread_t * p_lpcmdec;
115 intf_DbgMsg("lpcm_adec debug: thread launched, initializing.");
117 /* Allocate the memory needed to store the thread's structure */
118 if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
121 intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" );
126 * Initialize the thread properties
128 p_lpcmdec->p_config = p_config;
129 p_lpcmdec->p_fifo = p_config->p_decoder_fifo;
131 if( lpcm_adec_Init( p_lpcmdec ) )
136 intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n",
139 /* lpcm decoder thread's main loop */
140 while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
142 lpcm_adec_DecodeFrame(p_lpcmdec);
145 /* If b_error is set, the lpcm decoder thread enters the error loop */
146 if (p_lpcmdec->p_fifo->b_error)
148 lpcm_adec_ErrorThread (p_lpcmdec);
151 /* End of the lpcm decoder thread */
152 lpcm_adec_EndThread (p_lpcmdec);
157 /*****************************************************************************
158 * lpcm_adec_Init : initialize an lpcm decoder thread
159 *****************************************************************************/
160 static int lpcm_adec_Init (lpcmdec_thread_t * p_lpcmdec)
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,
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 )
179 /*****************************************************************************
180 * lpcm_adec_DecodeFrame: decodes a frame.
181 *****************************************************************************/
182 void lpcm_adec_DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
184 byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
188 if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
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;
196 p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
200 buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) +
201 (p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
203 RemoveBits32(&p_lpcmdec->bit_stream);
204 byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
205 byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
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) )
215 byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
218 GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
220 for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
222 buffer[2*i_loop]=p_temp[2*i_loop+1];
223 buffer[2*i_loop+1]=p_temp[2*i_loop];
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);
232 intf_DbgMsg( "LPCM Debug: %x", *buffer );
237 /*****************************************************************************
238 * lpcm_adec_ErrorThread : lpcm decoder's RunThread() error loop
239 *****************************************************************************/
240 static void lpcm_adec_ErrorThread( lpcmdec_thread_t * p_lpcmdec )
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 );
246 /* Wait until a `die' order is sent */
247 while( !p_lpcmdec->p_fifo->b_die )
249 /* Trash all received PES packets */
250 while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) )
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 );
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 );
262 /* We can release the lock before leaving */
263 vlc_mutex_unlock( &p_lpcmdec->p_fifo->data_lock );
266 /*****************************************************************************
267 * lpcm_adec_EndThread : lpcm decoder thread destruction
268 *****************************************************************************/
269 static void lpcm_adec_EndThread( lpcmdec_thread_t * p_lpcmdec )
271 intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", p_lpcmdec );
273 /* If the audio output fifo was created, we destroy it */
274 if( p_lpcmdec->p_aout_fifo != NULL )
276 aout_DestroyFifo( p_lpcmdec->p_aout_fifo );
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) );
284 /* Destroy descriptor */
287 intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p destroyed", p_lpcmdec );