]> git.sesse.net Git - vlc/commitdiff
aout: clean up output volume handling and fix races
authorRémi Denis-Courmont <remi@remlab.net>
Thu, 21 Jul 2011 17:58:49 +0000 (20:58 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Mon, 25 Jul 2011 19:49:22 +0000 (22:49 +0300)
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.

include/vlc_aout.h
src/audio_output/common.c
src/audio_output/intf.c
src/audio_output/output.c
src/libvlccore.sym

index 8805a8a8b389088d40303caf952e4952be84f769..b7d90437847926955bff24332facb9114fe7f4fe 100644 (file)
@@ -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 * );
 
 /* */
index f54083c36fdb20a745cb058b4f8919890e94b4d4..6ef4fdca532f22c370a44c43eb4771203d1bb437 100644 (file)
@@ -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 );
 
index bcb6f1e67e060a13d43f99950b62cf412844b964..375093a39a247d9b972eb070120ecadb990a02f9 100644 (file)
@@ -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
  */
index 8644b34f4c83b8a0b3e24e68a543d4f55b4830e4..4a2449bf55e6a38e12b03be63f19a82100ae865a 100644 (file)
@@ -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
  *****************************************************************************
index a5a3a345cb565c99f71010e06a19f13a1643950e..2a75e79898573786108d5a20a2313286038c08f5 100644 (file)
@@ -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