Message ID | 20190930053520.2711-2-paul.elder@ideasonboard.com |
---|---|
State | Superseded |
Delegated to: | Paul Elder |
Headers | show |
Series |
|
Related | show |
Hi Paul, Thanks for your work. On 2019-09-30 01:35:19 -0400, Paul Elder wrote: > Add a static method to DeviceEnumerator to check if the expected number > of cameras have been enumerated. The expected cameras are the supported > cameras declared by the pipeline handlers that the system has. > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > --- > src/libcamera/device_enumerator.cpp | 69 +++++++++++++++++++++++ > src/libcamera/include/device_enumerator.h | 4 ++ > 2 files changed, 73 insertions(+) > > diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp > index 0b596bce..7d28f9b8 100644 > --- a/src/libcamera/device_enumerator.cpp > +++ b/src/libcamera/device_enumerator.cpp > @@ -9,10 +9,15 @@ > #include "device_enumerator_sysfs.h" > #include "device_enumerator_udev.h" > > +#include <algorithm> > +#include <dirent.h> > +#include <fstream> > #include <string.h> > +#include <sys/types.h> > > #include "log.h" > #include "media_device.h" > +#include "pipeline_handler.h" > #include "utils.h" > > /** > @@ -306,4 +311,68 @@ std::shared_ptr<MediaDevice> DeviceEnumerator::search(const DeviceMatch &dm) > return nullptr; > } > > +int extractNumberFromFile(std::string &path) > +{ > + std::ifstream file; > + std::string line; > + > + file.open(path); > + if (!file) > + return -1; > + > + file >> line; > + int i = std::stoi(line, 0, 16); > + file.close(); > + > + return i; > +} > + > +bool DeviceEnumerator::haveExpectedCameras(CameraManager *cm) > +{ > + std::vector<std::reference_wrapper<DeviceID>> &supportedDevices = > + PipelineHandlerFactory::getDeviceIDs(); > + std::vector<DeviceID> availableDevices; > + std::vector<DeviceID> intersection; > + struct dirent *ent; > + DIR *dir; > + const char *pciDir = "/sys/bus/pci/devices"; > + > + dir = opendir(pciDir); > + if (!dir) { > + LOG(DeviceEnumerator, Error) > + << "Failed to open sysfs PCI directory"; > + /* We can't expect any cameras, so we vacuously have them all. */ > + return true; > + } > + > + while ((ent = readdir(dir)) != nullptr) { > + std::string path = pciDir + std::string("/") + ent->d_name + "/vendor"; > + int vendor = extractNumberFromFile(path); > + if (vendor < 0) > + continue; > + > + path = pciDir + std::string("/") + ent->d_name + "/device"; > + int device = extractNumberFromFile(path); > + if (device < 0) > + continue; > + > + availableDevices.push_back(PCIDeviceID(vendor, device)); > + } > + > + closedir(dir); > + > + std::set_intersection(supportedDevices.begin(), supportedDevices.end(), > + availableDevices.begin(), availableDevices.end(), > + back_inserter(intersection), > + compareDevices<PCIDeviceID>); > + > + if (cm->cameras().size() < intersection.size()) { > + LOG(DeviceEnumerator, Warning) << "Not enough cameras!"; > + return false; > + } To me this seems a bit too strict. Say that I have a Soraka device, run a kernel on it without IPU3 support, With this change libcamera would not function for a USB camera. Also comparing against cm->cameras().size() might be skewed if you run on a kernel with vivid and/or vimc support built in. > + > + LOG(DeviceEnumerator, Debug) << "All cameras correctly initialized"; > + return true; > +} > + > } /* namespace libcamera */ > diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h > index 770f4277..11c4cdfb 100644 > --- a/src/libcamera/include/device_enumerator.h > +++ b/src/libcamera/include/device_enumerator.h > @@ -13,6 +13,8 @@ > > #include <linux/media.h> > > +#include <libcamera/camera_manager.h> > + > namespace libcamera { > > class MediaDevice; > @@ -43,6 +45,8 @@ public: > > std::shared_ptr<MediaDevice> search(const DeviceMatch &dm); > > + static bool haveExpectedCameras(CameraManager *cm); > + > protected: > std::shared_ptr<MediaDevice> createDevice(const std::string &deviceNode); > void addDevice(const std::shared_ptr<MediaDevice> &media); > -- > 2.23.0 > > _______________________________________________ > libcamera-devel mailing list > libcamera-devel@lists.libcamera.org > https://lists.libcamera.org/listinfo/libcamera-devel
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index 0b596bce..7d28f9b8 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -9,10 +9,15 @@ #include "device_enumerator_sysfs.h" #include "device_enumerator_udev.h" +#include <algorithm> +#include <dirent.h> +#include <fstream> #include <string.h> +#include <sys/types.h> #include "log.h" #include "media_device.h" +#include "pipeline_handler.h" #include "utils.h" /** @@ -306,4 +311,68 @@ std::shared_ptr<MediaDevice> DeviceEnumerator::search(const DeviceMatch &dm) return nullptr; } +int extractNumberFromFile(std::string &path) +{ + std::ifstream file; + std::string line; + + file.open(path); + if (!file) + return -1; + + file >> line; + int i = std::stoi(line, 0, 16); + file.close(); + + return i; +} + +bool DeviceEnumerator::haveExpectedCameras(CameraManager *cm) +{ + std::vector<std::reference_wrapper<DeviceID>> &supportedDevices = + PipelineHandlerFactory::getDeviceIDs(); + std::vector<DeviceID> availableDevices; + std::vector<DeviceID> intersection; + struct dirent *ent; + DIR *dir; + const char *pciDir = "/sys/bus/pci/devices"; + + dir = opendir(pciDir); + if (!dir) { + LOG(DeviceEnumerator, Error) + << "Failed to open sysfs PCI directory"; + /* We can't expect any cameras, so we vacuously have them all. */ + return true; + } + + while ((ent = readdir(dir)) != nullptr) { + std::string path = pciDir + std::string("/") + ent->d_name + "/vendor"; + int vendor = extractNumberFromFile(path); + if (vendor < 0) + continue; + + path = pciDir + std::string("/") + ent->d_name + "/device"; + int device = extractNumberFromFile(path); + if (device < 0) + continue; + + availableDevices.push_back(PCIDeviceID(vendor, device)); + } + + closedir(dir); + + std::set_intersection(supportedDevices.begin(), supportedDevices.end(), + availableDevices.begin(), availableDevices.end(), + back_inserter(intersection), + compareDevices<PCIDeviceID>); + + if (cm->cameras().size() < intersection.size()) { + LOG(DeviceEnumerator, Warning) << "Not enough cameras!"; + return false; + } + + LOG(DeviceEnumerator, Debug) << "All cameras correctly initialized"; + return true; +} + } /* namespace libcamera */ diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h index 770f4277..11c4cdfb 100644 --- a/src/libcamera/include/device_enumerator.h +++ b/src/libcamera/include/device_enumerator.h @@ -13,6 +13,8 @@ #include <linux/media.h> +#include <libcamera/camera_manager.h> + namespace libcamera { class MediaDevice; @@ -43,6 +45,8 @@ public: std::shared_ptr<MediaDevice> search(const DeviceMatch &dm); + static bool haveExpectedCameras(CameraManager *cm); + protected: std::shared_ptr<MediaDevice> createDevice(const std::string &deviceNode); void addDevice(const std::shared_ptr<MediaDevice> &media);
Add a static method to DeviceEnumerator to check if the expected number of cameras have been enumerated. The expected cameras are the supported cameras declared by the pipeline handlers that the system has. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- src/libcamera/device_enumerator.cpp | 69 +++++++++++++++++++++++ src/libcamera/include/device_enumerator.h | 4 ++ 2 files changed, 73 insertions(+)