From 0f3bd8ba93673f8888fdf12b155a9a022de222cc Mon Sep 17 00:00:00 2001 From: Kurt Kartaltepe Date: Tue, 8 Sep 2020 18:52:27 -0700 Subject: [PATCH] linux-v4l2: Save device by path This adjusts device listing to be by /dev/v4l/by-path which is based on where the device is plugged in instead of when it is initialized. This should help people with multiple devices across restarts. Old plugin data will still work unchanged, when users modify settings the new options will be transparently backed by the new keys but names presented remain consistent. --- plugins/linux-v4l2/v4l2-input.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index fe98a8bf8eb..1baab424be4 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -276,10 +276,12 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) const char *cur_device_name; #ifdef __FreeBSD__ - dirp = opendir("/dev"); + const char *basedir = "/dev/"; #else - dirp = opendir("/sys/class/video4linux"); + const char *basedir = "/dev/v4l/by-path/"; #endif + + dirp = opendir(basedir); if (!dirp) return; @@ -288,7 +290,7 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) obs_property_list_clear(prop); - dstr_init_copy(&device, "/dev/"); + dstr_init(&device); while ((dp = readdir(dirp)) != NULL) { int fd; @@ -303,8 +305,16 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) if (dp->d_type == DT_DIR) continue; - dstr_resize(&device, 5); - dstr_cat(&device, dp->d_name); + char *dev_path = dp->d_name; + + char buf[1024]; + ssize_t len; + if ((len = readlink(dp->d_name, buf, sizeof(buf) - 1)) != -1) { + buf[len] = '\0'; + dev_path = &buf[0]; + } + dstr_copy(&device, basedir); + dstr_cat(&device, dev_path); if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) { blog(LOG_INFO, "Unable to open %s", device.array);