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 *****************************************************************************/
52 add_category_hint( N_("Libmad"), NULL );
53 set_description( _("libmad MPEG 1/2/3 audio decoder") );
54 set_capability( "decoder", 100 );
55 set_callbacks( OpenDecoder, NULL );
58 /*****************************************************************************
59 * OpenDecoder: probe the decoder and return score
60 *****************************************************************************
61 * Tries to launch a decoder and return score so that the interface is able
63 *****************************************************************************/
64 static int OpenDecoder( vlc_object_t *p_this )
66 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
68 if( p_fifo->i_fourcc != VLC_FOURCC('m','p','g','a') )
73 p_fifo->pf_run = RunDecoder;
77 /*****************************************************************************
78 * RunDecoder: this function is called just after the thread is created
79 *****************************************************************************/
80 static int RunDecoder( decoder_fifo_t *p_fifo )
82 mad_adec_thread_t * p_dec;
85 /* Allocate the memory needed to store the thread's structure */
86 p_dec = (mad_adec_thread_t *) malloc(sizeof(mad_adec_thread_t));
90 msg_Err( p_fifo, "out of memory" );
91 DecoderError( p_fifo );
96 * Initialize the thread properties
98 p_dec->p_fifo = p_fifo;
99 if( InitThread( p_dec ) )
101 msg_Err( p_fifo, "could not initialize thread" );
102 DecoderError( p_fifo );
107 /* mad decoder thread's main loop */
108 while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
110 msg_Dbg( p_dec->p_fifo, "starting libmad decoder" );
111 i_ret = mad_decoder_run( &p_dec->libmad_decoder,
112 MAD_DECODER_MODE_SYNC );
115 msg_Err( p_dec->p_fifo, "libmad decoder returned abnormally" );
116 DecoderError( p_dec->p_fifo );
122 /* If b_error is set, the mad decoder thread enters the error loop */
123 if (p_dec->p_fifo->b_error)
125 DecoderError( p_dec->p_fifo );
128 /* End of the mad decoder thread */
134 /*****************************************************************************
135 * InitThread: initialize data before entering main loop
136 *****************************************************************************/
137 static int InitThread( mad_adec_thread_t * p_dec )
139 decoder_fifo_t * p_fifo = p_dec->p_fifo;
141 /* Initialize the thread properties */
142 p_dec->p_aout = NULL;
143 p_dec->p_aout_input = NULL;
144 p_dec->output_format.i_format = AOUT_FMT_FIXED32;
147 * Properties of audio for libmad
150 /* Initialize the libmad decoder structures */
151 p_dec->i_current_pts = p_dec->i_next_pts = 0;
153 mad_decoder_init( &p_dec->libmad_decoder,
154 p_dec, /* vlc's thread structure and p_fifo playbuffer */
155 libmad_input, /* input_func */
156 NULL, /* header_func */
158 libmad_output, /* output_func */
160 NULL ); /* message */
162 mad_decoder_options( &p_dec->libmad_decoder, MAD_OPTION_IGNORECRC );
165 * Initialize the input properties
168 /* Get the first data packet. */
169 vlc_mutex_lock( &p_fifo->data_lock );
170 while ( p_fifo->p_first == NULL )
174 vlc_mutex_unlock( &p_fifo->data_lock );
177 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
179 vlc_mutex_unlock( &p_fifo->data_lock );
180 p_dec->p_data = p_fifo->p_first->p_first;
185 /*****************************************************************************
186 * EndThread : libmad decoder thread destruction
187 *****************************************************************************/
188 static void EndThread (mad_adec_thread_t * p_dec)
190 /* If the audio output fifo was created, we destroy it */
191 if (p_dec->p_aout_input != NULL)
193 aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
196 /* mad_decoder_finish releases the memory allocated inside the struct */
197 mad_decoder_finish( &p_dec->libmad_decoder );