Show a patch.

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

{
    "id": 9431,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/9431/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/9431/",
    "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": "<20200829115429.30010-6-david.plowman@raspberrypi.com>",
    "date": "2020-08-29T11:54:26",
    "name": "[libcamera-devel,v5,5/8] libcamera: Add user Transform to CameraConfiguration",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "a3708d018a2708adfe1369a7ae1c6cc86d7a849e",
    "submitter": {
        "id": 42,
        "url": "https://patchwork.libcamera.org/api/1.1/people/42/?format=api",
        "name": "David Plowman",
        "email": "david.plowman@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/9431/mbox/",
    "series": [
        {
            "id": 1252,
            "url": "https://patchwork.libcamera.org/api/1.1/series/1252/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1252",
            "date": "2020-08-29T11:54:21",
            "name": "2D transforms",
            "version": 5,
            "mbox": "https://patchwork.libcamera.org/series/1252/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/9431/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/9431/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 69B4DBF019\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 29 Aug 2020 11:54:42 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1AAA462927;\n\tSat, 29 Aug 2020 13:54:42 +0200 (CEST)",
            "from mail-wm1-x330.google.com (mail-wm1-x330.google.com\n\t[IPv6:2a00:1450:4864:20::330])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B710362927\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 29 Aug 2020 13:54:38 +0200 (CEST)",
            "by mail-wm1-x330.google.com with SMTP id s13so1446995wmh.4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 29 Aug 2020 04:54:38 -0700 (PDT)",
            "from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\tv16sm3071523wmj.14.2020.08.29.04.54.37\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 29 Aug 2020 04:54:37 -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=\"Xd1WGHgE\"; 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=LDActHwEwrBnVTFrJuJSA0jThMFh4nkAyDjeus8dcyw=;\n\tb=Xd1WGHgEUKSj5nONmY4DLmKmvl+XpTCGaJbVyRDTyYRak79YWCFKpPai993WZ5V6nQ\n\tQ1vHKP4x/gbI4eQefepAM/ZIbrpf3WVP0Iu74CFc6WeOPYTC4NBlHBnR1Bzj2phfxFNG\n\twAOb0VD/iVOWCYU+uJ65p3DZUxalGo7lJnO+aSJ5uuLnV0rwHdiW7J9jj6LI/DuXkXJt\n\taCa2F4SzAEBJUtETVSjwauaUvXU0YHOuvHJQiMdZd62bNbXEIDCg5G0euhX+j6d9Y08K\n\tboqXjJZI+ijvXlCC2og3meD99pMbbkND8HD7hejvHJ7BitXUDQBm2GyM+0phjPApwMKn\n\t4XTg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\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=LDActHwEwrBnVTFrJuJSA0jThMFh4nkAyDjeus8dcyw=;\n\tb=EugVDjE00rhoFFMKF/DMQkpvMax04IfeA+4DOHiTqcmJCUcM3XIRg2yRd7oyMCKdIS\n\tQjbHZpox1FPjgPXkbq62m1mKNy8QpTs3QuqRhFzbLUNZeyYQUZIgRlVr8uhMYg9n6ci3\n\tO+YMp9CDbog/wC4VDF+ke7K9vbZ7OgkRRUj6lVAVB1wSTnW3aU6cpSRruD5w3HTLehPt\n\twvLiyLTjlhlo9raIGTDuvRZ1r+1r4r/OZuXh2Sk9SecUK0RpwwpnZzt0vBK+jwD8e7uw\n\te5rEVP98aqxVyz34/LDHmbgVC5cmEDlHMmDle55M+QmZ1OHv7JBgG+9yiOJDD0FaZrz5\n\tn8dw==",
        "X-Gm-Message-State": "AOAM530RVZeKpb00/TIxA3cov6HhNI2mWW5/PYj/dik595M32IxzjWG3\n\twBlvaGLBeNnhbvsCKc0WSefn5ita4DGC/w==",
        "X-Google-Smtp-Source": "ABdhPJwUESL0dXCZfxAdhgKCx3fyK87QmZQstGc7aWRIaonDkSWPfHimzFBaCLF+e8OKVPXtjmqUwA==",
        "X-Received": "by 2002:a1c:27c2:: with SMTP id\n\tn185mr3103951wmn.78.1598702078134; \n\tSat, 29 Aug 2020 04:54:38 -0700 (PDT)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Sat, 29 Aug 2020 12:54:26 +0100",
        "Message-Id": "<20200829115429.30010-6-david.plowman@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.20.1",
        "In-Reply-To": "<20200829115429.30010-1-david.plowman@raspberrypi.com>",
        "References": "<20200829115429.30010-1-david.plowman@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH v5 5/8] libcamera: Add user Transform to\n\tCameraConfiguration",
        "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>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Add a field to the CameraConfiguration (including the necessary\ndocumentation) to represent a 2D transform requested by the\napplication. All pipeline handlers are amended to coerce this to the\nIdentity, marking the configuration as \"adjusted\" if something\ndifferent had been requested.\n\nPipeline handlers that support Transforms can be amended subsequently.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n include/libcamera/camera.h                       |  3 +++\n src/libcamera/camera.cpp                         | 16 +++++++++++++++-\n src/libcamera/pipeline/ipu3/ipu3.cpp             |  5 +++++\n .../pipeline/raspberrypi/raspberrypi.cpp         |  5 +++++\n src/libcamera/pipeline/rkisp1/rkisp1.cpp         |  5 +++++\n src/libcamera/pipeline/simple/simple.cpp         |  5 +++++\n src/libcamera/pipeline/uvcvideo/uvcvideo.cpp     |  5 +++++\n src/libcamera/pipeline/vimc/vimc.cpp             |  5 +++++\n 8 files changed, 48 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 272c12c..a2ee4e7 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -17,6 +17,7 @@\n #include <libcamera/request.h>\n #include <libcamera/signal.h>\n #include <libcamera/stream.h>\n+#include <libcamera/transform.h>\n \n namespace libcamera {\n \n@@ -61,6 +62,8 @@ public:\n \tbool empty() const;\n \tstd::size_t size() const;\n \n+\tTransform transform;\n+\n protected:\n \tCameraConfiguration();\n \ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 4a9c19c..b547ffe 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -93,7 +93,7 @@ LOG_DECLARE_CATEGORY(Camera)\n  * \\brief Create an empty camera configuration\n  */\n CameraConfiguration::CameraConfiguration()\n-\t: config_({})\n+\t: transform(Transform::Identity), config_({})\n {\n }\n \n@@ -250,6 +250,20 @@ std::size_t CameraConfiguration::size() const\n \treturn config_.size();\n }\n \n+/**\n+ * \\var CameraConfiguration::transform\n+ * \\brief User-specified transform to be applied to the image\n+ *\n+ * The transform is a user-specified 2D plane transform that will be applied\n+ * to the camera images by the processing pipeline before being handed to\n+ * the application. This is subsequent to any transform that is already\n+ * required to fix up any platform-defined rotation.\n+ *\n+ * The usual 2D plane transforms are allowed here (horizontal/vertical\n+ * flips, multiple of 90-degree rotations etc.), but the validate() function\n+ * may adjust this field at its discretion if the selection is not supported.\n+ */\n+\n /**\n  * \\var CameraConfiguration::config_\n  * \\brief The vector of stream configurations\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 2d881fe..22b8825 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -138,6 +138,11 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \t/* Cap the number of entries to the available streams. */\n \tif (config_.size() > IPU3_MAX_STREAMS) {\n \t\tconfig_.resize(IPU3_MAX_STREAMS);\ndiff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex 42c9caa..c554532 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -400,6 +400,11 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \tunsigned int rawCount = 0, outCount = 0, count = 0, maxIndex = 0;\n \tstd::pair<int, Size> outSize[2];\n \tSize maxSize;\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 4d89aab..6f53a1d 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -478,6 +478,11 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \t/* Cap the number of entries to the available streams. */\n \tif (config_.size() > 1) {\n \t\tconfig_.resize(1);\ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex eb72e3b..10223a9 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -438,6 +438,11 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \t/* Cap the number of entries to the available streams. */\n \tif (config_.size() > 1) {\n \t\tconfig_.resize(1);\ndiff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\nindex bafe6f1..ba0efc8 100644\n--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n@@ -109,6 +109,11 @@ CameraConfiguration::Status UVCCameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \t/* Cap the number of entries to the available streams. */\n \tif (config_.size() > 1) {\n \t\tconfig_.resize(1);\ndiff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex d192670..fc8085f 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -130,6 +130,11 @@ CameraConfiguration::Status VimcCameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tif (transform != Transform::Identity) {\n+\t\ttransform = Transform::Identity;\n+\t\tstatus = Adjusted;\n+\t}\n+\n \t/* Cap the number of entries to the available streams. */\n \tif (config_.size() > 1) {\n \t\tconfig_.resize(1);\n",
    "prefixes": [
        "libcamera-devel",
        "v5",
        "5/8"
    ]
}