]> git.sesse.net Git - vlc/blob - plugins/mpeg_adec/mpeg_adec.c
* ALL: got rid of p_object->p_this which is now useless.
[vlc] / plugins / mpeg_adec / mpeg_adec.c
1 /*****************************************************************************
2  * mpeg_adec.c: MPEG audio decoder thread
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: mpeg_adec.c,v 1.25 2002/06/01 18:04:49 sam Exp $
6  *
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>
11  *
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.
16  * 
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.
21  *
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  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include <stdlib.h>                                      /* malloc(), free() */
31 #include <string.h>
32
33 #include <vlc/vlc.h>
34 #include <vlc/decoder.h>
35 #include <vlc/aout.h>
36
37 #include "mpeg_adec_generic.h"
38 #include "mpeg_adec.h"
39
40 #define ADEC_FRAME_SIZE (2*1152)
41
42 /*****************************************************************************
43  * Local Prototypes
44  *****************************************************************************/
45 static int   decoder_Probe ( u8 * );
46 static int   decoder_Run   ( decoder_fifo_t * );
47 static void  EndThread     ( adec_thread_t * );
48 static void  DecodeThread  ( adec_thread_t * );
49
50 /*****************************************************************************
51  * Capabilities
52  *****************************************************************************/
53 void _M( adec_getfunctions )( function_list_t * p_function_list )
54 {
55     p_function_list->functions.dec.pf_probe = decoder_Probe;
56     p_function_list->functions.dec.pf_run   = decoder_Run;
57 }
58
59 /*****************************************************************************
60  * Build configuration tree.
61  *****************************************************************************/
62 MODULE_CONFIG_START
63 MODULE_CONFIG_STOP
64
65 MODULE_INIT_START
66     SET_DESCRIPTION( _("MPEG I/II layer 1/2 audio decoder") )
67     ADD_CAPABILITY( DECODER, 50 )
68     ADD_REQUIREMENT( FPU )
69     ADD_SHORTCUT( "builtin" )
70 MODULE_INIT_STOP
71
72 MODULE_ACTIVATE_START
73     _M( adec_getfunctions )( &p_module->p_functions->dec );
74 MODULE_ACTIVATE_STOP
75
76 MODULE_DEACTIVATE_START
77 MODULE_DEACTIVATE_STOP
78
79 /*****************************************************************************
80  * decoder_Probe: probe the decoder and return score
81  *****************************************************************************/
82 static int decoder_Probe( u8 *pi_type )
83 {
84     return( ( *pi_type == MPEG1_AUDIO_ES
85                || *pi_type == MPEG2_AUDIO_ES ) ? 0 : -1 );
86 }
87
88 /*****************************************************************************
89  * decoder_Run: initialize, go inside main loop, detroy
90  *****************************************************************************/
91 static int decoder_Run ( decoder_fifo_t * p_fifo )
92 {
93     adec_thread_t   * p_adec;
94     
95     /* Allocate the memory needed to store the thread's structure */
96     if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL ) 
97     {
98         msg_Err( p_fifo, "out of memory" );
99         DecoderError( p_fifo );
100         return 0;
101     }
102     
103     /*
104      * Initialize the thread properties
105      */
106     p_adec->p_fifo = p_fifo;
107
108     /* 
109      * Initilize the banks
110      */
111     p_adec->bank_0.actual = p_adec->bank_0.v1;
112     p_adec->bank_0.pos = 0;
113     p_adec->bank_1.actual = p_adec->bank_1.v1;
114     p_adec->bank_1.pos = 0;
115     
116     /*
117      * Initialize bit stream 
118      */
119     InitBitstream( &p_adec->bit_stream, p_adec->p_fifo, NULL, NULL );
120
121     /* We do not create the audio output fifo now, but
122        it will be created when the first frame is received */
123     p_adec->p_aout_fifo = NULL;
124
125     p_adec->i_sync = 0;
126
127     /* Audio decoder thread's main loop */
128     while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
129     {
130         DecodeThread( p_adec );
131     }
132     
133     /* If b_error is set, the audio decoder thread enters the error loop */
134     if( p_adec->p_fifo->b_error ) 
135     {
136         DecoderError( p_adec->p_fifo );
137     }
138
139     /* End of the audio decoder thread */
140     EndThread( p_adec );
141
142     return( 0 );
143 }
144
145 /*
146  * Following functions are local to this module
147  */
148
149 /*****************************************************************************
150  * DecodeThread: decodes a mpeg frame
151  *****************************************************************************/
152 static void DecodeThread( adec_thread_t * p_adec )
153 {
154     s16 *p_buffer;
155     adec_sync_info_t sync_info;
156
157     if( ! adec_SyncFrame (p_adec, &sync_info) )
158     {
159         
160         /* TODO: check if audio type has changed */
161         
162         /* Create the output fifo if it doesn't exist yet */
163         if( p_adec->p_aout_fifo == NULL )
164         {
165             int i_channels;
166             
167             if( !config_GetInt( p_adec->p_fifo, "mono" ) )
168             {
169                 msg_Dbg( p_adec->p_fifo, "setting stereo output" );
170                 i_channels = 2;
171             }
172             else if( sync_info.b_stereo )
173             {
174                 i_channels = 2;
175             }
176             else
177             {
178                 i_channels = 1;
179             }
180             p_adec->p_aout_fifo =
181                aout_CreateFifo( p_adec->p_fifo, AOUT_FIFO_PCM, i_channels,
182                                 sync_info.sample_rate, ADEC_FRAME_SIZE, NULL );
183             if( p_adec->p_aout_fifo == NULL)
184             {
185                 msg_Err( p_adec->p_fifo, "failed to create aout fifo" );
186                 p_adec->p_fifo->b_error = 1;
187                 return;
188             }
189         }
190
191         p_adec->i_sync = 1;
192
193         p_buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
194                     + (p_adec->p_aout_fifo->i_end_frame * ADEC_FRAME_SIZE);
195
196         CurrentPTS( &p_adec->bit_stream,
197             &p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame],
198             NULL );
199         if( !p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] )
200         {
201             p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->i_end_frame] =
202                 LAST_MDATE;
203         }
204
205         if( adec_DecodeFrame (p_adec, p_buffer) )
206         {
207             /* Ouch, failed decoding... We'll have to resync */
208             p_adec->i_sync = 0;
209         }
210         else
211         {
212             vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
213             p_adec->p_aout_fifo->i_end_frame =
214                 (p_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
215             vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
216             vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
217         }
218     }
219 }
220
221 /*****************************************************************************
222  * EndThread : audio decoder thread destruction
223  *****************************************************************************
224  * This function is called when the thread ends after a sucessful
225  * initialization.
226  *****************************************************************************/
227 static void EndThread ( adec_thread_t *p_adec )
228 {
229     /* If the audio output fifo was created, we destroy it */
230     if ( p_adec->p_aout_fifo != NULL ) 
231     {
232         aout_DestroyFifo ( p_adec->p_aout_fifo );
233
234         /* Make sure the output thread leaves the NextFrame() function */
235         vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
236         vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
237         vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
238     }
239     /* Destroy descriptor */
240     free( p_adec );
241 }
242