32#include "../video_device_monitor.h"
48class VideoDeviceMonitorImpl
73 mutable std::mutex mutex_;
85 throw std::invalid_argument(
"No ID_SERIAL detected");
140 if (path && std::string(path).find(
"/dev") != 0) {
147 if (monitor_->addDevice(
unique_name, {{{
"devPath", path}}}))
149 }
catch (
const std::exception&
e) {
150 JAMI_WARN(
"udev: %s, fallback on path (your camera may be a fake camera)",
e.what());
151 if (monitor_->addDevice(path, {{{
"devPath", path}}}))
152 currentPathToId_.emplace(path, path);
157 udev_enumerate_unref(devenum);
163 JAMI_ERR(
"udev enumeration failed");
166 udev_monitor_unref(udev_mon_);
173 for (
int idx = 0;; ++idx) {
175 if (!monitor_->addDevice(
"/dev/video" + std::to_string(idx)))
177 }
catch (
const std::runtime_error& e) {
185VideoDeviceMonitorImpl::start()
188 thread_ = std::thread(&VideoDeviceMonitorImpl::run,
this);
191VideoDeviceMonitorImpl::~VideoDeviceMonitorImpl()
194 if (thread_.joinable())
197 udev_monitor_unref(udev_mon_);
203VideoDeviceMonitorImpl::run()
210 const int udev_fd = udev_monitor_get_fd(udev_mon_);
212 timeval timeout = {0 , 500000 };
215 FD_SET(udev_fd, &set);
217 int ret = select(udev_fd + 1, &set, NULL, NULL, &timeout);
222 udev_device*
dev = udev_monitor_receive_device(udev_mon_);
224 const char* path = udev_device_get_devnode(
dev);
225 if (path && std::string(path).find(
"/dev") != 0) {
232 const char* action = udev_device_get_action(
dev);
233 if (!strcmp(action,
"add")) {
234 JAMI_DBG(
"udev: adding device with id %s", unique_name.c_str());
235 if (monitor_->addDevice(unique_name, {{{
"devPath", path}}}))
236 currentPathToId_.emplace(path, unique_name);
237 }
else if (!strcmp(action,
"remove")) {
238 auto it = currentPathToId_.find(path);
239 if (it != currentPathToId_.end()) {
240 JAMI_DBG(
"udev: removing %s", it->second.c_str());
241 monitor_->removeDevice(it->second);
242 currentPathToId_.erase(it);
245 JAMI_DBG(
"udev: removing %s", path);
246 monitor_->removeDevice(path);
249 }
catch (
const std::exception& e) {
253 udev_device_unref(
dev);
260 JAMI_ERR(
"udev monitoring thread: select failed (%m)");
265 JAMI_ERR(
"select() returned %d (%m)", ret);
272VideoDeviceMonitor::VideoDeviceMonitor()
275 , monitorImpl_(new VideoDeviceMonitorImpl(this))
277 monitorImpl_->start();
281VideoDeviceMonitor::~VideoDeviceMonitor() {}
VideoDeviceMonitorImpl(VideoDeviceMonitor *monitor)
std::map< std::string, std::string > currentPathToId_
~VideoDeviceMonitorImpl()
static constexpr int version
std::string getDeviceString(struct udev_device *udev_device)
static constexpr const char DEVICE_DESKTOP[]
static int is_v4l2(struct udev_device *dev)
void emitSignal(Args... args)
int32_t addDevice(const std::string &accountId, const std::string &uri)
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)