[libcamera-devel] [RFC PATCH 1/2] libcamera: Add SensorMode class

David Plowman david.plowman at raspberrypi.com
Thu Sep 16 15:20:14 CEST 2021


The CameraSensor gains the getSensorModes method which returns the
modes that the sensor supports. A user can browse this list and select
modes and sort them.

The CameraConfiguration acquires a field containing a SensorMode where
the application can configure "hints" about what the pipeline handler
should choose.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 include/libcamera/camera.h                 |  3 ++
 include/libcamera/internal/camera_sensor.h |  4 ++
 include/libcamera/meson.build              |  1 +
 include/libcamera/sensor_mode.h            | 50 ++++++++++++++++++
 src/libcamera/camera_sensor.cpp            | 15 ++++++
 src/libcamera/meson.build                  |  1 +
 src/libcamera/sensor_mode.cpp              | 60 ++++++++++++++++++++++
 7 files changed, 134 insertions(+)
 create mode 100644 include/libcamera/sensor_mode.h
 create mode 100644 src/libcamera/sensor_mode.cpp

diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 601ee46e..c07edc1b 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -18,6 +18,7 @@
 
 #include <libcamera/controls.h>
 #include <libcamera/request.h>
+#include <libcamera/sensor_mode.h>
 #include <libcamera/stream.h>
 #include <libcamera/transform.h>
 
@@ -66,6 +67,8 @@ public:
 
 	Transform transform;
 
+	SensorMode sensorMode;
+
 protected:
 	CameraConfiguration();
 
diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index d25a1165..5701d23d 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -16,6 +16,8 @@
 
 #include <libcamera/controls.h>
 #include <libcamera/geometry.h>
+#include <libcamera/sensor_mode.h>
+
 #include <libcamera/ipa/core_ipa_interface.h>
 
 #include "libcamera/internal/formats.h"
@@ -60,6 +62,8 @@ public:
 
 	void updateControlInfo();
 
+	SensorModeList getSensorModes() const;
+
 protected:
 	std::string logPrefix() const override;
 
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index 5b25ef84..821b5aa2 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -12,6 +12,7 @@ libcamera_public_headers = files([
     'logging.h',
     'pixel_format.h',
     'request.h',
+    'sensor_mode.h',
     'stream.h',
     'transform.h',
 ])
diff --git a/include/libcamera/sensor_mode.h b/include/libcamera/sensor_mode.h
new file mode 100644
index 00000000..9b51b7f9
--- /dev/null
+++ b/include/libcamera/sensor_mode.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Raspberry Pi (Trading) Ltd.
+ *
+ * sensor_mode.h - Definition of a sensor mode
+ */
+
+#ifndef __LIBCAMERA_SENSOR_MODE_H__
+#define __LIBCAMERA_SENSOR_MODE_H__
+
+#include <functional>
+#include <string>
+#include <vector>
+
+#include <libcamera/geometry.h>
+
+namespace libcamera {
+
+class SensorMode
+{
+public:
+	SensorMode()
+		: bitDepth(0)
+	{
+	}
+
+	SensorMode(unsigned int b, const SizeRange &s)
+		: bitDepth(b), sizeRange(s)
+	{
+	}
+
+	std::string toString() const;
+
+	unsigned int bitDepth;
+	SizeRange sizeRange;
+};
+
+using SensorModeList = std::vector<SensorMode>;
+
+using SensorModeSelectFunction = std::function<bool(const SensorMode &mode)>;
+
+SensorModeList selectSensorModes(const SensorModeList &modes, SensorModeSelectFunction selectFn);
+
+using SensorModeScoreFunction = std::function<float(const SensorMode &mode)>;
+
+void sortSensorModes(SensorModeList &modes, SensorModeScoreFunction scoreFn);
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_SENSOR_MODE_H__ */
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 87668509..88fae2bf 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -833,4 +833,19 @@ int CameraSensor::generateId()
 	return -EINVAL;
 }
 
+SensorModeList CameraSensor::getSensorModes() const
+{
+	SensorModeList modes;
+
+	for (const auto &format : formats_) {
+		const BayerFormat &bayerFmt = BayerFormat::fromMbusCode(format.first);
+		if (bayerFmt.isValid()) {
+			for (const auto &range : format.second)
+				modes.emplace_back(bayerFmt.bitDepth, range);
+		}
+	}
+
+	return modes;
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index e9230b98..d64f7038 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -36,6 +36,7 @@ libcamera_sources = files([
     'process.cpp',
     'pub_key.cpp',
     'request.cpp',
+    'sensor_mode.cpp',
     'source_paths.cpp',
     'stream.cpp',
     'sysfs.cpp',
diff --git a/src/libcamera/sensor_mode.cpp b/src/libcamera/sensor_mode.cpp
new file mode 100644
index 00000000..09317ff7
--- /dev/null
+++ b/src/libcamera/sensor_mode.cpp
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Raspberry Pi (Trading) Ltd.
+ *
+ * sensor_mode.cpp - Functions related to sensor modes
+ */
+
+#include <algorithm>
+#include <sstream>
+
+#include <libcamera/base/log.h>
+
+#include <libcamera/sensor_mode.h>
+
+/**
+ * \file sensor_mode.h
+ * \brief Data structures and procedures related to sensor modes
+ */
+
+namespace libcamera {
+
+std::string SensorMode::toString() const
+{
+	std::stringstream ss;
+
+	ss << bitDepth << ":";
+
+	if (sizeRange.min == sizeRange.max)
+		ss << sizeRange.min.toString();
+	else
+		ss << sizeRange.toString();
+
+	return ss.str();
+}
+
+/*
+ * Select modes from a list that match certain criteria, for example "all the modes that can
+ * output at least 720p", or "all the 12-bit modes".
+ */
+
+SensorModeList selectSensorModes(const SensorModeList &modes, SensorModeSelectFunction selectFn)
+{
+	SensorModeList selection;
+
+	std::copy_if(modes.begin(), modes.end(), std::back_inserter(selection), selectFn);
+
+	return selection;
+}
+
+/*
+ * Sort a list of modes according to an arbitrary scoring function. You might simply order them
+ * from smallest to largest, or use it to obtain the modes closest to a particular "target".
+ */
+
+void sortSensorModes(SensorModeList &modes, SensorModeScoreFunction scoreFn)
+{
+	std::sort(modes.begin(), modes.end(), [&scoreFn](const auto &lhs, const auto &rhs) { return scoreFn(lhs) < scoreFn(rhs); });
+}
+
+} /* namespace libcamera */
-- 
2.20.1



More information about the libcamera-devel mailing list