1 /*****************************************************************************
2 * dec.c : audio output API towards decoders
3 *****************************************************************************
4 * Copyright (C) 2002-2007 the VideoLAN team
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
33 #include <vlc_common.h>
36 #include <vlc_input.h>
38 #include "aout_internal.h"
42 * Creates an audio output
44 aout_input_t *aout_DecNew( aout_instance_t *p_aout,
45 audio_sample_format_t *p_format,
46 const audio_replay_gain_t *p_replay_gain,
47 const aout_request_vout_t *p_request_vout )
49 aout_input_t * p_input;
51 /* Sanitize audio format */
52 if( p_format->i_channels > 32 )
54 msg_Err( p_aout, "too many audio channels (%u)",
55 p_format->i_channels );
58 if( p_format->i_channels <= 0 )
60 msg_Err( p_aout, "no audio channels" );
63 if( p_format->i_channels != aout_FormatNbChannels( p_format ) )
65 msg_Err( p_aout, "incompatible audio channels count with layout mask" );
69 if( p_format->i_rate > 192000 )
71 msg_Err( p_aout, "excessive audio sample frequency (%u)",
75 if( p_format->i_rate < 4000 )
77 msg_Err( p_aout, "too low audio sample frequency (%u)",
82 /* We can only be called by the decoder, so no need to lock
84 aout_lock_mixer( p_aout );
85 assert( p_aout->i_nb_inputs == 0 );
87 p_input = calloc( 1, sizeof(aout_input_t));
91 vlc_mutex_init( &p_input->lock );
93 p_input->b_changed = false;
94 p_input->b_error = true;
95 p_input->b_paused = false;
96 p_input->i_pause_date = 0;
98 aout_FormatPrepare( p_format );
100 memcpy( &p_input->input, p_format,
101 sizeof(audio_sample_format_t) );
103 p_input->replay_gain = *p_replay_gain;
105 aout_lock_input_fifos( p_aout );
106 p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input;
107 p_aout->i_nb_inputs++;
109 if ( !p_aout->p_mixer )
113 var_Destroy( p_aout, "audio-device" );
114 var_Destroy( p_aout, "audio-channels" );
116 /* Recreate the output using the new format. */
117 if ( aout_OutputNew( p_aout, p_format ) < 0 )
119 for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
121 aout_lock_input( p_aout, p_aout->pp_inputs[i] );
122 aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
123 aout_unlock_input( p_aout, p_aout->pp_inputs[i] );
125 aout_unlock_input_fifos( p_aout );
126 aout_unlock_mixer( p_aout );
130 /* Create other input streams. */
131 for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
133 aout_input_t *p_input = p_aout->pp_inputs[i];
135 aout_lock_input( p_aout, p_input );
136 aout_InputDelete( p_aout, p_input );
137 aout_InputNew( p_aout, p_input, &p_input->request_vout );
138 aout_unlock_input( p_aout, p_input );
143 aout_MixerDelete( p_aout );
146 if ( aout_MixerNew( p_aout ) == -1 )
148 aout_OutputDelete( p_aout );
149 aout_unlock_input_fifos( p_aout );
153 aout_InputNew( p_aout, p_input, p_request_vout );
154 aout_unlock_input_fifos( p_aout );
156 aout_unlock_mixer( p_aout );
161 aout_unlock_mixer( p_aout );
165 /*****************************************************************************
166 * aout_DecDelete : delete a decoder
167 *****************************************************************************/
168 int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input )
172 /* This function can only be called by the decoder itself, so no need
173 * to lock p_input->lock. */
174 aout_lock_mixer( p_aout );
176 for ( i_input = 0; i_input < p_aout->i_nb_inputs; i_input++ )
178 if ( p_aout->pp_inputs[i_input] == p_input )
184 if ( i_input == p_aout->i_nb_inputs )
186 msg_Err( p_aout, "cannot find an input to delete" );
187 aout_unlock_mixer( p_aout );
191 /* Remove the input from the list. */
192 p_aout->i_nb_inputs--;
193 assert( p_aout->i_nb_inputs == 0 );
195 aout_InputDelete( p_aout, p_input );
197 vlc_mutex_destroy( &p_input->lock );
200 if ( !p_aout->i_nb_inputs )
202 aout_OutputDelete( p_aout );
203 aout_MixerDelete( p_aout );
204 var_Destroy( p_aout, "audio-device" );
205 var_Destroy( p_aout, "audio-channels" );
208 aout_unlock_mixer( p_aout );
218 /*****************************************************************************
219 * aout_DecNewBuffer : ask for a new empty buffer
220 *****************************************************************************/
221 aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input,
222 size_t i_nb_samples )
227 aout_lock_input( NULL, p_input );
229 if ( p_input->b_error )
231 aout_unlock_input( NULL, p_input );
235 length = i_nb_samples * p_input->input.i_bytes_per_frame
236 / p_input->input.i_frame_length;
237 block = block_Alloc( length );
239 /* Suppose the decoder doesn't have more than one buffered buffer */
240 p_input->b_changed = false;
242 aout_unlock_input( NULL, p_input );
244 if( likely(block != NULL) )
246 block->i_nb_samples = i_nb_samples;
247 block->i_pts = block->i_length = 0;
252 /*****************************************************************************
253 * aout_DecDeleteBuffer : destroy an undecoded buffer
254 *****************************************************************************/
255 void aout_DecDeleteBuffer( aout_instance_t * p_aout, aout_input_t * p_input,
256 aout_buffer_t * p_buffer )
258 (void)p_aout; (void)p_input;
259 aout_BufferFree( p_buffer );
262 /*****************************************************************************
263 * aout_DecPlay : filter & mix the decoded buffer
264 *****************************************************************************/
265 int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
266 aout_buffer_t * p_buffer, int i_input_rate )
268 assert( i_input_rate >= INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE &&
269 i_input_rate <= INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE );
271 assert( p_buffer->i_pts > 0 );
273 p_buffer->i_length = (mtime_t)p_buffer->i_nb_samples * 1000000
274 / p_input->input.i_rate;
276 aout_lock_mixer( p_aout );
277 aout_lock_input( p_aout, p_input );
279 if( p_input->b_error )
281 aout_unlock_input( p_aout, p_input );
282 aout_unlock_mixer( p_aout );
284 aout_BufferFree( p_buffer );
288 if( p_input->b_changed )
290 /* Maybe the allocation size has changed. Re-allocate a buffer. */
291 aout_buffer_t * p_new_buffer;
292 mtime_t duration = (1000000 * (mtime_t)p_buffer->i_nb_samples)
293 / p_input->input.i_rate;
295 p_new_buffer = aout_BufferAlloc( &p_input->input_alloc, duration, NULL);
296 vlc_memcpy( p_new_buffer->p_buffer, p_buffer->p_buffer,
297 p_buffer->i_buffer );
298 p_new_buffer->i_nb_samples = p_buffer->i_nb_samples;
299 p_new_buffer->i_buffer = p_buffer->i_buffer;
300 p_new_buffer->i_pts = p_buffer->i_pts;
301 p_new_buffer->i_length = p_buffer->i_length;
302 aout_BufferFree( p_buffer );
303 p_buffer = p_new_buffer;
304 p_input->b_changed = false;
307 aout_InputCheckAndRestart( p_aout, p_input );
308 aout_unlock_mixer( p_aout );
310 int i_ret = aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
312 aout_unlock_input( p_aout, p_input );
317 /* Run the mixer if it is able to run. */
318 aout_lock_mixer( p_aout );
320 aout_MixerRun( p_aout );
322 aout_unlock_mixer( p_aout );
327 int aout_DecGetResetLost( aout_instance_t *p_aout, aout_input_t *p_input )
329 aout_lock_input( p_aout, p_input );
330 int i_value = p_input->i_buffer_lost;
331 p_input->i_buffer_lost = 0;
332 aout_unlock_input( p_aout, p_input );
337 void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date )
339 mtime_t i_duration = 0;
340 aout_lock_input( p_aout, p_input );
341 assert( !p_input->b_paused || !b_paused );
342 if( p_input->b_paused )
344 i_duration = i_date - p_input->i_pause_date;
346 p_input->b_paused = b_paused;
347 p_input->i_pause_date = i_date;
348 aout_unlock_input( p_aout, p_input );
350 if( i_duration != 0 )
352 aout_lock_mixer( p_aout );
353 for( aout_buffer_t *p = p_input->mixer.fifo.p_first; p != NULL; p = p->p_next )
355 p->i_pts += i_duration;
357 aout_unlock_mixer( p_aout );
361 void aout_DecFlush( aout_instance_t *p_aout, aout_input_t *p_input )
363 aout_lock_input_fifos( p_aout );
365 aout_FifoSet( p_aout, &p_input->mixer.fifo, 0 );
366 p_input->mixer.begin = NULL;
368 aout_unlock_input_fifos( p_aout );