1 /*****************************************************************************
2 * mpeg_adec.c: MPEG audio decoder thread
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: mpeg_adec.c,v 1.5 2001/12/04 13:47:46 massiot Exp $
7 * Authors: Michel Kaempf <maxx@via.ecp.fr>
8 * Michel Lespinasse <walken@via.ecp.fr>
9 * Samuel Hocevar <sam@via.ecp.fr>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 *****************************************************************************/
26 #define MODULE_NAME mpeg_adec
27 #include "modules_inner.h"
29 /*****************************************************************************
31 *****************************************************************************/
34 #include <stdlib.h> /* malloc(), free() */
38 #include "common.h" /* boolean_t, byte_t */
44 #include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
47 #include "modules_export.h"
49 #include "stream_control.h"
50 #include "input_ext-dec.h"
52 #include "mpeg_adec_generic.h"
53 #include "mpeg_adec.h"
55 #define ADEC_FRAME_SIZE (2*1152)
57 /*****************************************************************************
59 *****************************************************************************/
60 static int adec_Probe( probedata_t * );
61 static int adec_RunThread ( decoder_config_t * );
62 static void adec_EndThread ( adec_thread_t * );
63 static void adec_ErrorThread ( adec_thread_t * );
64 static void adec_Decode( adec_thread_t * );
67 /*****************************************************************************
69 *****************************************************************************/
70 void _M( adec_getfunctions )( function_list_t * p_function_list )
72 p_function_list->pf_probe = adec_Probe;
73 p_function_list->functions.dec.pf_run = adec_RunThread;
76 /*****************************************************************************
77 * Build configuration tree.
78 *****************************************************************************/
80 ADD_WINDOW( "Configuration for mpeg audio decoder module" )
81 ADD_COMMENT( "Nothing to configure" )
85 p_module->i_capabilities = MODULE_CAPABILITY_DEC;
86 p_module->psz_longname = "Mpeg I layer 1/2 audio decoder";
90 _M( adec_getfunctions )( &p_module->p_functions->dec );
93 MODULE_DEACTIVATE_START
94 MODULE_DEACTIVATE_STOP
96 /*****************************************************************************
97 * adec_Probe: probe the decoder and return score
98 *****************************************************************************/
99 static int adec_Probe( probedata_t *p_data )
101 if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
103 if( !TestCPU( CPU_CAPABILITY_FPU ) )
105 /* This can work but we'd really prefer libmad to take over. */
108 if( TestMethod( ADEC_MPEG_VAR, "builtin" ) )
117 /*****************************************************************************
118 * adec_RunThread: initialize, go inside main loop, detroy
119 *****************************************************************************/
120 static int adec_RunThread ( decoder_config_t * p_config )
122 adec_thread_t * p_adec;
124 intf_DbgMsg("mpeg_adec debug: thread launched, initializing.");
126 /* Allocate the memory needed to store the thread's structure */
127 if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
129 intf_ErrMsg ( "adec error: not enough memory for"
130 " adec_CreateThread() to create the new thread" );
135 * Initialize the thread properties
137 p_adec->p_config = p_config;
138 p_adec->p_fifo = p_config->p_decoder_fifo;
141 * Initilize the banks
143 p_adec->bank_0.actual = p_adec->bank_0.v1;
144 p_adec->bank_0.pos = 0;
145 p_adec->bank_1.actual = p_adec->bank_1.v1;
146 p_adec->bank_1.pos = 0;
149 * Initialize bit stream
151 p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
152 p_adec->p_config->p_decoder_fifo, NULL, NULL );
154 /* Create the audio output fifo */
155 p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
156 ADEC_FRAME_SIZE, NULL );
157 if ( p_adec->p_aout_fifo == NULL )
159 intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
163 intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
167 /* Audio decoder thread's main loop */
168 while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
170 adec_Decode( p_adec );
173 /* If b_error is set, the audio decoder thread enters the error loop */
174 if( p_adec->p_fifo->b_error )
176 adec_ErrorThread( p_adec );
179 /* End of the audio decoder thread */
180 adec_EndThread( p_adec );
186 * Following finctions are local to this module
189 /*****************************************************************************
190 * adec_Decode: decodes a mpeg frame
191 *****************************************************************************/
192 static void adec_Decode( adec_thread_t * p_adec )
195 adec_sync_info_t sync_info;
197 if( ! adec_SyncFrame (p_adec, &sync_info) )
201 p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
203 buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
204 + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
206 if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
208 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
209 DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
210 DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
214 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
218 if( adec_DecodeFrame (p_adec, buffer) )
220 /* Ouch, failed decoding... We'll have to resync */
225 vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
227 p_adec->p_aout_fifo->l_end_frame =
228 (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
229 vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
230 vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
235 /*****************************************************************************
236 * adec_ErrorThread : audio decoder's RunThread() error loop
237 *****************************************************************************
238 * This function is called when an error occured during thread main's loop. The
239 * thread can still receive feed, but must be ready to terminate as soon as
241 *****************************************************************************/
242 static void adec_ErrorThread ( adec_thread_t *p_adec )
244 /* We take the lock, because we are going to read/write the start/end
245 * indexes of the decoder fifo */
246 vlc_mutex_lock ( &p_adec->p_fifo->data_lock );
248 /* Wait until a `die' order is sent */
249 while ( !p_adec->p_fifo->b_die )
251 /* Trash all received PES packets */
252 while ( !DECODER_FIFO_ISEMPTY(*p_adec->p_fifo) )
254 p_adec->p_fifo->pf_delete_pes ( p_adec->p_fifo->p_packets_mgt,
255 DECODER_FIFO_START(*p_adec->p_fifo) );
256 DECODER_FIFO_INCSTART ( *p_adec->p_fifo );
259 /* Waiting for the input thread to put new PES packets in the fifo */
260 vlc_cond_wait ( &p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock );
263 /* We can release the lock before leaving */
264 vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
268 /*****************************************************************************
269 * adec_EndThread : audio decoder thread destruction
270 *****************************************************************************
271 * This function is called when the thread ends after a sucessful
273 *****************************************************************************/
274 static void adec_EndThread ( adec_thread_t *p_adec )
276 intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );
278 /* If the audio output fifo was created, we destroy it */
279 if ( p_adec->p_aout_fifo != NULL )
281 aout_DestroyFifo ( p_adec->p_aout_fifo );
283 /* Make sure the output thread leaves the NextFrame() function */
284 vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
285 vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
286 vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
288 /* Destroy descriptor */
291 intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);