Show a patch.

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

{
    "id": 27098,
    "url": "https://patchwork.libcamera.org/api/patches/27098/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/27098/",
    "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": "<20260629163017.863145-20-barnabas.pocze@ideasonboard.com>",
    "date": "2026-06-29T16:29:42",
    "name": "[RFC,v1,19/54] libcamera: framebuffer: request(): Move to private type",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "419a34a0ce36394f4f267518b80a3cae04f5a5f5",
    "submitter": {
        "id": 216,
        "url": "https://patchwork.libcamera.org/api/people/216/?format=api",
        "name": "Barnabás Pőcze",
        "email": "barnabas.pocze@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/27098/mbox/",
    "series": [
        {
            "id": 6025,
            "url": "https://patchwork.libcamera.org/api/series/6025/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6025",
            "date": "2026-06-29T16:29:23",
            "name": "libcamera: Split requests and buffers",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/6025/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/27098/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/27098/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 801D3C3261\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Jun 2026 16:31:07 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 374FA65F4E;\n\tMon, 29 Jun 2026 18:30:58 +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 5FDDB65F2A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Jun 2026 18:30:25 +0200 (CEST)",
            "from pb-laptop.local (185.221.140.128.nat.pool.zt.hu\n\t[185.221.140.128])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 35FF31044\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Jun 2026 18:29:42 +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=\"r+dqhxNS\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1782750582;\n\tbh=i6QUviw1gSUZdOE9lYq+QkoZHCUpi+dBmjZE8ArEtxY=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=r+dqhxNSG4j6UcsbizozS9wzlVuZYRAMymmzy87l2OgLhaQl1SD4ajQjj4ZAoKvYt\n\tAa+AjRXy17ejbSqV9bhtSsPmeEufFbv+qT1/wp+l5Pi++QONrFjhW1ObcPCg+0DVjI\n\t9ybLs1DPJDun4f9wH/Sd3CU9xoaltHefZU9WSiWk=",
        "From": "=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Subject": "[RFC PATCH v1 19/54] libcamera: framebuffer: request(): Move to\n\tprivate type",
        "Date": "Mon, 29 Jun 2026 18:29:42 +0200",
        "Message-ID": "<20260629163017.863145-20-barnabas.pocze@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.54.0",
        "In-Reply-To": "<20260629163017.863145-1-barnabas.pocze@ideasonboard.com>",
        "References": "<20260629163017.863145-1-barnabas.pocze@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "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 `request()` is of not much interest to normal applications,\nmainly because the request-buffer association is removed when\nthe buffer completes. Therefore the only place where this can\nactually be used is in the `bufferCompleted` signal, but the\nrequest is already provided there by other means.\n\nSo move the function into the associated `Private` type.\n\nSigned-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n Documentation/guides/pipeline-handler.rst    |  8 ++++-\n include/libcamera/framebuffer.h              |  1 -\n include/libcamera/internal/framebuffer.h     |  2 ++\n src/libcamera/framebuffer.cpp                | 33 +++++++++-----------\n src/libcamera/pipeline/imx8-isi/imx8-isi.cpp |  3 +-\n src/libcamera/pipeline/mali-c55/mali-c55.cpp |  2 +-\n src/libcamera/pipeline/rkisp1/rkisp1.cpp     |  4 +--\n src/libcamera/pipeline/simple/simple.cpp     | 15 ++++-----\n src/libcamera/pipeline/uvcvideo/uvcvideo.cpp |  3 +-\n src/libcamera/pipeline/vimc/vimc.cpp         |  2 +-\n src/libcamera/pipeline/virtual/virtual.cpp   |  2 +-\n 11 files changed, 41 insertions(+), 34 deletions(-)",
    "diff": "diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst\nindex b33d8b8574..2d2231eb68 100644\n--- a/Documentation/guides/pipeline-handler.rst\n+++ b/Documentation/guides/pipeline-handler.rst\n@@ -1400,12 +1400,18 @@ code-base.\n \n    void VividCameraData::bufferReady(FrameBuffer *buffer)\n    {\n-          Request *request = buffer->request();\n+          Request *request = buffer->_d()->request();\n \n           pipe_->completeBuffer(request, buffer);\n           pipe_->completeRequest(request);\n    }\n \n+The following new include statements are needed for the above:\n+\n+.. code-block:: cpp\n+\n+   #include \"libcamera/internal/framebuffer.h\"\n+\n Testing a pipeline handler\n ~~~~~~~~~~~~~~~~~~~~~~~~~~\n \ndiff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h\nindex 723525d052..3ac1609f56 100644\n--- a/include/libcamera/framebuffer.h\n+++ b/include/libcamera/framebuffer.h\n@@ -63,7 +63,6 @@ public:\n \tvirtual ~FrameBuffer() {}\n \n \tSpan<const Plane> planes() const;\n-\tRequest *request() const;\n \tconst FrameMetadata &metadata() const;\n \n \tuint64_t cookie() const;\ndiff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h\nindex 67b090fc30..7e96100b6c 100644\n--- a/include/libcamera/internal/framebuffer.h\n+++ b/include/libcamera/internal/framebuffer.h\n@@ -27,7 +27,9 @@ public:\n \tPrivate(Span<const Plane> planes, uint64_t cookie = 0);\n \tvirtual ~Private();\n \n+\tRequest *request() const { return request_; }\n \tvoid setRequest(Request *request) { request_ = request; }\n+\n \tbool isContiguous() const { return isContiguous_; }\n \n \tFence *fence() const { return fence_.get(); }\ndiff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp\nindex 6ea4d6ea21..4f23df6482 100644\n--- a/src/libcamera/framebuffer.cpp\n+++ b/src/libcamera/framebuffer.cpp\n@@ -144,6 +144,21 @@ FrameBuffer::Private::~Private()\n {\n }\n \n+/**\n+ * \\fn FrameBuffer::Private::request()\n+ * \\brief Retrieve the request this buffer belongs to\n+ *\n+ * The intended callers of this function are buffer completion handlers that\n+ * need to associate a buffer to the request it belongs to.\n+ *\n+ * A FrameBuffer is associated to a request by Request::addBuffer() and the\n+ * association is valid until the buffer completes. The returned request\n+ * pointer is valid only during that interval.\n+ *\n+ * \\return The Request the FrameBuffer belongs to, or nullptr if the buffer is\n+ * not associated with a request\n+ */\n+\n /**\n  * \\fn FrameBuffer::Private::setRequest()\n  * \\brief Set the request this buffer belongs to\n@@ -364,24 +379,6 @@ Span<const FrameBuffer::Plane> FrameBuffer::planes() const\n \treturn _d()->planes_;\n }\n \n-/**\n- * \\brief Retrieve the request this buffer belongs to\n- *\n- * The intended callers of this function are buffer completion handlers that\n- * need to associate a buffer to the request it belongs to.\n- *\n- * A FrameBuffer is associated to a request by Request::addBuffer() and the\n- * association is valid until the buffer completes. The returned request\n- * pointer is valid only during that interval.\n- *\n- * \\return The Request the FrameBuffer belongs to, or nullptr if the buffer is\n- * not associated with a request\n- */\n-Request *FrameBuffer::request() const\n-{\n-\treturn _d()->request_;\n-}\n-\n /**\n  * \\brief Retrieve the dynamic metadata\n  * \\return Dynamic metadata for the frame contained in the buffer\ndiff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\nindex 5f15fbdc08..d3f152aa1e 100644\n--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n@@ -24,6 +24,7 @@\n #include \"libcamera/internal/camera.h\"\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n+#include \"libcamera/internal/framebuffer.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/media_pipeline.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n@@ -1124,7 +1125,7 @@ PipelineHandlerISI::Pipe *PipelineHandlerISI::pipeFromStream(ISICameraData *data\n \n void PipelineHandlerISI::bufferReady(FrameBuffer *buffer)\n {\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n \t/* Record the sensor's timestamp in the request metadata. */\n \tControlList &metadata = request->_d()->metadata();\ndiff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex b30455683e..0c7b7ed370 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -1649,7 +1649,7 @@ void PipelineHandlerMaliC55::tryComplete(MaliC55FrameInfo *info, bool cancelled)\n \n void PipelineHandlerMaliC55::imageBufferReady(FrameBuffer *buffer)\n {\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \tMaliC55FrameInfo *info = findFrameInfo(request);\n \tASSERT(info);\n \ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 4f9c0aa741..0c1e5767b4 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -1695,9 +1695,9 @@ void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer)\n {\n \tASSERT(activeCamera_);\n \tRkISP1CameraData *data = cameraData(activeCamera_);\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n-\tRkISP1FrameInfo *info = data->frameInfo_.find(buffer->request());\n+\tRkISP1FrameInfo *info = data->frameInfo_.find(request);\n \tif (!info)\n \t\treturn;\n \ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex e26f438d9a..381f8db3ee 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -40,6 +40,7 @@\n #include \"libcamera/internal/delayed_controls.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/formats.h\"\n+#include \"libcamera/internal/framebuffer.h\"\n #include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n@@ -887,7 +888,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)\n \tif (buffer->metadata().status != FrameMetadata::FrameSuccess) {\n \t\tif (!useConversion_ || rawStream_) {\n \t\t\t/* No conversion, just complete the request. */\n-\t\t\tRequest *request = buffer->request();\n+\t\t\tRequest *request = buffer->_d()->request();\n \t\t\tpipe->completeBuffer(request, buffer);\n \t\t\tSimpleFrameInfo *info = frameInfo_.find(request->sequence());\n \t\t\tif (info)\n@@ -927,7 +928,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)\n \t * \\todo The sensor timestamp should be better estimated by connecting\n \t * to the V4L2Device::frameStart signal if the platform provides it.\n \t */\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n \tif (useConversion_ && !conversionQueue_.empty()) {\n \t\tconst std::map<const Stream *, FrameBuffer *> &outputs =\n@@ -935,7 +936,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)\n \t\tif (!outputs.empty()) {\n \t\t\tFrameBuffer *outputBuffer = outputs.begin()->second;\n \t\t\tif (outputBuffer)\n-\t\t\t\trequest = outputBuffer->request();\n+\t\t\t\trequest = outputBuffer->_d()->request();\n \t\t}\n \t}\n \n@@ -960,8 +961,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)\n \t\telse\n \t\t\t/*\n \t\t\t * request->sequence() cannot be retrieved from `buffer' inside\n-\t\t\t * queueBuffers because unique_ptr's make buffer->request() invalid\n-\t\t\t * already here.\n+\t\t\t * queueBuffers because unique_ptr's make buffer->_d()->request()\n+\t\t\t * invalid already here.\n \t\t\t */\n \t\t\tswIsp_->queueBuffers(request->sequence(), buffer,\n \t\t\t\t\t     conversionQueue_.front().outputs);\n@@ -1005,7 +1006,7 @@ void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)\n {\n \tif (rawStream_) {\n \t\t/* Complete the input buffer as with raw-only processing. */\n-\t\tRequest *request = buffer->request();\n+\t\tRequest *request = buffer->_d()->request();\n \t\tif (pipe()->completeBuffer(request, buffer))\n \t\t\ttryCompleteRequest(request);\n \t} else {\n@@ -1019,7 +1020,7 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n \tSimplePipelineHandler *pipe = SimpleCameraData::pipe();\n \n \t/* Complete the buffer and the request. */\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \tif (pipe->completeBuffer(request, buffer))\n \t\ttryCompleteRequest(request);\n }\ndiff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\nindex 3435a76046..f8d49d9122 100644\n--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n@@ -28,6 +28,7 @@\n \n #include \"libcamera/internal/camera.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n+#include \"libcamera/internal/framebuffer.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/request.h\"\n@@ -892,7 +893,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n \n void UVCCameraData::imageBufferReady(FrameBuffer *buffer)\n {\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n \t/* \\todo Use the UVC metadata to calculate a more precise timestamp */\n \trequest->_d()->metadata().set(controls::SensorTimestamp,\ndiff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex 99ae60785b..528022776e 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -601,7 +601,7 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer)\n {\n \tPipelineHandlerVimc *pipe =\n \t\tstatic_cast<PipelineHandlerVimc *>(this->pipe());\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n \t/* If the buffer is cancelled force a complete of the whole request. */\n \tif (buffer->metadata().status == FrameMetadata::FrameCancelled) {\ndiff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp\nindex a7cd76e226..f9e2cecea3 100644\n--- a/src/libcamera/pipeline/virtual/virtual.cpp\n+++ b/src/libcamera/pipeline/virtual/virtual.cpp\n@@ -452,7 +452,7 @@ bool PipelineHandlerVirtual::initFrameGenerator(Camera *camera)\n \n void PipelineHandlerVirtual::bufferCompleted(FrameBuffer *buffer)\n {\n-\tRequest *request = buffer->request();\n+\tRequest *request = buffer->_d()->request();\n \n \tif (completeBuffer(request, buffer))\n \t\tcompleteRequest(request);\n",
    "prefixes": [
        "RFC",
        "v1",
        "19/54"
    ]
}