[vlc-devel] [PATCH] aout: add device cycling helper
Victorien Le Couviour--Tuffet
victorien.lecouviour.tuffet at gmail.com
Mon Nov 26 15:32:46 CET 2018
---
include/vlc_aout.h | 1 +
src/audio_output/output.c | 101 ++++++++++++++++++++++++++++++--------
src/libvlccore.sym | 1 +
3 files changed, 82 insertions(+), 21 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index aa49884001..ef78127c13 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -373,6 +373,7 @@ VLC_API int aout_MuteGet (audio_output_t *);
VLC_API int aout_MuteSet (audio_output_t *, bool);
VLC_API char *aout_DeviceGet (audio_output_t *);
VLC_API int aout_DeviceSet (audio_output_t *, const char *);
+VLC_API int aout_DeviceNext (audio_output_t *, char **);
VLC_API int aout_DevicesList (audio_output_t *, char ***, char ***);
/**
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 019797c5ef..dcf11e229d 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -686,6 +686,16 @@ char *aout_DeviceGet (audio_output_t *aout)
return var_GetNonEmptyString (aout, "device");
}
+static int aout_DeviceSetLocked(audio_output_t *aout, char const *id)
+{
+ aout_owner_t *owner = aout_owner(aout);
+ vlc_mutex_assert(&owner->dev.lock);
+ aout_OutputLock(aout);
+ int ret = aout->device_select(aout, id);
+ aout_OutputUnlock(aout);
+ return ret ? -1 : 0;
+}
+
/**
* Selects an audio output device.
* \param id device ID to select, or NULL for the default device
@@ -693,32 +703,21 @@ char *aout_DeviceGet (audio_output_t *aout)
*/
int aout_DeviceSet (audio_output_t *aout, const char *id)
{
- int ret;
-
- aout_OutputLock(aout);
- ret = aout->device_select(aout, id);
- aout_OutputUnlock(aout);
- return ret ? -1 : 0;
+ vlc_mutex_t *lock = &aout_owner(aout)->dev.lock;
+ vlc_mutex_lock(lock);
+ int ret = aout_DeviceSetLocked(aout, id);
+ vlc_mutex_unlock(lock);
+ return ret;
}
-/**
- * Enumerates possible audio output devices.
- *
- * The function will heap-allocate two tables of heap-allocated strings;
- * the caller is responsible for freeing all strings and both tables.
- *
- * \param ids pointer to a table of device identifiers [OUT]
- * \param names pointer to a table of device human-readable descriptions [OUT]
- * \return the number of devices, or negative on error.
- * \note In case of error, *ids and *names are undefined.
- */
-int aout_DevicesList (audio_output_t *aout, char ***ids, char ***names)
+static int aout_DevicesListLocked(audio_output_t *aout,
+ char ***ids, char ***names)
{
aout_owner_t *owner = aout_owner (aout);
+ vlc_mutex_assert(&owner->dev.lock);
char **tabid, **tabname;
unsigned i = 0;
- vlc_mutex_lock (&owner->dev.lock);
tabid = vlc_alloc (owner->dev.count, sizeof (*tabid));
tabname = vlc_alloc (owner->dev.count, sizeof (*tabname));
@@ -743,12 +742,10 @@ int aout_DevicesList (audio_output_t *aout, char ***ids, char ***names)
i++;
}
- vlc_mutex_unlock (&owner->dev.lock);
return i;
error:
- vlc_mutex_unlock(&owner->dev.lock);
while (i > 0)
{
i--;
@@ -760,6 +757,68 @@ error:
return -1;
}
+/**
+ * Enumerates possible audio output devices.
+ *
+ * The function will heap-allocate two tables of heap-allocated strings;
+ * the caller is responsible for freeing all strings and both tables.
+ *
+ * \param ids pointer to a table of device identifiers [OUT]
+ * \param names pointer to a table of device human-readable descriptions [OUT]
+ * \return the number of devices, or negative on error.
+ * \note In case of error, *ids and *names are undefined.
+ */
+int aout_DevicesList (audio_output_t *aout, char ***ids, char ***names)
+{
+ vlc_mutex_t *lock = &aout_owner(aout)->dev.lock;
+ vlc_mutex_lock(lock);
+ int ret = aout_DevicesListLocked(aout, ids, names);
+ vlc_mutex_unlock(lock);
+ return ret;
+}
+
+/**
+ * Cycle through audio output devices.
+ * \param p_name pointer to the selected device human-readable description [OUT]
+ * \return zero on success, non-zero on error.
+ */
+int aout_DeviceNext (audio_output_t *aout, char **p_name)
+{
+ aout_owner_t *owner = aout_owner(aout);
+ vlc_mutex_lock(&owner->dev.lock);
+
+ char **ids, **names;
+ int n = aout_DevicesListLocked(aout, &ids, &names);
+ if (n == -1)
+ {
+ vlc_mutex_unlock(&owner->dev.lock);
+ return -1;
+ }
+
+ char *device = aout_DeviceGet(aout);
+ int index;
+ for (index = 0; index < n; ++index)
+ if (!strcmp(ids[index], device))
+ {
+ index = (index + 1) % n;
+ break;
+ }
+ int ret = aout_DeviceSetLocked(aout, ids[index]);
+ vlc_mutex_unlock(&owner->dev.lock);
+ if (p_name != NULL)
+ *p_name = strdup(names[index]);
+
+ free(device);
+ for (int i = 0; i < n; ++i)
+ {
+ free(ids[i]);
+ free(names[i]);
+ }
+ free(ids);
+ free(names);
+ return ret;
+}
+
static void aout_ChangeViewpoint(audio_output_t *aout,
const vlc_viewpoint_t *p_viewpoint)
{
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 106135e3ca..d08e05d643 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -20,6 +20,7 @@ aout_MuteSet
aout_MuteGet
aout_DeviceGet
aout_DeviceSet
+aout_DeviceNext
aout_DevicesList
aout_FiltersNew
aout_FiltersChangeViewpoint
--
2.19.1
More information about the vlc-devel
mailing list