diff --git a/spa/plugins/alsa/alsa-monitor.c b/spa/plugins/alsa/alsa-monitor.c index 9bef481bd..830f10812 100644 --- a/spa/plugins/alsa/alsa-monitor.c +++ b/spa/plugins/alsa/alsa-monitor.c @@ -156,9 +156,11 @@ static int fill_item(struct impl *this, struct item *item, struct udev_device *d "alsa.card", str, NULL); - if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str) { + if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str) add_dict(builder, "device.class", str, NULL); - } + + if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str) + add_dict(builder, "device.plugged.usec", str, NULL); str = udev_device_get_property_value(dev, "ID_PATH"); if (!(str && *str)) @@ -208,10 +210,10 @@ static int fill_item(struct impl *this, struct item *item, struct udev_device *d return 1; } -static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id) +static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id, bool enumerated) { const char *str; - int idx, i; + int idx, i, found = -1; if (udev_device_get_property_value(dev, "PULSE_IGNORE")) return 0; @@ -224,26 +226,39 @@ static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id) idx = atoi(str); - if (id == SPA_MONITOR_EVENT_Added) { - for (i = 0; i < this->n_cards; i++) { - if (this->cards[i] == idx) - return 0; + for (i = 0; i < this->n_cards; i++) { + if (this->cards[i] == idx) { + found = i; + break; } + } + + switch (id) { + case SPA_MONITOR_EVENT_Added: + if (found != -1) + return 0; if (this->n_cards >= MAX_CARDS) return 0; this->cards[this->n_cards++] = idx; - } - if (id == SPA_MONITOR_EVENT_Removed) { - int found = -1; - for (i = 0; i < this->n_cards; i++) { - if (this->cards[i] == idx) { - found = i; - break; - } - } + /** don't notify on add, wait for the next change event */ + if (!enumerated) + return 0; + break; + + case SPA_MONITOR_EVENT_Changed: + if (found == -1) + return 0; + if ((str = udev_device_get_property_value(dev, "SOUND_INITIALIZED")) == NULL) + return 0; + break; + + case SPA_MONITOR_EVENT_Removed: if (found == -1) return 0; this->cards[found] = this->cards[--this->n_cards]; + break; + default: + return 0; } return 1; } @@ -266,6 +281,8 @@ static void impl_on_fd_events(struct spa_source *source) if ((action = udev_device_get_action(dev)) == NULL) action = "change"; + spa_log_debug(this->log, "action %s", action); + if (strcmp(action, "add") == 0) { id = SPA_MONITOR_EVENT_Added; } else if (strcmp(action, "change") == 0) { @@ -275,7 +292,7 @@ static void impl_on_fd_events(struct spa_source *source) } else return; - if (!need_notify(this, dev, id)) + if (!need_notify(this, dev, id, false)) return; spa_pod_builder_init(&b, buffer, sizeof(buffer)); @@ -369,7 +386,7 @@ static int impl_monitor_enum_items(struct spa_monitor *monitor, if (dev == NULL) goto next; - if (!need_notify(this, dev, SPA_MONITOR_EVENT_Added)) + if (!need_notify(this, dev, SPA_MONITOR_EVENT_Added, true)) goto next; if (fill_item(this, &this->uitem, dev, item, builder) != 1) diff --git a/spa/plugins/v4l2/v4l2-monitor.c b/spa/plugins/v4l2/v4l2-monitor.c index ebeda1250..bbac5eb6b 100644 --- a/spa/plugins/v4l2/v4l2-monitor.c +++ b/spa/plugins/v4l2/v4l2-monitor.c @@ -84,24 +84,24 @@ static inline void add_dict(struct spa_pod_builder *builder, const char *key, co spa_pod_builder_string(builder, val); } -static void fill_item(struct impl *this, struct item *item, struct udev_device *udevice, +static void fill_item(struct impl *this, struct item *item, struct udev_device *dev, struct spa_pod **result, struct spa_pod_builder *builder) { const char *str, *name; if (item->udevice) udev_device_unref(item->udevice); - item->udevice = udevice; - if (udevice == NULL) + item->udevice = dev; + if (dev == NULL) return; - name = udev_device_get_property_value(item->udevice, "ID_V4L_PRODUCT"); + name = udev_device_get_property_value(dev, "ID_V4L_PRODUCT"); if (!(name && *name)) { - name = udev_device_get_property_value(item->udevice, "ID_MODEL_FROM_DATABASE"); + name = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); if (!(name && *name)) { - name = udev_device_get_property_value(item->udevice, "ID_MODEL_ENC"); + name = udev_device_get_property_value(dev, "ID_MODEL_ENC"); if (!(name && *name)) { - name = udev_device_get_property_value(item->udevice, "ID_MODEL"); + name = udev_device_get_property_value(dev, "ID_MODEL"); } } } @@ -110,7 +110,7 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device * spa_pod_builder_push_object(builder, SPA_TYPE_OBJECT_MonitorItem, 0); spa_pod_builder_props(builder, - SPA_MONITOR_ITEM_id, &SPA_POD_Stringv(udev_device_get_syspath(item->udevice)), + SPA_MONITOR_ITEM_id, &SPA_POD_Stringv(udev_device_get_syspath(dev)), SPA_MONITOR_ITEM_flags, &SPA_POD_Id(SPA_MONITOR_ITEM_FLAG_NONE), SPA_MONITOR_ITEM_state, &SPA_POD_Id(SPA_MONITOR_ITEM_STATE_Available), SPA_MONITOR_ITEM_name, &SPA_POD_Stringv(name), @@ -123,48 +123,50 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device * spa_pod_builder_push_struct(builder); add_dict(builder, "udev-probed", "1"); add_dict(builder, "device.api", "v4l2"); - add_dict(builder, "device.path", udev_device_get_devnode(item->udevice)); + add_dict(builder, "device.path", udev_device_get_devnode(dev)); + if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str) + add_dict(builder, "device.plugged.usec", str); - str = udev_device_get_property_value(item->udevice, "ID_PATH"); + str = udev_device_get_property_value(dev, "ID_PATH"); if (!(str && *str)) - str = udev_device_get_syspath(item->udevice); + str = udev_device_get_syspath(dev); if (str && *str) { add_dict(builder, "device.bus_path", str); } - if ((str = udev_device_get_syspath(item->udevice)) && *str) { + if ((str = udev_device_get_syspath(dev)) && *str) { add_dict(builder, "sysfs.path", str); } - if ((str = udev_device_get_property_value(item->udevice, "ID_ID")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) { add_dict(builder, "udev.id", str); } - if ((str = udev_device_get_property_value(item->udevice, "ID_BUS")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) { add_dict(builder, "device.bus", str); } - if ((str = udev_device_get_property_value(item->udevice, "SUBSYSTEM")) && *str) { + if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) { add_dict(builder, "device.subsystem", str); } - if ((str = udev_device_get_property_value(item->udevice, "ID_VENDOR_ID")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) { add_dict(builder, "device.vendor.id", str); } - str = udev_device_get_property_value(item->udevice, "ID_VENDOR_FROM_DATABASE"); + str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE"); if (!(str && *str)) { - str = udev_device_get_property_value(item->udevice, "ID_VENDOR_ENC"); + str = udev_device_get_property_value(dev, "ID_VENDOR_ENC"); if (!(str && *str)) { - str = udev_device_get_property_value(item->udevice, "ID_VENDOR"); + str = udev_device_get_property_value(dev, "ID_VENDOR"); } } if (str && *str) { add_dict(builder, "device.vendor.name", str); } - if ((str = udev_device_get_property_value(item->udevice, "ID_MODEL_ID")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) { add_dict(builder, "device.product.id", str); } add_dict(builder, "device.product.name", name); - if ((str = udev_device_get_property_value(item->udevice, "ID_SERIAL")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) { add_dict(builder, "device.serial", str); } - if ((str = udev_device_get_property_value(item->udevice, "ID_V4L_CAPABILITIES")) && *str) { + if ((str = udev_device_get_property_value(dev, "ID_V4L_CAPABILITIES")) && *str) { add_dict(builder, "device.capabilities", str); } diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index bade49958..05ad57abc 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -116,8 +116,8 @@ static struct monitor_item *add_item(struct pw_spa_monitor *this, if ((str = pw_properties_get(props, "device.form_factor")) != NULL) if (strcmp(str, "internal") == 0) now = 0; - if (now != 0) - pw_properties_setf(props, "node.plugged", "%"PRIu64, now); + if (now != 0 && pw_properties_get(props, "device.plugged") == NULL) + pw_properties_setf(props, "device.plugged", "%"PRIu64, now); support = pw_core_get_support(impl->core, &n_support); @@ -227,11 +227,9 @@ static void change_item(struct pw_spa_monitor *this, struct spa_pod *item, uint6 switch (state) { case SPA_MONITOR_ITEM_STATE_Available: - pw_node_set_enabled(mitem->object, true); break; case SPA_MONITOR_ITEM_STATE_Disabled: case SPA_MONITOR_ITEM_STATE_Unavailable: - pw_node_set_enabled(mitem->object, false); break; default: break; @@ -247,7 +245,7 @@ static void on_monitor_event(void *data, struct spa_event *event) struct spa_pod *item; clock_gettime(CLOCK_MONOTONIC, &now); - now_nsec = now.tv_sec * SPA_NSEC_PER_SEC + now.tv_nsec; + now_nsec = SPA_TIMESPEC_TO_NSEC(&now); item = SPA_POD_CONTENTS(struct spa_event, event); switch (SPA_MONITOR_EVENT_ID(event)) {