Show a patch.

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

{
    "id": 17675,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/17675/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/17675/",
    "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": "<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>",
    "date": "2022-10-24T00:03:55",
    "name": "[libcamera-devel,v3,12/13] pipeline: rkisp1: Support raw Bayer capture at runtime",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "6415668aad53d1a360f495734d1c8b7a19e85480",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/17675/mbox/",
    "series": [
        {
            "id": 3574,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3574/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3574",
            "date": "2022-10-24T00:03:43",
            "name": "Add Bayer format support for RkISP1",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/3574/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/17675/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/17675/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 49829BD16B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Oct 2022 00:04:43 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 06D3562EDF;\n\tMon, 24 Oct 2022 02:04:43 +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 8757562F02\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Oct 2022 02:04:37 +0200 (CEST)",
            "from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 11B5588F;\n\tMon, 24 Oct 2022 02:04:37 +0200 (CEST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1666569883;\n\tbh=YTaYpDITiY7M40evmlcVErHC0HbEYRpFebqm3O/T4pA=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=rwfQ557ZUj7eZjw4G87WeSUY2fggiAXtUZa5TuGUD/lAYmVD7mRABsRKH7wnROWiN\n\t4rSqf4qRyiDmG8qGUcNEF+RB/Tw3tTeEeDDtp4yVuQetZs6OqSkgrZwe9Jb7nbmUin\n\tiWXKm3RWI0BOaIaEvX0P9m62YsL0R/gcQkFuplKHajhlvNmpIBv25YAbjgOOZxkS8O\n\tLU68ODltoePnQmN9jNgFW8eel0SDb4C7HKLycOwl9dtWR5TauZAfONZ2BFkVu4VQ0w\n\tT/0A8g9/7PhrGP46RnhbXMxaMs0qZSW1QpwT93e9Pt4EZZvVU1c9W+Sq7X+7Af++5c\n\tbMtx7CZUta4/g==",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1666569877;\n\tbh=YTaYpDITiY7M40evmlcVErHC0HbEYRpFebqm3O/T4pA=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=ZpXxCQeFfA8KfdOxF3X7IxPrRRvrBjdctW9p0ItO+mAzQ5UKD+yStXwEaVhjpQrlF\n\tnWi71kzEKqvoewV5t1gZ25zV1VBpQMd/8aSIQPDW5F88YhuGL84jxjqJYF1qcxGkUK\n\tpNVbwGu/Tzr+z1kjdTcyoDPZDIY+GsNU8lscPmpI="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"ZpXxCQeF\"; dkim-atps=neutral",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 24 Oct 2022 03:03:55 +0300",
        "Message-Id": "<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.37.4",
        "In-Reply-To": "<20221024000356.29521-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20221024000356.29521-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support raw\n\tBayer capture at runtime",
        "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>",
        "From": "Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "From: Florian Sylvestre <fsylvestre@baylibre.com>\n\nImplement support for raw Bayer capture at runtime, from start() to\nstop(). Support of raw formats in the camera configuration is split to a\nsubsequent change to ease review.\n\nIn raw mode, the ISP is bypassed. There is no need to provide parameter\nbuffers, and the ISP will not generate statistics. This requires\nmultiple changes in the buffer handling:\n\n- The params and stats buffers don't need to be allocated, and the\n  corresponding video nodes don't need to be started or stopped.\n\n- The IPA module fillParamsBuffer() operation must not be called in\n  queueRequestDevice(). As a result, the IPA module thus doesn't emit\n  the paramsBufferReady signal. The main and self path video buffers\n  must thus be queued directly in queueRequestDevice().\n\n- The tryCompleteRequest() function must not to wait until the params\n  buffer has been dequeued.\n\n- When the frame buffer has been captured, the IPA module\n  processStatsBuffer() operation must be called directly to fill request\n  metadata.\n\nSigned-off-by: Florian Sylvestre <fsylvestre@baylibre.com>\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v3:\n\n- Split from \"pipeline: rkisp1: Support raw Bayer capture\"\n- Drop new completeRaw() IPA operation\n- Don't queue params buffers in raw capture mode\n- Fix assertion failure when stopping capture\n---\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 148 ++++++++++++++---------\n 1 file changed, 93 insertions(+), 55 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex dcab5286aa56..e57411544f7a 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -67,7 +67,8 @@ class RkISP1Frames\n public:\n \tRkISP1Frames(PipelineHandler *pipe);\n \n-\tRkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request);\n+\tRkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request,\n+\t\t\t\tbool isRaw);\n \tint destroy(unsigned int frame);\n \tvoid clear();\n \n@@ -184,6 +185,7 @@ private:\n \tstd::unique_ptr<V4L2Subdevice> csi_;\n \n \tbool hasSelfPath_;\n+\tbool isRaw_;\n \n \tRkISP1MainPath mainPath_;\n \tRkISP1SelfPath selfPath_;\n@@ -203,28 +205,35 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)\n {\n }\n \n-RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request)\n+RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request,\n+\t\t\t\t      bool isRaw)\n {\n \tunsigned int frame = data->frame_;\n \n-\tif (pipe_->availableParamBuffers_.empty()) {\n-\t\tLOG(RkISP1, Error) << \"Parameters buffer underrun\";\n-\t\treturn nullptr;\n-\t}\n-\tFrameBuffer *paramBuffer = pipe_->availableParamBuffers_.front();\n+\tFrameBuffer *paramBuffer = nullptr;\n+\tFrameBuffer *statBuffer = nullptr;\n+\n+\tif (!isRaw) {\n+\t\tif (pipe_->availableParamBuffers_.empty()) {\n+\t\t\tLOG(RkISP1, Error) << \"Parameters buffer underrun\";\n+\t\t\treturn nullptr;\n+\t\t}\n+\n+\t\tif (pipe_->availableStatBuffers_.empty()) {\n+\t\t\tLOG(RkISP1, Error) << \"Statisitc buffer underrun\";\n+\t\t\treturn nullptr;\n+\t\t}\n+\n+\t\tparamBuffer = pipe_->availableParamBuffers_.front();\n+\t\tpipe_->availableParamBuffers_.pop();\n \n-\tif (pipe_->availableStatBuffers_.empty()) {\n-\t\tLOG(RkISP1, Error) << \"Statisitc buffer underrun\";\n-\t\treturn nullptr;\n+\t\tstatBuffer = pipe_->availableStatBuffers_.front();\n+\t\tpipe_->availableStatBuffers_.pop();\n \t}\n-\tFrameBuffer *statBuffer = pipe_->availableStatBuffers_.front();\n \n \tFrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_);\n \tFrameBuffer *selfPathBuffer = request->findBuffer(&data->selfPathStream_);\n \n-\tpipe_->availableParamBuffers_.pop();\n-\tpipe_->availableStatBuffers_.pop();\n-\n \tRkISP1FrameInfo *info = new RkISP1FrameInfo;\n \n \tinfo->frame = frame;\n@@ -665,6 +674,8 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)\n \t\t<< \"ISP input pad configured with \" << format\n \t\t<< \" crop \" << rect;\n \n+\tisRaw_ = false;\n+\n \t/* YUYV8_2X8 is required on the ISP source path pad for YUV output. */\n \tformat.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8;\n \tLOG(RkISP1, Debug)\n@@ -760,13 +771,15 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n \t\tdata->selfPathStream_.configuration().bufferCount,\n \t});\n \n-\tret = param_->allocateBuffers(maxCount, &paramBuffers_);\n-\tif (ret < 0)\n-\t\tgoto error;\n+\tif (!isRaw_) {\n+\t\tret = param_->allocateBuffers(maxCount, &paramBuffers_);\n+\t\tif (ret < 0)\n+\t\t\tgoto error;\n \n-\tret = stat_->allocateBuffers(maxCount, &statBuffers_);\n-\tif (ret < 0)\n-\t\tgoto error;\n+\t\tret = stat_->allocateBuffers(maxCount, &statBuffers_);\n+\t\tif (ret < 0)\n+\t\t\tgoto error;\n+\t}\n \n \tfor (std::unique_ptr<FrameBuffer> &buffer : paramBuffers_) {\n \t\tbuffer->setCookie(ipaBufferId++);\n@@ -842,23 +855,25 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n \n \tdata->frame_ = 0;\n \n-\tret = param_->streamOn();\n-\tif (ret) {\n-\t\tdata->ipa_->stop();\n-\t\tfreeBuffers(camera);\n-\t\tLOG(RkISP1, Error)\n-\t\t\t<< \"Failed to start parameters \" << camera->id();\n-\t\treturn ret;\n-\t}\n+\tif (!isRaw_) {\n+\t\tret = param_->streamOn();\n+\t\tif (ret) {\n+\t\t\tdata->ipa_->stop();\n+\t\t\tfreeBuffers(camera);\n+\t\t\tLOG(RkISP1, Error)\n+\t\t\t\t<< \"Failed to start parameters \" << camera->id();\n+\t\t\treturn ret;\n+\t\t}\n \n-\tret = stat_->streamOn();\n-\tif (ret) {\n-\t\tparam_->streamOff();\n-\t\tdata->ipa_->stop();\n-\t\tfreeBuffers(camera);\n-\t\tLOG(RkISP1, Error)\n-\t\t\t<< \"Failed to start statistics \" << camera->id();\n-\t\treturn ret;\n+\t\tret = stat_->streamOn();\n+\t\tif (ret) {\n+\t\t\tparam_->streamOff();\n+\t\t\tdata->ipa_->stop();\n+\t\t\tfreeBuffers(camera);\n+\t\t\tLOG(RkISP1, Error)\n+\t\t\t\t<< \"Failed to start statistics \" << camera->id();\n+\t\t\treturn ret;\n+\t\t}\n \t}\n \n \tif (data->mainPath_->isEnabled()) {\n@@ -903,15 +918,17 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)\n \t\tselfPath_.stop();\n \tmainPath_.stop();\n \n-\tret = stat_->streamOff();\n-\tif (ret)\n-\t\tLOG(RkISP1, Warning)\n-\t\t\t<< \"Failed to stop statistics for \" << camera->id();\n+\tif (!isRaw_) {\n+\t\tret = stat_->streamOff();\n+\t\tif (ret)\n+\t\t\tLOG(RkISP1, Warning)\n+\t\t\t\t<< \"Failed to stop statistics for \" << camera->id();\n \n-\tret = param_->streamOff();\n-\tif (ret)\n-\t\tLOG(RkISP1, Warning)\n-\t\t\t<< \"Failed to stop parameters for \" << camera->id();\n+\t\tret = param_->streamOff();\n+\t\tif (ret)\n+\t\t\tLOG(RkISP1, Warning)\n+\t\t\t\t<< \"Failed to stop parameters for \" << camera->id();\n+\t}\n \n \tASSERT(data->queuedRequests_.empty());\n \tdata->frameInfo_.clear();\n@@ -925,12 +942,21 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)\n {\n \tRkISP1CameraData *data = cameraData(camera);\n \n-\tRkISP1FrameInfo *info = data->frameInfo_.create(data, request);\n+\tRkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_);\n \tif (!info)\n \t\treturn -ENOENT;\n \n \tdata->ipa_->queueRequest(data->frame_, request->controls());\n-\tdata->ipa_->fillParamsBuffer(data->frame_, info->paramBuffer->cookie());\n+\tif (isRaw_) {\n+\t\tif (info->mainPathBuffer)\n+\t\t\tdata->mainPath_->queueBuffer(info->mainPathBuffer);\n+\n+\t\tif (data->selfPath_ && info->selfPathBuffer)\n+\t\t\tdata->selfPath_->queueBuffer(info->selfPathBuffer);\n+\t} else {\n+\t\tdata->ipa_->fillParamsBuffer(data->frame_,\n+\t\t\t\t\t     info->paramBuffer->cookie());\n+\t}\n \n \tdata->frame_++;\n \n@@ -1135,7 +1161,7 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info)\n \tif (!info->metadataProcessed)\n \t\treturn;\n \n-\tif (!info->paramDequeued)\n+\tif (!isRaw_ && !info->paramDequeued)\n \t\treturn;\n \n \tdata->frameInfo_.destroy(info->frame);\n@@ -1152,16 +1178,28 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)\n \tif (!info)\n \t\treturn;\n \n+\tconst FrameMetadata &metadata = buffer->metadata();\n \tRequest *request = buffer->request();\n \n-\t/*\n-\t * Record the sensor's timestamp in the request metadata.\n-\t *\n-\t * \\todo The sensor timestamp should be better estimated by connecting\n-\t * to the V4L2Device::frameStart signal.\n-\t */\n-\trequest->metadata().set(controls::SensorTimestamp,\n-\t\t\t\tbuffer->metadata().timestamp);\n+\tif (metadata.status != FrameMetadata::FrameCancelled) {\n+\t\t/*\n+\t\t * Record the sensor's timestamp in the request metadata.\n+\t\t *\n+\t\t * \\todo The sensor timestamp should be better estimated by connecting\n+\t\t * to the V4L2Device::frameStart signal.\n+\t\t */\n+\t\trequest->metadata().set(controls::SensorTimestamp,\n+\t\t\t\t\tmetadata.timestamp);\n+\n+\t\tif (isRaw_) {\n+\t\t\tconst ControlList &ctrls =\n+\t\t\t\tdata->delayedCtrls_->get(metadata.sequence);\n+\t\t\tdata->ipa_->processStatsBuffer(info->frame, 0, ctrls);\n+\t\t}\n+\t} else {\n+\t\tif (isRaw_)\n+\t\t\tinfo->metadataProcessed = true;\n+\t}\n \n \tcompleteBuffer(request, buffer);\n \ttryCompleteRequest(info);\n",
    "prefixes": [
        "libcamera-devel",
        "v3",
        "12/13"
    ]
}