summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/camera_manager.cpp2
-rw-r--r--src/libcamera/device_enumerator.cpp157
-rw-r--r--src/libcamera/device_enumerator_udev.cpp163
-rw-r--r--src/libcamera/include/device_enumerator.h24
-rw-r--r--src/libcamera/include/device_enumerator_udev.h42
-rw-r--r--src/libcamera/meson.build10
6 files changed, 218 insertions, 180 deletions
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 40a39bd2..cf881ce2 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -80,7 +80,7 @@ int CameraManager::start()
return -EBUSY;
enumerator_ = DeviceEnumerator::create();
- if (enumerator_->enumerate())
+ if (!enumerator_ || enumerator_->enumerate())
return -ENODEV;
/*
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index 49467546..f6878b3d 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -6,14 +6,9 @@
*/
#include "device_enumerator.h"
+#include "device_enumerator_udev.h"
-#include <fcntl.h>
-#include <libudev.h>
#include <string.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-#include <libcamera/event_notifier.h>
#include "log.h"
#include "media_device.h"
@@ -148,13 +143,11 @@ std::unique_ptr<DeviceEnumerator> DeviceEnumerator::create()
{
std::unique_ptr<DeviceEnumerator> enumerator;
- /**
- * \todo Add compile time checks to only try udev enumerator if libudev
- * is available.
- */
+#ifdef HAVE_LIBUDEV
enumerator = utils::make_unique<DeviceEnumeratorUdev>();
if (!enumerator->init())
return enumerator;
+#endif
/*
* Either udev is not available or udev initialization failed. Fall back
@@ -327,148 +320,4 @@ std::shared_ptr<MediaDevice> DeviceEnumerator::search(const DeviceMatch &dm)
* fails
*/
-/**
- * \class DeviceEnumeratorUdev
- * \brief Device enumerator based on libudev
- */
-
-DeviceEnumeratorUdev::DeviceEnumeratorUdev()
- : udev_(nullptr)
-{
-}
-
-DeviceEnumeratorUdev::~DeviceEnumeratorUdev()
-{
- delete notifier_;
-
- if (monitor_)
- udev_monitor_unref(monitor_);
- if (udev_)
- udev_unref(udev_);
-}
-
-int DeviceEnumeratorUdev::init()
-{
- int ret;
-
- if (udev_)
- return -EBUSY;
-
- udev_ = udev_new();
- if (!udev_)
- return -ENODEV;
-
- monitor_ = udev_monitor_new_from_netlink(udev_, "udev");
- if (!monitor_)
- return -ENODEV;
-
- ret = udev_monitor_filter_add_match_subsystem_devtype(monitor_, "media",
- nullptr);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int DeviceEnumeratorUdev::enumerate()
-{
- struct udev_enumerate *udev_enum = nullptr;
- struct udev_list_entry *ents, *ent;
- int ret;
-
- udev_enum = udev_enumerate_new(udev_);
- if (!udev_enum)
- return -ENOMEM;
-
- ret = udev_enumerate_add_match_subsystem(udev_enum, "media");
- if (ret < 0)
- goto done;
-
- ret = udev_enumerate_scan_devices(udev_enum);
- if (ret < 0)
- goto done;
-
- ents = udev_enumerate_get_list_entry(udev_enum);
- if (!ents)
- goto done;
-
- udev_list_entry_foreach(ent, ents) {
- struct udev_device *dev;
- const char *devnode;
- const char *syspath = udev_list_entry_get_name(ent);
-
- dev = udev_device_new_from_syspath(udev_, syspath);
- if (!dev) {
- LOG(DeviceEnumerator, Warning)
- << "Failed to get device for '"
- << syspath << "', skipping";
- continue;
- }
-
- devnode = udev_device_get_devnode(dev);
- if (!devnode) {
- udev_device_unref(dev);
- ret = -ENODEV;
- goto done;
- }
-
- addDevice(devnode);
-
- udev_device_unref(dev);
- }
-done:
- udev_enumerate_unref(udev_enum);
- if (ret < 0)
- return ret;
-
- ret = udev_monitor_enable_receiving(monitor_);
- if (ret < 0)
- return ret;
-
- int fd = udev_monitor_get_fd(monitor_);
- notifier_ = new EventNotifier(fd, EventNotifier::Read);
- notifier_->activated.connect(this, &DeviceEnumeratorUdev::udevNotify);
-
- return 0;
-}
-
-std::string DeviceEnumeratorUdev::lookupDeviceNode(int major, int minor)
-{
- struct udev_device *device;
- const char *name;
- dev_t devnum;
- std::string deviceNode = std::string();
-
- devnum = makedev(major, minor);
- device = udev_device_new_from_devnum(udev_, 'c', devnum);
- if (!device)
- return std::string();
-
- name = udev_device_get_devnode(device);
- if (name)
- deviceNode = name;
-
- udev_device_unref(device);
-
- return deviceNode;
-}
-
-void DeviceEnumeratorUdev::udevNotify(EventNotifier *notifier)
-{
- struct udev_device *dev = udev_monitor_receive_device(monitor_);
- std::string action(udev_device_get_action(dev));
- std::string deviceNode(udev_device_get_devnode(dev));
-
- LOG(DeviceEnumerator, Debug)
- << action << " device " << udev_device_get_devnode(dev);
-
- if (action == "add") {
- addDevice(deviceNode);
- } else if (action == "remove") {
- removeDevice(deviceNode);
- }
-
- udev_device_unref(dev);
-}
-
} /* namespace libcamera */
diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp
new file mode 100644
index 00000000..cb2d21b9
--- /dev/null
+++ b/src/libcamera/device_enumerator_udev.cpp
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2018-2019, Google Inc.
+ *
+ * device_enumerator_udev.cpp - udev-based device enumerator
+ */
+
+#include "device_enumerator_udev.h"
+
+#include <fcntl.h>
+#include <libudev.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <libcamera/event_notifier.h>
+
+#include "log.h"
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(DeviceEnumerator)
+
+DeviceEnumeratorUdev::DeviceEnumeratorUdev()
+ : udev_(nullptr)
+{
+}
+
+DeviceEnumeratorUdev::~DeviceEnumeratorUdev()
+{
+ delete notifier_;
+
+ if (monitor_)
+ udev_monitor_unref(monitor_);
+ if (udev_)
+ udev_unref(udev_);
+}
+
+int DeviceEnumeratorUdev::init()
+{
+ int ret;
+
+ if (udev_)
+ return -EBUSY;
+
+ udev_ = udev_new();
+ if (!udev_)
+ return -ENODEV;
+
+ monitor_ = udev_monitor_new_from_netlink(udev_, "udev");
+ if (!monitor_)
+ return -ENODEV;
+
+ ret = udev_monitor_filter_add_match_subsystem_devtype(monitor_, "media",
+ nullptr);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int DeviceEnumeratorUdev::enumerate()
+{
+ struct udev_enumerate *udev_enum = nullptr;
+ struct udev_list_entry *ents, *ent;
+ int ret;
+
+ udev_enum = udev_enumerate_new(udev_);
+ if (!udev_enum)
+ return -ENOMEM;
+
+ ret = udev_enumerate_add_match_subsystem(udev_enum, "media");
+ if (ret < 0)
+ goto done;
+
+ ret = udev_enumerate_scan_devices(udev_enum);
+ if (ret < 0)
+ goto done;
+
+ ents = udev_enumerate_get_list_entry(udev_enum);
+ if (!ents)
+ goto done;
+
+ udev_list_entry_foreach(ent, ents) {
+ struct udev_device *dev;
+ const char *devnode;
+ const char *syspath = udev_list_entry_get_name(ent);
+
+ dev = udev_device_new_from_syspath(udev_, syspath);
+ if (!dev) {
+ LOG(DeviceEnumerator, Warning)
+ << "Failed to get device for '"
+ << syspath << "', skipping";
+ continue;
+ }
+
+ devnode = udev_device_get_devnode(dev);
+ if (!devnode) {
+ udev_device_unref(dev);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ addDevice(devnode);
+
+ udev_device_unref(dev);
+ }
+done:
+ udev_enumerate_unref(udev_enum);
+ if (ret < 0)
+ return ret;
+
+ ret = udev_monitor_enable_receiving(monitor_);
+ if (ret < 0)
+ return ret;
+
+ int fd = udev_monitor_get_fd(monitor_);
+ notifier_ = new EventNotifier(fd, EventNotifier::Read);
+ notifier_->activated.connect(this, &DeviceEnumeratorUdev::udevNotify);
+
+ return 0;
+}
+
+std::string DeviceEnumeratorUdev::lookupDeviceNode(int major, int minor)
+{
+ struct udev_device *device;
+ const char *name;
+ dev_t devnum;
+ std::string deviceNode = std::string();
+
+ devnum = makedev(major, minor);
+ device = udev_device_new_from_devnum(udev_, 'c', devnum);
+ if (!device)
+ return std::string();
+
+ name = udev_device_get_devnode(device);
+ if (name)
+ deviceNode = name;
+
+ udev_device_unref(device);
+
+ return deviceNode;
+}
+
+void DeviceEnumeratorUdev::udevNotify(EventNotifier *notifier)
+{
+ struct udev_device *dev = udev_monitor_receive_device(monitor_);
+ std::string action(udev_device_get_action(dev));
+ std::string deviceNode(udev_device_get_devnode(dev));
+
+ LOG(DeviceEnumerator, Debug)
+ << action << " device " << udev_device_get_devnode(dev);
+
+ if (action == "add") {
+ addDevice(deviceNode);
+ } else if (action == "remove") {
+ removeDevice(deviceNode);
+ }
+
+ udev_device_unref(dev);
+}
+
+} /* namespace libcamera */
diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h
index 28018618..02aec3bc 100644
--- a/src/libcamera/include/device_enumerator.h
+++ b/src/libcamera/include/device_enumerator.h
@@ -7,19 +7,14 @@
#ifndef __LIBCAMERA_DEVICE_ENUMERATOR_H__
#define __LIBCAMERA_DEVICE_ENUMERATOR_H__
-#include <map>
#include <memory>
#include <string>
#include <vector>
#include <linux/media.h>
-struct udev;
-struct udev_monitor;
-
namespace libcamera {
-class EventNotifier;
class MediaDevice;
class DeviceMatch
@@ -58,25 +53,6 @@ private:
virtual std::string lookupDeviceNode(int major, int minor) = 0;
};
-class DeviceEnumeratorUdev: public DeviceEnumerator
-{
-public:
- DeviceEnumeratorUdev();
- ~DeviceEnumeratorUdev();
-
- int init() final;
- int enumerate() final;
-
-private:
- struct udev *udev_;
- struct udev_monitor *monitor_;
- EventNotifier *notifier_;
-
- std::string lookupDeviceNode(int major, int minor) final;
-
- void udevNotify(EventNotifier *notifier);
-};
-
} /* namespace libcamera */
#endif /* __LIBCAMERA_DEVICE_ENUMERATOR_H__ */
diff --git a/src/libcamera/include/device_enumerator_udev.h b/src/libcamera/include/device_enumerator_udev.h
new file mode 100644
index 00000000..80f9372b
--- /dev/null
+++ b/src/libcamera/include/device_enumerator_udev.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2018-2019, Google Inc.
+ *
+ * device_enumerator_udev.h - udev-based device enumerator
+ */
+#ifndef __LIBCAMERA_DEVICE_ENUMERATOR_UDEV_H__
+#define __LIBCAMERA_DEVICE_ENUMERATOR_UDEV_H__
+
+#include <string>
+
+#include "device_enumerator.h"
+
+struct udev;
+struct udev_monitor;
+
+namespace libcamera {
+
+class EventNotifier;
+
+class DeviceEnumeratorUdev : public DeviceEnumerator
+{
+public:
+ DeviceEnumeratorUdev();
+ ~DeviceEnumeratorUdev();
+
+ int init() final;
+ int enumerate() final;
+
+private:
+ struct udev *udev_;
+ struct udev_monitor *monitor_;
+ EventNotifier *notifier_;
+
+ std::string lookupDeviceNode(int major, int minor) final;
+
+ void udevNotify(EventNotifier *notifier);
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_DEVICE_ENUMERATOR_UDEV_H__ */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index cf4edec0..2b678237 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -26,6 +26,7 @@ libcamera_sources = files([
libcamera_headers = files([
'include/camera_sensor.h',
'include/device_enumerator.h',
+ 'include/device_enumerator_udev.h',
'include/event_dispatcher_poll.h',
'include/formats.h',
'include/log.h',
@@ -46,7 +47,14 @@ includes = [
subdir('pipeline')
-libudev = dependency('libudev')
+libudev = dependency('libudev', required: false)
+
+if libudev.found()
+ config_h.set('HAVE_LIBUDEV', 1)
+ libcamera_sources += files([
+ 'device_enumerator_udev.cpp',
+ ])
+endif
libcamera = shared_library('camera',
libcamera_sources,