[vlc-commits] aout: clean up output volume handling and fix races
Rémi Denis-Courmont
git at videolan.org
Mon Jul 25 21:54:52 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Jul 21 20:58:49 2011 +0300| [c7885fe12a838dd0d0269a23d3a9dbccc47f0f9d] | committer: Rémi Denis-Courmont
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.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c7885fe12a838dd0d0269a23d3a9dbccc47f0f9d
---
include/vlc_aout.h | 11 ++++--
src/audio_output/common.c | 1 +
src/audio_output/intf.c | 38 --------------------
src/audio_output/output.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
src/libvlccore.sym | 6 ++-
5 files changed, 98 insertions(+), 44 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 8805a8a..b7d9043 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -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 * );
/* */
diff --git a/src/audio_output/common.c b/src/audio_output/common.c
index f54083c..6ef4fdc 100644
--- a/src/audio_output/common.c
+++ b/src/audio_output/common.c
@@ -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 );
diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c
index bcb6f1e..375093a 100644
--- a/src/audio_output/intf.c
+++ b/src/audio_output/intf.c
@@ -231,44 +231,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
*/
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 8644b34..4a2449b 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -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
*****************************************************************************
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index a5a3a34..2a75e79 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -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
More information about the vlc-commits
mailing list