[vlc-commits] aout: add proper event for device hotplug (refs #8248)
Rémi Denis-Courmont
git at videolan.org
Sun Apr 14 10:51:34 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Apr 14 11:13:13 2013 +0300| [51406fae40544f6b9181b7429fd018d0120c70f5] | committer: Rémi Denis-Courmont
aout: add proper event for device hotplug (refs #8248)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=51406fae40544f6b9181b7429fd018d0120c70f5
---
include/vlc_aout.h | 12 +++++
src/audio_output/aout_internal.h | 8 ++++
src/audio_output/output.c | 95 ++++++++++++++++++++++++++++++++------
3 files changed, 100 insertions(+), 15 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index e660d47..eff26a8 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -178,6 +178,7 @@ struct audio_output
void (*mute_report)(audio_output_t *, bool);
void (*policy_report)(audio_output_t *, bool);
void (*device_report)(audio_output_t *, const char *);
+ void (*hotplug_report)(audio_output_t *, const char *, const char *);
int (*gain_request)(audio_output_t *, float);
void (*restart_request)(audio_output_t *, unsigned);
} event;
@@ -299,6 +300,17 @@ static inline void aout_DeviceReport(audio_output_t *aout, const char *id)
}
/**
+ * Report a device hot-plug event.
+ * @param id device ID
+ * @param name human-readable device name (NULL for hot unplug)
+ */
+static inline void aout_HotplugReport(audio_output_t *aout,
+ const char *id, const char *name)
+{
+ aout->event.hotplug_report(aout, id, name);
+}
+
+/**
* Request a change of software audio amplification.
* \param gain linear amplitude gain (must be positive)
* \warning Values in excess 1.0 may cause overflow and distorsion.
diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index 93c828f..b45df53 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -45,6 +45,7 @@ typedef struct
} aout_request_vout_t;
typedef struct aout_volume aout_volume_t;
+typedef struct aout_dev aout_dev_t;
typedef struct
{
@@ -62,6 +63,13 @@ typedef struct
struct
{
+ vlc_mutex_t lock;
+ aout_dev_t *list;
+ unsigned count;
+ } dev;
+
+ struct
+ {
mtime_t end; /**< Last seen PTS */
unsigned resamp_start_drift; /**< Resampler drift absolute value */
int resamp_type; /**< Resampler mode (FIXME: redundant / resampling) */
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 2f92c11..84653c3 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -37,6 +37,14 @@
static const char unset_str[1] = ""; /* Non-NULL constant string pointer */
+struct aout_dev
+{
+ aout_dev_t *next;
+ char *name;
+ char id[1];
+};
+
+
/* Local functions */
static void aout_OutputAssertLocked (audio_output_t *aout)
{
@@ -86,6 +94,50 @@ static void aout_DeviceNotify (audio_output_t *aout, const char *id)
var_SetString (aout, "device", (id != NULL) ? id : "");
}
+static void aout_HotplugNotify (audio_output_t *aout,
+ const char *id, const char *name)
+{
+ aout_owner_t *owner = aout_owner (aout);
+ aout_dev_t *dev, **pp = &owner->dev.list;
+
+ vlc_mutex_lock (&owner->dev.lock);
+ while ((dev = *pp) != NULL)
+ {
+ if (!strcmp (id, dev->id))
+ break;
+ pp = &dev->next;
+ }
+
+ if (name != NULL)
+ {
+ if (dev == NULL) /* Added device */
+ {
+ dev = malloc (sizeof (*dev) + strlen (id));
+ if (unlikely(dev == NULL))
+ goto out;
+ dev->next = NULL;
+ strcpy (dev->id, id);
+ *pp = dev;
+ owner->dev.count++;
+ }
+ else /* Modified device */
+ free (dev->name);
+ dev->name = strdup (name);
+ }
+ else
+ {
+ if (dev != NULL) /* Removed device */
+ {
+ owner->dev.count--;
+ *pp = dev->next;
+ free (dev->name);
+ free (dev);
+ }
+ }
+out:
+ vlc_mutex_unlock (&owner->dev.lock);
+}
+
static void aout_RestartNotify (audio_output_t *aout, unsigned mode)
{
aout_RequestRestart (aout, mode);
@@ -118,6 +170,7 @@ audio_output_t *aout_New (vlc_object_t *parent)
vlc_mutex_init (&owner->lock);
vlc_mutex_init (&owner->req.lock);
+ vlc_mutex_init (&owner->dev.lock);
owner->req.device = (char *)unset_str;
owner->req.volume = -1.f;
owner->req.mute = -1;
@@ -133,8 +186,9 @@ audio_output_t *aout_New (vlc_object_t *parent)
aout->event.volume_report = aout_VolumeNotify;
aout->event.mute_report = aout_MuteNotify;
- aout->event.device_report = aout_DeviceNotify;
aout->event.policy_report = aout_PolicyNotify;
+ aout->event.device_report = aout_DeviceNotify;
+ aout->event.hotplug_report = aout_HotplugNotify;
aout->event.gain_request = aout_GainNotify;
aout->event.restart_request = aout_RestartNotify;
@@ -143,7 +197,6 @@ audio_output_t *aout_New (vlc_object_t *parent)
aout->stop = NULL;
aout->volume_set = NULL;
aout->mute_set = NULL;
- aout->device_enum = NULL;
aout->device_select = NULL;
owner->module = module_need (aout, "audio output", "$aout", false);
if (owner->module == NULL)
@@ -277,6 +330,14 @@ static void aout_Destructor (vlc_object_t *obj)
audio_output_t *aout = (audio_output_t *)obj;
aout_owner_t *owner = aout_owner (aout);
+ vlc_mutex_destroy (&owner->dev.lock);
+ for (aout_dev_t *dev = owner->dev.list, *next; dev != NULL; dev = next)
+ {
+ next = dev->next;
+ free (dev->name);
+ free (dev);
+ }
+
assert (owner->req.device == unset_str);
vlc_mutex_destroy (&owner->req.lock);
vlc_mutex_destroy (&owner->lock);
@@ -461,14 +522,6 @@ static int aout_OutputDeviceSet (audio_output_t *aout, const char *id)
return (aout->device_select != NULL) ? aout->device_select (aout, id) : -1;
}
-static int aout_OutputDevicesEnum (audio_output_t *aout,
- char ***ids, char ***names)
-{
- aout_OutputAssertLocked (aout);
- return (aout->device_enum != NULL) ? aout->device_enum (aout, ids, names)
- : -1;
-}
-
void aout_OutputLock (audio_output_t *aout)
{
aout_owner_t *owner = aout_owner (aout);
@@ -624,10 +677,22 @@ int aout_DeviceSet (audio_output_t *aout, const char *id)
*/
int aout_DevicesList (audio_output_t *aout, char ***ids, char ***names)
{
- int ret;
+ aout_owner_t *owner = aout_owner (aout);
+ char **tabid, **tabname;
+ unsigned count;
+
+ vlc_mutex_lock (&owner->dev.lock);
+ count = owner->dev.count;
+ tabid = xmalloc (sizeof (*tabid) * count);
+ tabname = xmalloc (sizeof (*tabname) * count);
+ *ids = tabid;
+ *names = tabname;
+ for (aout_dev_t *dev = owner->dev.list; dev != NULL; dev = dev->next)
+ {
+ *(tabid++) = xstrdup (dev->id);
+ *(tabname++) = xstrdup (dev->name);
+ }
+ vlc_mutex_unlock (&owner->dev.lock);
- aout_OutputLock (aout);
- ret = aout_OutputDevicesEnum (aout, ids, names);
- aout_OutputUnlock (aout);
- return ret;
+ return count;
}
More information about the vlc-commits
mailing list