Commit c7885fe1 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

aout: clean up output volume handling and fix races

This should cleanup locking when applying the volume, though there are
still some (non-crashing) races in setting/getting the volume.

This also adds an API to report the volume from the output, though it's
currently left as a dummy.
parent 0ce2c2e5
......@@ -166,6 +166,8 @@ struct aout_fifo_t
struct aout_mixer_t;
typedef int (*aout_volume_cb) (audio_output_t *, float, bool);
/** Audio output object */
struct audio_output
{
......@@ -201,8 +203,7 @@ struct audio_output
void (*pf_play)( audio_output_t * ); /**< Audio buffer callback */
void (* pf_pause)( audio_output_t *, bool, mtime_t ); /**< Pause/resume
callback (optional, may be NULL) */
int (* pf_volume_set )(audio_output_t *, float, bool); /**< Volume setter
(optional, may be NULL) */
aout_volume_cb pf_volume_set; /**< Volume setter (or NULL) */
int i_nb_samples;
};
......@@ -273,9 +274,11 @@ VLC_API const char * aout_FormatPrintChannels( const audio_sample_format_t * ) V
VLC_API mtime_t aout_FifoFirstDate( const aout_fifo_t * ) VLC_USED;
VLC_API aout_buffer_t *aout_FifoPop( aout_fifo_t * p_fifo ) VLC_USED;
/* From intf.c : */
VLC_API void aout_VolumeSoftInit( audio_output_t * );
VLC_API void aout_VolumeNoneInit( audio_output_t * );
VLC_API void aout_VolumeSoftInit( audio_output_t * );
VLC_API void aout_VolumeHardInit( audio_output_t *, aout_volume_cb );
VLC_API void aout_VolumeHardSet( audio_output_t *, float, bool );
VLC_API int aout_ChannelsRestart( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * );
/* */
......
......@@ -66,6 +66,7 @@ audio_output_t *aout_New( vlc_object_t * p_parent )
p_aout->p_mixer = NULL;
p_aout->b_starving = true;
p_aout->module = NULL;
aout_VolumeNoneInit( p_aout );
var_Create( p_aout, "intf-change", VLC_VAR_VOID );
......
......@@ -230,44 +230,6 @@ int aout_SetMute (vlc_object_t *obj, audio_volume_t *volp, bool mute)
}
/*
* The next functions are not supposed to be called by the interface, but
* are placeholders for software-only scaling.
*/
static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
{
aout->mixer_multiplier = mute ? 0. : volume;
return 0;
}
/* Meant to be called by the output plug-in's Open(). */
void aout_VolumeSoftInit (audio_output_t *aout)
{
audio_volume_t volume = var_InheritInteger (aout, "volume");
bool mute = var_InheritBool (aout, "mute");
aout->pf_volume_set = aout_VolumeSoftSet;
aout_VolumeSoftSet (aout, volume / (float)AOUT_VOLUME_DEFAULT, mute);
}
/*
* The next functions are not supposed to be called by the interface, but
* are placeholders for unsupported scaling.
*/
static int aout_VolumeNoneSet (audio_output_t *aout, float volume, bool mute)
{
(void)aout; (void)volume; (void)mute;
return -1;
}
/* Meant to be called by the output plug-in's Open(). */
void aout_VolumeNoneInit( audio_output_t * p_aout )
{
p_aout->pf_volume_set = aout_VolumeNoneSet;
}
/*
* Pipelines management
*/
......
......@@ -30,6 +30,7 @@
#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_aout_intf.h>
#include <vlc_cpu.h>
#include <vlc_modules.h>
......@@ -210,6 +211,7 @@ void aout_OutputDelete( audio_output_t * p_aout )
return;
module_unneed( p_aout, p_aout->module );
aout_VolumeNoneInit( p_aout ); /* clear volume callback */
p_aout->module = NULL;
aout_FiltersDestroyPipeline( p_aout->pp_filters, p_aout->i_nb_filters );
aout_FifoDestroy( &p_aout->fifo );
......@@ -250,6 +252,90 @@ void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date )
aout->pf_pause( aout, pause, date );
}
/*** Volume handling ***/
/**
* Dummy volume setter. This is the default volume setter.
*/
static int aout_VolumeNoneSet (audio_output_t *aout, float volume, bool mute)
{
(void)aout; (void)volume; (void)mute;
return -1;
}
/**
* Configures the dummy volume setter.
* @note Audio output plugins for which volume is irrelevant
* should call this function during activation.
*/
void aout_VolumeNoneInit (audio_output_t *aout)
{
/* aout_New() -safely- calls this function without the lock, before any
* other thread knows of this audio output instance.
vlc_assert_locked (&aout->lock); */
aout->pf_volume_set = aout_VolumeNoneSet;
}
/**
* Volume setter for software volume.
*/
static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
{
vlc_assert_locked (&aout->lock);
aout->mixer_multiplier = mute ? 0. : volume;
return 0;
}
/**
* Configures the volume setter for software mixing
* and apply the default volume.
* @note Audio output plugins that cannot apply the volume
* should call this function during activation.
*/
void aout_VolumeSoftInit (audio_output_t *aout)
{
audio_volume_t volume = var_InheritInteger (aout, "volume");
bool mute = var_InheritBool (aout, "mute");
vlc_assert_locked (&aout->lock);
aout->pf_volume_set = aout_VolumeSoftSet;
aout_VolumeSoftSet (aout, volume / (float)AOUT_VOLUME_DEFAULT, mute);
}
/**
* Configures a custom volume setter. This is used by audio outputs that can
* control the hardware volume directly and/or emulate it internally.
* @param setter volume setter callback
*/
void aout_VolumeHardInit (audio_output_t *aout, aout_volume_cb setter)
{
vlc_assert_locked (&aout->lock);
aout->pf_volume_set = setter;
}
/**
* Supply or update the current custom ("hardware") volume.
* @note This only makes sense after calling aout_VolumeHardInit().
* @param setter volume setter callback
* @param volume current custom volume
* @param mute current mute flag
* @note Audio output plugins that cannot apply the volume
* should call this function during activation.
*/
void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute)
{
#warning FIXME
/* REVISIT: This is tricky. We cannot acquire the volume lock as this gets
* called from the audio output (it would cause a lock inversion).
* We also should not override the input manager volume, but only the
* volume of the current audio output... FIXME */
msg_Err (aout, "%s(%f, %u)", __func__, volume, (unsigned)mute);
}
/*** Buffer management ***/
/*****************************************************************************
* aout_OutputNextBuffer : give the audio output plug-in the right buffer
*****************************************************************************
......
......@@ -21,13 +21,15 @@ aout_FormatPrint
aout_FormatPrintChannels
aout_OutputNextBuffer
aout_VolumeGet
aout_VolumeSet
aout_VolumeUp
aout_ToggleMute
aout_IsMuted
aout_SetMute
aout_VolumeNoneInit
aout_VolumeSet
aout_VolumeSoftInit
aout_VolumeUp
aout_VolumeHardInit
aout_VolumeHardSet
block_Alloc
block_FifoCount
block_FifoEmpty
......
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