[libcamera-devel] [RFC PATCH 2/3] libcamera: device_enumerator: Check that expected cameras are available

Niklas Söderlund niklas.soderlund at ragnatech.se
Thu Oct 3 22:05:05 CEST 2019


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 at 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 at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

-- 
Regards,
Niklas Söderlund


More information about the libcamera-devel mailing list