summarylogtreecommitdiffstats
path: root/v4l2_by-path.patch
blob: b98225e95a1451a0c05ddcb77a84d48ec4e07f0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
From 0f3bd8ba93673f8888fdf12b155a9a022de222cc Mon Sep 17 00:00:00 2001
From: Kurt Kartaltepe <kkartaltepe@gmail.com>
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);