diff --git a/spa/plugins/alsa/alsa-device.c b/spa/plugins/alsa/alsa-device.c index 6d20b68b4..825eb32bf 100644 --- a/spa/plugins/alsa/alsa-device.c +++ b/spa/plugins/alsa/alsa-device.c @@ -99,26 +99,20 @@ static const char *get_subclass(snd_pcm_info_t *pcminfo) } } -static int emit_node(struct impl *this, snd_ctl_card_info_t *info, snd_pcm_info_t *pcminfo) +static int emit_node(struct impl *this, snd_pcm_info_t *pcminfo) { - struct spa_dict_item items[12]; + struct spa_dict_item items[6]; const struct spa_handle_factory *factory; char device_name[128]; snprintf(device_name, 128, "%s,%d", this->props.device, snd_pcm_info_get_device(pcminfo)); - items[0] = SPA_DICT_ITEM_INIT("alsa.device", device_name); - items[1] = SPA_DICT_ITEM_INIT("alsa.card.id", snd_ctl_card_info_get_id(info)); - items[2] = SPA_DICT_ITEM_INIT("alsa.card.components", snd_ctl_card_info_get_components(info)); - items[3] = SPA_DICT_ITEM_INIT("alsa.card.driver", snd_ctl_card_info_get_driver(info)); - items[4] = SPA_DICT_ITEM_INIT("alsa.card.name", snd_ctl_card_info_get_name(info)); - items[5] = SPA_DICT_ITEM_INIT("alsa.card.longname", snd_ctl_card_info_get_longname(info)); - items[6] = SPA_DICT_ITEM_INIT("alsa.card.mixername", snd_ctl_card_info_get_mixername(info)); - items[7] = SPA_DICT_ITEM_INIT("alsa.pcm.id", snd_pcm_info_get_id(pcminfo)); - items[8] = SPA_DICT_ITEM_INIT("alsa.pcm.name", snd_pcm_info_get_name(pcminfo)); - items[9] = SPA_DICT_ITEM_INIT("alsa.pcm.subname", snd_pcm_info_get_subdevice_name(pcminfo)); - items[10] = SPA_DICT_ITEM_INIT("alsa.pcm.class", get_class(pcminfo)); - items[11] = SPA_DICT_ITEM_INIT("alsa.pcm.subclass", get_subclass(pcminfo)); + items[0] = SPA_DICT_ITEM_INIT("alsa.device", device_name); + items[1] = SPA_DICT_ITEM_INIT("alsa.pcm.id", snd_pcm_info_get_id(pcminfo)); + items[2] = SPA_DICT_ITEM_INIT("alsa.pcm.name", snd_pcm_info_get_name(pcminfo)); + items[3] = SPA_DICT_ITEM_INIT("alsa.pcm.subname", snd_pcm_info_get_subdevice_name(pcminfo)); + items[4] = SPA_DICT_ITEM_INIT("alsa.pcm.class", get_class(pcminfo)); + items[5] = SPA_DICT_ITEM_INIT("alsa.pcm.subclass", get_subclass(pcminfo)); if (snd_pcm_info_get_stream(pcminfo) == SND_PCM_STREAM_PLAYBACK) factory = &spa_alsa_sink_factory; @@ -133,9 +127,10 @@ static int emit_node(struct impl *this, snd_ctl_card_info_t *info, snd_pcm_info_ return 0; } -static int emit_nodes(struct impl *this) +static int emit_info(struct impl *this) { int err = 0, dev; + struct spa_dict_item items[8]; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; @@ -153,6 +148,18 @@ static int emit_nodes(struct impl *this) goto exit; } + items[0] = SPA_DICT_ITEM_INIT("device.path", (char *)this->props.device); + items[1] = SPA_DICT_ITEM_INIT("media.class", "Audio/Device"); + items[2] = SPA_DICT_ITEM_INIT("alsa.card.id", snd_ctl_card_info_get_id(info)); + items[3] = SPA_DICT_ITEM_INIT("alsa.card.components", snd_ctl_card_info_get_components(info)); + items[4] = SPA_DICT_ITEM_INIT("alsa.card.driver", snd_ctl_card_info_get_driver(info)); + items[5] = SPA_DICT_ITEM_INIT("alsa.card.name", snd_ctl_card_info_get_name(info)); + items[6] = SPA_DICT_ITEM_INIT("alsa.card.longname", snd_ctl_card_info_get_longname(info)); + items[7] = SPA_DICT_ITEM_INIT("alsa.card.mixername", snd_ctl_card_info_get_mixername(info)); + + if (this->callbacks->info) + this->callbacks->info(this->callbacks_data, &SPA_DICT_INIT(items, 8)); + snd_pcm_info_alloca(&pcminfo); dev = -1; while (1) { @@ -171,28 +178,23 @@ static int emit_nodes(struct impl *this) if (err != -ENOENT) spa_log_error(this->log, "error pcm info: %s", snd_strerror(err)); } - if (err >= 0) - emit_node(this, info, pcminfo); + if (err >= 0 && this->callbacks->add) + emit_node(this, pcminfo); snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE); if ((err = snd_ctl_pcm_info(this->ctl_hndl, pcminfo)) < 0) { if (err != -ENOENT) spa_log_error(this->log, "error pcm info: %s", snd_strerror(err)); } - if (err >= 0) - emit_node(this, info, pcminfo); + if (err >= 0 && this->callbacks->add) + emit_node(this, pcminfo); } exit: snd_ctl_close(this->ctl_hndl); - return err; } -static const struct spa_dict_item info_items[] = { - { "media.class", "Audio/Device" }, -}; - static int impl_set_callbacks(struct spa_device *device, const struct spa_device_callbacks *callbacks, void *data) @@ -206,13 +208,8 @@ static int impl_set_callbacks(struct spa_device *device, this->callbacks = callbacks; this->callbacks_data = data; - if (callbacks) { - if (callbacks->info) - callbacks->info(data, &SPA_DICT_INIT_ARRAY(info_items)); - - if (this->callbacks->add) - emit_nodes(this); - } + if (callbacks) + emit_info(this); return 0; } diff --git a/spa/plugins/v4l2/v4l2-device.c b/spa/plugins/v4l2/v4l2-device.c index 84c31fd76..f4245e75e 100644 --- a/spa/plugins/v4l2/v4l2-device.c +++ b/spa/plugins/v4l2/v4l2-device.c @@ -69,16 +69,43 @@ struct impl { struct spa_v4l2_device dev; }; -static const struct spa_dict_item info_items[] = { - { "media.class", "Video/Device" }, -}; +static int emit_info(struct impl *this) +{ + int res; + struct spa_dict_item items[5]; + + if ((res = spa_v4l2_open(&this->dev, this->props.device)) < 0) + return res; + + items[0] = SPA_DICT_ITEM_INIT("device.path", (char *)this->props.device); + items[1] = SPA_DICT_ITEM_INIT("media.class", "Video/Device"); + items[2] = SPA_DICT_ITEM_INIT("v4l2.driver", (char *)this->dev.cap.driver); + items[3] = SPA_DICT_ITEM_INIT("v4l2.card", (char *)this->dev.cap.card); + items[4] = SPA_DICT_ITEM_INIT("v4l2.bus", (char *)this->dev.cap.bus_info); + + if (this->callbacks->info) + this->callbacks->info(this->callbacks_data, &SPA_DICT_INIT(items, 5)); + + if (this->callbacks->add) { + if (spa_v4l2_is_capture(&this->dev)) { + this->callbacks->add(this->callbacks_data, 0, + &spa_v4l2_source_factory, + SPA_TYPE_INTERFACE_Node, + &SPA_DICT_INIT(items, 1)); + } + } + + spa_v4l2_close(&this->dev); + + return 0; +} static int impl_set_callbacks(struct spa_device *device, const struct spa_device_callbacks *callbacks, void *data) { struct impl *this; - struct spa_dict_item items[1]; + int res = 0; spa_return_val_if_fail(device != NULL, -EINVAL); @@ -88,23 +115,9 @@ static int impl_set_callbacks(struct spa_device *device, this->callbacks_data = data; if (callbacks) { - if (callbacks->info) - callbacks->info(data, &SPA_DICT_INIT_ARRAY(info_items)); - - if (callbacks->add) { - if (spa_v4l2_is_capture(&this->dev)) { - items[0] = SPA_DICT_ITEM_INIT("device.path", this->props.device); - callbacks->add(data, 0, - &spa_v4l2_source_factory, - SPA_TYPE_INTERFACE_Node, - &SPA_DICT_INIT(items, 1)); - } - } - - + res = emit_info(this); } - - return 0; + return res; } static int impl_enum_params(struct spa_device *device, @@ -169,7 +182,6 @@ impl_init(const struct spa_handle_factory *factory, struct impl *this; uint32_t i; const char *str; - int res; spa_return_val_if_fail(factory != NULL, -EINVAL); spa_return_val_if_fail(handle != NULL, -EINVAL); @@ -194,12 +206,8 @@ impl_init(const struct spa_handle_factory *factory, reset_props(&this->props); - if (info && (str = spa_dict_lookup(info, "device.path"))) { + if (info && (str = spa_dict_lookup(info, "device.path"))) strncpy(this->props.device, str, 63); - if ((res = spa_v4l2_open(&this->dev, this->props.device)) < 0) - return res; - spa_v4l2_close(&this->dev); - } return 0; }