Commit 1d038ed7 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: privatize some attributes

parent da82f3f1
......@@ -164,8 +164,6 @@ struct aout_fifo_t
/* FIXME to remove once aout.h is cleaned a bit more */
#include <vlc_block.h>
struct aout_mixer_t;
typedef int (*aout_volume_cb) (audio_output_t *, float, bool);
/** Audio output object */
......@@ -173,32 +171,13 @@ struct audio_output
{
VLC_COMMON_MEMBERS
/* Lock for volume variables (FIXME: should be in input manager) */
vlc_mutex_t volume_lock;
vlc_mutex_t lock;
/* Input streams & pre-filters */
aout_input_t * p_input;
/* Mixer */
audio_sample_format_t mixer_format;
float mixer_multiplier;
struct audio_mixer *mixer;
audio_sample_format_t format; /**< Output format (plugin can modify it
only when succesfully probed and not afterward) */
/* Indicates whether the audio output is currently starving, to avoid
* printing a 1,000 "output is starving" messages. */
bool b_starving;
/* post-filters */
filter_t * pp_filters[AOUT_MAX_FILTERS];
int i_nb_filters;
aout_fifo_t fifo;
struct module_t *module; /**< Output plugin */
struct aout_sys_t *sys; /**< Output plugin private data */
void (*pf_play)( audio_output_t * ); /**< Audio buffer callback */
void (* pf_pause)( audio_output_t *, bool, mtime_t ); /**< Pause/resume
......
......@@ -91,7 +91,41 @@ struct aout_input_t
/* */
aout_fifo_t fifo;
};
};
typedef struct
{
module_t *module; /**< Output plugin (or NULL if inactive) */
aout_input_t *input;
struct
{
vlc_mutex_t lock;
float multiplier; /**< Software volume amplification multiplier */
struct audio_mixer *mixer; /**< Software volume plugin */
} volume; /**< Volume and gain management (FIXME: input manager?) */
audio_sample_format_t mixer_format;
/* Filters between mixer and output */
filter_t *filters[AOUT_MAX_FILTERS];
int nb_filters;
/* Indicates whether the audio output is currently starving, to avoid
* printing a 1,000 "output is starving" messages. */
bool b_starving;
} aout_owner_t;
typedef struct
{
audio_output_t output;
aout_owner_t owner;
} aout_instance_t;
static inline aout_owner_t *aout_owner (audio_output_t *aout)
{
return &((aout_instance_t *)aout)->owner;
}
/****************************************************************************
* Prototypes
......@@ -189,13 +223,13 @@ static inline void aout_unlock( audio_output_t *p_aout )
static inline void aout_lock_volume( audio_output_t *p_aout )
{
aout_lock_check( VOLUME_LOCK );
vlc_mutex_lock( &p_aout->volume_lock );
vlc_mutex_lock( &aout_owner(p_aout)->volume.lock );
}
static inline void aout_unlock_volume( audio_output_t *p_aout )
{
aout_unlock_check( VOLUME_LOCK );
vlc_mutex_unlock( &p_aout->volume_lock );
vlc_mutex_unlock( &aout_owner(p_aout)->volume.lock );
}
/* Helpers */
......@@ -206,8 +240,8 @@ static inline void aout_unlock_volume( audio_output_t *p_aout )
static inline void AoutInputsMarkToRestart( audio_output_t *p_aout )
{
aout_lock( p_aout );
if( p_aout->p_input != NULL )
p_aout->p_input->b_restart = true;
if( aout_owner(p_aout)->input != NULL )
aout_owner(p_aout)->input->b_restart = true;
aout_unlock( p_aout );
}
......
......@@ -49,40 +49,40 @@ static void aout_Destructor( vlc_object_t * p_this );
*****************************************************************************/
audio_output_t *aout_New( vlc_object_t * p_parent )
{
audio_output_t * p_aout;
/* Allocate descriptor. */
p_aout = vlc_custom_create( p_parent, sizeof( *p_aout ), "audio output" );
if( p_aout == NULL )
{
audio_output_t *aout = vlc_custom_create (p_parent,
sizeof (aout_instance_t),
"audio output");
if (unlikely(aout == NULL))
return NULL;
}
/* Initialize members. */
vlc_mutex_init( &p_aout->volume_lock );
vlc_mutex_init( &p_aout->lock );
p_aout->p_input = NULL;
p_aout->mixer_multiplier = 1.0;
p_aout->mixer = NULL;
p_aout->b_starving = true;
p_aout->module = NULL;
aout_VolumeNoneInit( p_aout );
aout_owner_t *owner = aout_owner (aout);
var_Create( p_aout, "intf-change", VLC_VAR_VOID );
owner->module = NULL;
owner->input = NULL;
vlc_mutex_init (&owner->volume.lock);
owner->volume.multiplier = 1.0;
owner->volume.mixer = NULL;
owner->b_starving = true;
vlc_object_set_destructor( p_aout, aout_Destructor );
vlc_mutex_init (&aout->lock);
return p_aout;
aout_VolumeNoneInit (aout);
vlc_object_set_destructor (aout, aout_Destructor);
var_Create (aout, "intf-change", VLC_VAR_VOID);
return aout;
}
/*****************************************************************************
* aout_Destructor: destroy aout structure
*****************************************************************************/
static void aout_Destructor( vlc_object_t * p_this )
static void aout_Destructor (vlc_object_t *obj)
{
audio_output_t * p_aout = (audio_output_t *)p_this;
vlc_mutex_destroy( &p_aout->volume_lock );
vlc_mutex_destroy( &p_aout->lock );
audio_output_t *aout = (audio_output_t *)obj;
aout_owner_t *owner = aout_owner (aout);
vlc_mutex_destroy (&owner->volume.lock);
vlc_mutex_destroy (&aout->lock);
}
#ifdef AOUT_DEBUG
......
......@@ -93,9 +93,10 @@ aout_input_t *aout_DecNew( audio_output_t *p_aout,
/* We can only be called by the decoder, so no need to lock
* p_input->lock. */
aout_owner_t *owner = aout_owner(p_aout);
aout_lock( p_aout );
assert( p_aout->p_input == NULL );
p_aout->p_input = p_input;
assert (owner->input == NULL);
owner->input = p_input;
var_Destroy( p_aout, "audio-device" );
var_Destroy( p_aout, "audio-channels" );
......@@ -105,9 +106,9 @@ aout_input_t *aout_DecNew( audio_output_t *p_aout,
#warning Input without output and mixer = bad idea.
goto out;
assert( p_aout->mixer == NULL );
p_aout->mixer = aout_MixerNew( p_aout, &p_aout->mixer_format );
if( p_aout->mixer == NULL )
assert (owner->volume.mixer == NULL);
owner->volume.mixer = aout_MixerNew (p_aout, &owner->mixer_format);
if (owner->volume.mixer == NULL)
{
aout_OutputDelete( p_aout );
#warning Memory leak.
......@@ -126,19 +127,24 @@ out:
*****************************************************************************/
void aout_DecDelete( audio_output_t * p_aout, aout_input_t * p_input )
{
aout_owner_t *owner = aout_owner (p_aout);
struct audio_mixer *mixer;
aout_lock( p_aout );
/* Remove the input. */
assert( p_input == p_aout->p_input ); /* buggy decoder? */
p_aout->p_input = NULL;
assert (owner->input == p_input); /* buggy decoder? */
owner->input = NULL;
aout_InputDelete( p_aout, p_input );
aout_OutputDelete( p_aout );
aout_MixerDelete( p_aout->mixer );
p_aout->mixer = NULL;
mixer = owner->volume.mixer;
owner->volume.mixer = NULL;
var_Destroy( p_aout, "audio-device" );
var_Destroy( p_aout, "audio-channels" );
aout_unlock( p_aout );
aout_MixerDelete (mixer);
free( p_input );
}
......@@ -180,6 +186,7 @@ void aout_DecDeleteBuffer( audio_output_t * p_aout, aout_input_t * p_input,
int aout_DecPlay( audio_output_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer, int i_input_rate )
{
aout_owner_t *owner = aout_owner (p_aout);
assert( i_input_rate >= INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE &&
i_input_rate <= INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE );
assert( p_buffer->i_pts > 0 );
......@@ -202,8 +209,8 @@ int aout_DecPlay( audio_output_t * p_aout, aout_input_t * p_input,
if( p_buffer != NULL )
{
/* Mixer */
float amp = p_aout->mixer_multiplier * p_input->multiplier;
aout_MixerRun( p_aout->mixer, p_buffer, amp );
float amp = owner->volume.multiplier * p_input->multiplier;
aout_MixerRun (owner->volume.mixer, p_buffer, amp);
/* Output */
aout_OutputPlay( p_aout, p_buffer );
......@@ -227,8 +234,10 @@ int aout_DecGetResetLost( audio_output_t *p_aout, aout_input_t *p_input )
void aout_DecChangePause( audio_output_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date )
{
aout_owner_t *owner = aout_owner (p_aout);
aout_lock( p_aout );
assert( p_aout->p_input == p_input );
assert (owner->input == p_input);
aout_OutputPause( p_aout, b_paused, i_date );
......
......@@ -70,6 +70,7 @@ static vout_thread_t *RequestVout( void *,
*****************************************************************************/
int aout_InputNew( audio_output_t * p_aout, aout_input_t * p_input, const aout_request_vout_t *p_request_vout )
{
aout_owner_t *owner = aout_owner (p_aout);
audio_sample_format_t chain_input_format;
audio_sample_format_t chain_output_format;
vlc_value_t val, text;
......@@ -81,7 +82,7 @@ int aout_InputNew( audio_output_t * p_aout, aout_input_t * p_input, const aout_r
p_input->i_nb_resamplers = p_input->i_nb_filters = 0;
/* Prepare FIFO. */
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer_format.i_rate );
aout_FifoInit (p_aout, &p_input->fifo, owner->mixer_format.i_rate);
/* */
if( p_request_vout )
......@@ -96,7 +97,7 @@ int aout_InputNew( audio_output_t * p_aout, aout_input_t * p_input, const aout_r
/* Prepare format structure */
chain_input_format = p_input->input;
chain_output_format = p_aout->mixer_format;
chain_output_format = owner->mixer_format;
chain_output_format.i_rate = p_input->input.i_rate;
aout_FormatPrepare( &chain_output_format );
......@@ -384,20 +385,20 @@ int aout_InputNew( audio_output_t * p_aout, aout_input_t * p_input, const aout_r
}
/* Create resamplers. */
if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer_format ) )
if (!AOUT_FMT_NON_LINEAR(&owner->mixer_format))
{
chain_output_format.i_rate = (__MAX(p_input->input.i_rate,
p_aout->mixer_format.i_rate)
owner->mixer_format.i_rate)
* (100 + AOUT_MAX_RESAMPLING)) / 100;
if ( chain_output_format.i_rate == p_aout->mixer_format.i_rate )
if ( chain_output_format.i_rate == owner->mixer_format.i_rate )
{
/* Just in case... */
chain_output_format.i_rate++;
}
if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers,
&p_input->i_nb_resamplers,
&chain_output_format,
&p_aout->mixer_format ) < 0 )
if (aout_FiltersCreatePipeline (p_aout, p_input->pp_resamplers,
&p_input->i_nb_resamplers,
&chain_output_format,
&owner->mixer_format) < 0)
{
inputFailure( p_aout, p_input, "couldn't set a resampler pipeline");
return -1;
......@@ -458,6 +459,7 @@ int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input )
*****************************************************************************/
void aout_InputCheckAndRestart( audio_output_t * p_aout, aout_input_t * p_input )
{
aout_owner_t *owner = aout_owner (p_aout);
AOUT_ASSERT_LOCKED;
if( !p_input->b_restart )
......@@ -468,7 +470,7 @@ void aout_InputCheckAndRestart( audio_output_t * p_aout, aout_input_t * p_input
aout_fifo_t fifo = p_input->fifo;
mtime_t i_pause_date = p_input->i_pause_date;
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer_format.i_rate );
aout_FifoInit (p_aout, &p_input->fifo, owner->mixer_format.i_rate);
aout_InputDelete( p_aout, p_input );
......@@ -856,12 +858,13 @@ static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd,
{
VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
VLC_UNUSED(newval); VLC_UNUSED(p_data);
audio_output_t *p_aout = (audio_output_t *)p_this;
audio_output_t *aout = (audio_output_t *)p_this;
aout_owner_t *owner = aout_owner (aout);
aout_lock( p_aout );
if( p_aout->p_input != NULL )
ReplayGainSelect( p_aout, p_aout->p_input );
aout_unlock( p_aout );
aout_lock (aout);
if (owner->input != NULL)
ReplayGainSelect (aout, owner->input);
aout_unlock (aout);
return VLC_SUCCESS;
}
......
......@@ -86,11 +86,12 @@ static int commitVolume (vlc_object_t *obj, audio_output_t *aout,
if (aout != NULL)
{
aout_owner_t *owner = aout_owner (aout);
float vol = volume / (float)AOUT_VOLUME_DEFAULT;
aout_lock (aout);
#warning FIXME: wrong test. Need to check that aout_output is ready.
if (aout->mixer != NULL)
if (owner->volume.mixer != NULL)
ret = aout->pf_volume_set (aout, vol, mute);
aout_unlock (aout);
......@@ -244,9 +245,10 @@ int aout_SetMute (vlc_object_t *obj, audio_volume_t *volp, bool mute)
static int aout_Restart( audio_output_t * p_aout )
{
aout_input_t *p_input;
aout_owner_t *owner = aout_owner (p_aout);
aout_lock( p_aout );
p_input = p_aout->p_input;
p_input = owner->input;
if( p_input == NULL )
{
aout_unlock( p_aout );
......@@ -256,8 +258,8 @@ static int aout_Restart( audio_output_t * p_aout )
/* Reinitializes the output */
aout_InputDelete( p_aout, p_input );
aout_MixerDelete( p_aout->mixer );
p_aout->mixer = NULL;
aout_MixerDelete (owner->volume.mixer);
owner->volume.mixer = NULL;
aout_OutputDelete( p_aout );
/* FIXME: This function is notoriously dangerous/unsafe.
......@@ -269,8 +271,8 @@ static int aout_Restart( audio_output_t * p_aout )
return -1;
}
p_aout->mixer = aout_MixerNew( p_aout, &p_aout->mixer_format );
if( p_aout->mixer == NULL )
owner->volume.mixer = aout_MixerNew (p_aout, &owner->mixer_format);
if (owner->volume.mixer == NULL)
{
aout_OutputDelete( p_aout );
aout_unlock( p_aout );
......
......@@ -43,9 +43,11 @@
*****************************************************************************
* This function is entered with the mixer lock.
*****************************************************************************/
int aout_OutputNew( audio_output_t * p_aout,
int aout_OutputNew( audio_output_t *p_aout,
const audio_sample_format_t * p_format )
{
aout_owner_t *owner = aout_owner (p_aout);
vlc_assert_locked( &p_aout->lock );
p_aout->format = *p_format;
......@@ -56,8 +58,8 @@ int aout_OutputNew( audio_output_t * p_aout,
aout_FormatPrepare( &p_aout->format );
/* Find the best output plug-in. */
p_aout->module = module_need( p_aout, "audio output", "$aout", false );
if ( p_aout->module == NULL )
owner->module = module_need (p_aout, "audio output", "$aout", false);
if (owner->module == NULL)
{
msg_Err( p_aout, "no suitable audio output module" );
return -1;
......@@ -163,37 +165,36 @@ int aout_OutputNew( audio_output_t * p_aout,
aout_FormatPrint( p_aout, "output", &p_aout->format );
/* Choose the mixer format. */
p_aout->mixer_format = p_aout->format;
if ( AOUT_FMT_NON_LINEAR(&p_aout->format) )
p_aout->mixer_format.i_format = p_format->i_format;
owner->mixer_format = p_aout->format;
if (AOUT_FMT_NON_LINEAR(&p_aout->format))
owner->mixer_format.i_format = p_format->i_format;
else
/* Most audio filters can only deal with single-precision,
* so lets always use that when hardware supports floating point. */
if( HAVE_FPU )
p_aout->mixer_format.i_format = VLC_CODEC_FL32;
owner->mixer_format.i_format = VLC_CODEC_FL32;
else
/* Otherwise, audio filters will not work. Use fixed-point if the input has
* more than 16-bits depth. */
if( p_format->i_bitspersample > 16 )
p_aout->mixer_format.i_format = VLC_CODEC_FI32;
owner->mixer_format.i_format = VLC_CODEC_FI32;
else
/* Fallback to 16-bits. This avoids pointless conversion to and from
* 32-bits samples for the sole purpose of software mixing. */
p_aout->mixer_format.i_format = VLC_CODEC_S16N;
owner->mixer_format.i_format = VLC_CODEC_S16N;
aout_FormatPrepare( &p_aout->mixer_format );
aout_FormatPrint( p_aout, "mixer", &p_aout->mixer_format );
aout_FormatPrepare (&owner->mixer_format);
aout_FormatPrint (p_aout, "mixer", &owner->mixer_format);
/* Create filters. */
p_aout->i_nb_filters = 0;
if ( aout_FiltersCreatePipeline( p_aout, p_aout->pp_filters,
&p_aout->i_nb_filters,
&p_aout->mixer_format,
&p_aout->format ) < 0 )
owner->nb_filters = 0;
if (aout_FiltersCreatePipeline (p_aout, owner->filters,
&owner->nb_filters, &owner->mixer_format,
&p_aout->format) < 0)
{
msg_Err( p_aout, "couldn't create audio output pipeline" );
module_unneed( p_aout, p_aout->module );
p_aout->module = NULL;
module_unneed (p_aout, owner->module);
owner->module = NULL;
return -1;
}
return 0;
......@@ -206,15 +207,17 @@ int aout_OutputNew( audio_output_t * p_aout,
*****************************************************************************/
void aout_OutputDelete( audio_output_t * p_aout )
{
aout_owner_t *owner = aout_owner (p_aout);
vlc_assert_locked( &p_aout->lock );
if( p_aout->module == NULL )
if (owner->module == NULL)
return;
module_unneed( p_aout, p_aout->module );
module_unneed (p_aout, owner->module);
aout_VolumeNoneInit( p_aout ); /* clear volume callback */
p_aout->module = NULL;
aout_FiltersDestroyPipeline( p_aout->pp_filters, p_aout->i_nb_filters );
owner->module = NULL;
aout_FiltersDestroyPipeline (owner->filters, owner->nb_filters);
aout_FifoDestroy( &p_aout->fifo );
}
......@@ -227,9 +230,11 @@ static block_t *aout_OutputSlice( audio_output_t *, aout_fifo_t * );
*****************************************************************************/
void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer )
{
aout_owner_t *owner = aout_owner (p_aout);
vlc_assert_locked( &p_aout->lock );
aout_FiltersPlay( p_aout->pp_filters, p_aout->i_nb_filters, &p_buffer );
aout_FiltersPlay (owner->filters, owner->nb_filters, &p_buffer);
if( !p_buffer )
return;
if( p_buffer->i_buffer == 0 )
......@@ -238,7 +243,7 @@ void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer )
return;
}
aout_fifo_t *fifo = &p_aout->p_input->fifo;
aout_fifo_t *fifo = &owner->input->fifo;
/* XXX: cleanup */
aout_FifoPush( fifo, p_buffer );
......@@ -256,13 +261,15 @@ void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer )
*/
void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date )
{
aout_owner_t *owner = aout_owner (aout);
vlc_assert_locked( &aout->lock );
if( aout->pf_pause != NULL )
aout->pf_pause( aout, pause, date );
if( !pause )
{
mtime_t duration = date - aout->p_input->i_pause_date;
mtime_t duration = date - owner->input->i_pause_date;
/* XXX: ^ onk onk! gruik! ^ */
aout_FifoMoveDates( &aout->fifo, duration );
}
......@@ -313,6 +320,8 @@ void aout_VolumeNoneInit (audio_output_t *aout)
*/
static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
{
aout_owner_t *owner = aout_owner (aout);
vlc_assert_locked (&aout->lock);
/* Cubic mapping from software volume to amplification factor.
......@@ -326,7 +335,7 @@ static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
else
volume = 0.;
aout->mixer_multiplier = volume;
owner->volume.multiplier = volume;
return 0;
}
......@@ -541,6 +550,7 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
mtime_t start_date,
bool b_can_sleek )
{
aout_owner_t *owner = aout_owner (p_aout);
aout_fifo_t *p_fifo = &p_aout->fifo;
aout_buffer_t * p_buffer;
mtime_t now = mdate();
......@@ -581,15 +591,15 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
*/
if ( 0 > delta + p_buffer->i_length )
{
if ( !p_aout->b_starving )
if (!owner->b_starving)
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
"playing silence", -delta );
p_aout->b_starving = true;
owner->b_starving = true;
p_buffer = NULL;
goto out;
}
p_aout->b_starving = false;
owner->b_starving = false;
p_buffer = aout_FifoPop( p_fifo );
if( !b_can_sleek
......@@ -599,7 +609,7 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", delta );
aout_FifoMoveDates( &p_aout->p_input->fifo, delta );
aout_FifoMoveDates (&owner->input->fifo, delta);
aout_FifoMoveDates( p_fifo, delta );
}
out:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment