mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
monitor: remove monitor API and use device
Remove the monitor API, we can use the device API for it. Make sure we support creating devices (like alsa) from another device (udev). Use new object.id to store the object id in the object properties. Use the port.id/node.id etc to make relations to other objects.
This commit is contained in:
parent
818fb9e904
commit
6756a3c8fc
43 changed files with 474 additions and 1015 deletions
|
|
@ -1,6 +1,6 @@
|
|||
v4l2_sources = ['v4l2.c',
|
||||
'v4l2-device.c',
|
||||
'v4l2-monitor.c',
|
||||
'v4l2-udev.c',
|
||||
'v4l2-source.c']
|
||||
|
||||
v4l2lib = shared_library('spa-v4l2',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Spa V4l2 Monitor
|
||||
/* Spa V4l2 udev monitor
|
||||
*
|
||||
* Copyright © 2018 Wim Taymans
|
||||
*
|
||||
|
|
@ -37,19 +37,22 @@
|
|||
#include <spa/utils/type.h>
|
||||
#include <spa/utils/keys.h>
|
||||
#include <spa/utils/names.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
#include <spa/monitor/device.h>
|
||||
#include <spa/monitor/utils.h>
|
||||
|
||||
#define NAME "v4l2-monitor"
|
||||
#define NAME "v4l2-udev"
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_monitor monitor;
|
||||
struct spa_device device;
|
||||
|
||||
struct spa_log *log;
|
||||
struct spa_loop *main_loop;
|
||||
|
||||
struct spa_callbacks callbacks;
|
||||
struct spa_hook_list hooks;
|
||||
|
||||
uint64_t info_all;
|
||||
struct spa_device_info info;
|
||||
|
||||
struct udev *udev;
|
||||
struct udev_monitor *umonitor;
|
||||
|
|
@ -172,20 +175,20 @@ static void unescape(const char *src, char *dst)
|
|||
|
||||
static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *dev)
|
||||
{
|
||||
struct spa_monitor_object_info info;
|
||||
struct spa_device_object_info info;
|
||||
const char *str;
|
||||
struct spa_dict_item items[20];
|
||||
uint32_t n_items = 0;
|
||||
|
||||
info = SPA_MONITOR_OBJECT_INFO_INIT();
|
||||
info = SPA_DEVICE_OBJECT_INFO_INIT();
|
||||
|
||||
info.type = SPA_TYPE_INTERFACE_Device;
|
||||
info.factory_name = SPA_NAME_API_V4L2_DEVICE;
|
||||
info.change_mask = SPA_MONITOR_OBJECT_CHANGE_MASK_FLAGS |
|
||||
SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS;
|
||||
info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_FLAGS |
|
||||
SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
|
||||
info.flags = 0;
|
||||
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_MONITOR_API,"udev");
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ENUM_API,"udev");
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "v4l2");
|
||||
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_V4L2_PATH, udev_device_get_devnode(dev));
|
||||
|
|
@ -256,7 +259,7 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *
|
|||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_CAPABILITIES, str);
|
||||
}
|
||||
info.props = &SPA_DICT_INIT(items, n_items);
|
||||
spa_monitor_call_object_info(&this->callbacks, id, &info);
|
||||
spa_device_emit_object_info(&this->hooks, id, &info);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -282,7 +285,7 @@ static void impl_on_fd_events(struct spa_source *source)
|
|||
strcmp(action, "change") == 0) {
|
||||
emit_object_info(this, id, dev);
|
||||
} else {
|
||||
spa_monitor_call_object_info(&this->callbacks, id, NULL);
|
||||
spa_device_emit_object_info(&this->hooks, id, NULL);
|
||||
}
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
|
|
@ -358,38 +361,68 @@ static int enum_devices(struct impl *this)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_dict_item device_info_items[] = {
|
||||
{ SPA_KEY_DEVICE_API, "udev" },
|
||||
{ SPA_KEY_DEVICE_NICK, "v4l2-udev" },
|
||||
{ SPA_KEY_API_UDEV_MATCH, "video4linux" },
|
||||
};
|
||||
|
||||
static int
|
||||
impl_monitor_set_callbacks(void *object,
|
||||
const struct spa_monitor_callbacks *callbacks,
|
||||
void *data)
|
||||
|
||||
static void emit_device_info(struct impl *this, bool full)
|
||||
{
|
||||
int res;
|
||||
struct impl *this = object;
|
||||
if (full)
|
||||
this->info.change_mask = this->info_all;
|
||||
if (this->info.change_mask) {
|
||||
this->info.props = &SPA_DICT_INIT_ARRAY(device_info_items);
|
||||
spa_device_emit_info(&this->hooks, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
spa_return_val_if_fail(this != NULL, -EINVAL);
|
||||
|
||||
this->callbacks = SPA_CALLBACKS_INIT(callbacks, data);
|
||||
|
||||
if (callbacks) {
|
||||
if ((res = impl_udev_open(this)) < 0)
|
||||
return res;
|
||||
|
||||
if ((res = enum_devices(this)) < 0)
|
||||
return res;
|
||||
|
||||
if ((res = start_monitor(this)) < 0)
|
||||
return res;
|
||||
} else {
|
||||
static void impl_hook_removed(struct spa_hook *hook)
|
||||
{
|
||||
struct impl *this = hook->priv;
|
||||
if (spa_hook_list_is_empty(&this->hooks)) {
|
||||
stop_monitor(this);
|
||||
impl_udev_close(this);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
impl_device_add_listener(void *object, struct spa_hook *listener,
|
||||
const struct spa_device_events *events, void *data)
|
||||
{
|
||||
int res;
|
||||
struct impl *this = object;
|
||||
struct spa_hook_list save;
|
||||
|
||||
spa_return_val_if_fail(this != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(events != NULL, -EINVAL);
|
||||
|
||||
if ((res = impl_udev_open(this)) < 0)
|
||||
return res;
|
||||
|
||||
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
|
||||
|
||||
emit_device_info(this, true);
|
||||
|
||||
if ((res = enum_devices(this)) < 0)
|
||||
return res;
|
||||
|
||||
if ((res = start_monitor(this)) < 0)
|
||||
return res;
|
||||
|
||||
spa_hook_list_join(&this->hooks, &save);
|
||||
|
||||
listener->removed = impl_hook_removed;
|
||||
listener->priv = this;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_monitor_methods impl_monitor = {
|
||||
SPA_VERSION_MONITOR_METHODS,
|
||||
.set_callbacks = impl_monitor_set_callbacks,
|
||||
static const struct spa_device_methods impl_device = {
|
||||
SPA_VERSION_DEVICE_METHODS,
|
||||
.add_listener = impl_device_add_listener,
|
||||
};
|
||||
|
||||
static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **interface)
|
||||
|
|
@ -401,10 +434,13 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **i
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (type == SPA_TYPE_INTERFACE_Monitor)
|
||||
*interface = &this->monitor;
|
||||
else
|
||||
switch (type) {
|
||||
case SPA_TYPE_INTERFACE_Device:
|
||||
*interface = &this->device;
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -412,7 +448,8 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **i
|
|||
static int impl_clear(struct spa_handle *handle)
|
||||
{
|
||||
struct impl *this = (struct impl *) handle;
|
||||
impl_monitor_set_callbacks(this, NULL, NULL);
|
||||
stop_monitor(this);
|
||||
impl_udev_close(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -455,17 +492,23 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_error(this->log, "a main-loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
spa_hook_list_init(&this->hooks);
|
||||
|
||||
this->monitor.iface = SPA_INTERFACE_INIT(
|
||||
SPA_TYPE_INTERFACE_Monitor,
|
||||
SPA_VERSION_MONITOR,
|
||||
&impl_monitor, this);
|
||||
this->device.iface = SPA_INTERFACE_INIT(
|
||||
SPA_TYPE_INTERFACE_Device,
|
||||
SPA_VERSION_DEVICE,
|
||||
&impl_device, this);
|
||||
|
||||
this->info = SPA_DEVICE_INFO_INIT();
|
||||
this->info_all = SPA_DEVICE_CHANGE_MASK_FLAGS |
|
||||
SPA_DEVICE_CHANGE_MASK_PROPS;
|
||||
this->info.flags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE_INTERFACE_Monitor,},
|
||||
{SPA_TYPE_INTERFACE_Device,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
@ -485,9 +528,9 @@ impl_enum_interface_info(const struct spa_handle_factory *factory,
|
|||
return 1;
|
||||
}
|
||||
|
||||
const struct spa_handle_factory spa_v4l2_monitor_factory = {
|
||||
const struct spa_handle_factory spa_v4l2_udev_factory = {
|
||||
SPA_VERSION_HANDLE_FACTORY,
|
||||
SPA_NAME_API_V4L2_MONITOR,
|
||||
SPA_NAME_API_V4L2_ENUM_UDEV,
|
||||
NULL,
|
||||
impl_get_size,
|
||||
impl_init,
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_v4l2_source_factory;
|
||||
extern const struct spa_handle_factory spa_v4l2_monitor_factory;
|
||||
extern const struct spa_handle_factory spa_v4l2_udev_factory;
|
||||
extern const struct spa_handle_factory spa_v4l2_device_factory;
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -42,7 +42,7 @@ int spa_handle_factory_enum(const struct spa_handle_factory **factory,
|
|||
*factory = &spa_v4l2_source_factory;
|
||||
break;
|
||||
case 1:
|
||||
*factory = &spa_v4l2_monitor_factory;
|
||||
*factory = &spa_v4l2_udev_factory;
|
||||
break;
|
||||
case 2:
|
||||
*factory = &spa_v4l2_device_factory;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue