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;
aout->event.device_report(aout, 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)
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)
{
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);
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;
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;
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)
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);
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);
*/
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;
}