Explorar el Código

linux-v4l2: Replace custom udev callbacks

Use the signal system provided by obs instead of the custom callback
implementation. This reduces the amount of code and complexity.
fryshorts hace 10 años
padre
commit
4bf7a7b61e
Se han modificado 3 ficheros con 66 adiciones y 112 borrados
  1. 19 7
      plugins/linux-v4l2/v4l2-input.c
  2. 40 65
      plugins/linux-v4l2/v4l2-udev.c
  3. 7 40
      plugins/linux-v4l2/v4l2-udev.h

+ 19 - 7
plugins/linux-v4l2/v4l2-input.c

@@ -80,7 +80,6 @@ struct v4l2_data {
 	obs_source_t *source;
 	pthread_t thread;
 	os_event_t *event;
-	void *udev;
 
 	int_fast32_t dev;
 	int width;
@@ -674,12 +673,15 @@ static bool resolution_selected(obs_properties_t *props, obs_property_t *p,
  * If everything went fine we can start capturing again when the device is
  * reconnected
  */
-static void device_added(const char *dev, void *vptr)
+static void device_added(void *vptr, calldata_t *calldata)
 {
 	V4L2_DATA(vptr);
 
 	obs_source_update_properties(data->source);
 
+	const char *dev;
+	calldata_get_string(calldata, "device", &dev);
+
 	if (strcmp(data->device_id, dev))
 		return;
 
@@ -692,12 +694,15 @@ static void device_added(const char *dev, void *vptr)
  *
  * We stop recording here so we don't block the device node
  */
-static void device_removed(const char *dev, void *vptr)
+static void device_removed(void *vptr, calldata_t *calldata)
 {
 	V4L2_DATA(vptr);
 
 	obs_source_update_properties(data->source);
 
+	const char *dev;
+	calldata_get_string(calldata, "device", &dev);
+
 	if (strcmp(data->device_id, dev))
 		return;
 
@@ -790,7 +795,12 @@ static void v4l2_destroy(void *vptr)
 		bfree(data->device_id);
 
 #if HAVE_UDEV
-	v4l2_unref_udev(data->udev);
+	signal_handler_t *sh = v4l2_get_udev_signalhandler();
+
+	signal_handler_disconnect(sh, "device_added", device_added, data);
+	signal_handler_disconnect(sh, "device_removed", device_removed, data);
+
+	v4l2_unref_udev();
 #endif
 
 	bfree(data);
@@ -946,9 +956,11 @@ static void *v4l2_create(obs_data_t *settings, obs_source_t *source)
 	v4l2_update(data, settings);
 
 #if HAVE_UDEV
-	data->udev = v4l2_init_udev();
-	v4l2_set_device_added_callback(data->udev, &device_added, data);
-	v4l2_set_device_removed_callback(data->udev, &device_removed, data);
+	v4l2_init_udev();
+	signal_handler_t *sh = v4l2_get_udev_signalhandler();
+
+	signal_handler_connect(sh, "device_added", &device_added, data);
+	signal_handler_connect(sh, "device_removed", &device_removed, data);
 #endif
 
 	return data;

+ 40 - 65
plugins/linux-v4l2/v4l2-udev.c

@@ -23,9 +23,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "v4l2-udev.h"
 
-#define UDEV_DATA(voidptr) struct v4l2_udev_mon_t *m \
-		= (struct v4l2_udev_mon_t *) voidptr;
-
 /** udev action enum */
 enum udev_action {
 	UDEV_ACTION_ADDED,
@@ -33,14 +30,10 @@ enum udev_action {
 	UDEV_ACTION_UNKNOWN
 };
 
-/** monitor object holding the callbacks */
-struct v4l2_udev_mon_t {
-	/* data for the device added callback */
-	void *dev_added_userdata;
-	v4l2_device_added_cb dev_added_cb;
-	/* data for the device removed callback */
-	void *dev_removed_userdata;
-	v4l2_device_removed_cb dev_removed_cb;
+static const char *udev_signals[] = {
+	"void device_added(string device)",
+	"void device_removed(string device)",
+	NULL
 };
 
 /* global data */
@@ -50,7 +43,7 @@ static pthread_mutex_t udev_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_t udev_thread;
 static os_event_t *udev_event;
 
-static DARRAY(struct v4l2_udev_mon_t) udev_clients;
+static signal_handler_t *udev_signalhandler = NULL;
 
 /**
  * udev gives us the device action as string, so we convert it here ...
@@ -76,35 +69,36 @@ static enum udev_action udev_action_to_enum(const char *action)
  *
  * @param dev udev device that had an event occuring
  */
-static inline void udev_call_callbacks(struct udev_device *dev)
+static inline void udev_signal_event(struct udev_device *dev)
 {
 	const char *node;
 	enum udev_action action;
+	struct calldata data;
 
 	pthread_mutex_lock(&udev_mutex);
 
 	node   = udev_device_get_devnode(dev);
 	action = udev_action_to_enum(udev_device_get_action(dev));
 
-	for (size_t idx = 0; idx < udev_clients.num; idx++) {
-		struct v4l2_udev_mon_t *c = &udev_clients.array[idx];
-
-		switch (action) {
-		case UDEV_ACTION_ADDED:
-			if (!c->dev_added_cb)
-				continue;
-			c->dev_added_cb(node, c->dev_added_userdata);
-			break;
-		case UDEV_ACTION_REMOVED:
-			if (!c->dev_removed_cb)
-				continue;
-			c->dev_removed_cb(node, c->dev_removed_userdata);
-			break;
-		default:
-			break;
-		}
+	calldata_init(&data);
+
+	calldata_set_string(&data, "device", node);
+
+	switch (action) {
+	case UDEV_ACTION_ADDED:
+		signal_handler_signal(udev_signalhandler,
+				"device_added", &data);
+		break;
+	case UDEV_ACTION_REMOVED:
+		signal_handler_signal(udev_signalhandler,
+				"device_removed", &data);
+		break;
+	default:
+		break;
 	}
 
+	calldata_free(&data);
+
 	pthread_mutex_unlock(&udev_mutex);
 }
 
@@ -146,7 +140,7 @@ static void *udev_event_thread(void *vptr)
 		if (!dev)
 			continue;
 
-		udev_call_callbacks(dev);
+		udev_signal_event(dev);
 
 		udev_device_unref(dev);
 	}
@@ -157,10 +151,8 @@ static void *udev_event_thread(void *vptr)
 	return NULL;
 }
 
-void *v4l2_init_udev(void)
+void v4l2_init_udev(void)
 {
-	struct v4l2_udev_mon_t *ret = NULL;
-
 	pthread_mutex_lock(&udev_mutex);
 
 	/* set up udev */
@@ -170,55 +162,38 @@ void *v4l2_init_udev(void)
 		if (pthread_create(&udev_thread, NULL, udev_event_thread,
 				NULL) != 0)
 			goto fail;
-		da_init(udev_clients);
+
+		udev_signalhandler = signal_handler_create();
+		if (!udev_signalhandler)
+			goto fail;
+		signal_handler_add_array(udev_signalhandler, udev_signals);
+
 	}
 	udev_refs++;
 
-	/* create monitor object */
-	ret = da_push_back_new(udev_clients);
 fail:
 	pthread_mutex_unlock(&udev_mutex);
-	return ret;
 }
 
-void v4l2_unref_udev(void *monitor)
+void v4l2_unref_udev(void)
 {
-	UDEV_DATA(monitor);
 	pthread_mutex_lock(&udev_mutex);
 
-	/* clean up monitor object */
-	da_erase_item(udev_clients, m);
-
 	/* unref udev monitor */
-	udev_refs--;
-	if (udev_refs == 0) {
+	if (udev_refs && --udev_refs == 0) {
 		os_event_signal(udev_event);
 		pthread_join(udev_thread, NULL);
 		os_event_destroy(udev_event);
-		da_free(udev_clients);
+
+		if (udev_signalhandler)
+			signal_handler_destroy(udev_signalhandler);
+		udev_signalhandler = NULL;
 	}
 
 	pthread_mutex_unlock(&udev_mutex);
 }
 
-void v4l2_set_device_added_callback(void *monitor, v4l2_device_added_cb cb,
-		void *userdata)
+signal_handler_t *v4l2_get_udev_signalhandler(void)
 {
-	UDEV_DATA(monitor);
-	if (!m)
-		return;
-
-	m->dev_added_cb = cb;
-	m->dev_added_userdata = userdata;
-}
-
-void v4l2_set_device_removed_callback(void *monitor, v4l2_device_removed_cb cb,
-		void *userdata)
-{
-	UDEV_DATA(monitor);
-	if (!m)
-		return;
-
-	m->dev_removed_cb = cb;
-	m->dev_removed_userdata = userdata;
+	return udev_signalhandler;
 }

+ 7 - 40
plugins/linux-v4l2/v4l2-udev.h

@@ -19,61 +19,28 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <inttypes.h>
 
+#include <callback/signal.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
  * Initialize udev system to watch for device events
- *
- * @return monitor object, or NULL on error
  */
-void *v4l2_init_udev(void);
+void v4l2_init_udev(void);
 
 /**
  * Unref the udev system
- *
- * This will also remove any registered callbacks if there are any
- *
- * @param monitor monitor object
- */
-void v4l2_unref_udev(void *monitor);
-
-/**
- * Callback when a device was added.
- *
- * @param dev device node of the device that was added
- * @param userdata pointer to userdata specified when registered
- */
-typedef void (*v4l2_device_added_cb)(const char *dev, void *userdata);
-
-/**
- * Callback when a device was removed.
- *
- * @param dev device node of the device that was removed
- * @param userdata pointer to userdata specified when registered
- */
-typedef void (*v4l2_device_removed_cb)(const char *dev, void *userdata);
-
-/**
- * Register the device added callback
- *
- * @param monitor monitor object
- * @param cb the function that should be called
- * @param userdata pointer to userdata that should be passed to the callback
  */
-void v4l2_set_device_added_callback(void *monitor, v4l2_device_added_cb cb,
-		void *userdata);
+void v4l2_unref_udev(void);
 
 /**
- * Register the device remove callback
+ * Get signal handler
  *
- * @param monitor monitor object
- * @param cb the function that should be called
- * @param userdata pointer to userdata that should be passed to the callback
+ * @return signal handler for udev events
  */
-void v4l2_set_device_removed_callback(void *monitor, v4l2_device_removed_cb cb,
-		void *userdata);
+signal_handler_t *v4l2_get_udev_signalhandler(void);
 
 #ifdef __cplusplus
 }