Show a patch.

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

{
    "id": 19523,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/19523/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/19523/",
    "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": "<20240221174015.52958-2-jacopo.mondi@ideasonboard.com>",
    "date": "2024-02-21T17:40:09",
    "name": "[1/5] libcamera: Allow pipeline to provide a Private request",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "53ef879cafdf7e1e5ee182bd6b15e3d6df622d21",
    "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/19523/mbox/",
    "series": [
        {
            "id": 4176,
            "url": "https://patchwork.libcamera.org/api/1.1/series/4176/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4176",
            "date": "2024-02-21T17:40:08",
            "name": "libcamera: Replace IPU3/RkISP1FrameInfo",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/4176/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/19523/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/19523/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 2F625C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 21 Feb 2024 17:40:33 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0A5C262819;\n\tWed, 21 Feb 2024 18:40:30 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CAE4A62805\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 21 Feb 2024 18:40:27 +0100 (CET)",
            "from localhost.localdomain (unknown\n\t[IPv6:2001:b07:5d2e:52c9:cc1e:e404:491f:e6ea])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AA10E720;\n\tWed, 21 Feb 2024 18:40:19 +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=\"qjE3qpmr\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1708537219;\n\tbh=C9zQWpF2Pk3tAkuTtTdIwy50nUFri2LcYCqo1c4smko=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=qjE3qpmrYZqmSyAaG5zJsOzxLjIrNqlx+B1mHUfuuTB0NbYvwag5iTJLo5wpnviGS\n\tBK5ZyRvMKPWR0KVG0QjoqyJTYZiZIyPCosKzaicg4yoM+jBmzUbMLBIoLiMVOEE12P\n\t8BxcnCUlKFsSrX1kulOpcuQswppAODCpYxEDpqLI=",
        "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Subject": "[PATCH 1/5] libcamera: Allow pipeline to provide a Private request",
        "Date": "Wed, 21 Feb 2024 18:40:09 +0100",
        "Message-ID": "<20240221174015.52958-2-jacopo.mondi@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20240221174015.52958-1-jacopo.mondi@ideasonboard.com>",
        "References": "<20240221174015.52958-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>",
        "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "In order to allow each pipeline handler to create a Request::Private\nderived class to store ancillary data associated with a capture request,\nmodify the way a Request is created by the PipelineHandler base class.\n\nIntroduce a virtual PipelineHandler::createRequestDevice() that pipeline\nhandler implementation can optionally override to provide a custom\nprivate data type to initialize the Request with.\n\nAs we can't anymore create a Request without going through an active\ncamera, drop the queueRequest() checks from the Camera statemachine\ntest.\n\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n include/libcamera/internal/pipeline_handler.h |  5 ++-\n include/libcamera/request.h                   |  3 +-\n src/libcamera/camera.cpp                      |  8 +---\n src/libcamera/pipeline_handler.cpp            | 38 ++++++++++++++++---\n src/libcamera/request.cpp                     | 15 +++++---\n test/camera/statemachine.cpp                  | 12 ------\n 6 files changed, 50 insertions(+), 31 deletions(-)",
    "diff": "diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex c96944f4ecc4..bbe74f22e5ae 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -21,6 +21,7 @@\n #include <libcamera/stream.h>\n \n #include \"libcamera/internal/ipa_proxy.h\"\n+#include \"libcamera/internal/request.h\"\n \n namespace libcamera {\n \n@@ -59,7 +60,7 @@ public:\n \tvoid stop(Camera *camera);\n \tbool hasPendingRequests(const Camera *camera) const;\n \n-\tvoid registerRequest(Request *request);\n+\tstd::unique_ptr<Request> createRequest(Camera *camera, uint64_t cookie);\n \tvoid queueRequest(Request *request);\n \n \tbool completeBuffer(Request *request, FrameBuffer *buffer);\n@@ -74,6 +75,8 @@ protected:\n \tvoid registerCamera(std::shared_ptr<Camera> camera);\n \tvoid hotplugMediaDevice(MediaDevice *media);\n \n+\tvirtual std::unique_ptr<Request> createRequestDevice(Camera *camera,\n+\t\t\t\t\t\t\t     uint64_t cookie);\n \tvirtual int queueRequestDevice(Camera *camera, Request *request) = 0;\n \tvirtual void stopDevice(Camera *camera) = 0;\n \ndiff --git a/include/libcamera/request.h b/include/libcamera/request.h\nindex dffde1536cad..e16e61a93873 100644\n--- a/include/libcamera/request.h\n+++ b/include/libcamera/request.h\n@@ -45,9 +45,10 @@ public:\n \n \tusing BufferMap = std::map<const Stream *, FrameBuffer *>;\n \n-\tRequest(Camera *camera, uint64_t cookie = 0);\n+\tRequest(std::unique_ptr<Private> d, uint64_t cookie = 0);\n \t~Request();\n \n+\tstatic std::unique_ptr<Request> create(std::unique_ptr<Private> d, uint64_t);\n \tvoid reuse(ReuseFlag flags = Default);\n \n \tControlList &controls() { return *controls_; }\ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex a71dc933b911..b7053576fe42 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -1236,12 +1236,8 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)\n \tif (ret < 0)\n \t\treturn nullptr;\n \n-\tstd::unique_ptr<Request> request = std::make_unique<Request>(this, cookie);\n-\n-\t/* Associate the request with the pipeline handler. */\n-\td->pipe_->registerRequest(request.get());\n-\n-\treturn request;\n+\t/* Create a Request from the pipeline handler. */\n+\treturn d->pipe_->createRequest(this, cookie);\n }\n \n /**\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 29e0c98a6db5..f2a8cdac0408 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -371,20 +371,25 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const\n }\n \n /**\n- * \\fn PipelineHandler::registerRequest()\n- * \\brief Register a request for use by the pipeline handler\n- * \\param[in] request The request to register\n+ * \\fn PipelineHandler::createRequest()\n+ * \\brief Create a request and register it for use by the pipeline handler\n+ * \\param[in] camera The camera the Request belongs to\n+ * \\param[in] cookie The Request unique identifier\n  *\n- * This function is called when the request is created, and allows the pipeline\n- * handler to perform any one-time initialization it requries for the request.\n+ * This function is called to create a Request by calling createRequestDevice()\n+ * which can be optionally provided by the PipelineHandler derived classes.\n  */\n-void PipelineHandler::registerRequest(Request *request)\n+std::unique_ptr<Request> PipelineHandler::createRequest(Camera *camera, uint64_t cookie)\n {\n+\tstd::unique_ptr<Request> request = createRequestDevice(camera, cookie);\n+\n \t/*\n \t * Connect the request prepared signal to notify the pipeline handler\n \t * when a request is ready to be processed.\n \t */\n \trequest->_d()->prepared.connect(this, &PipelineHandler::doQueueRequests);\n+\n+\treturn request;\n }\n \n /**\n@@ -462,6 +467,27 @@ void PipelineHandler::doQueueRequests()\n \t}\n }\n \n+/**\n+ * \\brief Create a Request from the pipeline handler\n+ * \\param[in] camera The camera the Request belongs to\n+ * \\param[in] cookie The Request unique identifier\n+ *\n+ * A virtual function that PipelineHandler derived classes are free to override\n+ * in order to initialize a Request with a custom Request::Private derived\n+ * class.\n+ *\n+ * This is the base class implementation that use Request::Private to\n+ * initialize the Request.\n+ *\n+ * \\return A unique pointer to a newly created Request\n+ */\n+std::unique_ptr<Request>\n+PipelineHandler::createRequestDevice(Camera *camera, uint64_t cookie)\n+{\n+\tauto d = std::make_unique<Request::Private>(camera);\n+\treturn Request::create(std::move(d), cookie);\n+}\n+\n /**\n  * \\fn PipelineHandler::queueRequestDevice()\n  * \\brief Queue a request to the device\ndiff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\nindex 949c556fa437..d1051ad3d25e 100644\n--- a/src/libcamera/request.cpp\n+++ b/src/libcamera/request.cpp\n@@ -336,7 +336,7 @@ void Request::Private::timeout()\n \n /**\n  * \\brief Create a capture request for a camera\n- * \\param[in] camera The camera that creates the request\n+ * \\param[in] d The request private data\n  * \\param[in] cookie Opaque cookie for application use\n  *\n  * The \\a cookie is stored in the request and is accessible through the\n@@ -344,12 +344,17 @@ void Request::Private::timeout()\n  * the request to an external resource in the request completion handler, and is\n  * completely opaque to libcamera.\n  */\n-Request::Request(Camera *camera, uint64_t cookie)\n-\t: Extensible(std::make_unique<Private>(camera)),\n-\t  cookie_(cookie), status_(RequestPending)\n+std::unique_ptr<Request> Request::create(std::unique_ptr<Private> d,\n+\t\t\t\t\t uint64_t cookie)\n+{\n+\treturn std::make_unique<Request>(std::move(d), cookie);\n+}\n+\n+Request::Request(std::unique_ptr<Request::Private> d, uint64_t cookie)\n+\t: Extensible(std::move(d)), cookie_(cookie), status_(RequestPending)\n {\n \tcontrols_ = new ControlList(controls::controls,\n-\t\t\t\t    camera->_d()->validator());\n+\t\t\t\t    _d()->camera()->_d()->validator());\n \n \t/**\n \t * \\todo Add a validator for metadata controls.\ndiff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp\nindex 9c2b0c6a7d99..5714061f88b5 100644\n--- a/test/camera/statemachine.cpp\n+++ b/test/camera/statemachine.cpp\n@@ -38,10 +38,6 @@ protected:\n \t\tif (camera_->start() != -EACCES)\n \t\t\treturn TestFail;\n \n-\t\tRequest request(camera_.get());\n-\t\tif (camera_->queueRequest(&request) != -EACCES)\n-\t\t\treturn TestFail;\n-\n \t\t/* Test operations which should pass. */\n \t\tif (camera_->release())\n \t\t\treturn TestFail;\n@@ -68,10 +64,6 @@ protected:\n \t\tif (camera_->start() != -EACCES)\n \t\t\treturn TestFail;\n \n-\t\tRequest request(camera_.get());\n-\t\tif (camera_->queueRequest(&request) != -EACCES)\n-\t\t\treturn TestFail;\n-\n \t\t/* Test operations which should pass. */\n \t\tif (camera_->stop())\n \t\t\treturn TestFail;\n@@ -95,10 +87,6 @@ protected:\n \t\tif (camera_->acquire() != -EBUSY)\n \t\t\treturn TestFail;\n \n-\t\tRequest request1(camera_.get());\n-\t\tif (camera_->queueRequest(&request1) != -EACCES)\n-\t\t\treturn TestFail;\n-\n \t\t/* Test operations which should pass. */\n \t\tstd::unique_ptr<Request> request2 = camera_->createRequest();\n \t\tif (!request2)\n",
    "prefixes": [
        "1/5"
    ]
}