Show a patch.

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

{
    "id": 24761,
    "url": "https://patchwork.libcamera.org/api/patches/24761/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/24761/",
    "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": "<20251023144841.403689-35-stefan.klug@ideasonboard.com>",
    "date": "2025-10-23T14:48:35",
    "name": "[v2,34/35] DNI libcamera: rkisp1: Implement dw100 specific features",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "18435a0b38ced45ab6ce1db83e4e7f1526d3757d",
    "submitter": {
        "id": 184,
        "url": "https://patchwork.libcamera.org/api/people/184/?format=api",
        "name": "Stefan Klug",
        "email": "stefan.klug@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/24761/mbox/",
    "series": [
        {
            "id": 5520,
            "url": "https://patchwork.libcamera.org/api/series/5520/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5520",
            "date": "2025-10-23T14:48:01",
            "name": "Full dewarper support on imx8mp",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/5520/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/24761/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/24761/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 C0BEFC3347\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Oct 2025 14:50:29 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C7D260865;\n\tThu, 23 Oct 2025 16:50:29 +0200 (CEST)",
            "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 8C648607ED\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Oct 2025 16:50:28 +0200 (CEST)",
            "from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:7328:357b:4ce1:72b6])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 91B42192B; \n\tThu, 23 Oct 2025 16:48:43 +0200 (CEST)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"R8QkNssV\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761230923;\n\tbh=jNkATD4IVKZDk3Nr2jeaeEoD0w69FOUxdlyhHGDPwO0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=R8QkNssVKikSvpXWkrqqtmvJr8iwFzOXea/+WXHv5lxNxCh+EWj+iIQSeZDu9rnAl\n\tf1GGvs4l6tZBRbh6iqgKiQxGuZT64dm1utGmAIB7GexyYJPxlAlIs9xmoHyWIjMf5C\n\t9RfFvbegOx3TLcMq1rzH/sLiKrqHWi5SZwkdOeiY=",
        "From": "Stefan Klug <stefan.klug@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Stefan Klug <stefan.klug@ideasonboard.com>",
        "Subject": "[PATCH v2 34/35] DNI libcamera: rkisp1: Implement dw100 specific\n\tfeatures",
        "Date": "Thu, 23 Oct 2025 16:48:35 +0200",
        "Message-ID": "<20251023144841.403689-35-stefan.klug@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.48.1",
        "In-Reply-To": "<20251023144841.403689-1-stefan.klug@ideasonboard.com>",
        "References": "<20251023144841.403689-1-stefan.klug@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": "The dw100 allows more features implemented in the dw100 vertex map.\nImplement these features for the rkisp1 pipeline.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\n---\n\nChanges in v2:\n- Marked as DoNotIntegrate because the puplic interface needs further\n  discussions\n- Added Dw100EffectiveScale metadata\n---\n .../converter/converter_dw100_vertexmap.h     |  2 +-\n src/libcamera/control_ids_draft.yaml          | 45 ++++++++++++++++++\n src/libcamera/pipeline/rkisp1/rkisp1.cpp      | 46 ++++++++++++++++---\n 3 files changed, 86 insertions(+), 7 deletions(-)",
    "diff": "diff --git a/include/libcamera/internal/converter/converter_dw100_vertexmap.h b/include/libcamera/internal/converter/converter_dw100_vertexmap.h\nindex b05ed8338a23..5fa46452f9ef 100644\n--- a/include/libcamera/internal/converter/converter_dw100_vertexmap.h\n+++ b/include/libcamera/internal/converter/converter_dw100_vertexmap.h\n@@ -47,7 +47,7 @@ public:\n \tconst Transform &transform() const { return transform_; }\n \n \tvoid setScale(const float scale) { scale_ = scale; }\n-\tfloat effectiveScale() const { return (effectiveScaleX_ + effectiveScaleY_) * 0.5; }\n+\tstd::array<float, 2> effectiveScale() const { return { static_cast<float>(effectiveScaleX_), static_cast<float>(effectiveScaleY_) }; }\n \n \tvoid setRotation(const float rotation) { rotation_ = rotation; }\n \tfloat rotation() const { return rotation_; }\ndiff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml\nindex 03309eeac34f..30c832e32159 100644\n--- a/src/libcamera/control_ids_draft.yaml\n+++ b/src/libcamera/control_ids_draft.yaml\n@@ -206,6 +206,51 @@ controls:\n             available only on this camera device are at least this numeric\n             value. All of the custom test patterns will be static (that is the\n             raw image must not vary from frame to frame).\n+  - Dw100ScaleMode:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Scale mode of the dewarper.\n+      enum:\n+        - name: Fill\n+          value: 0\n+          description: |\n+            Fills the given output size with the largest rectangle possible.\n+            Aspect ratio is not preserved. Dw100Scale is ignored.\n+        - name: Crop\n+          value: 1\n+          description: |\n+            Crops to the given output size. The scale factor can be specified\n+            using Dw100Scale. Aspect ratio is preserved.\n+  - Dw100Scale:\n+      type: float\n+      direction: inout\n+      description: |\n+        Scale factor applied to the image when Dw100ScaleMode is set to Crop.\n+        This value is clamped, so that all pixels have valid input data.\n+        Therefore a value of 0 always provides the largest possible field of\n+        view. Scaling happens centered around the center of the ScalerCrop +\n+        Dw10Offset.\n+  - Dw100Rotation:\n+      type: float\n+      direction: inout\n+      description: |\n+        Rotates the image by the given angle in degrees in clockwise direction\n+        around the center of ScalerCrop + Dw100Offset\n+  - Dw100Offset:\n+      type: Point\n+      direction: inout\n+      description: |\n+        Moves the image by the given values in x and y direction in sensor\n+        coordinate space. This is clamped, so that all output pixels contain\n+        valid data. The offset is therefore ignored when the Dw100Scale value is\n+        too small.\n+  - Dw100EffectiveScale:\n+      type: float\n+      direction: out\n+      description: |\n+        Effective scale\n+      size: [2]\n \n   - FaceDetectMode:\n       type: int32_t\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 9a156d4a01f2..6538fbcc9698 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -1500,13 +1500,18 @@ int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)\n \t\t\t\t\t\t\t\t      maxCrop);\n \t\t}\n \n-\t\tif (data->dewarpParams_.has_value()) {\n-\t\t\tif (dewarper_->supportsRequests())\n+\t\tif (dewarper_->supportsRequests()) {\n+\t\t\tcontrols[&controls::draft::Dw100Scale] = ControlInfo(0.2f, 8.0f, 1.0f);\n+\t\t\tcontrols[&controls::draft::Dw100Rotation] = ControlInfo(-180.0f, 180.0f, 0.0f);\n+\t\t\tcontrols[&controls::draft::Dw100Offset] = ControlInfo(Point(-10000, -10000), Point(10000, 10000), Point(0, 0));\n+\t\t\tcontrols[&controls::draft::Dw100ScaleMode] = ControlInfo(controls::draft::Dw100ScaleModeValues, controls::draft::Fill);\n+\n+\t\t\tif (data->dewarpParams_.has_value())\n \t\t\t\tcontrols[&controls::LensDewarpEnable] = ControlInfo(false, true, true);\n-\t\t\telse\n-\t\t\t\tLOG(RkISP1, Warning)\n-\t\t\t\t\t<< \"dw100 kernel driver has no requests support.\"\n-\t\t\t\t\t   \" No dynamic configuration possible.\";\n+\t\t} else {\n+\t\t\tLOG(RkISP1, Warning)\n+\t\t\t\t<< \"dw100 kernel driver has no requests support.\"\n+\t\t\t\t   \" No dynamic configuration possible.\";\n \t\t}\n \t}\n \n@@ -1784,6 +1789,30 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n \tbool update = false;\n \tauto &vertexMap = dewarper_->vertexMap(&data->mainPathStream_);\n \n+\tconst auto &scale = request->controls().get(controls::draft::Dw100Scale);\n+\tif (scale) {\n+\t\tvertexMap.setScale(*scale);\n+\t\tupdate = true;\n+\t}\n+\n+\tconst auto &rotation = request->controls().get(controls::draft::Dw100Rotation);\n+\tif (rotation) {\n+\t\tvertexMap.setRotation(*rotation);\n+\t\tupdate = true;\n+\t}\n+\n+\tconst auto &offset = request->controls().get(controls::draft::Dw100Offset);\n+\tif (offset) {\n+\t\tvertexMap.setOffset(*offset);\n+\t\tupdate = true;\n+\t}\n+\n+\tconst auto &scaleMode = request->controls().get(controls::draft::Dw100ScaleMode);\n+\tif (scaleMode) {\n+\t\tvertexMap.setMode(static_cast<Dw100VertexMap::ScaleMode>(*scaleMode));\n+\t\tupdate = true;\n+\t}\n+\n \tconst auto &lensDewarpEnable = request->controls().get(controls::LensDewarpEnable);\n \tif (lensDewarpEnable) {\n \t\tvertexMap.setLensDewarpEnable(*lensDewarpEnable);\n@@ -1836,6 +1865,11 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n \t}\n \n \tauto &meta = request->metadata();\n+\tstd::array<float, 2> effectiveScale = vertexMap.effectiveScale();\n+\tmeta.set(controls::draft::Dw100EffectiveScale, effectiveScale);\n+\tmeta.set(controls::draft::Dw100Scale, (effectiveScale[0] + effectiveScale[1]) / 2.0);\n+\tmeta.set(controls::draft::Dw100Rotation, vertexMap.rotation());\n+\tmeta.set(controls::draft::Dw100Offset, vertexMap.effectiveOffset());\n \tmeta.set(controls::ScalerCrop, vertexMap.effectiveScalerCrop());\n \n \tif (vertexMap.dewarpParamsValid())\n",
    "prefixes": [
        "v2",
        "34/35"
    ]
}