1 /*****************************************************************************
2 * decoder.c: MPEG audio decoder thread
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: decoder.c,v 1.1 2002/08/04 17:23:42 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() */
34 #include <vlc/decoder.h>
40 #define ADEC_FRAME_SIZE (2*1152)
42 /*****************************************************************************
44 *****************************************************************************/
45 static int OpenDecoder ( vlc_object_t * );
46 static int RunDecoder ( decoder_fifo_t * );
48 static void EndThread ( adec_thread_t * );
49 static void DecodeThread ( adec_thread_t * );
51 /*****************************************************************************
53 *****************************************************************************/
55 set_description( _("MPEG I/II layer 1/2 audio decoder") );
56 set_capability( "decoder", 50 );
57 add_requirement( FPU );
58 add_shortcut( "builtin" );
59 set_callbacks( OpenDecoder, NULL );
62 /*****************************************************************************
63 * OpenDecoder: probe the decoder and return score
64 *****************************************************************************
65 * Tries to launch a decoder and return score so that the interface is able
67 *****************************************************************************/
68 static int OpenDecoder( vlc_object_t *p_this )
70 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
72 if( p_fifo->i_fourcc != VLC_FOURCC('m','p','g','a') )
77 p_fifo->pf_run = RunDecoder;
81 /*****************************************************************************
82 * RunDecoder: initialize, go inside main loop, destroy
83 *****************************************************************************/
84 static int RunDecoder( decoder_fifo_t *p_fifo )
86 adec_thread_t * p_adec;
88 /* Allocate the memory needed to store the thread's structure */
89 if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
91 msg_Err( p_fifo, "out of memory" );
92 DecoderError( p_fifo );
97 * Initialize the thread properties
99 p_adec->p_fifo = p_fifo;
102 * Initilize the banks
104 p_adec->bank_0.actual = p_adec->bank_0.v1;
105 p_adec->bank_0.pos = 0;
106 p_adec->bank_1.actual = p_adec->bank_1.v1;
107 p_adec->bank_1.pos = 0;
110 * Initialize bit stream
112 InitBitstream( &p_adec->bit_stream, p_adec->p_fifo, NULL, NULL );
114 /* We do not create the audio output fifo now, but
115 it will be created when the first frame is received */
116 p_adec->p_aout_fifo = NULL;
120 /* Audio decoder thread's main loop */
121 while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
123 DecodeThread( p_adec );
126 /* If b_error is set, the audio decoder thread enters the error loop */
127 if( p_adec->p_fifo->b_error )
129 DecoderError( p_adec->p_fifo );
132 /* End of the audio decoder thread */
139 * Following functions are local to this module
142 /*****************************************************************************
143 * DecodeThread: decodes a mpeg frame
144 *****************************************************************************/
145 static void DecodeThread( adec_thread_t * p_adec )
148 adec_sync_info_t sync_info;
150 if( ! adec_SyncFrame (p_adec, &sync_info) )
153 /* TODO: check if audio type has changed */
155 /* Create the output fifo if it doesn't exist yet */
156 if( p_adec->p_aout_fifo == NULL )
160 if( !config_GetInt( p_adec->p_fifo, "mono" ) )
162 msg_Dbg( p_adec->p_fifo, "setting stereo output" );
165 else if( sync_info.b_stereo )
173 p_adec->p_aout_fifo =
174 aout_CreateFifo( p_adec->p_fifo, AOUT_FIFO_PCM, i_channels,
175 sync_info.sample_rate, ADEC_FRAME_SIZE, NULL );
176 if( p_adec->p_aout_fifo == NULL)
178 msg_Err( p_adec->p_fifo, "failed to create aout fifo" );
179 p_adec->p_fifo->b_error = 1;
186 p_buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
187 + (p_adec->p_aout_fifo->i_end_frame * ADEC_FRAME_SIZE);
189 CurrentPTS( &p_adec->bit_stream,
190 &p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame],
192 if( !p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] )
194 p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] =
198 if( adec_DecodeFrame (p_adec, p_buffer) )
200 /* Ouch, failed decoding... We'll have to resync */
205 vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
206 p_adec->p_aout_fifo->i_end_frame =
207 (p_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
208 vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
209 vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
214 /*****************************************************************************
215 * EndThread : audio decoder thread destruction
216 *****************************************************************************
217 * This function is called when the thread ends after a sucessful
219 *****************************************************************************/
220 static void EndThread ( adec_thread_t *p_adec )
222 /* If the audio output fifo was created, we destroy it */
223 if ( p_adec->p_aout_fifo != NULL )
225 aout_DestroyFifo ( p_adec->p_aout_fifo );
227 /* Make sure the output thread leaves the NextFrame() function */
228 vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
229 vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
230 vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
232 /* Destroy descriptor */