@@ -35,6 +35,14 @@ static bool get_name(int num, std::string& str) {
35
35
return true ;
36
36
}
37
37
38
+ // Unity Capture does not have an exclusive access / locking mechanism.
39
+ // To avoid selecting the same device more than once,
40
+ // we keep track of the ones we use ourselves.
41
+ // Obviously, this won't help if multiple processes are used
42
+ // or if devices are used by other tools.
43
+ // In this case, explicitly specifying the device seems the only solution.
44
+ static std::set<std::string> ACTIVE_DEVICES;
45
+
38
46
class VirtualOutput {
39
47
private:
40
48
uint32_t _width;
@@ -51,6 +59,11 @@ class VirtualOutput {
51
59
int i;
52
60
if (device.has_value ()) {
53
61
std::string name = *device;
62
+ if (ACTIVE_DEVICES.count (name)) {
63
+ throw std::invalid_argument (
64
+ " Device " + name + " is already in use."
65
+ );
66
+ }
54
67
for (i = 0 ; i < MAX_CAPNUM; i++) {
55
68
if (get_name (i, _device) && _device == name)
56
69
break ;
@@ -59,12 +72,20 @@ class VirtualOutput {
59
72
throw std::runtime_error (" No camera registered with this name." );
60
73
}
61
74
} else {
75
+ bool found_one = false ;
62
76
for (i = 0 ; i < MAX_CAPNUM; i++) {
63
- if (get_name (i, _device))
64
- break ;
77
+ if (get_name (i, _device)) {
78
+ found_one = true ;
79
+ if (!ACTIVE_DEVICES.count (_device))
80
+ break ;
81
+ }
65
82
}
66
83
if (i == MAX_CAPNUM) {
67
- throw std::runtime_error (" No camera registered. Did you install any camera?" );
84
+ if (found_one) {
85
+ throw std::runtime_error (" All cameras are already in use." );
86
+ } else {
87
+ throw std::runtime_error (" No camera registered. Did you install any camera?" );
88
+ }
68
89
}
69
90
}
70
91
_shm = std::make_unique<SharedImageMemory>(i);
@@ -92,6 +113,7 @@ class VirtualOutput {
92
113
" Unsupported image format."
93
114
);
94
115
}
116
+ ACTIVE_DEVICES.insert (_device);
95
117
_running = true ;
96
118
}
97
119
@@ -100,6 +122,7 @@ class VirtualOutput {
100
122
return ;
101
123
_shm = nullptr ;
102
124
_running = false ;
125
+ ACTIVE_DEVICES.erase (_device);
103
126
}
104
127
105
128
void send (const uint8_t *frame) {
0 commit comments