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_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 <spa/include/spa/id-map.h>
#include <spa/include/spa/node-event.h>
#include <spa/include/spa/monitor.h>
typedef struct _PinosURI PinosURI;
@ -56,6 +57,7 @@ struct _PinosURI {
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
SpaMonitorTypes monitor_types;
};
void pinos_uri_init (PinosURI *uri);

View file

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

View file

@ -31,26 +31,62 @@ typedef struct _SpaMonitor SpaMonitor;
#include <spa/defs.h>
#include <spa/dict.h>
#include <spa/plugin.h>
#include <spa/event.h>
/**
* SpaMonitorEventType:
* @SPA_MONITOR_EVENT_TYPE_INVALID: invalid event
* @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
* @SPA_MONITOR_EVENT_TYPE_CHANGED: an item was changed, data points to #SpaMonitorItem
*/
typedef enum {
SPA_MONITOR_EVENT_TYPE_INVALID = 0,
SPA_MONITOR_EVENT_TYPE_ADDED,
SPA_MONITOR_EVENT_TYPE_REMOVED,
SPA_MONITOR_EVENT_TYPE_CHANGED,
} SpaMonitorEventType;
typedef SpaEvent SpaMonitorEvent;
#define SPA_MONITOR_EVENT_URI "http://spaplug.in/ns/monitor-event"
#define SPA_MONITOR_EVENT_PREFIX SPA_MONITOR_EVENT_URI "#"
#define SPA_MONITOR_EVENT__Added SPA_MONITOR_EVENT_PREFIX "Added"
#define SPA_MONITOR_EVENT__Removed SPA_MONITOR_EVENT_PREFIX "Removed"
#define SPA_MONITOR_EVENT__Changed SPA_MONITOR_EVENT_PREFIX "Changed"
typedef SpaPODObject SpaMonitorItem;
#define SPA_MONITOR_ITEM_URI "http://spaplug.in/ns/monitor-item"
#define SPA_MONITOR_ITEM_PREFIX SPA_MONITOR_ITEM_URI "#"
#define SPA_MONITOR_ITEM__id SPA_MONITOR_ITEM_PREFIX "id"
#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 {
SpaMonitorEventType type;
uint32_t size;
} SpaMonitorEvent;
uint32_t Monitor;
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 {
SPA_MONITOR_ITEM_FLAG_NONE = 0,
@ -68,17 +104,6 @@ typedef enum {
SPA_MONITOR_ITEM_STATE_UNAVAILABLE,
} 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:
* @node: a #SpaMonitor emiting the event
@ -88,9 +113,9 @@ typedef struct {
* This will be called when a monitor event is notified
* on @monitor.
*/
typedef void (*SpaMonitorEventCallback) (SpaMonitor *monitor,
SpaMonitorEvent *event,
void *user_data);
typedef void (*SpaMonitorEventCallback) (SpaMonitor *monitor,
SpaMonitorEvent *event,
void *user_data);
/**
* SpaMonitor:

View file

@ -27,6 +27,9 @@ extern "C" {
#include <spa/defs.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 _SpaHandleFactory SpaHandleFactory;

View file

@ -233,6 +233,15 @@ spa_pod_builder_bytes (SpaPODBuilder *builder, const void *bytes, uint32_t len)
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 } }
static inline uint32_t
@ -329,6 +338,7 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
SpaPODDouble double_pod;
SpaPODString string_pod;
SpaPODBytes bytes_pod;
SpaPODPointer pointer_pod;
SpaPODRectangle rectangle_pod;
SpaPODFraction fraction_pod;
SpaPODArray array_pod;
@ -400,6 +410,14 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
head.bytes_pod.pod.size = body_size;
head_size = sizeof (SpaPOD);
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:
head.rectangle_pod.pod.type = SPA_POD_TYPE_RECTANGLE;
head.rectangle_pod.pod.size = body_size = sizeof (SpaRectangle);

View file

@ -116,7 +116,9 @@ spa_pod_iter_getv (SpaPODIter *iter,
uint32_t type,
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);
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);
}
return true;
return res;
}
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, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \
break; \
case SPA_POD_TYPE_POINTER: \
{ \
SpaPODPointerBody *b = SPA_POD_BODY (pod); \
*(va_arg (args, void **)) = b->value; \
break; \
} \
case SPA_POD_TYPE_RECTANGLE: \
*(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \
break; \
@ -143,6 +149,7 @@ spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key)
#define SPA_POD_COLLECT_SKIP(type,args) \
switch (type) { \
case SPA_POD_TYPE_BYTES: \
case SPA_POD_TYPE_POINTER: \
va_arg (args, void*); \
/* fallthrough */ \
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);
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)) {
SPA_POD_COLLECT (&prop->body.value, type, args);
count++;
@ -202,6 +209,9 @@ spa_pod_contents_query (const SpaPOD *pod, uint32_t offset, uint32_t key, ...)
return count;
}
#define spa_pod_object_query(object,key, ...) \
spa_pod_contents_query (&object->pod, sizeof (SpaPODObject), key, __VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

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

View file

@ -195,6 +195,7 @@ struct pod_type_name {
{ "float", "Float" },
{ "double", "Double" },
{ "string", "String" },
{ "pointer", "Pointer" },
{ "rectangle", "Rectangle" },
{ "fraction", "Fraction" },
{ "bitmask", "Bitmask" },
@ -231,6 +232,13 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
case SPA_POD_TYPE_STRING:
printf ("%-*sString \"%s\"\n", prefix, "", (char *) body);
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:
{
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);
if (id < this->n_uris)
if (id <= this->n_uris)
return this->uris[id];
return NULL;

View file

@ -39,14 +39,13 @@ extern const SpaHandleFactory spa_alsa_source_factory;
typedef struct _SpaALSAMonitor SpaALSAMonitor;
typedef struct {
SpaMonitorItem item;
SpaMonitorItem *item;
struct udev_device *udevice;
SpaDict info;
SpaDictItem info_items[32];
} ALSAItem;
typedef struct {
uint32_t monitor;
uint32_t handle_factory;
SpaMonitorTypes monitor_types;
} URI;
struct _SpaALSAMonitor {
@ -66,6 +65,7 @@ struct _SpaALSAMonitor {
struct udev_enumerate *enumerate;
uint32_t index;
struct udev_list_entry *devices;
uint8_t item_buffer[4096];
ALSAItem uitem;
@ -107,10 +107,12 @@ static int
fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice)
{
int err;
uint32_t i;
const char *str;
const char *str, *name;
snd_pcm_t *hndl;
char device[64];
SpaPODBuilder b = { NULL, };
const SpaHandleFactory *factory = NULL;
SpaPODFrame f[3];
if (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));
return -1;
} else {
item->item.factory = &spa_alsa_source_factory;
factory = &spa_alsa_source_factory;
snd_pcm_close (hndl);
}
} else {
item->item.factory = &spa_alsa_sink_factory;
factory = &spa_alsa_sink_factory;
snd_pcm_close (hndl);
}
item->item.id = udev_device_get_syspath (item->udevice);
item->item.flags = 0;
item->item.state = SPA_MONITOR_ITEM_STATE_AVAILABLE;
item->item.klass = "Audio/Device";
item->item.info = &item->info;
name = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
if (!(str && *str))
name = "Unknown";
item->info.items = item->info_items;
i = 0;
item->info_items[i].key = "alsa.card";
item->info_items[i++].value = str;
item->info_items[i].key = "udev-probed";
item->info_items[i++].value = "1";
item->info_items[i].key = "device.api";
item->info_items[i++].value = "alsa";
spa_pod_builder_init (&b, this->item_buffer, sizeof (this->item_buffer));
spa_pod_builder_push_object (&b, &f[0], 0, this->uri.monitor_types.MonitorItem);
spa_pod_builder_add (&b,
SPA_POD_PROP (&f[1], this->uri.monitor_types.id, 0, SPA_POD_TYPE_STRING, 1, udev_device_get_syspath (item->udevice)),
SPA_POD_PROP (&f[1], this->uri.monitor_types.flags, 0, SPA_POD_TYPE_INT, 1, 0),
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) {
item->info_items[i].key = "device.class";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.class", SPA_POD_TYPE_STRING, str, 0);
}
str = udev_device_get_property_value (item->udevice, "ID_PATH");
if (!(str && *str))
str = udev_device_get_syspath (item->udevice);
if (str && *str) {
item->info_items[i].key = "device.bus_path";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_syspath (item->udevice)) && *str) {
item->info_items[i].key = "sysfs.path";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) {
item->info_items[i].key = "udev.id";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) {
item->info_items[i].key = "device.bus";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) {
item->info_items[i].key = "device.subsystem";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.subsystem", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) {
item->info_items[i].key = "device.vendor.id";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.id", SPA_POD_TYPE_STRING, str, 0);
}
str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE");
if (!(str && *str)) {
@ -211,36 +225,28 @@ fill_item (SpaALSAMonitor *this, ALSAItem *item, struct udev_device *udevice)
}
}
if (str && *str) {
item->info_items[i].key = "device.vendor.name";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.name", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) {
item->info_items[i].key = "device.product.id";
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.id", SPA_POD_TYPE_STRING, str, 0);
}
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) {
item->info_items[i].key = "device.serial";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "SOUND_FORM_FACTOR")) && *str) {
item->info_items[i].key = "device.form_factor";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.form_factor", SPA_POD_TYPE_STRING, str, 0);
}
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;
}
@ -250,8 +256,12 @@ alsa_on_fd_events (SpaSource *source)
{
SpaALSAMonitor *this = source->data;
struct udev_device *dev;
SpaEvent *event;
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);
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)
str = "change";
item = &this->uitem.item;
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) {
item->event.type = SPA_MONITOR_EVENT_TYPE_CHANGED;
type = this->uri.monitor_types.Changed;
} else if (strcmp (str, "remove") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_REMOVED;
}
item->event.size = sizeof (this->uitem);
this->event_cb (&this->monitor, &item->event, this->user_data);
type = this->uri.monitor_types.Removed;
} else
return;
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
@ -364,7 +378,7 @@ again:
this->index++;
*item = &this->uitem.item;
*item = this->uitem.item;
return SPA_RESULT_OK;
}
@ -388,7 +402,7 @@ spa_alsa_monitor_get_interface (SpaHandle *handle,
this = (SpaALSAMonitor *) handle;
if (interface_id == this->uri.monitor)
if (interface_id == this->uri.monitor_types.Monitor)
*interface = &this->monitor;
else
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");
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;

View file

@ -36,14 +36,13 @@ extern const SpaHandleFactory spa_v4l2_source_factory;
typedef struct _SpaV4l2Monitor SpaV4l2Monitor;
typedef struct {
SpaMonitorItem item;
SpaMonitorItem *item;
struct udev_device *udevice;
SpaDict info;
SpaDictItem info_items[32];
} V4l2Item;
typedef struct {
uint32_t monitor;
uint32_t handle_factory;
SpaMonitorTypes monitor_types;
} URI;
struct _SpaV4l2Monitor {
@ -63,6 +62,7 @@ struct _SpaV4l2Monitor {
struct udev_enumerate *enumerate;
uint32_t index;
struct udev_list_entry *devices;
uint8_t item_buffer[4096];
V4l2Item uitem;
@ -81,10 +81,11 @@ v4l2_udev_open (SpaV4l2Monitor *this)
}
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;
const char *str, *name;
SpaPODBuilder b = { NULL, };
SpaPODFrame f[3];
if (item->udevice)
udev_device_unref (item->udevice);
@ -92,48 +93,64 @@ fill_item (V4l2Item *item, struct udev_device *udevice)
if (udevice == NULL)
return;
item->item.id = udev_device_get_syspath (item->udevice);
item->item.flags = 0;
item->item.state = SPA_MONITOR_ITEM_STATE_AVAILABLE;
item->item.klass = "Video/Source";
item->item.info = &item->info;
item->item.factory = &spa_v4l2_source_factory;
name = udev_device_get_property_value (item->udevice, "ID_V4L_PRODUCT");
if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(name && *name)) {
name = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
}
if (!(name && *name))
name = "Unknown";
item->info.items = item->info_items;
i = 0;
item->info_items[i].key = "udev-probed";
item->info_items[i++].value = "1";
item->info_items[i].key = "device.api";
item->info_items[i++].value = "v4l2";
item->info_items[i].key = "device.path";
item->info_items[i++].value = udev_device_get_devnode (item->udevice);
spa_pod_builder_init (&b, this->item_buffer, sizeof (this->item_buffer));
spa_pod_builder_push_object (&b, &f[0], 0, this->uri.monitor_types.MonitorItem);
spa_pod_builder_add (&b,
SPA_POD_PROP (&f[1], this->uri.monitor_types.id, 0, SPA_POD_TYPE_STRING, 1, udev_device_get_syspath (item->udevice)),
SPA_POD_PROP (&f[1], this->uri.monitor_types.flags, 0, SPA_POD_TYPE_INT, 1, 0),
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");
if (!(str && *str))
str = udev_device_get_syspath (item->udevice);
if (str && *str) {
item->info_items[i].key = "device.bus_path";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_syspath (item->udevice)) && *str) {
item->info_items[i].key = "sysfs.path";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_ID")) && *str) {
item->info_items[i].key = "udev.id";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_BUS")) && *str) {
item->info_items[i].key = "device.bus";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "SUBSYSTEM")) && *str) {
item->info_items[i].key = "device.subsystem";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.subsystem", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_VENDOR_ID")) && *str) {
item->info_items[i].key = "device.vendor.id";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.id", SPA_POD_TYPE_STRING, str, 0);
}
str = udev_device_get_property_value (item->udevice, "ID_VENDOR_FROM_DATABASE");
if (!(str && *str)) {
@ -143,69 +160,64 @@ fill_item (V4l2Item *item, struct udev_device *udevice)
}
}
if (str && *str) {
item->info_items[i].key = "device.vendor.name";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.vendor.name", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_MODEL_ID")) && *str) {
item->info_items[i].key = "device.product.id";
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.id", SPA_POD_TYPE_STRING, str, 0);
}
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) {
item->info_items[i].key = "device.serial";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, str, 0);
}
if ((str = udev_device_get_property_value (item->udevice, "ID_V4L_CAPABILITIES")) && *str) {
item->info_items[i].key = "device.capabilities";
item->info_items[i++].value = str;
spa_pod_builder_add (&b, SPA_POD_TYPE_STRING, "device.capabilities", SPA_POD_TYPE_STRING, str, 0);
}
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
v4l2_on_fd_events (SpaSource *source)
{
SpaV4l2Monitor *this = source->data;
struct udev_device *dev;
SpaEvent *event;
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);
fill_item (&this->uitem, dev);
fill_item (this, &this->uitem, dev);
if (dev == NULL)
return;
if ((action = udev_device_get_action (dev)) == NULL)
action = "change";
item = &this->uitem.item;
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) {
item->event.type = SPA_MONITOR_EVENT_TYPE_CHANGED;
type = this->uri.monitor_types.Changed;
} else if (strcmp (action, "remove") == 0) {
item->event.type = SPA_MONITOR_EVENT_TYPE_REMOVED;
}
item->event.size = sizeof (this->uitem);
this->event_cb (&this->monitor, &item->event, this->user_data);
type = this->uri.monitor_types.Removed;
} else
return;
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
@ -283,18 +295,18 @@ spa_v4l2_monitor_enum_items (SpaMonitor *monitor,
this->index++;
}
if (this->devices == NULL) {
fill_item (&this->uitem, NULL);
fill_item (this, &this->uitem, NULL);
return SPA_RESULT_ENUM_END;
}
dev = udev_device_new_from_syspath (this->udev,
udev_list_entry_get_name (this->devices));
fill_item (&this->uitem, dev);
fill_item (this, &this->uitem, dev);
if (dev == NULL)
return SPA_RESULT_ENUM_END;
*item = &this->uitem.item;
*item = this->uitem.item;
this->devices = udev_list_entry_get_next (this->devices);
this->index++;
@ -321,7 +333,7 @@ spa_v4l2_monitor_get_interface (SpaHandle *handle,
this = (SpaV4l2Monitor *) handle;
if (interface_id == this->uri.monitor)
if (interface_id == this->uri.monitor_types.Monitor)
*interface = &this->monitor;
else
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");
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;

View file

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