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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include "singleton.hpp"
#include "internal.hpp"
#include "ps3eye.hpp"
//#define USE_CONTEXT
USBMgr::USBMgr()
{
#ifdef USE_CONTEXT
libusb_init(&usb_context);
#else
libusb_init(nullptr);
#endif
libusb_set_debug(usb_context, 3);
}
USBMgr::~USBMgr()
{
#ifdef USE_CONTEXT
stop_xfer_thread();
libusb_exit(usb_context);
#endif
}
USBMgr& USBMgr::instance()
{
static USBMgr ret;
return ret;
}
void USBMgr::camera_started()
{
if (++active_camera_count == 1)
start_xfer_thread();
}
void USBMgr::camera_stopped()
{
if (--active_camera_count == 0)
stop_xfer_thread();
}
void USBMgr::start_xfer_thread()
{
update_thread = std::thread(&USBMgr::transfer_loop, this);
}
void USBMgr::stop_xfer_thread()
{
exit_signaled = true;
update_thread.join();
// Reset the exit signal flag.
// If we don't and we call start_xfer_thread() again, transfer_loop will exit immediately.
exit_signaled = false;
}
void USBMgr::transfer_loop()
{
struct timeval tv {
0,
50 * 1000, // ms
};
debug2("-> xfer loop");
while (!exit_signaled.load(std::memory_order_relaxed))
{
int status = libusb_handle_events_timeout_completed(usb_context, &tv, nullptr);
if (status != LIBUSB_SUCCESS && status != LIBUSB_ERROR_INTERRUPTED)
debug("libusb error(%d) %s\n", status, libusb_strerror((enum libusb_error)status));
}
debug2("<- xfer loop\n");
}
int USBMgr::list_devices(std::vector<ps3eye_camera::device>& list)
{
libusb_device **devs;
libusb_device_handle *devhandle;
int cnt = (int)libusb_get_device_list(usb_context, &devs);
if (cnt < 0)
debug("device scan failed\n");
cnt = 0;
for (int i = 0; devs[i]; i++)
{
libusb_device* dev = devs[i];
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc))
continue;
if (desc.idVendor == ps3eye_camera::VENDOR_ID && desc.idProduct == ps3eye_camera::PRODUCT_ID)
{
if (libusb_open(dev, &devhandle))
continue;
libusb_ref_device(dev);
libusb_close(devhandle);
list.emplace_back(std::make_shared<ps3eye_camera>(dev));
cnt++;
}
}
libusb_free_device_list(devs, 1);
return cnt;
}
|