Skip to content

Commit 1dc2cee

Browse files
committed
unity capture: keep track of cameras in-use
1 parent 6186d75 commit 1dc2cee

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

pyvirtualcam/native_windows_unity_capture/virtual_output.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ static bool get_name(int num, std::string& str) {
3535
return true;
3636
}
3737

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+
3846
class VirtualOutput {
3947
private:
4048
uint32_t _width;
@@ -51,6 +59,11 @@ class VirtualOutput {
5159
int i;
5260
if (device.has_value()) {
5361
std::string name = *device;
62+
if (ACTIVE_DEVICES.count(name)) {
63+
throw std::invalid_argument(
64+
"Device " + name + " is already in use."
65+
);
66+
}
5467
for (i = 0; i < MAX_CAPNUM; i++) {
5568
if (get_name(i, _device) && _device == name)
5669
break;
@@ -59,12 +72,20 @@ class VirtualOutput {
5972
throw std::runtime_error("No camera registered with this name.");
6073
}
6174
} else {
75+
bool found_one = false;
6276
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+
}
6582
}
6683
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+
}
6889
}
6990
}
7091
_shm = std::make_unique<SharedImageMemory>(i);
@@ -92,6 +113,7 @@ class VirtualOutput {
92113
"Unsupported image format."
93114
);
94115
}
116+
ACTIVE_DEVICES.insert(_device);
95117
_running = true;
96118
}
97119

@@ -100,6 +122,7 @@ class VirtualOutput {
100122
return;
101123
_shm = nullptr;
102124
_running = false;
125+
ACTIVE_DEVICES.erase(_device);
103126
}
104127

105128
void send(const uint8_t *frame) {

0 commit comments

Comments
 (0)