[vlc-devel] [PATCH] aout: add device cycling helper
Thomas Guillem
thomas at gllm.fr
Wed Nov 28 15:11:07 CET 2018
On Wed, Nov 28, 2018, at 15:05, Victorien Le Couviour--Tuffet wrote:
> ---
> include/vlc_aout.h | 1 +
> src/audio_output/output.c | 101 +++++++++++++++++++++++++++++++-------
> src/libvlccore.sym | 1 +
> 3 files changed, 84 insertions(+), 19 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..fa07569925 100644
> --- a/src/audio_output/output.c
> +++ b/src/audio_output/output.c
> @@ -686,6 +686,14 @@ 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->lock);
> + vlc_mutex_assert(&owner->dev.lock);
> + return aout->device_select(aout, id) ? -1 : 0;
Deadlock if a module calls aout_HotplugReport() from this callback.
> +}
> +
> /**
> * Selects an audio output device.
> * \param id device ID to select, or NULL for the default device
> @@ -693,32 +701,23 @@ 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);
> + vlc_mutex_t *lock = &aout_owner(aout)->dev.lock;
> + vlc_mutex_lock(lock);
> + int ret = aout_DeviceSetLocked(aout, id);
> + vlc_mutex_unlock(lock);
> aout_OutputUnlock(aout);
> - return ret ? -1 : 0;
> + 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,72 @@ 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)
> +{
> + int ret = -1;
> + aout_OutputLock(aout);
> + vlc_mutex_t *lock = &aout_owner(aout)->dev.lock;
> + vlc_mutex_lock(lock);
> +
> + char **ids, **names;
> + int n = aout_DevicesListLocked(aout, &ids, &names);
> + if (n == -1)
> + goto end;
> + char *device = aout_DeviceGet(aout);
> + if (!device)
> + goto no_dev;
> +
> + int index;
> + for (index = 0; index < n; ++index)
> + if (!strcmp(ids[index], device))
> + {
> + index = (index + 1) % n;
> + break;
> + }
> + ret = aout_DeviceSetLocked(aout, ids[index]);
> + if (p_name != NULL)
> + *p_name = strdup(names[index]);
> +
> + free(device);
> +no_dev:
> + for (int i = 0; i < n; ++i)
> + {
> + free(ids[i]);
> + free(names[i]);
> + }
> + free(ids);
> + free(names);
> +end:
> + vlc_mutex_unlock(lock);
> + aout_OutputUnlock(aout);
> + 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 d4db4ccc51..41af4b48db 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
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list