1 /*****************************************************************************
2 * mpeg_adec.c: MPEG audio decoder thread
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: mpeg_adec.c,v 1.22 2002/04/19 13:56:11 sam Exp $
7 * Authors: Michel Kaempf <maxx@via.ecp.fr>
8 * Michel Lespinasse <walken@via.ecp.fr>
9 * Samuel Hocevar <sam@via.ecp.fr>
10 * Cyril Deguet <asmax@via.ecp.fr>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
30 #include <stdlib.h> /* malloc(), free() */
33 #include <videolan/vlc.h>
35 #include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
37 #include "stream_control.h"
38 #include "input_ext-dec.h"
40 #include "mpeg_adec_generic.h"
41 #include "mpeg_adec.h"
43 #define ADEC_FRAME_SIZE (2*1152)
45 /*****************************************************************************
47 *****************************************************************************/
48 static int decoder_Probe ( u8 * );
49 static int decoder_Run ( decoder_config_t * );
50 static void EndThread ( adec_thread_t * );
51 static void DecodeThread ( adec_thread_t * );
53 /*****************************************************************************
55 *****************************************************************************/
56 void _M( adec_getfunctions )( function_list_t * p_function_list )
58 p_function_list->functions.dec.pf_probe = decoder_Probe;
59 p_function_list->functions.dec.pf_run = decoder_Run;
62 /*****************************************************************************
63 * Build configuration tree.
64 *****************************************************************************/
69 SET_DESCRIPTION( _("MPEG I/II layer 1/2 audio decoder") )
70 ADD_CAPABILITY( DECODER, 100 )
71 ADD_REQUIREMENT( FPU )
72 ADD_SHORTCUT( "builtin" )
76 _M( adec_getfunctions )( &p_module->p_functions->dec );
79 MODULE_DEACTIVATE_START
80 MODULE_DEACTIVATE_STOP
82 /*****************************************************************************
83 * decoder_Probe: probe the decoder and return score
84 *****************************************************************************/
85 static int decoder_Probe( u8 *pi_type )
87 return( ( *pi_type == MPEG1_AUDIO_ES
88 || *pi_type == MPEG2_AUDIO_ES ) ? 0 : -1 );
91 /*****************************************************************************
92 * decoder_Run: initialize, go inside main loop, detroy
93 *****************************************************************************/
94 static int decoder_Run ( decoder_config_t * p_config )
96 adec_thread_t * p_adec;
98 /* Allocate the memory needed to store the thread's structure */
99 if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
101 intf_ErrMsg ( "adec error: not enough memory for"
102 " adec_CreateThread() to create the new thread" );
103 DecoderError( p_config->p_decoder_fifo );
108 * Initialize the thread properties
110 p_adec->p_config = p_config;
111 p_adec->p_fifo = p_config->p_decoder_fifo;
114 * Initilize the banks
116 p_adec->bank_0.actual = p_adec->bank_0.v1;
117 p_adec->bank_0.pos = 0;
118 p_adec->bank_1.actual = p_adec->bank_1.v1;
119 p_adec->bank_1.pos = 0;
122 * Initialize bit stream
124 InitBitstream( &p_adec->bit_stream, p_adec->p_config->p_decoder_fifo,
127 /* We do not create the audio output fifo now, but
128 it will be created when the first frame is received */
129 p_adec->p_aout_fifo = NULL;
133 /* Audio decoder thread's main loop */
134 while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
136 DecodeThread( p_adec );
139 /* If b_error is set, the audio decoder thread enters the error loop */
140 if( p_adec->p_fifo->b_error )
142 DecoderError( p_adec->p_fifo );
145 /* End of the audio decoder thread */
152 * Following functions are local to this module
155 /*****************************************************************************
156 * DecodeThread: decodes a mpeg frame
157 *****************************************************************************/
158 static void DecodeThread( adec_thread_t * p_adec )
161 adec_sync_info_t sync_info;
163 if( ! adec_SyncFrame (p_adec, &sync_info) )
166 /* TODO: check if audio type has changed */
168 /* Create the output fifo if it doesn't exist yet */
169 if( p_adec->p_aout_fifo == NULL )
173 if( p_main->b_stereo )
175 intf_WarnMsg( 4, "adec info: setting stereo output" );
178 else if( sync_info.b_stereo )
186 p_adec->p_aout_fifo = aout_CreateFifo( AOUT_FIFO_PCM, i_channels,
187 sync_info.sample_rate, ADEC_FRAME_SIZE, NULL );
188 if( p_adec->p_aout_fifo == NULL)
190 intf_ErrMsg( "adec error: failed to create aout fifo" );
191 p_adec->p_fifo->b_error = 1;
198 p_buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
199 + (p_adec->p_aout_fifo->i_end_frame * ADEC_FRAME_SIZE);
201 CurrentPTS( &p_adec->bit_stream,
202 &p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame],
204 if( !p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] )
206 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] =
210 if( adec_DecodeFrame (p_adec, p_buffer) )
212 /* Ouch, failed decoding... We'll have to resync */
217 vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
218 p_adec->p_aout_fifo->i_end_frame =
219 (p_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
220 vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
221 vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
226 /*****************************************************************************
227 * EndThread : audio decoder thread destruction
228 *****************************************************************************
229 * This function is called when the thread ends after a sucessful
231 *****************************************************************************/
232 static void EndThread ( adec_thread_t *p_adec )
234 /* If the audio output fifo was created, we destroy it */
235 if ( p_adec->p_aout_fifo != NULL )
237 aout_DestroyFifo ( p_adec->p_aout_fifo );
239 /* Make sure the output thread leaves the NextFrame() function */
240 vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
241 vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
242 vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
244 /* Destroy descriptor */