Use udev events in the v4l2 plugin.
This adds code to set up the udev monitoring library and use the events to detect connects/disconnects of devices. When the currently used device is disconnected the plugin will stop recording and clean up, so that the device node is freed up. On reconnection of the device the plugin will use the event to automatically start the capture again.master
parent
1bae57668c
commit
9a37b2ce9c
|
@ -36,6 +36,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "v4l2-helpers.h"
|
#include "v4l2-helpers.h"
|
||||||
|
|
||||||
|
#if HAVE_UDEV
|
||||||
|
#include "v4l2-udev.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define V4L2_DATA(voidptr) struct v4l2_data *data = voidptr;
|
#define V4L2_DATA(voidptr) struct v4l2_data *data = voidptr;
|
||||||
|
|
||||||
#define timeval2ns(tv) \
|
#define timeval2ns(tv) \
|
||||||
|
@ -58,6 +62,7 @@ struct v4l2_data {
|
||||||
obs_source_t *source;
|
obs_source_t *source;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
os_event_t *event;
|
os_event_t *event;
|
||||||
|
void *udev;
|
||||||
|
|
||||||
int_fast32_t dev;
|
int_fast32_t dev;
|
||||||
int width;
|
int width;
|
||||||
|
@ -69,6 +74,10 @@ struct v4l2_data {
|
||||||
uint64_t frames;
|
uint64_t frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* forward declarations */
|
||||||
|
static void v4l2_init(struct v4l2_data *data);
|
||||||
|
static void v4l2_terminate(struct v4l2_data *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the output frame structure for obs and compute plane offsets
|
* Prepare the output frame structure for obs and compute plane offsets
|
||||||
*
|
*
|
||||||
|
@ -504,6 +513,43 @@ static bool resolution_selected(obs_properties_t *props, obs_property_t *p,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_UDEV
|
||||||
|
/**
|
||||||
|
* Device added callback
|
||||||
|
*
|
||||||
|
* If everything went fine we can start capturing again when the device is
|
||||||
|
* reconnected
|
||||||
|
*/
|
||||||
|
static void device_added(const char *dev, void *vptr)
|
||||||
|
{
|
||||||
|
V4L2_DATA(vptr);
|
||||||
|
|
||||||
|
if (strcmp(data->device_id, dev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blog(LOG_INFO, "Device %s reconnected", dev);
|
||||||
|
|
||||||
|
v4l2_init(data);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Device removed callback
|
||||||
|
*
|
||||||
|
* We stop recording here so we don't block the device node
|
||||||
|
*/
|
||||||
|
static void device_removed(const char *dev, void *vptr)
|
||||||
|
{
|
||||||
|
V4L2_DATA(vptr);
|
||||||
|
|
||||||
|
if (strcmp(data->device_id, dev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blog(LOG_INFO, "Device %s disconnected", dev);
|
||||||
|
|
||||||
|
v4l2_terminate(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static obs_properties_t *v4l2_properties(void *unused)
|
static obs_properties_t *v4l2_properties(void *unused)
|
||||||
{
|
{
|
||||||
UNUSED_PARAMETER(unused);
|
UNUSED_PARAMETER(unused);
|
||||||
|
@ -567,6 +613,11 @@ static void v4l2_destroy(void *vptr)
|
||||||
|
|
||||||
if (data->device_id)
|
if (data->device_id)
|
||||||
bfree(data->device_id);
|
bfree(data->device_id);
|
||||||
|
|
||||||
|
#if HAVE_UDEV
|
||||||
|
v4l2_unref_udev(data->udev);
|
||||||
|
#endif
|
||||||
|
|
||||||
bfree(data);
|
bfree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,6 +723,12 @@ static void *v4l2_create(obs_data_t *settings, obs_source_t *source)
|
||||||
|
|
||||||
v4l2_update(data, settings);
|
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue