{"id":13862,"url":"https://patchwork.libcamera.org/api/1.1/patches/13862/?format=json","web_url":"https://patchwork.libcamera.org/patch/13862/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210916132015.1790-2-david.plowman@raspberrypi.com>","date":"2021-09-16T13:20:14","name":"[libcamera-devel,RFC,1/2] libcamera: Add SensorMode class","commit_ref":null,"pull_url":null,"state":"not-applicable","archived":false,"hash":"63803111feadc36cc37828cb8a8fb7e6a7855589","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/1.1/people/42/?format=json","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/13862/mbox/","series":[{"id":2538,"url":"https://patchwork.libcamera.org/api/1.1/series/2538/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2538","date":"2021-09-16T13:20:13","name":"Sensor mode hints","version":1,"mbox":"https://patchwork.libcamera.org/series/2538/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/13862/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/13862/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9C11FBF01C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 16 Sep 2021 13:20:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BA35469188;\n\tThu, 16 Sep 2021 15:20:24 +0200 (CEST)","from mail-wr1-x433.google.com (mail-wr1-x433.google.com\n\t[IPv6:2a00:1450:4864:20::433])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1422F6916F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 16 Sep 2021 15:20:23 +0200 (CEST)","by mail-wr1-x433.google.com with SMTP id g16so9468401wrb.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 16 Sep 2021 06:20:23 -0700 (PDT)","from pi4-davidp.pitowers.org\n\t([2a00:1098:3142:14:1ce1:9965:4328:89c4])\n\tby smtp.gmail.com with ESMTPSA id\n\tf3sm3233425wmj.28.2021.09.16.06.20.21\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 16 Sep 2021 06:20:21 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"Sf1vZJFe\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=xPux191sneH09IHtVU0TV9Nyl0lEEsyPR4HtpznDQf8=;\n\tb=Sf1vZJFetFuaaa5d1XAPytPkZ8/Z5HlmiNjoLAHGGjcaXAFy8Cw6ZjbV9Y4RtFRqJ8\n\tIW3cfRerHGbq2ECRsGf09AbsnJ/CU01LLNNnbbWpYpQePhfg7h7Dz7un1tAndiB73WPr\n\tI2qGk3ckggAQiKP50sEUhl4xniBuG/p2+kVE5gNY3cy5Da/TzhiVy36BJnrr6qrTIvG0\n\tSzWRLeTNmGjWY2bsLGumtwzYp+BVMLzPxJWPd9wFq4DGKpnbyngVzUPNfkZiyGduaRBG\n\tLnchmTErRhUEAsSIPRzJXQR/WSZe0PC9+ZCixT/01rSK5vuJiTqARX7ldMcdNyifi5hP\n\tsyhA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=xPux191sneH09IHtVU0TV9Nyl0lEEsyPR4HtpznDQf8=;\n\tb=K1NkFY5yGwtGpIWE0kMEu3o7AyERuQXns9ctVhuYVirLgf3ZwxHTatTYv2F3I/3D3W\n\thsdm+33X60AQgUXny29bCHmvMWfEzEgIiNuq48zXsqBfYapZ5yjiAQr7KCmx0EzwS69f\n\tlkDgzskvCpbb50wXuOuEn/CH+vxiyw8pjiIYOFhE0L9JF1VQ5NlkzIYXUOPk34RQOp9Q\n\tBR0FBa0LjnksSyTU6brO+nTA929U3YwMOZpbsXmKeNKLYByguorkSbGnH1kx5Lod5lGX\n\t7e/a3rRJGDpneE5XsceZCYtrY9pvnqlBR9b6K6RU/li+T5Xhq9ahIEOnx7YzNl/bP0+U\n\t1k2A==","X-Gm-Message-State":"AOAM532EuiloViLvrJ4Tma2nFfJRMSZhRr+guYF1POMgpsx1xBaYUPyX\n\t+3sHuYnYvDajH6qyD0hiKT/zmS7Ujh9W6YtD","X-Google-Smtp-Source":"ABdhPJwa1PdN2ckpRc4WVdo8IGbxfzaBCTxFbQV0S9D71tnPIaKGOKNaQOG5yY81HQLOAcNz8rkWPg==","X-Received":"by 2002:adf:df0d:: with SMTP id\n\ty13mr6002989wrl.335.1631798422401; \n\tThu, 16 Sep 2021 06:20:22 -0700 (PDT)","From":"David Plowman <david.plowman@raspberrypi.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Thu, 16 Sep 2021 14:20:14 +0100","Message-Id":"<20210916132015.1790-2-david.plowman@raspberrypi.com>","X-Mailer":"git-send-email 2.20.1","In-Reply-To":"<20210916132015.1790-1-david.plowman@raspberrypi.com>","References":"<20210916132015.1790-1-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [RFC PATCH 1/2] libcamera: Add SensorMode class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The CameraSensor gains the getSensorModes method which returns the\nmodes that the sensor supports. A user can browse this list and select\nmodes and sort them.\n\nThe CameraConfiguration acquires a field containing a SensorMode where\nthe application can configure \"hints\" about what the pipeline handler\nshould choose.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\n---\n include/libcamera/camera.h                 |  3 ++\n include/libcamera/internal/camera_sensor.h |  4 ++\n include/libcamera/meson.build              |  1 +\n include/libcamera/sensor_mode.h            | 50 ++++++++++++++++++\n src/libcamera/camera_sensor.cpp            | 15 ++++++\n src/libcamera/meson.build                  |  1 +\n src/libcamera/sensor_mode.cpp              | 60 ++++++++++++++++++++++\n 7 files changed, 134 insertions(+)\n create mode 100644 include/libcamera/sensor_mode.h\n create mode 100644 src/libcamera/sensor_mode.cpp","diff":"diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 601ee46e..c07edc1b 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -18,6 +18,7 @@\n \n #include <libcamera/controls.h>\n #include <libcamera/request.h>\n+#include <libcamera/sensor_mode.h>\n #include <libcamera/stream.h>\n #include <libcamera/transform.h>\n \n@@ -66,6 +67,8 @@ public:\n \n \tTransform transform;\n \n+\tSensorMode sensorMode;\n+\n protected:\n \tCameraConfiguration();\n \ndiff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\nindex d25a1165..5701d23d 100644\n--- a/include/libcamera/internal/camera_sensor.h\n+++ b/include/libcamera/internal/camera_sensor.h\n@@ -16,6 +16,8 @@\n \n #include <libcamera/controls.h>\n #include <libcamera/geometry.h>\n+#include <libcamera/sensor_mode.h>\n+\n #include <libcamera/ipa/core_ipa_interface.h>\n \n #include \"libcamera/internal/formats.h\"\n@@ -60,6 +62,8 @@ public:\n \n \tvoid updateControlInfo();\n \n+\tSensorModeList getSensorModes() const;\n+\n protected:\n \tstd::string logPrefix() const override;\n \ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 5b25ef84..821b5aa2 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -12,6 +12,7 @@ libcamera_public_headers = files([\n     'logging.h',\n     'pixel_format.h',\n     'request.h',\n+    'sensor_mode.h',\n     'stream.h',\n     'transform.h',\n ])\ndiff --git a/include/libcamera/sensor_mode.h b/include/libcamera/sensor_mode.h\nnew file mode 100644\nindex 00000000..9b51b7f9\n--- /dev/null\n+++ b/include/libcamera/sensor_mode.h\n@@ -0,0 +1,50 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Raspberry Pi (Trading) Ltd.\n+ *\n+ * sensor_mode.h - Definition of a sensor mode\n+ */\n+\n+#ifndef __LIBCAMERA_SENSOR_MODE_H__\n+#define __LIBCAMERA_SENSOR_MODE_H__\n+\n+#include <functional>\n+#include <string>\n+#include <vector>\n+\n+#include <libcamera/geometry.h>\n+\n+namespace libcamera {\n+\n+class SensorMode\n+{\n+public:\n+\tSensorMode()\n+\t\t: bitDepth(0)\n+\t{\n+\t}\n+\n+\tSensorMode(unsigned int b, const SizeRange &s)\n+\t\t: bitDepth(b), sizeRange(s)\n+\t{\n+\t}\n+\n+\tstd::string toString() const;\n+\n+\tunsigned int bitDepth;\n+\tSizeRange sizeRange;\n+};\n+\n+using SensorModeList = std::vector<SensorMode>;\n+\n+using SensorModeSelectFunction = std::function<bool(const SensorMode &mode)>;\n+\n+SensorModeList selectSensorModes(const SensorModeList &modes, SensorModeSelectFunction selectFn);\n+\n+using SensorModeScoreFunction = std::function<float(const SensorMode &mode)>;\n+\n+void sortSensorModes(SensorModeList &modes, SensorModeScoreFunction scoreFn);\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_SENSOR_MODE_H__ */\ndiff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp\nindex 87668509..88fae2bf 100644\n--- a/src/libcamera/camera_sensor.cpp\n+++ b/src/libcamera/camera_sensor.cpp\n@@ -833,4 +833,19 @@ int CameraSensor::generateId()\n \treturn -EINVAL;\n }\n \n+SensorModeList CameraSensor::getSensorModes() const\n+{\n+\tSensorModeList modes;\n+\n+\tfor (const auto &format : formats_) {\n+\t\tconst BayerFormat &bayerFmt = BayerFormat::fromMbusCode(format.first);\n+\t\tif (bayerFmt.isValid()) {\n+\t\t\tfor (const auto &range : format.second)\n+\t\t\t\tmodes.emplace_back(bayerFmt.bitDepth, range);\n+\t\t}\n+\t}\n+\n+\treturn modes;\n+}\n+\n } /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex e9230b98..d64f7038 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -36,6 +36,7 @@ libcamera_sources = files([\n     'process.cpp',\n     'pub_key.cpp',\n     'request.cpp',\n+    'sensor_mode.cpp',\n     'source_paths.cpp',\n     'stream.cpp',\n     'sysfs.cpp',\ndiff --git a/src/libcamera/sensor_mode.cpp b/src/libcamera/sensor_mode.cpp\nnew file mode 100644\nindex 00000000..09317ff7\n--- /dev/null\n+++ b/src/libcamera/sensor_mode.cpp\n@@ -0,0 +1,60 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Raspberry Pi (Trading) Ltd.\n+ *\n+ * sensor_mode.cpp - Functions related to sensor modes\n+ */\n+\n+#include <algorithm>\n+#include <sstream>\n+\n+#include <libcamera/base/log.h>\n+\n+#include <libcamera/sensor_mode.h>\n+\n+/**\n+ * \\file sensor_mode.h\n+ * \\brief Data structures and procedures related to sensor modes\n+ */\n+\n+namespace libcamera {\n+\n+std::string SensorMode::toString() const\n+{\n+\tstd::stringstream ss;\n+\n+\tss << bitDepth << \":\";\n+\n+\tif (sizeRange.min == sizeRange.max)\n+\t\tss << sizeRange.min.toString();\n+\telse\n+\t\tss << sizeRange.toString();\n+\n+\treturn ss.str();\n+}\n+\n+/*\n+ * Select modes from a list that match certain criteria, for example \"all the modes that can\n+ * output at least 720p\", or \"all the 12-bit modes\".\n+ */\n+\n+SensorModeList selectSensorModes(const SensorModeList &modes, SensorModeSelectFunction selectFn)\n+{\n+\tSensorModeList selection;\n+\n+\tstd::copy_if(modes.begin(), modes.end(), std::back_inserter(selection), selectFn);\n+\n+\treturn selection;\n+}\n+\n+/*\n+ * Sort a list of modes according to an arbitrary scoring function. You might simply order them\n+ * from smallest to largest, or use it to obtain the modes closest to a particular \"target\".\n+ */\n+\n+void sortSensorModes(SensorModeList &modes, SensorModeScoreFunction scoreFn)\n+{\n+\tstd::sort(modes.begin(), modes.end(), [&scoreFn](const auto &lhs, const auto &rhs) { return scoreFn(lhs) < scoreFn(rhs); });\n+}\n+\n+} /* namespace libcamera */\n","prefixes":["libcamera-devel","RFC","1/2"]}