monitor: use dynamic types

Make the monitor item a POD object and use dynamic types.
This commit is contained in:
Wim Taymans 2017-03-23 08:54:04 +01:00
parent c44a7c9735
commit 7270986c3a
14 changed files with 360 additions and 248 deletions

View file

@ -51,4 +51,5 @@ pinos_uri_init (PinosURI *uri)
spa_node_events_map (uri->map, &uri->node_events); spa_node_events_map (uri->map, &uri->node_events);
spa_node_commands_map (uri->map, &uri->node_commands); spa_node_commands_map (uri->map, &uri->node_commands);
spa_monitor_types_map (uri->map, &uri->monitor_types);
} }

View file

@ -30,6 +30,7 @@ extern "C" {
#include <pinos/client/map.h> #include <pinos/client/map.h>
#include <spa/include/spa/id-map.h> #include <spa/include/spa/id-map.h>
#include <spa/include/spa/node-event.h> #include <spa/include/spa/node-event.h>
#include <spa/include/spa/monitor.h>
typedef struct _PinosURI PinosURI; typedef struct _PinosURI PinosURI;
@ -56,6 +57,7 @@ struct _PinosURI {
SpaNodeEvents node_events; SpaNodeEvents node_events;
SpaNodeCommands node_commands; SpaNodeCommands node_commands;
SpaMonitorTypes monitor_types;
}; };
void pinos_uri_init (PinosURI *uri); void pinos_uri_init (PinosURI *uri);

View file

@ -28,6 +28,7 @@
#include <spa/include/spa/node.h> #include <spa/include/spa/node.h>
#include <spa/include/spa/monitor.h> #include <spa/include/spa/monitor.h>
#include <spa/include/spa/pod-iter.h>
#include <pinos/client/log.h> #include <pinos/client/log.h>
#include <pinos/server/node.h> #include <pinos/server/node.h>
@ -61,13 +62,24 @@ add_item (PinosSpaMonitor *this, SpaMonitorItem *item)
void *node_iface; void *node_iface;
void *clock_iface; void *clock_iface;
PinosProperties *props = NULL; PinosProperties *props = NULL;
const char *name, *id, *klass;
SpaHandleFactory *factory;
SpaPOD *info = NULL;
pinos_log_debug ("monitor %p: add: \"%s\" (%s)", this, item->name, item->id); spa_pod_object_query (item,
impl->core->uri.monitor_types.name, SPA_POD_TYPE_STRING, &name,
impl->core->uri.monitor_types.id, SPA_POD_TYPE_STRING, &id,
impl->core->uri.monitor_types.klass, SPA_POD_TYPE_STRING, &klass,
impl->core->uri.monitor_types.factory, SPA_POD_TYPE_POINTER, &factory,
impl->core->uri.monitor_types.info, SPA_POD_TYPE_STRUCT, &info,
0);
handle = calloc (1, item->factory->size); pinos_log_debug ("monitor %p: add: \"%s\" (%s)", this, name, id);
if ((res = spa_handle_factory_init (item->factory,
handle = calloc (1, factory->size);
if ((res = spa_handle_factory_init (factory,
handle, handle,
item->info, NULL, //item->info,
impl->core->support, impl->core->support,
impl->core->n_support)) < 0) { impl->core->n_support)) < 0) {
pinos_log_error ("can't make factory instance: %d", res); pinos_log_error ("can't make factory instance: %d", res);
@ -83,22 +95,23 @@ add_item (PinosSpaMonitor *this, SpaMonitorItem *item)
props = pinos_properties_new (NULL, NULL); props = pinos_properties_new (NULL, NULL);
if (item->info) { if (info) {
uint32_t i; SpaPODIter it;
for (i = 0; i < item->info->n_items; i++) { spa_pod_iter_pod (&it, info);
pinos_properties_set (props, while (true) {
item->info->items[i].key, const char *key, *val;
item->info->items[i].value); if (!spa_pod_iter_get (&it, SPA_POD_TYPE_STRING, &key, SPA_POD_TYPE_STRING, &val, 0))
break;
pinos_properties_set (props, key, val);
} }
} }
pinos_properties_set (props, "media.class", klass);
pinos_properties_set (props, "media.class", item->klass);
mitem = calloc (1, sizeof (PinosSpaMonitorItem)); mitem = calloc (1, sizeof (PinosSpaMonitorItem));
mitem->id = strdup (item->id); mitem->id = strdup (id);
mitem->node = pinos_node_new (impl->core, mitem->node = pinos_node_new (impl->core,
item->name, name,
node_iface, node_iface,
clock_iface, clock_iface,
props); props);
@ -133,10 +146,17 @@ destroy_item (PinosSpaMonitorItem *mitem)
static void static void
remove_item (PinosSpaMonitor *this, SpaMonitorItem *item) remove_item (PinosSpaMonitor *this, SpaMonitorItem *item)
{ {
PinosSpaMonitorImpl *impl = SPA_CONTAINER_OF (this, PinosSpaMonitorImpl, this);
PinosSpaMonitorItem *mitem; PinosSpaMonitorItem *mitem;
const char *name, *id;
pinos_log_debug ("monitor %p: remove: \"%s\" (%s)", this, item->name, item->id); spa_pod_object_query (item,
mitem = find_item (this, item->id); impl->core->uri.monitor_types.name, SPA_POD_TYPE_STRING, &name,
impl->core->uri.monitor_types.id, SPA_POD_TYPE_STRING, &id,
0);
pinos_log_debug ("monitor %p: remove: \"%s\" (%s)", this, name, id);
mitem = find_item (this, id);
if (mitem) if (mitem)
destroy_item (mitem); destroy_item (mitem);
} }
@ -147,27 +167,25 @@ on_monitor_event (SpaMonitor *monitor,
void *user_data) void *user_data)
{ {
PinosSpaMonitor *this = user_data; PinosSpaMonitor *this = user_data;
PinosSpaMonitorImpl *impl = SPA_CONTAINER_OF (this, PinosSpaMonitorImpl, this);
switch (event->type) { if (SPA_EVENT_TYPE (event) == impl->core->uri.monitor_types.Added) {
case SPA_MONITOR_EVENT_TYPE_ADDED: SpaMonitorItem *item = SPA_POD_CONTENTS (SpaEvent, event);
{ add_item (this, item);
SpaMonitorItem *item = (SpaMonitorItem *) event; }
add_item (this, item); else if (SPA_EVENT_TYPE (event) == impl->core->uri.monitor_types.Removed) {
break; SpaMonitorItem *item = SPA_POD_CONTENTS (SpaEvent, event);
} remove_item (this, item);
case SPA_MONITOR_EVENT_TYPE_REMOVED: }
{ else if (SPA_EVENT_TYPE (event) == impl->core->uri.monitor_types.Changed) {
SpaMonitorItem *item = (SpaMonitorItem *) event; SpaMonitorItem *item = SPA_POD_CONTENTS (SpaEvent, event);
remove_item (this, item); const char *name;
}
case SPA_MONITOR_EVENT_TYPE_CHANGED: spa_pod_object_query (item,
{ impl->core->uri.monitor_types.name, SPA_POD_TYPE_STRING, &name,
SpaMonitorItem *item = (SpaMonitorItem *) event; 0);
pinos_log_debug ("monitor %p: changed: \"%s\"", this, item->name);
break; pinos_log_debug ("monitor %p: changed: \"%s\"", this, name);
}
default:
break;
} }
} }

View file

@ -31,26 +31,62 @@ typedef struct _SpaMonitor SpaMonitor;
#include <spa/defs.h> #include <spa/defs.h>
#include <spa/dict.h> #include <spa/dict.h>
#include <spa/plugin.h> #include <spa/event.h>
/** typedef SpaEvent SpaMonitorEvent;
* SpaMonitorEventType: #define SPA_MONITOR_EVENT_URI "http://spaplug.in/ns/monitor-event"
* @SPA_MONITOR_EVENT_TYPE_INVALID: invalid event #define SPA_MONITOR_EVENT_PREFIX SPA_MONITOR_EVENT_URI "#"
* @SPA_MONITOR_EVENT_TYPE_ADDED: an item was added, data points to #SpaMonitorItem
* @SPA_MONITOR_EVENT_TYPE_REMOVED: an item was removed, data points to #SpaMonitorItem #define SPA_MONITOR_EVENT__Added SPA_MONITOR_EVENT_PREFIX "Added"
* @SPA_MONITOR_EVENT_TYPE_CHANGED: an item was changed, data points to #SpaMonitorItem #define SPA_MONITOR_EVENT__Removed SPA_MONITOR_EVENT_PREFIX "Removed"
*/ #define SPA_MONITOR_EVENT__Changed SPA_MONITOR_EVENT_PREFIX "Changed"
typedef enum {
SPA_MONITOR_EVENT_TYPE_INVALID = 0, typedef SpaPODObject SpaMonitorItem;
SPA_MONITOR_EVENT_TYPE_ADDED, #define SPA_MONITOR_ITEM_URI "http://spaplug.in/ns/monitor-item"
SPA_MONITOR_EVENT_TYPE_REMOVED, #define SPA_MONITOR_ITEM_PREFIX SPA_MONITOR_ITEM_URI "#"
SPA_MONITOR_EVENT_TYPE_CHANGED, #define SPA_MONITOR_ITEM__id SPA_MONITOR_ITEM_PREFIX "id"
} SpaMonitorEventType; #define SPA_MONITOR_ITEM__flags SPA_MONITOR_ITEM_PREFIX "flags"
#define SPA_MONITOR_ITEM__state SPA_MONITOR_ITEM_PREFIX "state"
#define SPA_MONITOR_ITEM__name SPA_MONITOR_ITEM_PREFIX "name"
#define SPA_MONITOR_ITEM__class SPA_MONITOR_ITEM_PREFIX "class"
#define SPA_MONITOR_ITEM__info SPA_MONITOR_ITEM_PREFIX "info"
#define SPA_MONITOR_ITEM__factory SPA_MONITOR_ITEM_PREFIX "factory"
typedef struct { typedef struct {
SpaMonitorEventType type; uint32_t Monitor;
uint32_t size;
} SpaMonitorEvent; uint32_t Added;
uint32_t Removed;
uint32_t Changed;
uint32_t MonitorItem;
uint32_t id;
uint32_t flags;
uint32_t state;
uint32_t name;
uint32_t klass;
uint32_t info;
uint32_t factory;
} SpaMonitorTypes;
static inline void
spa_monitor_types_map (SpaIDMap *map, SpaMonitorTypes *types)
{
if (types->Added == 0) {
types->Monitor = spa_id_map_get_id (map, SPA_MONITOR_URI);
types->Added = spa_id_map_get_id (map, SPA_MONITOR_EVENT__Added);
types->Removed = spa_id_map_get_id (map, SPA_MONITOR_EVENT__Removed);
types->Changed = spa_id_map_get_id (map, SPA_MONITOR_EVENT__Changed);
types->MonitorItem = spa_id_map_get_id (map, SPA_MONITOR_ITEM_URI);
types->id = spa_id_map_get_id (map, SPA_MONITOR_ITEM__id);
types->flags = spa_id_map_get_id (map, SPA_MONITOR_ITEM__flags);
types->state = spa_id_map_get_id (map, SPA_MONITOR_ITEM__state);
types->name = spa_id_map_get_id (map, SPA_MONITOR_ITEM__name);
types->klass = spa_id_map_get_id (map, SPA_MONITOR_ITEM__class);
types->info = spa_id_map_get_id (map, SPA_MONITOR_ITEM__info);
types->factory = spa_id_map_get_id (map, SPA_MONITOR_ITEM__factory);
}
}
typedef enum { typedef enum {
SPA_MONITOR_ITEM_FLAG_NONE = 0, SPA_MONITOR_ITEM_FLAG_NONE = 0,
@ -68,17 +104,6 @@ typedef enum {
SPA_MONITOR_ITEM_STATE_UNAVAILABLE, SPA_MONITOR_ITEM_STATE_UNAVAILABLE,
} SpaMonitorItemState; } SpaMonitorItemState;
typedef struct {
SpaMonitorEvent event;
const char *id;
SpaMonitorItemFlags flags;
SpaMonitorItemState state;
const char *name;
const char *klass;
const SpaDict *info;
const SpaHandleFactory *factory;
} SpaMonitorItem;
/** /**
* SpaMonitorCallback: * SpaMonitorCallback:
* @node: a #SpaMonitor emiting the event * @node: a #SpaMonitor emiting the event
@ -88,9 +113,9 @@ typedef struct {
* This will be called when a monitor event is notified * This will be called when a monitor event is notified
* on @monitor. * on @monitor.
*/ */
typedef void (*SpaMonitorEventCallback) (SpaMonitor *monitor, typedef void (*SpaMonitorEventCallback) (SpaMonitor *monitor,
SpaMonitorEvent *event, SpaMonitorEvent *event,
void *user_data); void *user_data);
/** /**
* SpaMonitor: * SpaMonitor:

View file

@ -27,6 +27,9 @@ extern "C" {
#include <spa/defs.h> #include <spa/defs.h>
#include <spa/dict.h> #include <spa/dict.h>
#define SPA_HANDLE_URI "http://spaplug.in/ns/handle"
#define SPA_HANDLE_FACTORY_URI "http://spaplug.in/ns/handle-factory"
typedef struct _SpaHandle SpaHandle; typedef struct _SpaHandle SpaHandle;
typedef struct _SpaHandleFactory SpaHandleFactory; typedef struct _SpaHandleFactory SpaHandleFactory;

View file

@ -233,6 +233,15 @@ spa_pod_builder_bytes (SpaPODBuilder *builder, const void *bytes, uint32_t len)
return ref; return ref;
} }
#define SPA_POD_POINTER_INIT(type,value) { { sizeof (SpaPODPointerBody), SPA_POD_TYPE_POINTER }, { type, value } }
static inline uint32_t
spa_pod_builder_pointer (SpaPODBuilder *builder, uint32_t type, void *val)
{
const SpaPODPointer p = SPA_POD_POINTER_INIT (type, val);
return spa_pod_builder_primitive (builder, &p.pod);
}
#define SPA_POD_RECTANGLE_INIT(width,height) { { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE }, { width, height } } #define SPA_POD_RECTANGLE_INIT(width,height) { { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE }, { width, height } }
static inline uint32_t static inline uint32_t
@ -329,6 +338,7 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
SpaPODDouble double_pod; SpaPODDouble double_pod;
SpaPODString string_pod; SpaPODString string_pod;
SpaPODBytes bytes_pod; SpaPODBytes bytes_pod;
SpaPODPointer pointer_pod;
SpaPODRectangle rectangle_pod; SpaPODRectangle rectangle_pod;
SpaPODFraction fraction_pod; SpaPODFraction fraction_pod;
SpaPODArray array_pod; SpaPODArray array_pod;
@ -400,6 +410,14 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
head.bytes_pod.pod.size = body_size; head.bytes_pod.pod.size = body_size;
head_size = sizeof (SpaPOD); head_size = sizeof (SpaPOD);
goto primitive; goto primitive;
case SPA_POD_TYPE_POINTER:
head.pointer_pod.pod.type = SPA_POD_TYPE_POINTER;
head.pointer_pod.pod.size = body_size = sizeof (SpaPODPointerBody);
head.pointer_pod.body.type = va_arg (args, uint32_t);
head.pointer_pod.body.value = va_arg (args, void *);
head_size = sizeof (SpaPOD);
body = &head.pointer_pod.body;
goto primitive;
case SPA_POD_TYPE_RECTANGLE: case SPA_POD_TYPE_RECTANGLE:
head.rectangle_pod.pod.type = SPA_POD_TYPE_RECTANGLE; head.rectangle_pod.pod.type = SPA_POD_TYPE_RECTANGLE;
head.rectangle_pod.pod.size = body_size = sizeof (SpaRectangle); head.rectangle_pod.pod.size = body_size = sizeof (SpaRectangle);

View file

@ -116,7 +116,9 @@ spa_pod_iter_getv (SpaPODIter *iter,
uint32_t type, uint32_t type,
va_list args) va_list args)
{ {
while (type && spa_pod_iter_has_next (iter)) { bool res = true;
while (type && (res = spa_pod_iter_has_next (iter))) {
SpaPOD *pod = spa_pod_iter_next (iter); SpaPOD *pod = spa_pod_iter_next (iter);
if (type != SPA_POD_TYPE_POD && pod->type != type) if (type != SPA_POD_TYPE_POD && pod->type != type)
@ -126,7 +128,7 @@ spa_pod_iter_getv (SpaPODIter *iter,
type = va_arg (args, uint32_t); type = va_arg (args, uint32_t);
} }
return true; return res;
} }
static inline bool static inline bool

View file

@ -120,6 +120,12 @@ spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key)
*(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); \ *(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); \
*(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \ *(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \
break; \ break; \
case SPA_POD_TYPE_POINTER: \
{ \
SpaPODPointerBody *b = SPA_POD_BODY (pod); \
*(va_arg (args, void **)) = b->value; \
break; \
} \
case SPA_POD_TYPE_RECTANGLE: \ case SPA_POD_TYPE_RECTANGLE: \
*(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \ *(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \
break; \ break; \
@ -143,6 +149,7 @@ spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key)
#define SPA_POD_COLLECT_SKIP(type,args) \ #define SPA_POD_COLLECT_SKIP(type,args) \
switch (type) { \ switch (type) { \
case SPA_POD_TYPE_BYTES: \ case SPA_POD_TYPE_BYTES: \
case SPA_POD_TYPE_POINTER: \
va_arg (args, void*); \ va_arg (args, void*); \
/* fallthrough */ \ /* fallthrough */ \
case SPA_POD_TYPE_BOOL: \ case SPA_POD_TYPE_BOOL: \
@ -177,7 +184,7 @@ spa_pod_contents_queryv (const SpaPOD *pod, uint32_t offset, uint32_t key, va_li
type = va_arg (args, uint32_t); type = va_arg (args, uint32_t);
if (prop && prop->body.key == key && if (prop && prop->body.key == key &&
prop->body.value.type == type && (type == SPA_POD_TYPE_POD || prop->body.value.type == type) &&
!(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) { !(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) {
SPA_POD_COLLECT (&prop->body.value, type, args); SPA_POD_COLLECT (&prop->body.value, type, args);
count++; count++;
@ -202,6 +209,9 @@ spa_pod_contents_query (const SpaPOD *pod, uint32_t offset, uint32_t key, ...)
return count; return count;
} }
#define spa_pod_object_query(object,key, ...) \
spa_pod_contents_query (&object->pod, sizeof (SpaPODObject), key, __VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -45,6 +45,7 @@ typedef enum {
SPA_POD_TYPE_DOUBLE, SPA_POD_TYPE_DOUBLE,
SPA_POD_TYPE_STRING, SPA_POD_TYPE_STRING,
SPA_POD_TYPE_BYTES, SPA_POD_TYPE_BYTES,
SPA_POD_TYPE_POINTER,
SPA_POD_TYPE_RECTANGLE, SPA_POD_TYPE_RECTANGLE,
SPA_POD_TYPE_FRACTION, SPA_POD_TYPE_FRACTION,
SPA_POD_TYPE_BITMASK, SPA_POD_TYPE_BITMASK,
@ -94,6 +95,16 @@ typedef struct {
/* value here */ /* value here */
} SpaPODBytes; } SpaPODBytes;
typedef struct {
uint32_t type;
void *value;
} SpaPODPointerBody;
typedef struct {
SpaPOD pod;
SpaPODPointerBody body;
} SpaPODPointer;
typedef struct { typedef struct {
SpaPOD pod; SpaPOD pod;
SpaRectangle value; SpaRectangle value;

View file

@ -195,6 +195,7 @@ struct pod_type_name {
{ "float", "Float" }, { "float", "Float" },
{ "double", "Double" }, { "double", "Double" },
{ "string", "String" }, { "string", "String" },
{ "pointer", "Pointer" },
{ "rectangle", "Rectangle" }, { "rectangle", "Rectangle" },
{ "fraction", "Fraction" }, { "fraction", "Fraction" },
{ "bitmask", "Bitmask" }, { "bitmask", "Bitmask" },
@ -231,6 +232,13 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
case SPA_POD_TYPE_STRING: case SPA_POD_TYPE_STRING:
printf ("%-*sString \"%s\"\n", prefix, "", (char *) body); printf ("%-*sString \"%s\"\n", prefix, "", (char *) body);
break; break;
case SPA_POD_TYPE_POINTER:
{
SpaPODPointerBody *b = body;
printf ("%-*sPointer %s %p\n", prefix, "",
spa_id_map_get_uri (spa_id_map_get_default(), b->type), b->value);
break;
}
case SPA_POD_TYPE_RECTANGLE: case SPA_POD_TYPE_RECTANGLE:
{ {
SpaRectangle *r = body; SpaRectangle *r = body;

View file

@ -56,7 +56,7 @@ id_map_get_uri (SpaIDMap *map, uint32_t id)
{ {
IDMap *this = SPA_CONTAINER_OF (map, IDMap, map); IDMap *this = SPA_CONTAINER_OF (map, IDMap, map);
if (id < this->n_uris) if (id <= this->n_uris)
return this->uris[id]; return this->uris[id];
return NULL; return NULL;

View file

@ -39,14 +39,13 @@ extern const SpaHandleFactory spa_alsa_source_factory;
typedef struct _SpaALSAMonitor SpaALSAMonitor; typedef struct _SpaALSAMonitor SpaALSAMonitor;
typedef struct { typedef struct {
SpaMonitorItem item; SpaMonitorItem *item;
struct udev_device *udevice; struct udev_device *udevice;
SpaDict info;
SpaDictItem info_items[32];
} ALSAItem; } ALSAItem;
typedef struct { typedef struct {
uint32_t monitor; uint32_t handle_factory;
SpaMonitorTypes monitor_types;
} URI; } URI;
struct _SpaALSAMonitor { struct _SpaALSAMonitor {
@ -66,6 +65,7 @@ struct _SpaALSAMonitor {
struct udev_enumerate *enumerate; struct udev_enumerate *enumerate;
uint32_t index; uint32_t index;
struct udev_list_entry *devices; struct udev_list_entry *devices;
uint8_t item_buffer[4096];
ALSAItem uitem; ALSAItem uitem;
@ -107,10 +107,12 @@ static int
fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice) fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice)
{ {
int err; int err;
uint32_t i; const char *str, *name;
const char *str;
snd_pcm_t *hndl; snd_pcm_t *hndl;
char device[64]; char device[64];
SpaPODBuilder b = { NULL, };
const SpaHandleFactory *factory = NULL;
SpaPODFrame f[3];
if (item->udevice) if (item->udevice)
udev_device_unref (item->udevice); udev_device_unref (item->udevice);
@ -148,60 +150,72 @@ fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice)
spa_log_error (this->log, "CAPTURE open failed: %s", snd_strerror(err)); spa_log_error (this->log, "CAPTURE open failed: %s", snd_strerror(err));
return -1; return -1;
} else { } else {
item->item.factory = &spa_alsa_source_factory; factory = &spa_alsa_source_factory;
snd_pcm_close (hndl); snd_pcm_close (hndl);
} }
} else { } else {
item->item.factory = &spa_alsa_sink_factory; factory = &spa_alsa_sink_factory;
snd_pcm_close (hndl); snd_pcm_close (hndl);
} }
item->item.id = udev_device_get_syspath (item->udevice); name = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
item->item.flags = 0; if (!(name && *name)) {
item->item.state = SPA_MONITOR_ITEM_STATE_AVAILABLE; name = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
item->item.klass = "Audio/Device"; if (!(name && *name)) {
item->item.info = &item->info; name = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
if (!(str && *str))
name = "Unknown";
item->info.items = item->info_items; spa_pod_builder_init (&b, this->item_buffer, sizeof (this->item_buffer));
i = 0;
item->info_items[i].key = "alsa.card"; spa_pod_builder_push_object (&b, &f[0], 0, this->uri.monitor_types.MonitorItem);
item->info_items[i++].value = str;
item->info_items[i].key = "udev-probed"; spa_pod_builder_add (&b,
item->info_items[i++].value = "1"; SPA_POD_PROP (&f[1], this->uri.monitor_types.id, 0, SPA_POD_TYPE_STRING, 1, udev_device_get_syspath (item->udevice)),
item->info_items[i].key = "device.api"; SPA_POD_PROP (&f[1], this->uri.monitor_types.flags, 0, SPA_POD_TYPE_INT, 1, 0),
item->info_items[i++].value = "alsa"; SPA_POD_PROP (&f[1], this->uri.monitor_types.state, 0, SPA_POD_TYPE_INT, 1, SPA_MONITOR_ITEM_STATE_AVAILABLE),
SPA_POD_PROP (&f[1], this->uri.monitor_types.name, 0, SPA_POD_TYPE_STRING, 1, name),
SPA_POD_PROP (&f[1], this->uri.monitor_types.klass, 0, SPA_POD_TYPE_STRING, 1, "Audio/Device"),
SPA_POD_PROP (&f[1], this->uri.monitor_types.factory, 0, SPA_POD_TYPE_POINTER, 1, this->uri.handle_factory,
factory),
0);
spa_pod_builder_add (&b,
SPA_POD_TYPE_PROP, &f[1], this->uri.monitor_types.info, 0,
SPA_POD_TYPE_STRUCT, 1, &f[2], 0);
spa_pod_builder_add (&b,
SPA_POD_TYPE_STRING, "alsa.card", SPA_POD_TYPE_STRING, str,
SPA_POD_TYPE_STRING, "udev-probed", SPA_POD_TYPE_STRING, "1",
SPA_POD_TYPE_STRING, "device.api", SPA_POD_TYPE_STRING, "alsa",
0);
if ((str = udev_device_get_property_value (udevice, "SOUND_CLASS")) && *str) { if ((str = udev_device_get_property_value (udevice, "SOUND_CLASS")) && *str) {
item->info_items[i].key = "device.class"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.class", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
str = udev_device_get_property_value (item->udevice, "ID_PATH"); str = udev_device_get_property_value (item->udevice, "ID_PATH");
if (!(str && *str)) if (!(str && *str))
str = udev_device_get_syspath (item->udevice); str = udev_device_get_syspath (item->udevice);
if (str && *str) { if (str && *str) {
item->info_items[i].key = "device.bus_path"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_syspath (item->udevice)) && *str) { if ((str = udev_device_get_syspath (item->udevice)) && *str) {
item->info_items[i].key = "sysfs.path"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) {
item->info_items[i].key = "udev.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) {
item->info_items[i].key = "device.bus"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) {
item->info_items[i].key = "device.subsystem"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.subsystem", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) {
item->info_items[i].key = "device.vendor.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE"); str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE");
if (!(str && *str)) { if (!(str && *str)) {
@ -211,36 +225,28 @@ fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice)
} }
} }
if (str && *str) { if (str && *str) {
item->info_items[i].key = "device.vendor.name"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.name", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) {
item->info_items[i].key = "device.product.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.product.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
}
str = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
if (str && *str) {
item->info_items[i].key = "device.product.name";
item->info_items[i++].value = str;
item->item.name = str;
} else {
item->item.name = "Unknown";
} }
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.product.name", SPA_POD_TYPE_STRING, name, 0);
if ((str = udev_device_get_property_value (item->udevice, "ID_SERIAL")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_SERIAL")) && *str) {
item->info_items[i].key = "device.serial"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "SOUND_FORM_FACTOR")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "SOUND_FORM_FACTOR")) && *str) {
item->info_items[i].key = "device.form_factor"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.form_factor", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
item->info.n_items = i;
spa_pod_builder_add (&b,
-SPA_POD_TYPE_STRUCT, &f[2],
-SPA_POD_TYPE_PROP, &f[1],
0);
spa_pod_builder_pop (&b, &f[0]);
item->item = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaMonitorItem);
return 0; return 0;
} }
@ -250,8 +256,12 @@ alsa_on_fd_events (SpaSource *source)
{ {
SpaALSAMonitor *this = source->data; SpaALSAMonitor *this = source->data;
struct udev_device *dev; struct udev_device *dev;
SpaEvent *event;
const char *str; const char *str;
SpaMonitorItem *item; uint32_t type;
SpaPODBuilder b = { NULL, };
SpaPODFrame f[1];
uint8_t buffer[4096];
dev = udev_monitor_receive_device (this->umonitor); dev = udev_monitor_receive_device (this->umonitor);
if (fill_item (this, &this->uitem, dev) < 0) if (fill_item (this, &this->uitem, dev) < 0)
@ -260,17 +270,21 @@ alsa_on_fd_events (SpaSource *source)
if ((str = udev_device_get_action (dev)) == NULL) if ((str = udev_device_get_action (dev)) == NULL)
str = "change"; str = "change";
item = &this->uitem.item;
if (strcmp (str, "add") == 0) { if (strcmp (str, "add") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_ADDED; type = this->uri.monitor_types.Added;
} else if (strcmp (str, "change") == 0) { } else if (strcmp (str, "change") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_CHANGED; type = this->uri.monitor_types.Changed;
} else if (strcmp (str, "remove") == 0) { } else if (strcmp (str, "remove") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_REMOVED; type = this->uri.monitor_types.Removed;
} } else
item->event.size = sizeof (this->uitem); return;
this->event_cb (&this->monitor, &item->event, this->user_data);
spa_pod_builder_init (&b, buffer, sizeof (buffer));
spa_pod_builder_object (&b, &f[0], 0, type,
SPA_POD_TYPE_POD, this->uitem.item);
event = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaMonitorEvent);
this->event_cb (&this->monitor, event, this->user_data);
} }
static SpaResult static SpaResult
@ -364,7 +378,7 @@ again:
this->index++; this->index++;
*item = &this->uitem.item; *item = this->uitem.item;
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -388,7 +402,7 @@ spa_alsa_monitor_get_interface (SpaHandle *handle,
this = (SpaALSAMonitor *) handle; this = (SpaALSAMonitor *) handle;
if (interface_id == this->uri.monitor) if (interface_id == this->uri.monitor_types.Monitor)
*interface = &this->monitor; *interface = &this->monitor;
else else
return SPA_RESULT_UNKNOWN_INTERFACE; return SPA_RESULT_UNKNOWN_INTERFACE;
@ -436,7 +450,8 @@ alsa_monitor_init (const SpaHandleFactory *factory,
spa_log_error (this->log, "a main-loop is needed"); spa_log_error (this->log, "a main-loop is needed");
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.monitor = spa_id_map_get_id (this->map, SPA_MONITOR_URI); this->uri.handle_factory = spa_id_map_get_id (this->map, SPA_HANDLE_FACTORY_URI);
spa_monitor_types_map (this->map, &this->uri.monitor_types);
this->monitor = alsamonitor; this->monitor = alsamonitor;

View file

@ -36,14 +36,13 @@ extern const SpaHandleFactory spa_v4l2_source_factory;
typedef struct _SpaV4l2Monitor SpaV4l2Monitor; typedef struct _SpaV4l2Monitor SpaV4l2Monitor;
typedef struct { typedef struct {
SpaMonitorItem item; SpaMonitorItem *item;
struct udev_device *udevice; struct udev_device *udevice;
SpaDict info;
SpaDictItem info_items[32];
} V4l2Item; } V4l2Item;
typedef struct { typedef struct {
uint32_t monitor; uint32_t handle_factory;
SpaMonitorTypes monitor_types;
} URI; } URI;
struct _SpaV4l2Monitor { struct _SpaV4l2Monitor {
@ -63,6 +62,7 @@ struct _SpaV4l2Monitor {
struct udev_enumerate *enumerate; struct udev_enumerate *enumerate;
uint32_t index; uint32_t index;
struct udev_list_entry *devices; struct udev_list_entry *devices;
uint8_t item_buffer[4096];
V4l2Item uitem; V4l2Item uitem;
@ -81,10 +81,11 @@ v4l2_udev_open (SpaV4l2Monitor *this)
} }
static void static void
fill_item (V4l2Item *item, struct udev_device *udevice) fill_item (SpaV4l2Monitor *this, V4l2Item *item, struct udev_device *udevice)
{ {
uint32_t i; const char *str, *name;
const char *str; SpaPODBuilder b = { NULL, };
SpaPODFrame f[3];
if (item->udevice) if (item->udevice)
udev_device_unref (item->udevice); udev_device_unref (item->udevice);
@ -92,48 +93,64 @@ fill_item (V4l2Item *item, struct udev_device *udevice)
if (udevice == NULL) if (udevice == NULL)
return; return;
item->item.id = udev_device_get_syspath (item->udevice); name = udev_device_get_property_value (item->udevice, "ID_V4L_PRODUCT");
item->item.flags = 0; if (!(name && *name)) {
item->item.state = SPA_MONITOR_ITEM_STATE_AVAILABLE; name = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
item->item.klass = "Video/Source"; if (!(name && *name)) {
item->item.info = &item->info; name = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
item->item.factory = &spa_v4l2_source_factory; if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
}
if (!(name && *name))
name = "Unknown";
item->info.items = item->info_items; spa_pod_builder_init (&b, this->item_buffer, sizeof (this->item_buffer));
i = 0;
item->info_items[i].key = "udev-probed"; spa_pod_builder_push_object (&b, &f[0], 0, this->uri.monitor_types.MonitorItem);
item->info_items[i++].value = "1";
item->info_items[i].key = "device.api"; spa_pod_builder_add (&b,
item->info_items[i++].value = "v4l2"; SPA_POD_PROP (&f[1], this->uri.monitor_types.id, 0, SPA_POD_TYPE_STRING, 1, udev_device_get_syspath (item->udevice)),
item->info_items[i].key = "device.path"; SPA_POD_PROP (&f[1], this->uri.monitor_types.flags, 0, SPA_POD_TYPE_INT, 1, 0),
item->info_items[i++].value = udev_device_get_devnode (item->udevice); SPA_POD_PROP (&f[1], this->uri.monitor_types.state, 0, SPA_POD_TYPE_INT, 1, SPA_MONITOR_ITEM_STATE_AVAILABLE),
SPA_POD_PROP (&f[1], this->uri.monitor_types.name, 0, SPA_POD_TYPE_STRING, 1, name),
SPA_POD_PROP (&f[1], this->uri.monitor_types.klass, 0, SPA_POD_TYPE_STRING, 1, "Video/Source"),
SPA_POD_PROP (&f[1], this->uri.monitor_types.factory, 0, SPA_POD_TYPE_POINTER, 1, this->uri.handle_factory,
&spa_v4l2_source_factory),
0);
spa_pod_builder_add (&b,
SPA_POD_TYPE_PROP, &f[1], this->uri.monitor_types.info, 0,
SPA_POD_TYPE_STRUCT, 1, &f[2], 0);
spa_pod_builder_add (&b,
SPA_POD_TYPE_STRING, "udev-probed", SPA_POD_TYPE_STRING, "1",
SPA_POD_TYPE_STRING, "device.api", SPA_POD_TYPE_STRING, "v4l2",
SPA_POD_TYPE_STRING, "device.path", SPA_POD_TYPE_STRING, udev_device_get_devnode (item->udevice),
0);
str = udev_device_get_property_value (item->udevice, "ID_PATH"); str = udev_device_get_property_value (item->udevice, "ID_PATH");
if (!(str && *str)) if (!(str && *str))
str = udev_device_get_syspath (item->udevice); str = udev_device_get_syspath (item->udevice);
if (str && *str) { if (str && *str) {
item->info_items[i].key = "device.bus_path"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_syspath (item->udevice)) && *str) { if ((str = udev_device_get_syspath (item->udevice)) && *str) {
item->info_items[i].key = "sysfs.path"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) {
item->info_items[i].key = "udev.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) {
item->info_items[i].key = "device.bus"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) {
item->info_items[i].key = "device.subsystem"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.subsystem", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) {
item->info_items[i].key = "device.vendor.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE"); str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE");
if (!(str && *str)) { if (!(str && *str)) {
@ -143,69 +160,64 @@ fill_item (V4l2Item *item, struct udev_device *udevice)
} }
} }
if (str && *str) { if (str && *str) {
item->info_items[i].key = "device.vendor.name"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.name", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) {
item->info_items[i].key = "device.product.id"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.product.id", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
}
str = udev_device_get_property_value (item->udevice, "ID_V4L_PRODUCT");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
}
if (str && *str) {
item->info_items[i].key = "device.product.name";
item->info_items[i++].value = str;
item->item.name = str;
} else {
item->item.name = "Unknown";
} }
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.product.name", SPA_POD_TYPE_STRING, name, 0);
if ((str = udev_device_get_property_value (item->udevice, "ID_SERIAL")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_SERIAL")) && *str) {
item->info_items[i].key = "device.serial"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
if ((str = udev_device_get_property_value (item->udevice, "ID_V4L_CAPABILITIES")) && *str) { if ((str = udev_device_get_property_value (item->udevice, "ID_V4L_CAPABILITIES")) && *str) {
item->info_items[i].key = "device.capabilities"; spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.capabilities", SPA_POD_TYPE_STRING, str, 0);
item->info_items[i++].value = str;
} }
item->info.n_items = i;
}
spa_pod_builder_add (&b,
-SPA_POD_TYPE_STRUCT, &f[2],
-SPA_POD_TYPE_PROP, &f[1],
0);
spa_pod_builder_pop (&b, &f[0]);
item->item = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaMonitorItem);
}
static void static void
v4l2_on_fd_events (SpaSource *source) v4l2_on_fd_events (SpaSource *source)
{ {
SpaV4l2Monitor *this = source->data; SpaV4l2Monitor *this = source->data;
struct udev_device *dev; struct udev_device *dev;
SpaEvent *event;
const char *action; const char *action;
SpaMonitorItem *item; uint32_t type;
SpaPODBuilder b = { NULL, };
SpaPODFrame f[1];
uint8_t buffer[4096];
dev = udev_monitor_receive_device (this->umonitor); dev = udev_monitor_receive_device (this->umonitor);
fill_item (&this->uitem, dev); fill_item (this, &this->uitem, dev);
if (dev == NULL) if (dev == NULL)
return; return;
if ((action = udev_device_get_action (dev)) == NULL) if ((action = udev_device_get_action (dev)) == NULL)
action = "change"; action = "change";
item = &this->uitem.item;
if (strcmp (action, "add") == 0) { if (strcmp (action, "add") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_ADDED; type = this->uri.monitor_types.Added;
} else if (strcmp (action, "change") == 0) { } else if (strcmp (action, "change") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_CHANGED; type = this->uri.monitor_types.Changed;
} else if (strcmp (action, "remove") == 0) { } else if (strcmp (action, "remove") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_REMOVED; type = this->uri.monitor_types.Removed;
} } else
item->event.size = sizeof (this->uitem); return;
this->event_cb (&this->monitor, &item->event, this->user_data);
spa_pod_builder_init (&b, buffer, sizeof (buffer));
spa_pod_builder_object (&b, &f[0], 0, type,
SPA_POD_TYPE_POD, this->uitem.item);
event = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaMonitorEvent);
this->event_cb (&this->monitor, event, this->user_data);
} }
static SpaResult static SpaResult
@ -283,18 +295,18 @@ spa_v4l2_monitor_enum_items (SpaMonitor *monitor,
this->index++; this->index++;
} }
if (this->devices == NULL) { if (this->devices == NULL) {
fill_item (&this->uitem, NULL); fill_item (this, &this->uitem, NULL);
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
} }
dev = udev_device_new_from_syspath (this->udev, dev = udev_device_new_from_syspath (this->udev,
udev_list_entry_get_name (this->devices)); udev_list_entry_get_name (this->devices));
fill_item (&this->uitem, dev); fill_item (this, &this->uitem, dev);
if (dev == NULL) if (dev == NULL)
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
*item = &this->uitem.item; *item = this->uitem.item;
this->devices = udev_list_entry_get_next (this->devices); this->devices = udev_list_entry_get_next (this->devices);
this->index++; this->index++;
@ -321,7 +333,7 @@ spa_v4l2_monitor_get_interface (SpaHandle *handle,
this = (SpaV4l2Monitor *) handle; this = (SpaV4l2Monitor *) handle;
if (interface_id == this->uri.monitor) if (interface_id == this->uri.monitor_types.Monitor)
*interface = &this->monitor; *interface = &this->monitor;
else else
return SPA_RESULT_UNKNOWN_INTERFACE; return SPA_RESULT_UNKNOWN_INTERFACE;
@ -369,7 +381,8 @@ v4l2_monitor_init (const SpaHandleFactory *factory,
spa_log_error (this->log, "a main-loop is needed"); spa_log_error (this->log, "a main-loop is needed");
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.monitor = spa_id_map_get_id (this->map, SPA_MONITOR_URI); this->uri.handle_factory = spa_id_map_get_id (this->map, SPA_HANDLE_FACTORY_URI);
spa_monitor_types_map (this->map, &this->uri.monitor_types);
this->monitor = v4l2monitor; this->monitor = v4l2monitor;

View file

@ -33,7 +33,7 @@
#include <lib/mapper.h> #include <lib/mapper.h>
typedef struct { typedef struct {
uint32_t monitor; SpaMonitorTypes monitor_types;
} URI; } URI;
typedef struct { typedef struct {
@ -58,41 +58,27 @@ typedef struct {
static void static void
inspect_item (SpaMonitorItem *item) inspect_item (SpaMonitorItem *item)
{ {
fprintf (stderr, " name: %s\n", item->name); spa_debug_pod (&item->pod);
fprintf (stderr, " class: %s\n", item->klass);
if (item->info)
spa_debug_dict (item->info);
} }
static void static void
on_monitor_event (SpaMonitor *monitor, on_monitor_event (SpaMonitor *monitor,
SpaMonitorEvent *event, SpaEvent *event,
void *user_data) void *user_data)
{ {
switch (event->type) { AppData *data = user_data;
case SPA_MONITOR_EVENT_TYPE_ADDED:
{ if (SPA_EVENT_TYPE (event) == data->uri.monitor_types.Added) {
SpaMonitorItem *item = (SpaMonitorItem *) event; fprintf (stderr, "added:\n");
fprintf (stderr, "added:\n"); inspect_item ((SpaMonitorItem*)event);
inspect_item (item); }
break; else if (SPA_EVENT_TYPE (event) == data->uri.monitor_types.Removed) {
} fprintf (stderr, "removed:\n");
case SPA_MONITOR_EVENT_TYPE_REMOVED: inspect_item ((SpaMonitorItem*)event);
{ }
SpaMonitorItem *item = (SpaMonitorItem *) event; else if (SPA_EVENT_TYPE (event) == data->uri.monitor_types.Changed) {
fprintf (stderr, "removed:\n"); fprintf (stderr, "changed:\n");
inspect_item (item); inspect_item ((SpaMonitorItem*)event);
break;
}
case SPA_MONITOR_EVENT_TYPE_CHANGED:
{
SpaMonitorItem *item = (SpaMonitorItem *) event;
fprintf (stderr, "changed:\n");
inspect_item (item);
break;
}
default:
break;
} }
} }
@ -198,7 +184,7 @@ main (int argc, char *argv[])
data.support[2].data = &data.main_loop; data.support[2].data = &data.main_loop;
data.n_support = 3; data.n_support = 3;
data.uri.monitor = spa_id_map_get_id (data.map, SPA_MONITOR_URI); spa_monitor_types_map (data.map, &data.uri.monitor_types);
if (argc < 2) { if (argc < 2) {
printf ("usage: %s <plugin.so>\n", argv[0]); printf ("usage: %s <plugin.so>\n", argv[0]);
@ -243,7 +229,7 @@ main (int argc, char *argv[])
continue; continue;
} }
if ((res = spa_handle_get_interface (handle, data.uri.monitor, &interface)) < 0) { if ((res = spa_handle_get_interface (handle, data.uri.monitor_types.Monitor, &interface)) < 0) {
printf ("can't get interface: %d\n", res); printf ("can't get interface: %d\n", res);
continue; continue;
} }