1 /***************************************************************************
2 mad_adec.c - description
4 Plugin Module definition for using libmad audio decoder in vlc. The
5 libmad codec uses integer arithmic only. This makes it suitable for using
6 it on architectures without a hardware FPU unit, such as the StrongArm
10 copyright : (C) 2001 by Jean-Paul Saman
11 email : jpsaman@wxs.nl
12 ***************************************************************************/
14 /***************************************************************************
16 * This program is free software; you can redistribute it and/or modify *
17 * it under the terms of the GNU General Public License as published by *
18 * the Free Software Foundation; either version 2 of the License, or *
19 * (at your option) any later version. *
21 ***************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
26 #include <stdlib.h> /* malloc(), free() */
27 #include <string.h> /* strdup() */
29 #include <videolan/vlc.h>
31 #include "audio_output.h"
33 #include "stream_control.h"
34 #include "input_ext-dec.h"
38 /*****************************************************************************
39 * Libmad include files *
40 *****************************************************************************/
43 #include "mad_libmad.h"
45 /*****************************************************************************
47 *****************************************************************************/
48 static int decoder_Probe ( probedata_t * );
49 static int decoder_Run ( decoder_config_t * );
50 static int InitThread ( mad_adec_thread_t * p_mad_adec );
51 static void EndThread ( mad_adec_thread_t * p_mad_adec );
53 /*****************************************************************************
55 *****************************************************************************/
56 void _M( adec_getfunctions )( function_list_t * p_function_list )
58 p_function_list->pf_probe = decoder_Probe;
59 p_function_list->functions.dec.pf_run = decoder_Run;
62 /*****************************************************************************
63 * Build configuration tree.
64 *****************************************************************************/
69 SET_DESCRIPTION( "Libmad MPEG 1/2/3 audio decoder library" )
70 ADD_CAPABILITY( DECODER, 50 )
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 * Tries to launch a decoder and return score so that the interface is able
86 *****************************************************************************/
87 static int decoder_Probe( probedata_t *p_data )
89 if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
99 /*****************************************************************************
100 * decoder_Run: this function is called just after the thread is created
101 *****************************************************************************/
102 static int decoder_Run ( decoder_config_t * p_config )
104 mad_adec_thread_t * p_mad_adec;
106 intf_ErrMsg( "mad_adec debug: mad_adec thread launched, initializing" );
108 /* Allocate the memory needed to store the thread's structure */
109 p_mad_adec = (mad_adec_thread_t *) malloc(sizeof(mad_adec_thread_t));
111 if (p_mad_adec == NULL)
113 intf_ErrMsg ( "mad_adec error: not enough memory "
114 "for decoder_Run() to allocate p_mad_adec" );
115 DecoderError( p_config->p_decoder_fifo );
120 * Initialize the thread properties
122 p_mad_adec->p_config = p_config;
123 p_mad_adec->p_fifo = p_mad_adec->p_config->p_decoder_fifo;
124 if( InitThread( p_mad_adec ) )
126 intf_ErrMsg( "mad_adec error: could not initialize thread" );
127 DecoderError( p_config->p_decoder_fifo );
132 /* mad decoder thread's main loop */
133 while ((!p_mad_adec->p_fifo->b_die) && (!p_mad_adec->p_fifo->b_error))
135 intf_ErrMsg( "mad_adec: starting libmad decoder" );
136 if (mad_decoder_run(p_mad_adec->libmad_decoder, MAD_DECODER_MODE_SYNC)==-1)
138 intf_ErrMsg( "mad_adec error: libmad decoder returns abnormally");
139 DecoderError( p_mad_adec->p_fifo );
140 EndThread(p_mad_adec);
145 /* If b_error is set, the mad decoder thread enters the error loop */
146 if (p_mad_adec->p_fifo->b_error)
148 DecoderError( p_mad_adec->p_fifo );
151 /* End of the ac3 decoder thread */
152 EndThread (p_mad_adec);
157 /*****************************************************************************
158 * InitThread: initialize data before entering main loop
159 *****************************************************************************/
160 static int InitThread( mad_adec_thread_t * p_mad_adec )
163 * Properties of audio for libmad
166 /* Initialize the libmad decoder structures */
167 p_mad_adec->libmad_decoder = (struct mad_decoder*) malloc(sizeof(struct mad_decoder));
168 if (p_mad_adec->libmad_decoder == NULL) {
169 intf_ErrMsg ( "mad_adec error: not enough memory "
170 "for decoder_InitThread() to allocate p_mad_adec->libmad_decder" );
173 p_mad_adec->i_current_pts = p_mad_adec->i_next_pts = 0;
176 * Initialize bit stream
178 p_mad_adec->p_config->pf_init_bit_stream( &p_mad_adec->bit_stream,
179 p_mad_adec->p_config->p_decoder_fifo,
180 NULL, /* pf_bitstream_callback */
183 mad_decoder_init( p_mad_adec->libmad_decoder,
184 p_mad_adec, /* vlc's thread structure and p_fifo playbuffer */
185 libmad_input, /* input_func */
188 libmad_output, /* output_func */
192 mad_decoder_options(p_mad_adec->libmad_decoder, MAD_OPTION_IGNORECRC);
193 mad_timer_reset(&p_mad_adec->libmad_timer);
196 * Initialize the output properties
198 p_mad_adec->p_aout_fifo=NULL;
200 intf_ErrMsg("mad_adec debug: mad decoder thread %p initialized", p_mad_adec);
205 /*****************************************************************************
206 * EndThread : libmad decoder thread destruction
207 *****************************************************************************/
208 static void EndThread (mad_adec_thread_t * p_mad_adec)
210 intf_ErrMsg ("mad_adec debug: destroying mad decoder thread %p", p_mad_adec);
212 /* If the audio output fifo was created, we destroy it */
213 if (p_mad_adec->p_aout_fifo != NULL)
215 aout_DestroyFifo (p_mad_adec->p_aout_fifo);
217 /* Make sure the output thread leaves the NextFrame() function */
218 vlc_mutex_lock (&(p_mad_adec->p_aout_fifo->data_lock));
219 vlc_cond_signal (&(p_mad_adec->p_aout_fifo->data_wait));
220 vlc_mutex_unlock (&(p_mad_adec->p_aout_fifo->data_lock));
223 /* mad_decoder_finish releases the memory allocated inside the struct */
224 mad_decoder_finish( p_mad_adec->libmad_decoder );
226 /* Unlock the modules, p_mad_adec->p_config is released by the decoder subsystem */
227 free( p_mad_adec->libmad_decoder );
230 intf_ErrMsg ("mad_adec debug: mad decoder thread %p destroyed", p_mad_adec);