mpg123: simplify NULL checks
[vlc.git] / modules / codec / mpg123.c
blob9480bc6c76899505457cfd4e8d9bb7649c3fb176
1 /*****************************************************************************
2 * mpg123.c: MPEG-1 & 2 audio layer I, II, III + MPEG 2.5 decoder
3 *****************************************************************************
4 * Copyright (C) 2001-2014 VLC authors and VideoLAN
6 * Authors: Ludovic Fauvet <etix@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
24 * Preamble
25 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <mpg123.h>
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_aout.h>
36 #include <vlc_block.h>
37 #include <vlc_codec.h>
39 /*****************************************************************************
40 * Local prototypes
41 *****************************************************************************/
42 static int OpenDecoder( vlc_object_t * );
43 static void CloseDecoder( vlc_object_t * );
44 static block_t *DecodeBlock( decoder_t *, block_t ** );
45 static void Flush( decoder_t * );
46 static int InitMPG123( void );
47 static void ExitMPG123( void );
49 static unsigned int mpg123_refcount = 0;
50 static vlc_mutex_t mpg123_mutex = VLC_STATIC_MUTEX;
52 /*****************************************************************************
53 * Local structures
54 *****************************************************************************/
55 struct decoder_sys_t
57 mpg123_handle * p_handle;
58 date_t end_date;
60 struct mpg123_frameinfo frame_info;
63 /*****************************************************************************
64 * Module descriptor
65 *****************************************************************************/
66 vlc_module_begin ()
67 set_category( CAT_INPUT )
68 set_subcategory( SUBCAT_INPUT_ACODEC )
69 set_description( N_("MPEG audio decoder using mpg123") )
70 set_capability( "decoder", 99 )
71 set_shortname( "mpg123" )
72 set_callbacks( OpenDecoder, CloseDecoder )
73 vlc_module_end ()
75 /*****************************************************************************
76 * Flush:
77 *****************************************************************************/
78 static void Flush( decoder_t *p_dec )
80 decoder_sys_t *p_sys = p_dec->p_sys;
82 date_Set( &p_sys->end_date, 0 );
85 /****************************************************************************
86 * DecodeBlock: the whole thing
87 ****************************************************************************/
88 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
90 int i_err;
91 decoder_sys_t *p_sys = p_dec->p_sys;
93 if( !pp_block || !*pp_block )
94 return NULL;
95 block_t *p_block = *pp_block;
97 if( p_block->i_buffer == 0 )
98 return NULL;
100 if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID )
102 /* We've just started the stream, wait for the first PTS. */
103 msg_Dbg( p_dec, "waiting for PTS" );
104 goto error;
107 if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
109 Flush( p_dec );
110 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
111 goto error;
114 /* Feed mpg123 with raw data */
115 i_err = mpg123_feed( p_sys->p_handle, p_block->p_buffer,
116 p_block->i_buffer );
118 if( i_err != MPG123_OK )
120 msg_Err( p_dec, "mpg123_feed failed: %s", mpg123_plain_strerror( i_err ) );
121 goto error;
124 /* Get details about the stream */
125 i_err = mpg123_info( p_sys->p_handle, &p_sys->frame_info );
127 if( i_err == MPG123_NEED_MORE )
129 /* Need moar data */
130 goto error;
132 else if( i_err != MPG123_OK )
134 msg_Err( p_dec, "mpg123_info failed: %s", mpg123_plain_strerror( i_err ) );
135 goto error;
138 /* Configure the output */
139 p_block->i_nb_samples = mpg123_spf( p_sys->p_handle );
140 p_dec->fmt_out.i_bitrate = p_sys->frame_info.bitrate * 1000;
142 switch( p_sys->frame_info.mode )
144 case MPG123_M_STEREO:
145 case MPG123_M_JOINT:
146 p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
147 break;
148 case MPG123_M_DUAL:
149 p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
150 | AOUT_CHAN_DUALMONO;
151 break;
152 case MPG123_M_MONO:
153 p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_CENTER;
154 break;
155 default:
156 msg_Err( p_dec, "Unknown mode");
157 goto error;
160 p_dec->fmt_out.audio.i_physical_channels =
161 p_dec->fmt_out.audio.i_original_channels & AOUT_CHAN_PHYSMASK;
163 /* Date management */
164 if( p_dec->fmt_out.audio.i_rate != p_sys->frame_info.rate )
166 p_dec->fmt_out.audio.i_rate = p_sys->frame_info.rate;
167 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
168 date_Set( &p_sys->end_date, 0 );
171 if( p_block->i_pts > VLC_TS_INVALID &&
172 p_block->i_pts != date_Get( &p_sys->end_date ) )
174 date_Set( &p_sys->end_date, p_block->i_pts );
177 /* Request a new audio buffer */
178 block_t *p_out = decoder_NewAudioBuffer( p_dec, p_block->i_nb_samples );
179 if( unlikely( !p_out ) )
180 goto error;
182 /* Configure the buffer */
183 p_out->i_nb_samples = p_block->i_nb_samples;
184 p_out->i_dts = p_out->i_pts = date_Get( &p_sys->end_date );
185 p_out->i_length = date_Increment( &p_sys->end_date, p_block->i_nb_samples )
186 - p_out->i_pts;
188 /* Make mpg123 write directly into the VLC output buffer */
189 i_err = mpg123_replace_buffer( p_sys->p_handle, p_out->p_buffer, p_out->i_buffer );
190 if( i_err != MPG123_OK )
192 msg_Err( p_dec, "could not replace buffer: %s", mpg123_plain_strerror( i_err ) );
193 block_Release( p_out );
194 goto error;
197 *pp_block = NULL; /* avoid being fed the same packet again */
199 /* Do the actual decoding now */
200 i_err = mpg123_decode_frame( p_sys->p_handle, NULL, NULL, NULL );
201 if( i_err != MPG123_OK )
203 if( i_err == MPG123_NEED_MORE )
204 msg_Dbg( p_dec, "mpg123_decode_frame: %s", mpg123_plain_strerror( i_err ) );
205 else if( i_err != MPG123_NEW_FORMAT )
206 msg_Err( p_dec, "mpg123_decode_frame error: %s", mpg123_plain_strerror( i_err ) );
207 block_Release( p_out );
208 goto error;
211 block_Release( p_block );
212 return p_out;
214 error:
215 block_Release( p_block );
216 return NULL;
219 /*****************************************************************************
220 * OpenDecoder :
221 *****************************************************************************/
222 static int OpenDecoder( vlc_object_t *p_this )
224 decoder_t *p_dec = (decoder_t *)p_this;
225 decoder_sys_t *p_sys;
227 if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGA &&
228 p_dec->fmt_in.i_codec != VLC_CODEC_MP3 )
229 return VLC_EGENERIC;
231 p_dec->fmt_out.i_cat = AUDIO_ES;
232 p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
234 /* Initialize libmpg123 */
235 if( InitMPG123() != MPG123_OK )
236 return VLC_EGENERIC;
238 /* Allocate the memory needed to store the module's structure */
239 p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
240 if( p_sys == NULL )
241 return VLC_ENOMEM;
243 /* Create our mpg123 handle */
244 if( ( p_sys->p_handle = mpg123_new( NULL, NULL ) ) == NULL )
245 goto error;
247 /* Open a new bitstream */
248 if( mpg123_open_feed( p_sys->p_handle ) != MPG123_OK )
250 msg_Err( p_this, "mpg123 error: can't open feed" );
251 goto error;
254 /* Disable resync stream after error */
255 mpg123_param( p_sys->p_handle, MPG123_ADD_FLAGS, MPG123_NO_RESYNC, 0 );
257 /* Setup output format */
258 mpg123_format_none( p_sys->p_handle );
260 if( MPG123_OK != mpg123_format( p_sys->p_handle,
261 p_dec->fmt_in.audio.i_rate,
262 MPG123_MONO | MPG123_STEREO,
263 MPG123_ENC_FLOAT_32 ) )
265 msg_Err( p_this, "mpg123 error: %s",
266 mpg123_strerror( p_sys->p_handle ) );
267 mpg123_close( p_sys->p_handle );
268 goto error;
271 p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
272 p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
273 p_dec->pf_decode_audio = DecodeBlock;
274 p_dec->pf_flush = Flush;
276 msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i",
277 (char *)&p_dec->fmt_in.i_codec,
278 (char *)&p_dec->fmt_out.i_codec,
279 aout_BitsPerSample( p_dec->fmt_out.i_codec ) );
281 return VLC_SUCCESS;
282 error:
283 mpg123_delete( p_sys->p_handle );
284 ExitMPG123();
285 free( p_sys );
286 return VLC_EGENERIC;
289 /*****************************************************************************
290 * CloseDecoder : deallocate data structures
291 *****************************************************************************/
292 static void CloseDecoder( vlc_object_t *p_this )
294 decoder_t *p_dec = (decoder_t *)p_this;
295 decoder_sys_t *p_sys = p_dec->p_sys;
297 mpg123_close( p_sys->p_handle );
298 mpg123_delete( p_sys->p_handle );
299 ExitMPG123();
300 free( p_sys );
303 /*****************************************************************************
304 * InitMPG123 : initialize the mpg123 library (reentrant)
305 *****************************************************************************/
306 static int InitMPG123( void )
308 int i_ret;
309 vlc_mutex_lock( &mpg123_mutex );
310 if( mpg123_refcount > 0 )
312 mpg123_refcount++;
313 vlc_mutex_unlock( &mpg123_mutex );
314 return MPG123_OK;
316 if( ( i_ret = mpg123_init() ) == MPG123_OK )
317 mpg123_refcount++;
318 vlc_mutex_unlock( &mpg123_mutex );
319 return i_ret;
322 /*****************************************************************************
323 * ExitMPG123 : close down the mpg123 library (reentrant)
324 *****************************************************************************/
325 static void ExitMPG123( void )
327 vlc_mutex_lock( &mpg123_mutex );
328 mpg123_refcount--;
329 if( mpg123_refcount == 0 )
330 mpg123_exit();
331 vlc_mutex_unlock( &mpg123_mutex );