[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