Show a patch.

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

{
    "id": 22466,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/22466/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/22466/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20250108104924.163077-7-jacopo.mondi@ideasonboard.com>",
    "date": "2025-01-08T10:49:23",
    "name": "[v3,6/6] libcamera: camera_sensor: Add support for embedded data",
    "commit_ref": "3feb4df755d5013c2e058370de7a074f5cc35b71",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "66263b50ad9cef91bcd21c8c9e27bd0bde0cdafa",
    "submitter": {
        "id": 143,
        "url": "https://patchwork.libcamera.org/api/1.1/people/143/?format=api",
        "name": "Jacopo Mondi",
        "email": "jacopo.mondi@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/22466/mbox/",
    "series": [
        {
            "id": 4933,
            "url": "https://patchwork.libcamera.org/api/1.1/series/4933/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4933",
            "date": "2025-01-08T10:49:17",
            "name": "libcamera: Initial support for generic line based metadata",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/4933/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/22466/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/22466/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 22F71C3311\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Jan 2025 10:49:50 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4DCE768516;\n\tWed,  8 Jan 2025 11:49:49 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BD66B68516\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Jan 2025 11:49:40 +0100 (CET)",
            "from ideasonboard.com (mob-5-90-140-184.net.vodafone.it\n\t[5.90.140.184])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 825841A89;\n\tWed,  8 Jan 2025 11:48:47 +0100 (CET)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"DjDOA+Aq\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1736333328;\n\tbh=jtZyfP8XOs6WAyyMuDcZi+j7toHRAWiHY8q+abPzHYU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=DjDOA+AqGwU9no6QLKXJiIVkCYzgMXlqinFMugtceVRI3G4WT9nOoL0x4Ee4x0p75\n\tFuaik9xiFFDfaZlEwp/viLvJopED8tusBBP3LaFqM8m8mt6fH/usp2ds1DZ0gL72ZJ\n\t791cnwPAk+iGcNn6Q6WBYQDC+oPRPVMjcw1r+hNY=",
        "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>, naush@raspberrypi.com,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>",
        "Subject": "[PATCH v3 6/6] libcamera: camera_sensor: Add support for embedded\n\tdata",
        "Date": "Wed,  8 Jan 2025 11:49:23 +0100",
        "Message-ID": "<20250108104924.163077-7-jacopo.mondi@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.47.1",
        "In-Reply-To": "<20250108104924.163077-1-jacopo.mondi@ideasonboard.com>",
        "References": "<20250108104924.163077-1-jacopo.mondi@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nSome sensors support producing and transmitting embedded data over a\nstream separate from the image stream. Add support for this feature in\nthe CameraSensor interface, and implement it for the CameraSensorRaw\nclass. The CameraSensorLegacy uses the default stub implementation, as\nthe corresponding kernel drivers don't support embedded data.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n include/libcamera/internal/camera_sensor.h |  5 ++\n src/libcamera/sensor/camera_sensor.cpp     | 67 ++++++++++++++++++++\n src/libcamera/sensor/camera_sensor_raw.cpp | 72 ++++++++++++++++++++++\n 3 files changed, 144 insertions(+)",
    "diff": "diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\nindex 605ea8136900..f6002c5f5644 100644\n--- a/include/libcamera/internal/camera_sensor.h\n+++ b/include/libcamera/internal/camera_sensor.h\n@@ -62,6 +62,11 @@ public:\n \t\t\t\t       Transform transform = Transform::Identity,\n \t\t\t\t       V4L2SubdeviceFormat *sensorFormat = nullptr) = 0;\n \n+\tvirtual V4L2Subdevice::Stream imageStream() const;\n+\tvirtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const;\n+\tvirtual V4L2SubdeviceFormat embeddedDataFormat() const;\n+\tvirtual int setEmbeddedDataEnabled(bool enable);\n+\n \tvirtual const ControlList &properties() const = 0;\n \tvirtual int sensorInfo(IPACameraSensorInfo *info) const = 0;\n \tvirtual Transform computeTransform(Orientation *orientation) const = 0;\ndiff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp\nindex a131ac224ec0..d19b5e2e719e 100644\n--- a/src/libcamera/sensor/camera_sensor.cpp\n+++ b/src/libcamera/sensor/camera_sensor.cpp\n@@ -199,6 +199,73 @@ CameraSensor::~CameraSensor() = default;\n  * error code otherwise\n  */\n \n+/**\n+ * \\brief Retrieve the image source stream\n+ *\n+ * Sensors that produce multiple streams do not guarantee that the image stream\n+ * is always assigned number 0. This function allows callers to retrieve the\n+ * image stream on the sensor's source pad, in order to configure the receiving\n+ * side accordingly.\n+ *\n+ * \\return The image source stream\n+ */\n+V4L2Subdevice::Stream CameraSensor::imageStream() const\n+{\n+\treturn { 0, 0 };\n+}\n+\n+/**\n+ * \\brief Retrieve the embedded data source stream\n+ *\n+ * Some sensors produce embedded data in a stream separate from the image\n+ * stream. This function indicates if the sensor supports this feature by\n+ * returning the embedded data stream on the sensor's source pad if available,\n+ * or an std::optional<> without a value otheriwse.\n+ *\n+ * \\return The embedded data source stream\n+ */\n+std::optional<V4L2Subdevice::Stream> CameraSensor::embeddedDataStream() const\n+{\n+\treturn {};\n+}\n+\n+/**\n+ * \\brief Retrieve the format on the embedded data stream\n+ *\n+ * When an embedded data stream is available, this function returns the\n+ * corresponding format on the sensor's source pad. The format may vary with\n+ * the image stream format, and should therefore be retrieved after configuring\n+ * the image stream.\n+ *\n+ * If the sensor doesn't support embedded data, this function returns a\n+ * default-constructed format.\n+ *\n+ * \\return The format on the embedded data stream\n+ */\n+V4L2SubdeviceFormat CameraSensor::embeddedDataFormat() const\n+{\n+\treturn {};\n+}\n+\n+/**\n+ * \\brief Enable or disable the embedded data stream\n+ * \\param[in] enable True to enable the embedded data stream, false to disable it\n+ *\n+ * For sensors that support embedded data, this function enables or disables\n+ * generation of embedded data. Some of such sensors always produce embedded\n+ * data, in which case this function return -EISCONN if the caller attempts to\n+ * disable embedded data.\n+ *\n+ * If the sensor doesn't support embedded data, this function returns 0 when \\a\n+ * enable is false, and -ENOSTR otherwise.\n+ *\n+ * \\return 0 on success, or a negative error code otherwise\n+ */\n+int CameraSensor::setEmbeddedDataEnabled(bool enable)\n+{\n+\treturn enable ? -ENOSTR : 0;\n+}\n+\n /**\n  * \\fn CameraSensor::properties()\n  * \\brief Retrieve the camera sensor properties\ndiff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\nindex 33e7bcf2091f..ab75b1f8204c 100644\n--- a/src/libcamera/sensor/camera_sensor_raw.cpp\n+++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n@@ -85,6 +85,11 @@ public:\n \t\t\t       Transform transform = Transform::Identity,\n \t\t\t       V4L2SubdeviceFormat *sensorFormat = nullptr) override;\n \n+\tV4L2Subdevice::Stream imageStream() const override;\n+\tstd::optional<V4L2Subdevice::Stream> embeddedDataStream() const override;\n+\tV4L2SubdeviceFormat embeddedDataFormat() const override;\n+\tint setEmbeddedDataEnabled(bool enable) override;\n+\n \tconst ControlList &properties() const override { return properties_; }\n \tint sensorInfo(IPACameraSensorInfo *info) const override;\n \tTransform computeTransform(Orientation *orientation) const override;\n@@ -908,6 +913,73 @@ int CameraSensorRaw::applyConfiguration(const SensorConfiguration &config,\n \treturn 0;\n }\n \n+V4L2Subdevice::Stream CameraSensorRaw::imageStream() const\n+{\n+\treturn streams_.image.source;\n+}\n+\n+std::optional<V4L2Subdevice::Stream> CameraSensorRaw::embeddedDataStream() const\n+{\n+\tif (!streams_.edata)\n+\t\treturn {};\n+\n+\treturn { streams_.edata->source };\n+}\n+\n+V4L2SubdeviceFormat CameraSensorRaw::embeddedDataFormat() const\n+{\n+\tif (!streams_.edata)\n+\t\treturn {};\n+\n+\tV4L2SubdeviceFormat format;\n+\tint ret = subdev_->getFormat(streams_.edata->source, &format);\n+\tif (ret)\n+\t\treturn {};\n+\n+\treturn format;\n+}\n+\n+int CameraSensorRaw::setEmbeddedDataEnabled(bool enable)\n+{\n+\tif (!streams_.edata)\n+\t\treturn enable ? -ENOSTR : 0;\n+\n+\tV4L2Subdevice::Routing routing{ 2 };\n+\n+\trouting[0].sink = streams_.image.sink;\n+\trouting[0].source = streams_.image.source;\n+\trouting[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;\n+\n+\trouting[1].sink = streams_.edata->sink;\n+\trouting[1].source = streams_.edata->source;\n+\trouting[1].flags = enable ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0;\n+\n+\tint ret = subdev_->setRouting(&routing);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * Check if the embedded data stream has been enabled or disabled\n+\t * correctly. Assume at least one route will match the embedded data\n+\t * source stream, as there would be something seriously wrong\n+\t * otherwise.\n+\t */\n+\tbool enabled = false;\n+\n+\tfor (const V4L2Subdevice::Route &route : routing) {\n+\t\tif (route.source != streams_.edata->source)\n+\t\t\tcontinue;\n+\n+\t\tenabled = route.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE;\n+\t\tbreak;\n+\t}\n+\n+\tif (enabled != enable)\n+\t\treturn enabled ? -EISCONN : -ENOSTR;\n+\n+\treturn 0;\n+}\n+\n int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const\n {\n \tinfo->model = model();\n",
    "prefixes": [
        "v3",
        "6/6"
    ]
}