1 /***************************************************************************
2 decoder.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() */
31 #include <vlc/decoder.h>
33 /*****************************************************************************
34 * Libmad include files *
35 *****************************************************************************/
40 /*****************************************************************************
42 *****************************************************************************/
43 static int OpenDecoder ( vlc_object_t * );
44 static int RunDecoder ( decoder_fifo_t * );
45 static int InitThread ( mad_adec_thread_t * );
46 static void EndThread ( mad_adec_thread_t * );
48 /*****************************************************************************
50 *****************************************************************************/
51 #define DOWNSCALE_TEXT N_("mad audio downscale routine (fast,mpg321)")
52 #define DOWNSCALE_LONGTEXT N_( \
53 "Specify the mad audio downscale routine you want to use. By default " \
54 "the mad plugin will use the fastest routine.")
57 add_category_hint( N_("Libmad"), NULL );
58 add_string( "downscale", "fast", NULL, DOWNSCALE_TEXT, DOWNSCALE_LONGTEXT );
59 set_description( _("libmad MPEG 1/2/3 audio decoder") );
60 set_capability( "decoder", 100 );
61 set_callbacks( OpenDecoder, NULL );
64 /*****************************************************************************
65 * OpenDecoder: probe the decoder and return score
66 *****************************************************************************
67 * Tries to launch a decoder and return score so that the interface is able
69 *****************************************************************************/
70 static int OpenDecoder( vlc_object_t *p_this )
72 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
74 if( p_fifo->i_fourcc != VLC_FOURCC('m','p','g','a') )
79 p_fifo->pf_run = RunDecoder;
83 /*****************************************************************************
84 * RunDecoder: this function is called just after the thread is created
85 *****************************************************************************/
86 static int RunDecoder( decoder_fifo_t *p_fifo )
88 mad_adec_thread_t * p_dec;
91 /* Allocate the memory needed to store the thread's structure */
92 p_dec = (mad_adec_thread_t *) malloc(sizeof(mad_adec_thread_t));
96 msg_Err( p_fifo, "out of memory" );
97 DecoderError( p_fifo );
102 * Initialize the thread properties
104 p_dec->p_fifo = p_fifo;
105 if( InitThread( p_dec ) )
107 msg_Err( p_fifo, "could not initialize thread" );
108 DecoderError( p_fifo );
113 /* mad decoder thread's main loop */
114 while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
116 msg_Dbg( p_dec->p_fifo, "starting libmad decoder" );
117 i_ret = mad_decoder_run( &p_dec->libmad_decoder,
118 MAD_DECODER_MODE_SYNC );
121 msg_Err( p_dec->p_fifo, "libmad decoder returned abnormally" );
122 DecoderError( p_dec->p_fifo );
128 /* If b_error is set, the mad decoder thread enters the error loop */
129 if (p_dec->p_fifo->b_error)
131 DecoderError( p_dec->p_fifo );
134 /* End of the mad decoder thread */
140 /*****************************************************************************
141 * InitThread: initialize data before entering main loop
142 *****************************************************************************/
143 static int InitThread( mad_adec_thread_t * p_dec )
145 decoder_fifo_t * p_fifo = p_dec->p_fifo;
146 char *psz_downscale = NULL;
148 /* Initialize the thread properties */
149 p_dec->p_aout = NULL;
150 p_dec->p_aout_input = NULL;
151 p_dec->output_format.i_format = AOUT_FMT_FIXED32;
152 p_dec->output_format.i_channels = 2; /* FIXME ! */
155 * Properties of audio for libmad
158 /* Look what scaling method was requested by the user */
159 psz_downscale = config_GetPsz( p_fifo, "downscale" );
161 if ( strncmp(psz_downscale,"fast",4)==0 )
163 p_dec->audio_scaling = FAST_SCALING;
164 msg_Dbg( p_fifo, "downscale fast selected" );
166 else if ( strncmp(psz_downscale,"mpg321",7)==0 )
168 p_dec->audio_scaling = MPG321_SCALING;
169 msg_Dbg( p_fifo, "downscale mpg321 selected" );
173 p_dec->audio_scaling = FAST_SCALING;
174 msg_Dbg( p_fifo, "downscale default fast selected" );
177 if (psz_downscale) free(psz_downscale);
179 /* Initialize the libmad decoder structures */
180 p_dec->i_current_pts = p_dec->i_next_pts = 0;
182 mad_decoder_init( &p_dec->libmad_decoder,
183 p_dec, /* vlc's thread structure and p_fifo playbuffer */
184 libmad_input, /* input_func */
185 NULL, /* header_func */
187 libmad_output, /* output_func */
189 NULL ); /* message */
191 mad_decoder_options( &p_dec->libmad_decoder, MAD_OPTION_IGNORECRC );
194 * Initialize the input properties
197 /* Init the Bitstream */
198 InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL );
200 /* Get the first data packet. */
201 vlc_mutex_lock( &p_fifo->data_lock );
202 while ( p_fifo->p_first == NULL )
206 vlc_mutex_unlock( &p_fifo->data_lock );
209 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
211 vlc_mutex_unlock( &p_fifo->data_lock );
212 p_dec->p_data = p_fifo->p_first->p_first;
217 /*****************************************************************************
218 * EndThread : libmad decoder thread destruction
219 *****************************************************************************/
220 static void EndThread (mad_adec_thread_t * p_dec)
222 /* If the audio output fifo was created, we destroy it */
223 if (p_dec->p_aout_input != NULL)
225 aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
228 /* mad_decoder_finish releases the memory allocated inside the struct */
229 mad_decoder_finish( &p_dec->libmad_decoder );