Show a patch.

GET /api/patches/13862/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 13862,
    "url": "https://patchwork.libcamera.org/api/patches/13862/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/13862/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "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/people/42/?format=api",
        "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/series/2538/?format=api",
            "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"
    ]
}