1 /*****************************************************************************
2 * mpeg_adec.c: MPEG audio decoder thread
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: mpeg_adec.c,v 1.10 2001/12/30 07:09:55 sam 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 /*****************************************************************************
28 *****************************************************************************/
29 #include <stdlib.h> /* malloc(), free() */
32 #include <videolan/vlc.h>
34 #include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
36 #include "stream_control.h"
37 #include "input_ext-dec.h"
39 #include "mpeg_adec_generic.h"
40 #include "mpeg_adec.h"
42 #define ADEC_FRAME_SIZE (2*1152)
44 /*****************************************************************************
46 *****************************************************************************/
47 static int decoder_Probe ( probedata_t * );
48 static int decoder_Run ( decoder_config_t * );
49 static void EndThread ( adec_thread_t * );
50 static void DecodeThread ( adec_thread_t * );
52 /*****************************************************************************
54 *****************************************************************************/
55 void _M( adec_getfunctions )( function_list_t * p_function_list )
57 p_function_list->pf_probe = decoder_Probe;
58 p_function_list->functions.dec.pf_run = decoder_Run;
61 /*****************************************************************************
62 * Build configuration tree.
63 *****************************************************************************/
68 SET_DESCRIPTION( "Mpeg I layer 1/2 audio decoder" )
69 ADD_CAPABILITY( DECODER, 100 )
70 ADD_REQUIREMENT( FPU )
71 ADD_SHORTCUT( "builtin" )
75 _M( adec_getfunctions )( &p_module->p_functions->dec );
78 MODULE_DEACTIVATE_START
79 MODULE_DEACTIVATE_STOP
81 /*****************************************************************************
82 * decoder_Probe: probe the decoder and return score
83 *****************************************************************************/
84 static int decoder_Probe( probedata_t *p_data )
86 return( ( p_data->i_type == MPEG1_AUDIO_ES
87 || p_data->i_type == MPEG2_AUDIO_ES ) ? 100 : 0 );
90 /*****************************************************************************
91 * decoder_Run: initialize, go inside main loop, detroy
92 *****************************************************************************/
93 static int decoder_Run ( decoder_config_t * p_config )
95 adec_thread_t * p_adec;
97 intf_DbgMsg("mpeg_adec debug: thread launched, initializing.");
99 /* Allocate the memory needed to store the thread's structure */
100 if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
102 intf_ErrMsg ( "adec error: not enough memory for"
103 " adec_CreateThread() to create the new thread" );
104 DecoderError( p_config->p_decoder_fifo );
109 * Initialize the thread properties
111 p_adec->p_config = p_config;
112 p_adec->p_fifo = p_config->p_decoder_fifo;
115 * Initilize the banks
117 p_adec->bank_0.actual = p_adec->bank_0.v1;
118 p_adec->bank_0.pos = 0;
119 p_adec->bank_1.actual = p_adec->bank_1.v1;
120 p_adec->bank_1.pos = 0;
123 * Initialize bit stream
125 p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
126 p_adec->p_config->p_decoder_fifo, NULL, NULL );
128 /* Create the audio output fifo */
129 p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
130 ADEC_FRAME_SIZE, NULL );
131 if ( p_adec->p_aout_fifo == NULL )
133 intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
137 intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
141 /* Audio decoder thread's main loop */
142 while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
144 DecodeThread( p_adec );
147 /* If b_error is set, the audio decoder thread enters the error loop */
148 if( p_adec->p_fifo->b_error )
150 DecoderError( p_adec->p_fifo );
153 /* End of the audio decoder thread */
160 * Following finctions are local to this module
163 /*****************************************************************************
164 * DecodeThread: decodes a mpeg frame
165 *****************************************************************************/
166 static void DecodeThread( adec_thread_t * p_adec )
169 adec_sync_info_t sync_info;
171 if( ! adec_SyncFrame (p_adec, &sync_info) )
175 p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
177 buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
178 + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
180 if( p_adec->p_fifo->p_first->i_pts )
182 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
183 p_adec->p_fifo->p_first->i_pts;
184 p_adec->p_fifo->p_first->i_pts = 0;
188 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
192 if( adec_DecodeFrame (p_adec, buffer) )
194 /* Ouch, failed decoding... We'll have to resync */
199 vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
201 p_adec->p_aout_fifo->l_end_frame =
202 (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
203 vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
204 vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
209 /*****************************************************************************
210 * EndThread : audio decoder thread destruction
211 *****************************************************************************
212 * This function is called when the thread ends after a sucessful
214 *****************************************************************************/
215 static void EndThread ( adec_thread_t *p_adec )
217 intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );
219 /* If the audio output fifo was created, we destroy it */
220 if ( p_adec->p_aout_fifo != NULL )
222 aout_DestroyFifo ( p_adec->p_aout_fifo );
224 /* Make sure the output thread leaves the NextFrame() function */
225 vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
226 vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
227 vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
229 /* Destroy descriptor */
232 intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);