[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