[{"id":25536,"web_url":"https://patchwork.libcamera.org/comment/25536/","msgid":"<20221024092255.GF3874866@pyrite.rasen.tech>","date":"2022-10-24T09:22:55","subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer capture at runtime","submitter":{"id":97,"url":"https://patchwork.libcamera.org/api/people/97/","name":"Nicolas Dufresne via libcamera-devel","email":"libcamera-devel@lists.libcamera.org"},"content":"On Mon, Oct 24, 2022 at 03:03:55AM +0300, Laurent Pinchart wrote:\n> From: Florian Sylvestre <fsylvestre@baylibre.com>\n> \n> Implement support for raw Bayer capture at runtime, from start() to\n> stop(). Support of raw formats in the camera configuration is split to a\n> subsequent change to ease review.\n> \n> In raw mode, the ISP is bypassed. There is no need to provide parameter\n> buffers, and the ISP will not generate statistics. This requires\n> multiple 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> \n> Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com>\n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n> Changes 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(-)\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 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> -- \n> Regards,\n> \n> Laurent Pinchart\n>","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 4227CBDB16\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Oct 2022 09:23:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8F77C62F00;\n\tMon, 24 Oct 2022 11:23:05 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D5ECC61F4D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Oct 2022 11:23:03 +0200 (CEST)","from pyrite.rasen.tech (h175-177-042-159.catv02.itscom.jp\n\t[175.177.42.159])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D569C471;\n\tMon, 24 Oct 2022 11:23:01 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1666603385;\n\tbh=66Q2oHdIfUY2/6qkvibCoSzT8SOMv3NhGCO3e0hSCXg=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=iDdvZYyXNnphbiaww/92G5vt3UpSMgO6rIDgCFMVuC1EfhehL0mJ0tecCU5Ai1zrg\n\ttrLyq+3qtOJws4LQYsp6SSH0OtQtjQ3WHyDqR6xgWmAq+zii07zzzNoXfUcdHJh3U4\n\tbon9YNsEu/4me7TivJCwbhjzrtB1C5qkLSgU1zbNZMbRV4tX3REEGUX8jJxmtAlIfh\n\tWVlk1zxAhurwoxQUClyiO/tcTPLTZ+nZxHFBukNAfxD6rVPRjK/276rqMHhbZwXhAD\n\t79ieS5LN5zNYkTGQYnD/Yr95oVcPshzt9bRZASwQAhUKI7B4o4BDoPgoUww49EVtw8\n\tQS8CNANK7mH7g==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1666603383;\n\tbh=66Q2oHdIfUY2/6qkvibCoSzT8SOMv3NhGCO3e0hSCXg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=h+grKUrn0Y+mMP6szUSaHvwXmUFaEYv6SUMK8Z0QDJd4mncCB5c4TLZ88J9snvc3j\n\tqjc4syJo/G8zLqqPJkP2J/nT7SRYc6pLXl+h8zmGsmz2GrgPzz5anRQR4cUUXTZOyc\n\tZjqkrnEsKqqXUvrIt2ESMZzA4dcYOAoCWZLVz7jQ="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"h+grKUrn\"; dkim-atps=neutral","Date":"Mon, 24 Oct 2022 18:22:55 +0900","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20221024092255.GF3874866@pyrite.rasen.tech>","References":"<20221024000356.29521-1-laurent.pinchart@ideasonboard.com>\n\t<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer 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":"Paul Elder via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"paul.elder@ideasonboard.com","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25612,"web_url":"https://patchwork.libcamera.org/comment/25612/","msgid":"<20221026165804.upj2v4h4rpdf23md@uno.localdomain>","date":"2022-10-26T16:58:04","subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer capture at runtime","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nfirst of all I've been testing this as well and it works, I can\ncapture raw images and they look correct, without any noticeable regression\nin the other capture modes\n\nTested-by: Jacopo Mondi <jacopo@jmondi.org>\n\nOn Mon, Oct 24, 2022 at 03:03:55AM +0300, Laurent Pinchart via libcamera-devel wrote:\n> From: Florian Sylvestre <fsylvestre@baylibre.com>\n>\n> Implement support for raw Bayer capture at runtime, from start() to\n> stop(). Support of raw formats in the camera configuration is split to a\n> subsequent change to ease review.\n>\n> In raw mode, the ISP is bypassed. There is no need to provide parameter\n> buffers, and the ISP will not generate statistics. This requires\n> multiple 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>\n> Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com>\n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n> Changes 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(-)\n>\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 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\nWill a single variable global to the whole pipeline handler prevents\nany use case in future ?\n\nRight now I don't think it's an issue, but it might be nicer to have\nthis per-CameraData.\n\nHowever, in all the platforms we have, the ISP has a single input\nhence it's not possible to have different applications using multiple\ncameras at the same time, so this is not a real issue for now\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n\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> --\n> Regards,\n>\n> Laurent Pinchart\n>","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 83842BDB16\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 26 Oct 2022 16:58:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CCC8662F63;\n\tWed, 26 Oct 2022 18:58:07 +0200 (CEST)","from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net\n\t[IPv6:2001:4b98:dc4:8::222])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B97A261F4B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 26 Oct 2022 18:58:06 +0200 (CEST)","(Authenticated sender: jacopo@jmondi.org)\n\tby mail.gandi.net (Postfix) with ESMTPSA id 31E0840003;\n\tWed, 26 Oct 2022 16:58:06 +0000 (UTC)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1666803487;\n\tbh=1W6xlBv+DVjlTI9x0g7KmhZMeg34TmiFik7T6xA9mn0=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=xiHDiNkxe2cRZbIQ6AQLtj48EIvPUn5Kv4GdQw5i38Uosx9BYIXp6W0Ry9y2qH1tm\n\toOaMHqtHUjSPGnUmPO2ahV7RyS9IySd0JWEwhrNiE6OMGohSFcjrvD6vF/pg2icMW0\n\tHOvUBvuM1Wuxxjv+CtZkKChPY1afP8vn1cao0t0ch/S2sEqmYmdXcNdc4ro+MJRJZF\n\tivSJhA5Qyb1d6R+yjYpI2nY0AuR0MsY8W23HdBQLU+S0dQNl2ms/bBHIejGnBAugtN\n\tGHAOTxSH0J2fcFTEQKlZegYjlB9t+dLtmmimEnM5953kwQJRd7GxLUr6GTYqLDhSEa\n\toQ0CN6wKxLUcw==","Date":"Wed, 26 Oct 2022 18:58:04 +0200","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20221026165804.upj2v4h4rpdf23md@uno.localdomain>","References":"<20221024000356.29521-1-laurent.pinchart@ideasonboard.com>\n\t<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer 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":"Jacopo Mondi via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25687,"web_url":"https://patchwork.libcamera.org/comment/25687/","msgid":"<Y16z2HW+Oik5JsM2@pendragon.ideasonboard.com>","date":"2022-10-30T17:26:48","subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer capture at runtime","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Wed, Oct 26, 2022 at 06:58:04PM +0200, Jacopo Mondi wrote:\n> Hi Laurent,\n> \n> first of all I've been testing this as well and it works, I can\n> capture raw images and they look correct, without any noticeable regression\n> in the other capture modes\n> \n> Tested-by: Jacopo Mondi <jacopo@jmondi.org>\n> \n> On Mon, Oct 24, 2022 at 03:03:55AM +0300, Laurent Pinchart via libcamera-devel wrote:\n> > From: Florian Sylvestre <fsylvestre@baylibre.com>\n> >\n> > Implement support for raw Bayer capture at runtime, from start() to\n> > stop(). Support of raw formats in the camera configuration is split to a\n> > subsequent change to ease review.\n> >\n> > In raw mode, the ISP is bypassed. There is no need to provide parameter\n> > buffers, and the ISP will not generate statistics. This requires\n> > multiple 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> >\n> > Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com>\n> > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> > Changes 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(-)\n> >\n> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> > index 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> Will a single variable global to the whole pipeline handler prevents\n> any use case in future ?\n\nI don't think so, as we can't use multiple cameras concurrently;\n\n> Right now I don't think it's an issue, but it might be nicer to have\n> this per-CameraData.\n> \n> However, in all the platforms we have, the ISP has a single input\n> hence it's not possible to have different applications using multiple\n> cameras at the same time, so this is not a real issue for now\n\nEven with multiple inputs, there's a single ISP, it can only use one\nsensor at a time.\n\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\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);","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 F33CDBD16B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 30 Oct 2022 17:27:14 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6519663025;\n\tSun, 30 Oct 2022 18:27:14 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F2B2161F47\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 30 Oct 2022 18:27:12 +0100 (CET)","from pendragon.ideasonboard.com (85-76-13-148-nat.elisa-mobile.fi\n\t[85.76.13.148])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B8E622F5;\n\tSun, 30 Oct 2022 18:27:11 +0100 (CET)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1667150834;\n\tbh=MiaNX0uB4WTMIM68z8srEFWcLMVrdulGKyE23VBFS/I=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=D5bVqxR9kJfz8j8fKPTXxS4qcIJ9KfGGAkQTzqZv2cGxHkthKSa/e/Qlbm29TeA2w\n\t7nXD/2rvC4hdtMCxnBgxPC6PDqHfqtdQpXRkSR9x9BK0pm4ptXemBVxdSq47A90TLa\n\tjUjxwjES9KwPntfc8XQ6IKnX59tjaTknEeHBrQGUrvHXUQW8OUipK+MdJYZVWxPtdd\n\tizlKRi41ly5OT3h/gGk9PIcff0CPeEHwxJYiLUOdy4WKjkvqPh5ngbmcxy8nhR5oIM\n\tO/0CLC8SVw43e0u8QzA2oRAwCcghT0BYUatLywIeNzeJqeObx3RF5w74Jc4yVqZJcV\n\tUkPu22NamWebA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1667150832;\n\tbh=MiaNX0uB4WTMIM68z8srEFWcLMVrdulGKyE23VBFS/I=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PzPgfnYNNfvFvJs/RGtebNqN9mxOahE4bGHcK0XaMXwLO5SJM41G5xiFf1iibVTNX\n\t4xcPhnvHUDlxMTU3A/aEPDXJXh/1pQcKIfk6HPH8qqw8EHoGH+oVclrPUy+2gSo3eh\n\ttglUtjboRysrlay9YDQUYARS08F1zyBVjt9bDclE="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"PzPgfnYN\"; dkim-atps=neutral","Date":"Sun, 30 Oct 2022 19:26:48 +0200","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<Y16z2HW+Oik5JsM2@pendragon.ideasonboard.com>","References":"<20221024000356.29521-1-laurent.pinchart@ideasonboard.com>\n\t<20221024000356.29521-13-laurent.pinchart@ideasonboard.com>\n\t<20221026165804.upj2v4h4rpdf23md@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20221026165804.upj2v4h4rpdf23md@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH v3 12/13] pipeline: rkisp1: Support\n\traw Bayer 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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]