Commit 33cf1494 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

libvlc: thread-safe and more straight-forward audio devices API

Also improve documentation, and deprecate the old broken functions.
parent b27ba687
...@@ -72,6 +72,17 @@ typedef struct libvlc_audio_output_t ...@@ -72,6 +72,17 @@ typedef struct libvlc_audio_output_t
} libvlc_audio_output_t; } libvlc_audio_output_t;
/**
* Description for audio output device.
*/
typedef struct libvlc_audio_output_device_t
{
struct libvlc_audio_output_device_t *p_next; /**< Next entry in list */
char *psz_device; /**< Device identifier string */
char *psz_description; /**< User-friendly device description */
/* More fields may be added here in later versions */
} libvlc_audio_output_device_t;
/** /**
* Rectangle type for video geometry * Rectangle type for video geometry
*/ */
...@@ -1362,7 +1373,7 @@ typedef enum libvlc_audio_output_channel_t { ...@@ -1362,7 +1373,7 @@ typedef enum libvlc_audio_output_channel_t {
/** /**
* Get the list of available audio outputs * Gets the list of available audio outputs
* *
* \param p_instance libvlc instance * \param p_instance libvlc instance
* \return list of available audio outputs. It must be freed it with * \return list of available audio outputs. It must be freed it with
...@@ -1370,18 +1381,20 @@ typedef enum libvlc_audio_output_channel_t { ...@@ -1370,18 +1381,20 @@ typedef enum libvlc_audio_output_channel_t {
* In case of error, NULL is returned. * In case of error, NULL is returned.
*/ */
LIBVLC_API libvlc_audio_output_t * LIBVLC_API libvlc_audio_output_t *
libvlc_audio_output_list_get( libvlc_instance_t *p_instance ); libvlc_audio_output_list_get( libvlc_instance_t *p_instance );
/** /**
* Free the list of available audio outputs * Frees the list of available audio outputs
* *
* \param p_list list with audio outputs for release * \param p_list list with audio outputs for release
*/ */
LIBVLC_API void libvlc_audio_output_list_release( libvlc_audio_output_t *p_list ); LIBVLC_API
void libvlc_audio_output_list_release( libvlc_audio_output_t *p_list );
/** /**
* Set the audio output. * Sets the audio output.
* Change will be applied after stop and play. * \note Any change will take be effect only after playback is stopped and
* restarted. Audio output cannot be changed while playing.
* *
* \param p_mi media player * \param p_mi media player
* \param psz_name name of audio output, * \param psz_name name of audio output,
...@@ -1392,46 +1405,81 @@ LIBVLC_API int libvlc_audio_output_set( libvlc_media_player_t *p_mi, ...@@ -1392,46 +1405,81 @@ LIBVLC_API int libvlc_audio_output_set( libvlc_media_player_t *p_mi,
const char *psz_name ); const char *psz_name );
/** /**
* Get count of devices for audio output, these devices are hardware oriented * Backward compatibility stub. Do not use in new code.
* like analor or digital output of sound card * Use libvlc_audio_output_device_list_get() instead.
* * \return always 0.
* \param p_instance libvlc instance */
* \param psz_audio_output - name of audio output, \see libvlc_audio_output_t LIBVLC_DEPRECATED
* \return number of devices int libvlc_audio_output_device_count( libvlc_instance_t *, const char * );
/**
* Backward compatibility stub. Do not use in new code.
* Use libvlc_audio_output_device_list_get() instead.
* \return always NULL.
*/
LIBVLC_DEPRECATED
char *libvlc_audio_output_device_longname( libvlc_instance_t *, const char *,
int );
/**
* Backward compatibility stub. Do not use in new code.
* Use libvlc_audio_output_device_list_get() instead.
* \return always NULL.
*/ */
LIBVLC_API int libvlc_audio_output_device_count( libvlc_instance_t *p_instance, LIBVLC_DEPRECATED
const char *psz_audio_output ); char *libvlc_audio_output_device_id( libvlc_instance_t *, const char *, int );
/** /**
* Get long name of device, if not available short name given * Gets a list of audio output devices for a given audio output.
* \see libvlc_audio_output_device_set().
*
* \note Not all audio outputs support this. In particular, an empty (NULL)
* list of devices does <b>not</b> imply that the specified audio output does
* not work.
*
* \note The list might not be exhaustive.
*
* \warning Some audio output devices in the list might not actually work in
* some circumstances. By default, it is recommended to not specify any
* explicit audio device.
* *
* \param p_instance libvlc instance * \param p_instance libvlc instance
* \param psz_audio_output - name of audio output, \see libvlc_audio_output_t * \param psz_aout audio output name
* \param i_device device index * (as returned by libvlc_audio_output_list_get())
* \return long name of device * \return A NULL-terminated linked list of potential audio output devices.
* It must be freed it with libvlc_audio_output_device_list_release()
* \version LibVLC 2.1.0 or later.
*/ */
LIBVLC_API char * libvlc_audio_output_device_longname( libvlc_instance_t *p_instance, LIBVLC_API libvlc_audio_output_device_t *
const char *psz_audio_output, libvlc_audio_output_device_list_get( libvlc_instance_t *p_instance,
int i_device ); const char *aout );
/** /**
* Get id name of device * Frees a list of available audio output devices.
* *
* \param p_instance libvlc instance * \param p_list list with audio outputs for release
* \param psz_audio_output - name of audio output, \see libvlc_audio_output_t * \version LibVLC 2.1.0 or later.
* \param i_device device index
* \return id name of device, use for setting device, need to be free after use
*/ */
LIBVLC_API char * libvlc_audio_output_device_id( libvlc_instance_t *p_instance, LIBVLC_API void libvlc_audio_output_device_list_release(
const char *psz_audio_output, libvlc_audio_output_device_t *p_list );
int i_device );
/** /**
* Set audio output device. Changes are only effective after stop and play. * Configures an explicit audio output device for a given audio output plugin.
* A list of possible devices can be obtained with
* libvlc_audio_output_device_list_get().
*
* \note This function does not select the specified audio output plugin.
* libvlc_audio_output_set() is used for that purpose.
*
* \warning The syntax for the device parameter depends on the audio output.
* This is not portable. Only use this function if you know what you are doing.
* Some audio outputs do not support this function (e.g. PulseAudio, WASAPI).
* Some audio outputs require further parameters (e.g. ALSA: channels map).
* *
* \param p_mi media player * \param p_mi media player
* \param psz_audio_output - name of audio output, \see libvlc_audio_output_t * \param psz_audio_output - name of audio output, \see libvlc_audio_output_t
* \param psz_device_id device * \param psz_device_id device
* \return Nothing. Errors are ignored.
*/ */
LIBVLC_API void libvlc_audio_output_device_set( libvlc_media_player_t *p_mi, LIBVLC_API void libvlc_audio_output_device_set( libvlc_media_player_t *p_mi,
const char *psz_audio_output, const char *psz_audio_output,
......
...@@ -135,119 +135,71 @@ int libvlc_audio_output_set( libvlc_media_player_t *mp, const char *psz_name ) ...@@ -135,119 +135,71 @@ int libvlc_audio_output_set( libvlc_media_player_t *mp, const char *psz_name )
return 0; return 0;
} }
/**************************** libvlc_audio_output_device_t *
* Get count of devices. libvlc_audio_output_device_list_get( libvlc_instance_t *p_instance,
*****************************/ const char *aout )
int libvlc_audio_output_device_count( libvlc_instance_t *p_instance,
const char *psz_audio_output )
{ {
char *psz_config_name; char varname[32];
if( !psz_audio_output ) if( (size_t)snprintf( varname, sizeof(varname), "%s-output-device", aout )
return 0; >= sizeof(varname) )
if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 ) return NULL;
return 0;
module_config_t *p_module_config = config_FindConfig(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name );
if( p_module_config && p_module_config->pf_update_list ) libvlc_audio_output_device_t *list = NULL, **pp = &list;
char **values, **texts;
ssize_t count = config_GetPszChoices( VLC_OBJECT(p_instance->p_libvlc_int),
varname, &values, &texts );
for( ssize_t i = 0; i < count; i++ )
{ {
vlc_value_t val; libvlc_audio_output_device_t *item = malloc( sizeof(*item) );
val.psz_string = strdup( p_module_config->value.psz ); if( unlikely(item == NULL) )
break;
p_module_config->pf_update_list(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL );
free( val.psz_string );
free( psz_config_name );
return p_module_config->i_list; *pp = item;
pp = &item->p_next;
item->psz_device = values[i];
item->psz_description = texts[i];
} }
free( psz_config_name ); *pp = NULL;
return 0; free( texts );
free( values );
(void) p_instance;
return list;
} }
/******************************** void libvlc_audio_output_device_list_release( libvlc_audio_output_device_t *l )
* Get long name of device
*********************************/
char * libvlc_audio_output_device_longname( libvlc_instance_t *p_instance,
const char *psz_audio_output,
int i_device )
{ {
char *psz_config_name; while( l != NULL )
if( !psz_audio_output )
return NULL;
if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 )
return NULL;
module_config_t *p_module_config = config_FindConfig(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name );
if( p_module_config )
{
// refresh if there arent devices
if( p_module_config->i_list < 2 && p_module_config->pf_update_list )
{
vlc_value_t val;
val.psz_string = strdup( p_module_config->value.psz );
p_module_config->pf_update_list(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL );
free( val.psz_string );
}
if( i_device >= 0 && i_device < p_module_config->i_list )
{ {
free( psz_config_name ); libvlc_audio_output_device_t *next = l->p_next;
if( p_module_config->ppsz_list_text[i_device] ) free( l->psz_description );
return strdup( p_module_config->ppsz_list_text[i_device] ); free( l->psz_device );
else free( l );
return strdup( p_module_config->ppsz_list[i_device] ); l = next;
}
} }
}
free( psz_config_name ); int libvlc_audio_output_device_count( libvlc_instance_t *p_instance,
return NULL; const char *psz_audio_output )
{
(void) p_instance; (void) psz_audio_output;
return 0;
} }
/******************************** char *libvlc_audio_output_device_longname( libvlc_instance_t *p_instance,
* Get id name of device
*********************************/
char * libvlc_audio_output_device_id( libvlc_instance_t *p_instance,
const char *psz_audio_output, const char *psz_audio_output,
int i_device ) int i_device )
{ {
char *psz_config_name; (void) p_instance; (void) psz_audio_output; (void) i_device;
if( !psz_audio_output )
return NULL; return NULL;
if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1) }
return NULL;
module_config_t *p_module_config = config_FindConfig(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name );
if( p_module_config )
{
// refresh if there arent devices
if( p_module_config->i_list < 2 && p_module_config->pf_update_list )
{
vlc_value_t val;
val.psz_string = strdup( p_module_config->value.psz );
p_module_config->pf_update_list(
VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL );
free( val.psz_string );
}
if( i_device >= 0 && i_device < p_module_config->i_list )
{
free( psz_config_name );
return strdup( p_module_config->ppsz_list[i_device] );
}
}
free( psz_config_name ); char *libvlc_audio_output_device_id( libvlc_instance_t *p_instance,
const char *psz_audio_output,
int i_device )
{
(void) p_instance; (void) psz_audio_output; (void) i_device;
return NULL; return NULL;
} }
......
...@@ -5,6 +5,8 @@ libvlc_vprinterr ...@@ -5,6 +5,8 @@ libvlc_vprinterr
libvlc_add_intf libvlc_add_intf
libvlc_audio_output_device_count libvlc_audio_output_device_count
libvlc_audio_output_device_id libvlc_audio_output_device_id
libvlc_audio_output_device_list_get
libvlc_audio_output_device_list_release
libvlc_audio_output_device_longname libvlc_audio_output_device_longname
libvlc_audio_output_device_set libvlc_audio_output_device_set
libvlc_audio_output_get_device_type libvlc_audio_output_get_device_type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment