Show a patch.

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

{
    "id": 25392,
    "url": "https://patchwork.libcamera.org/api/patches/25392/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25392/",
    "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": "<20251209180954.332392-4-isaac.scott@ideasonboard.com>",
    "date": "2025-12-09T18:09:51",
    "name": "[RFC,3/6] pipeline: rkisp1: Add support for YUV passthrough",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "ef92c9245e1fd5718ccadf86fe18475305396c5a",
    "submitter": {
        "id": 215,
        "url": "https://patchwork.libcamera.org/api/people/215/?format=api",
        "name": "Isaac Scott",
        "email": "isaac.scott@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25392/mbox/",
    "series": [
        {
            "id": 5643,
            "url": "https://patchwork.libcamera.org/api/series/5643/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5643",
            "date": "2025-12-09T18:09:48",
            "name": "rkisp1: Add support for YUV bypass",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5643/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25392/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25392/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 19EE0BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  9 Dec 2025 18:10:12 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C8D9961429;\n\tTue,  9 Dec 2025 19:10:09 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4426F61429\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  9 Dec 2025 19:10:06 +0100 (CET)",
            "from isaac-ThinkPad-T16-Gen-2.infra.iob\n\t(cpc90716-aztw32-2-0-cust408.18-1.cable.virginm.net [86.26.101.153])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C224710;\n\tTue,  9 Dec 2025 19:10:05 +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=\"vsuGqn4j\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1765303805;\n\tbh=UD6fpWZwvBFwoCKR6V5tU+NV5XY0uUzW5yrhZrm2P24=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=vsuGqn4jaFVuLG2OalJldOM+wCrmqpPZT31op0BdG/U63CM8aV5hSAVWicR9G0xJ/\n\texiP1+PSnByUe9jRSREte2wQbgu9diOQNWkeYSltlJYfOY/AlOiZ6Es1135yzl9cye\n\twLoPq9k0WU0AP+heqaEn5w+pPWNwNHlcgkTEn6FE=",
        "From": "Isaac Scott <isaac.scott@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Isaac Scott <isaac.scott@ideasonboard.com>",
        "Subject": "[RFC PATCH 3/6] pipeline: rkisp1: Add support for YUV passthrough",
        "Date": "Tue,  9 Dec 2025 18:09:51 +0000",
        "Message-ID": "<20251209180954.332392-4-isaac.scott@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20251209180954.332392-1-isaac.scott@ideasonboard.com>",
        "References": "<20251209180954.332392-1-isaac.scott@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": "When the rkisp1 is configured to bypass ISP blocks, we will have no\nparams buffers. Modify the rkisp1 pipeline handler to not wait for\nparams buffers to become available before queueing buffers back to the\nrkisp1.\n\nSigned-off-by: Isaac Scott <isaac.scott@ideasonboard.com>\n---\n src/libcamera/pipeline/rkisp1/rkisp1.cpp      | 39 +++++++++++--------\n src/libcamera/pipeline/rkisp1/rkisp1_path.cpp |  7 ++--\n 2 files changed, 26 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 5fd110269..ad0f3af34 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -77,7 +77,7 @@ public:\n \tRkISP1Frames(PipelineHandler *pipe);\n \n \tRkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request,\n-\t\t\t\tbool isRaw);\n+\t\t\t\tbool isIspBypassed);\n \tint destroy(unsigned int frame);\n \tvoid clear();\n \n@@ -232,7 +232,7 @@ private:\n \tstd::unique_ptr<V4L2VideoDevice> stat_;\n \n \tbool hasSelfPath_;\n-\tbool isRaw_;\n+\tbool isIspBypassed_;\n \n \tRkISP1MainPath mainPath_;\n \tRkISP1SelfPath selfPath_;\n@@ -257,7 +257,7 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)\n }\n \n RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request,\n-\t\t\t\t      bool isRaw)\n+\t\t\t\t      bool isIspBypassed)\n {\n \tunsigned int frame = data->frame_;\n \n@@ -266,7 +266,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req\n \tFrameBuffer *mainPathBuffer = nullptr;\n \tFrameBuffer *selfPathBuffer = nullptr;\n \n-\tif (!isRaw) {\n+\tif (!isIspBypassed) {\n \t\tif (pipe_->availableParamBuffers_.empty()) {\n \t\t\tLOG(RkISP1, Error) << \"Parameters buffer underrun\";\n \t\t\treturn nullptr;\n@@ -970,8 +970,15 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)\n \n \tRectangle outputCrop = inputCrop;\n \n+\t/* We cannot convert YUV to bayer, so YUV must be passthrough */\n+\tisIspBypassed_ = info.colourEncoding == PixelFormatInfo::ColourEncodingRAW ||\n+\t\t\t info.colourEncoding == PixelFormatInfo::ColourEncodingYUV;\n+\n+\tLOG(RkISP1, Debug)\n+\t\t<< \"ISP is \" << (isIspBypassed_ ? \"in \" : \"not in \") << \"bypass\";\n+\n \t/* YUYV8_2X8 is required on the ISP source path pad for YUV output. */\n-\tif (!isRaw_)\n+\tif (!isIspBypassed_)\n \t\tformat.code = MEDIA_BUS_FMT_YUYV8_2X8;\n \n \t/*\n@@ -1047,7 +1054,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)\n \t\t\t * the isp output to the same size as the sensor output.\n \t\t\t */\n \t\t\tStreamConfiguration ispCfg = cfg;\n-\t\t\tif (data->usesDewarper_) {\n+\t\t\tif (data->usesDewarper_ && !isIspBypassed_) {\n \t\t\t\toutputCfgs.push_back(const_cast<StreamConfiguration &>(cfg));\n \n \t\t\t\tispCfg.bufferCount = kRkISP1MinBufferCount;\n@@ -1151,7 +1158,7 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n \t\tmainPathBuffers_.clear();\n \t} };\n \n-\tif (!isRaw_) {\n+\tif (!isIspBypassed_) {\n \t\tret = param_->allocateBuffers(kRkISP1MinBufferCount, &paramBuffers_);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n@@ -1248,7 +1255,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n \n \tdata->frame_ = 0;\n \n-\tif (!isRaw_) {\n+\tif (!isIspBypassed_) {\n \t\tret = param_->streamOn();\n \t\tif (ret) {\n \t\t\tLOG(RkISP1, Error)\n@@ -1312,7 +1319,7 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)\n \t\tselfPath_.stop();\n \tmainPath_.stop();\n \n-\tif (!isRaw_) {\n+\tif (!isIspBypassed_) {\n \t\tret = stat_->streamOff();\n \t\tif (ret)\n \t\t\tLOG(RkISP1, Warning)\n@@ -1339,12 +1346,12 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)\n {\n \tRkISP1CameraData *data = cameraData(camera);\n \n-\tRkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_);\n+\tRkISP1FrameInfo *info = data->frameInfo_.create(data, request, isIspBypassed_);\n \tif (!info)\n \t\treturn -ENOENT;\n \n \tdata->ipa_->queueRequest(data->frame_, request->controls());\n-\tif (isRaw_) {\n+\tif (isIspBypassed_) {\n \t\tif (info->mainPathBuffer)\n \t\t\tdata->mainPath_->queueBuffer(info->mainPathBuffer);\n \n@@ -1588,10 +1595,10 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info)\n \tif (request->hasPendingBuffers())\n \t\treturn;\n \n-\tif (!info->metadataProcessed)\n+\tif (!isIspBypassed_ && !info->metadataProcessed)\n \t\treturn;\n \n-\tif (!isRaw_ && !info->paramDequeued)\n+\tif (!isIspBypassed_ && !info->paramDequeued)\n \t\treturn;\n \n \tdata->frameInfo_.destroy(info->frame);\n@@ -1646,14 +1653,14 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n \t\trequest->metadata().set(controls::SensorTimestamp,\n \t\t\t\t\tmetadata.timestamp);\n \n-\t\tif (isRaw_) {\n+\t\t/* We do not have stats buffers in bypass mode */\n+\t\tif (!isIspBypassed_) {\n \t\t\tconst ControlList &ctrls =\n \t\t\t\tdata->delayedCtrls_->get(metadata.sequence);\n \t\t\tdata->ipa_->processStats(info->frame, 0, ctrls);\n \t\t}\n \t} else {\n-\t\tif (isRaw_)\n-\t\t\tinfo->metadataProcessed = true;\n+\t\tinfo->metadataProcessed = true;\n \t}\n \n \tif (!data->usesDewarper_) {\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\nindex ef9cfbdc3..903e1aaeb 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n@@ -238,11 +238,10 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size,\n \t\tif (!rawFormat.isValid()) {\n \t\t\tLOG(RkISP1, Error)\n \t\t\t\t<< \"Sensor \" << sensor->model()\n-\t\t\t\t<< \" doesn't support raw capture\";\n-\t\t\treturn {};\n+\t\t\t\t<< \" doesn't support raw/bypass capture\";\n+\t\t} else {\n+\t\t\tformat = rawFormat;\n \t\t}\n-\n-\t\tformat = rawFormat;\n \t} else {\n \t\tformat = formats::NV12;\n \t}\n",
    "prefixes": [
        "RFC",
        "3/6"
    ]
}