Commit 922af8fe authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

udev: refactor

parent cf72f532
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <poll.h> #include <poll.h>
#include <errno.h> #include <errno.h>
static int Open (vlc_object_t *); static int OpenV4L (vlc_object_t *);
static void Close (vlc_object_t *); static void Close (vlc_object_t *);
/* /*
...@@ -43,13 +43,22 @@ vlc_module_begin () ...@@ -43,13 +43,22 @@ vlc_module_begin ()
set_category (CAT_PLAYLIST) set_category (CAT_PLAYLIST)
set_subcategory (SUBCAT_PLAYLIST_SD) set_subcategory (SUBCAT_PLAYLIST_SD)
set_capability ("services_discovery", 0) set_capability ("services_discovery", 0)
set_callbacks (Open, Close) set_callbacks (OpenV4L, Close)
add_shortcut ("udev") add_shortcut ("udev")
vlc_module_end () vlc_module_end ()
struct subsys
{
const char *name;
char * (*get_mrl) (struct udev_device *dev);
char * (*get_name) (struct udev_device *dev);
char * (*get_cat) (struct udev_device *dev);
};
struct services_discovery_sys_t struct services_discovery_sys_t
{ {
const struct subsys *subsys;
struct udev_monitor *monitor; struct udev_monitor *monitor;
vlc_thread_t thread; vlc_thread_t thread;
input_item_t **itemv; input_item_t **itemv;
...@@ -62,15 +71,15 @@ static void HandleDevice (services_discovery_t *, struct udev_device *, bool); ...@@ -62,15 +71,15 @@ static void HandleDevice (services_discovery_t *, struct udev_device *, bool);
/** /**
* Probes and initializes. * Probes and initializes.
*/ */
static int Open (vlc_object_t *obj) static int Open (vlc_object_t *obj, const struct subsys *subsys)
{ {
const char subsys[] = "video4linux";
services_discovery_t *sd = (services_discovery_t *)obj; services_discovery_t *sd = (services_discovery_t *)obj;
services_discovery_sys_t *p_sys = malloc (sizeof (*p_sys)); services_discovery_sys_t *p_sys = malloc (sizeof (*p_sys));
if (p_sys == NULL) if (p_sys == NULL)
return VLC_ENOMEM; return VLC_ENOMEM;
sd->p_sys = p_sys; sd->p_sys = p_sys;
p_sys->subsys = subsys;
p_sys->itemv = NULL; p_sys->itemv = NULL;
p_sys->itemc = 0; p_sys->itemc = 0;
...@@ -81,7 +90,8 @@ static int Open (vlc_object_t *obj) ...@@ -81,7 +90,8 @@ static int Open (vlc_object_t *obj)
mon = udev_monitor_new_from_netlink (udev, "udev"); mon = udev_monitor_new_from_netlink (udev, "udev");
if (mon == NULL if (mon == NULL
|| udev_monitor_filter_add_match_subsystem_devtype (mon, subsys, NULL)) || udev_monitor_filter_add_match_subsystem_devtype (mon, subsys->name,
NULL))
goto error; goto error;
p_sys->monitor = mon; p_sys->monitor = mon;
...@@ -89,7 +99,7 @@ static int Open (vlc_object_t *obj) ...@@ -89,7 +99,7 @@ static int Open (vlc_object_t *obj)
struct udev_enumerate *devenum = udev_enumerate_new (udev); struct udev_enumerate *devenum = udev_enumerate_new (udev);
if (devenum == NULL) if (devenum == NULL)
goto error; goto error;
if (udev_enumerate_add_match_subsystem (devenum, subsys)) if (udev_enumerate_add_match_subsystem (devenum, subsys->name))
{ {
udev_enumerate_unref (devenum); udev_enumerate_unref (devenum);
goto error; goto error;
...@@ -174,9 +184,10 @@ static void *Run (void *data) ...@@ -174,9 +184,10 @@ static void *Run (void *data)
continue; continue;
/* FIXME: handle change, offline, online */ /* FIXME: handle change, offline, online */
if (!strcmp (udev_device_get_action (dev), "add")) const char *action = udev_device_get_action (dev);
if (!strcmp (action, "add"))
HandleDevice (sd, dev, true); HandleDevice (sd, dev, true);
else if (!strcmp (udev_device_get_action (dev), "remove")) else if (!strcmp (action, "remove"))
HandleDevice (sd, dev, false); HandleDevice (sd, dev, false);
udev_device_unref (dev); udev_device_unref (dev);
...@@ -228,26 +239,14 @@ static char *decode_property (struct udev_device *dev, const char *name) ...@@ -228,26 +239,14 @@ static char *decode_property (struct udev_device *dev, const char *name)
return decode (udev_device_get_property_value (dev, name)); return decode (udev_device_get_property_value (dev, name));
} }
static bool is_v4l_legacy (struct udev_device *dev)
{
const char *version;
version = udev_device_get_property_value (dev, "ID_V4L_VERSION");
return version && !strcmp (version, "1");
}
static void HandleDevice (services_discovery_t *sd, struct udev_device *dev, static void HandleDevice (services_discovery_t *sd, struct udev_device *dev,
bool add) bool add)
{ {
services_discovery_sys_t *p_sys = sd->p_sys; services_discovery_sys_t *p_sys = sd->p_sys;
/* Determine media location */ /* Determine media location */
const char *scheme = "v4l2"; char *mrl = p_sys->subsys->get_mrl (dev);
if (is_v4l_legacy (dev)) if (mrl == NULL)
scheme = "v4l";
const char *node = udev_device_get_devnode (dev);
char *mrl;
if (asprintf (&mrl, "%s://%s", scheme, node) == -1)
return; return;
/* Find item in list */ /* Find item in list */
...@@ -269,19 +268,20 @@ static void HandleDevice (services_discovery_t *sd, struct udev_device *dev, ...@@ -269,19 +268,20 @@ static void HandleDevice (services_discovery_t *sd, struct udev_device *dev,
/* Add/Remove old item */ /* Add/Remove old item */
if (add && (item == NULL)) if (add && (item == NULL))
{ {
char *vnd = decode_property (dev, "ID_VENDOR_ENC"); char *name = p_sys->subsys->get_name (dev);
const char *name = udev_device_get_property_value (dev,
"ID_V4L_PRODUCT");
item = input_item_NewWithType (VLC_OBJECT (sd), mrl, item = input_item_NewWithType (VLC_OBJECT (sd), mrl,
name ? name : "Unnamed", name ? name : "Unnamed",
0, NULL, 0, -1, ITEM_TYPE_CARD); 0, NULL, 0, -1, ITEM_TYPE_CARD);
msg_Dbg (sd, "adding %s", mrl); free (name);
if (item != NULL) if (item != NULL)
{ {
services_discovery_AddItem (sd, item, vnd ? vnd : "Generic"); msg_Dbg (sd, "adding %s", mrl);
name = p_sys->subsys->get_cat (dev);
services_discovery_AddItem (sd, item, name ? name : "Generic");
free (name);
TAB_APPEND (p_sys->itemc, p_sys->itemv, item); TAB_APPEND (p_sys->itemc, p_sys->itemv, item);
} }
free (vnd);
} }
else if (!add && (item != NULL)) else if (!add && (item != NULL))
{ {
...@@ -292,3 +292,46 @@ static void HandleDevice (services_discovery_t *sd, struct udev_device *dev, ...@@ -292,3 +292,46 @@ static void HandleDevice (services_discovery_t *sd, struct udev_device *dev,
} }
free (mrl); free (mrl);
} }
/*** Video4Linux support ***/
static bool is_v4l_legacy (struct udev_device *dev)
{
const char *version;
version = udev_device_get_property_value (dev, "ID_V4L_VERSION");
return version && !strcmp (version, "1");
}
static char *v4l_get_mrl (struct udev_device *dev)
{
/* Determine media location */
const char *scheme = "v4l2";
if (is_v4l_legacy (dev))
scheme = "v4l";
const char *node = udev_device_get_devnode (dev);
char *mrl;
if (asprintf (&mrl, "%s://%s", scheme, node) == -1)
mrl = NULL;
return mrl;
}
static char *v4l_get_name (struct udev_device *dev)
{
const char *prd = udev_device_get_property_value (dev, "ID_V4L_PRODUCT");
return prd ? strdup (prd) : NULL;
}
static char *v4l_get_cat (struct udev_device *dev)
{
return decode_property (dev, "ID_VENDOR_ENC");
}
int OpenV4L (vlc_object_t *obj)
{
static const struct subsys subsys = {
"video4linux", v4l_get_mrl, v4l_get_name, v4l_get_cat,
};
return Open (obj, &subsys);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment