[{"id":28654,"web_url":"https://patchwork.libcamera.org/comment/28654/","msgid":"<viwrjfk2tqxp3csfrmv4jjq2zlmcsllgq2ymwqhrxphbcpbmcl@qlqn6yj63kpn>","date":"2024-02-13T13:16:33","subject":"Re: [PATCH 5/5] libcamera: rkisp1: Remove RkISP1FrameInfo","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Dan\n\nOn Mon, Feb 12, 2024 at 03:35:32PM +0000, Daniel Scally wrote:\n> The RkISP1FrameInfo class existed to hold varying bits of info to\n> help guarantee that a Request is not completed until all of the\n> image buffers are returned to userspace and the metadata has been\n> filled by the IPA module. Now that we're no longer using it for\n> that function it can be removed.\n>\n> Remove the class and refactor its code out to the rest of the\n> Pipeline Handler.\n>\n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n\nThis is clearly missing something\n\n6015.846619 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 2073600/1036800\n[1:40:15.848820375] [297] ERROR RkISP1 rkisp1.cpp:973 Parameters buffer underrun\n\nIn particular, the parameters buffers, once completed never gets\ninserted back in the availableParamBuffers_ queue. This used to happen\nat RkISP1FrameInfo::destroy and we in a similar way as you do for the\nstat buffers\n\nThe following patch fixes it\n\n -------------------------------------------------------------------------------\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 4f3e4095c8f0..6381c23bbb4d 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -145,6 +145,7 @@ private:\n        void tryCompleteRequest(Request *request);\n        void bufferReady(FrameBuffer *buffer);\n        void statReady(FrameBuffer *buffer);\n+       void paramReady(FrameBuffer *buffer);\n        void frameStart(uint32_t sequence);\n\n        int allocateBuffers(Camera *camera);\n@@ -167,6 +168,7 @@ private:\n        std::queue<FrameBuffer *> availableParamBuffers_;\n        std::queue<FrameBuffer *> availableStatBuffers_;\n        std::map<int, FrameBuffer *> inFlightStatBuffers_;\n+       std::map<int, FrameBuffer *> inFlightParamBuffers_;\n\n        Camera *activeCamera_;\n\n@@ -976,6 +978,7 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)\n\n                paramBuffer = availableParamBuffers_.front();\n                availableParamBuffers_.pop();\n+               inFlightParamBuffers_[request->sequence()] = paramBuffer;\n                paramBuffer->_d()->setRequest(request);\n        }\n\n@@ -1178,6 +1181,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)\n        if (hasSelfPath_)\n                selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);\n        stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);\n+       param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);\n\n        /*\n         * Enumerate all sensors connected to the ISP and create one\n@@ -1205,6 +1209,10 @@ void PipelineHandlerRkISP1::tryCompleteRequest(Request *request)\n            inFlightStatBuffers_.end())\n                return;\n\n+       if (inFlightParamBuffers_.find(request->sequence()) !=\n+           inFlightParamBuffers_.end())\n+               return;\n+\n        completeRequest(request);\n }\n\n@@ -1243,7 +1251,6 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)\n        RkISP1CameraData *data = cameraData(activeCamera_);\n        Request *request = buffer->request();\n\n-\n        if (buffer->metadata().status == FrameMetadata::FrameCancelled) {\n                inFlightStatBuffers_.erase(request->sequence());\n                availableStatBuffers_.push(buffer);\n@@ -1255,6 +1262,16 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)\n                                       data->delayedCtrls_->get(request->sequence()));\n }\n\n+void PipelineHandlerRkISP1::paramReady(FrameBuffer *buffer)\n+{\n+       ASSERT(activeCamera_);\n+       Request *request = buffer->request();\n+\n+       inFlightParamBuffers_.erase(request->sequence());\n+       availableParamBuffers_.push(buffer);\n+       tryCompleteRequest(request);\n+}\n+\n REGISTER_PIPELINE_HANDLER(PipelineHandlerRkISP1)\n\n } /* namespace libcamera */\n -------------------------------------------------------------------------------\n\nI'm noticing a slower startup of the agc algorithm with this patch. I\ncan't tell why yet or if it's due to other issues with my testing\nsetup. How have you validated the series ?\n\nAnyway, I think this is a good first step to remove RkISP1FramesInfo (as\nwell as IPU3FramesInfo) but we shouldn't be stopping here.\n\nNow that we have the ability to easily creare ::Private subclasses for\napplication facing classes, I would like to experiment with the\ncreation of a per-pipeline Request::Private class, which should serve\nthe same purpose as RkISP1FramesInfo and IPU3FramesInfo did and save\nsome boilerplate code for pipeline handlers\n\nEven if the net total of code lines added/removed by this series is\nnegative (\\o/) there still is quite some manual work in keeping track\nof the inFlighStat/Params buffer and a few more code patterns that\nwill end up being replicated by all pipelines handlers (reversing the\nassociation between a buffer id and a request, in example).\n\nI'll have a look, basing my work on this series, once you confirm you\ndon't see visual differences in the algorithm's behaviour.\n\nThanks\n  j\n\n> ---\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 252 +++++------------------\n>  1 file changed, 46 insertions(+), 206 deletions(-)\n>\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index d8f27e96..f6dfd1cb 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -52,44 +52,13 @@ LOG_DEFINE_CATEGORY(RkISP1)\n>  class PipelineHandlerRkISP1;\n>  class RkISP1CameraData;\n>\n> -struct RkISP1FrameInfo {\n> -\tunsigned int frame;\n> -\tRequest *request;\n> -\n> -\tFrameBuffer *paramBuffer;\n> -\tFrameBuffer *statBuffer;\n> -\tFrameBuffer *mainPathBuffer;\n> -\tFrameBuffer *selfPathBuffer;\n> -\n> -\tbool metadataProcessed;\n> -};\n> -\n> -class RkISP1Frames\n> -{\n> -public:\n> -\tRkISP1Frames(PipelineHandler *pipe);\n> -\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> -\tRkISP1FrameInfo *find(unsigned int frame);\n> -\tRkISP1FrameInfo *find(FrameBuffer *buffer);\n> -\tRkISP1FrameInfo *find(Request *request);\n> -\n> -private:\n> -\tPipelineHandlerRkISP1 *pipe_;\n> -\tstd::map<unsigned int, RkISP1FrameInfo *> frameInfo_;\n> -};\n> -\n>  class RkISP1CameraData : public Camera::Private\n>  {\n>  public:\n>  \tRkISP1CameraData(PipelineHandler *pipe, RkISP1MainPath *mainPath,\n>  \t\t\t RkISP1SelfPath *selfPath)\n> -\t\t: Camera::Private(pipe), frameInfo_(pipe),\n> -\t\t  mainPath_(mainPath), selfPath_(selfPath)\n> +\t\t: Camera::Private(pipe), mainPath_(mainPath),\n> +\t\t  selfPath_(selfPath)\n>  \t{\n>  \t}\n>\n> @@ -101,7 +70,6 @@ public:\n>  \tstd::unique_ptr<CameraSensor> sensor_;\n>  \tstd::unique_ptr<DelayedControls> delayedCtrls_;\n>  \tstd::vector<IPABuffer> ipaBuffers_;\n> -\tRkISP1Frames frameInfo_;\n>\n>  \tRkISP1MainPath *mainPath_;\n>  \tRkISP1SelfPath *selfPath_;\n> @@ -169,7 +137,6 @@ private:\n>  \t}\n>\n>  \tfriend RkISP1CameraData;\n> -\tfriend RkISP1Frames;\n>\n>  \tint initLinks(Camera *camera, const CameraSensor *sensor,\n>  \t\t      const RkISP1CameraConfiguration &config);\n> @@ -205,130 +172,6 @@ private:\n>  \tconst MediaPad *ispSink_;\n>  };\n>\n> -RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)\n> -\t: pipe_(static_cast<PipelineHandlerRkISP1 *>(pipe))\n> -{\n> -}\n> -\n> -RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request,\n> -\t\t\t\t      bool isRaw)\n> -{\n> -\tunsigned int frame = request->sequence();\n> -\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) << \"Statistic buffer underrun\";\n> -\t\t\treturn nullptr;\n> -\t\t}\n> -\n> -\t\tparamBuffer = pipe_->availableParamBuffers_.front();\n> -\t\tpipe_->availableParamBuffers_.pop();\n> -\t\tparamBuffer->_d()->setRequest(request);\n> -\n> -\t\tstatBuffer = pipe_->availableStatBuffers_.front();\n> -\t\tpipe_->availableStatBuffers_.pop();\n> -\t\tstatBuffer->_d()->setRequest(request);\n> -\t}\n> -\n> -\tFrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_);\n> -\tFrameBuffer *selfPathBuffer = request->findBuffer(&data->selfPathStream_);\n> -\n> -\tRkISP1FrameInfo *info = new RkISP1FrameInfo;\n> -\n> -\tinfo->frame = frame;\n> -\tinfo->request = request;\n> -\tinfo->paramBuffer = paramBuffer;\n> -\tinfo->mainPathBuffer = mainPathBuffer;\n> -\tinfo->selfPathBuffer = selfPathBuffer;\n> -\tinfo->statBuffer = statBuffer;\n> -\tinfo->metadataProcessed = false;\n> -\n> -\tframeInfo_[frame] = info;\n> -\n> -\treturn info;\n> -}\n> -\n> -int RkISP1Frames::destroy(unsigned int frame)\n> -{\n> -\tRkISP1FrameInfo *info = find(frame);\n> -\tif (!info)\n> -\t\treturn -ENOENT;\n> -\n> -\tpipe_->availableParamBuffers_.push(info->paramBuffer);\n> -\tpipe_->availableStatBuffers_.push(info->statBuffer);\n> -\n> -\tframeInfo_.erase(info->frame);\n> -\n> -\tdelete info;\n> -\n> -\treturn 0;\n> -}\n> -\n> -void RkISP1Frames::clear()\n> -{\n> -\tfor (const auto &entry : frameInfo_) {\n> -\t\tRkISP1FrameInfo *info = entry.second;\n> -\n> -\t\tpipe_->availableParamBuffers_.push(info->paramBuffer);\n> -\t\tpipe_->availableStatBuffers_.push(info->statBuffer);\n> -\n> -\t\tdelete info;\n> -\t}\n> -\n> -\tframeInfo_.clear();\n> -}\n> -\n> -RkISP1FrameInfo *RkISP1Frames::find(unsigned int frame)\n> -{\n> -\tauto itInfo = frameInfo_.find(frame);\n> -\n> -\tif (itInfo != frameInfo_.end())\n> -\t\treturn itInfo->second;\n> -\n> -\tLOG(RkISP1, Fatal) << \"Can't locate info from frame\";\n> -\n> -\treturn nullptr;\n> -}\n> -\n> -RkISP1FrameInfo *RkISP1Frames::find(FrameBuffer *buffer)\n> -{\n> -\tfor (auto &itInfo : frameInfo_) {\n> -\t\tRkISP1FrameInfo *info = itInfo.second;\n> -\n> -\t\tif (info->paramBuffer == buffer ||\n> -\t\t    info->statBuffer == buffer ||\n> -\t\t    info->mainPathBuffer == buffer ||\n> -\t\t    info->selfPathBuffer == buffer)\n> -\t\t\treturn info;\n> -\t}\n> -\n> -\tLOG(RkISP1, Fatal) << \"Can't locate info from buffer\";\n> -\n> -\treturn nullptr;\n> -}\n> -\n> -RkISP1FrameInfo *RkISP1Frames::find(Request *request)\n> -{\n> -\tfor (auto &itInfo : frameInfo_) {\n> -\t\tRkISP1FrameInfo *info = itInfo.second;\n> -\n> -\t\tif (info->request == request)\n> -\t\t\treturn info;\n> -\t}\n> -\n> -\tLOG(RkISP1, Fatal) << \"Can't locate info from request\";\n> -\n> -\treturn nullptr;\n> -}\n> -\n>  PipelineHandlerRkISP1 *RkISP1CameraData::pipe()\n>  {\n>  \treturn static_cast<PipelineHandlerRkISP1 *>(Camera::Private::pipe());\n> @@ -387,20 +230,30 @@ void RkISP1CameraData::paramFilled(unsigned int bufferId)\n>  \t\tif (paramBuffer->cookie() != bufferId)\n>  \t\t\tcontinue;\n>\n> -\t\tRkISP1FrameInfo *info = frameInfo_.find(paramBuffer.get());\n> -\t\tif (!info)\n> +\t\tRequest *request = paramBuffer->request();\n> +\t\tFrameBuffer *mainPathBuffer = request->findBuffer(&mainPathStream_);\n> +\t\tFrameBuffer *selfPathBuffer = request->findBuffer(&selfPathStream_);\n> +\n> +\t\tif (pipe->availableStatBuffers_.empty()) {\n> +\t\t\tLOG(RkISP1, Fatal) << \"Parameters buffer underrun\";\n>  \t\t\treturn;\n> +\t\t}\n> +\n> +\t\tFrameBuffer *statBuffer = pipe->availableStatBuffers_.front();\n> +\t\tpipe->availableStatBuffers_.pop();\n> +\t\tpipe->inFlightStatBuffers_[request->sequence()] = statBuffer;\n> +\t\tstatBuffer->_d()->setRequest(request);\n>\n> -\t\tinfo->paramBuffer->_d()->metadata().planes()[0].bytesused =\n> +\t\tparamBuffer->_d()->metadata().planes()[0].bytesused =\n>  \t\t\tsizeof(struct rkisp1_params_cfg);\n> -\t\tpipe->param_->queueBuffer(info->paramBuffer);\n> -\t\tpipe->stat_->queueBuffer(info->statBuffer);\n> +\t\tpipe->param_->queueBuffer(paramBuffer.get());\n> +\t\tpipe->stat_->queueBuffer(statBuffer);\n>\n> -\t\tif (info->mainPathBuffer)\n> -\t\t\tmainPath_->queueBuffer(info->mainPathBuffer);\n> +\t\tif (mainPathBuffer)\n> +\t\t\tmainPath_->queueBuffer(mainPathBuffer);\n>\n> -\t\tif (selfPath_ && info->selfPathBuffer)\n> -\t\t\tselfPath_->queueBuffer(info->selfPathBuffer);\n> +\t\tif (selfPath_ && selfPathBuffer)\n> +\t\t\tselfPath_->queueBuffer(selfPathBuffer);\n>\n>  \t\treturn;\n>  \t}\n> @@ -422,15 +275,13 @@ void RkISP1CameraData::metadataReady(unsigned int bufferId,\n>  \t\tif (statBuffer->cookie() != bufferId)\n>  \t\t\tcontinue;\n>\n> -\t\tRkISP1FrameInfo *info = frameInfo_.find(statBuffer.get());\n> -\t\tif (!info)\n> -\t\t\treturn;\n> +\t\tRequest *request = statBuffer->request();\n>\n> -\t\tinfo->request->metadata().merge(metadata);\n> -\t\tinfo->metadataProcessed = true;\n> -\t\tpipe()->inFlightStatBuffers_.erase(info->request->sequence());\n> +\t\trequest->metadata().merge(metadata);\n> +\t\tpipe()->inFlightStatBuffers_.erase(request->sequence());\n> +\t\tpipe()->availableStatBuffers_.push(statBuffer.get());\n> +\t\tpipe()->tryCompleteRequest(request);\n>\n> -\t\tpipe()->tryCompleteRequest(statBuffer->request());\n>  \t\treturn;\n>  \t}\n>\n> @@ -1033,7 +884,6 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)\n>  \t}\n>\n>  \tASSERT(data->queuedRequests_.empty());\n> -\tdata->frameInfo_.clear();\n>\n>  \tfreeBuffers(camera);\n>\n> @@ -1043,23 +893,32 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)\n>  int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)\n>  {\n>  \tRkISP1CameraData *data = cameraData(camera);\n> +\tFrameBuffer *paramBuffer = nullptr;\n>\n> -\tRkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_);\n> -\tif (!info)\n> -\t\treturn -ENOENT;\n> +\tif (!isRaw_) {\n> +\t\tif (availableParamBuffers_.empty()) {\n> +\t\t\tLOG(RkISP1, Error) << \"Parameters buffer underrun\";\n> +\t\t\treturn -ENOENT;\n> +\t\t}\n>\n> -\tinFlightStatBuffers_[request->sequence()] = info->statBuffer;\n> +\t\tparamBuffer = availableParamBuffers_.front();\n> +\t\tavailableParamBuffers_.pop();\n> +\t\tparamBuffer->_d()->setRequest(request);\n> +\t}\n>\n>  \tdata->ipa_->queueRequest(request->sequence(), request->controls());\n>  \tif (isRaw_) {\n> -\t\tif (info->mainPathBuffer)\n> -\t\t\tdata->mainPath_->queueBuffer(info->mainPathBuffer);\n> +\t\tFrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_);\n> +\t\tFrameBuffer *selfPathBuffer = request->findBuffer(&data->selfPathStream_);\n> +\n> +\t\tif (mainPathBuffer)\n> +\t\t\tdata->mainPath_->queueBuffer(mainPathBuffer);\n>\n> -\t\tif (data->selfPath_ && info->selfPathBuffer)\n> -\t\t\tdata->selfPath_->queueBuffer(info->selfPathBuffer);\n> +\t\tif (data->selfPath_ && selfPathBuffer)\n> +\t\t\tdata->selfPath_->queueBuffer(selfPathBuffer);\n>  \t} else {\n>  \t\tdata->ipa_->fillParamsBuffer(request->sequence(),\n> -\t\t\t\t\t     info->paramBuffer->cookie());\n> +\t\t\t\t\t     paramBuffer->cookie());\n>  \t}\n>\n>  \treturn 0;\n> @@ -1253,12 +1112,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)\n>\n>  void PipelineHandlerRkISP1::tryCompleteRequest(Request *request)\n>  {\n> -\tRkISP1CameraData *data = cameraData(activeCamera_);\n> -\n> -\tRkISP1FrameInfo *info = data->frameInfo_.find(request);\n> -\tif (!info)\n> -\t\treturn;\n> -\n>  \tif (request->hasPendingBuffers())\n>  \t\treturn;\n>\n> @@ -1266,8 +1119,6 @@ void PipelineHandlerRkISP1::tryCompleteRequest(Request *request)\n>  \t    inFlightStatBuffers_.end())\n>  \t\treturn;\n>\n> -\tdata->frameInfo_.destroy(info->frame);\n> -\n>  \tcompleteRequest(request);\n>  }\n>\n> @@ -1275,11 +1126,6 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)\n>  {\n>  \tASSERT(activeCamera_);\n>  \tRkISP1CameraData *data = cameraData(activeCamera_);\n> -\n> -\tRkISP1FrameInfo *info = data->frameInfo_.find(buffer);\n> -\tif (!info)\n> -\t\treturn;\n> -\n>  \tconst FrameMetadata &metadata = buffer->metadata();\n>  \tRequest *request = buffer->request();\n>\n> @@ -1299,9 +1145,6 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)\n>  \t\t\tdata->ipa_->processStatsBuffer(request->sequence(),\n>  \t\t\t\t\t\t       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> @@ -1314,18 +1157,15 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)\n>  \tRkISP1CameraData *data = cameraData(activeCamera_);\n>  \tRequest *request = buffer->request();\n>\n> -\tRkISP1FrameInfo *info = data->frameInfo_.find(buffer);\n> -\tif (!info)\n> -\t\treturn;\n>\n>  \tif (buffer->metadata().status == FrameMetadata::FrameCancelled) {\n> -\t\tinfo->metadataProcessed = true;\n>  \t\tinFlightStatBuffers_.erase(request->sequence());\n> +\t\tavailableStatBuffers_.push(buffer);\n>  \t\ttryCompleteRequest(request);\n>  \t\treturn;\n>  \t}\n>\n> -\tdata->ipa_->processStatsBuffer(request->sequence(), info->statBuffer->cookie(),\n> +\tdata->ipa_->processStatsBuffer(request->sequence(), buffer->cookie(),\n>  \t\t\t\t       data->delayedCtrls_->get(request->sequence()));\n>  }\n>\n> --\n> 2.34.1\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 AF642BDE17\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 13 Feb 2024 13:16:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 11ADF62801;\n\tTue, 13 Feb 2024 14:16:38 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A4E661CB8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 13 Feb 2024 14:16:36 +0100 (CET)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AF1FB83F;\n\tTue, 13 Feb 2024 14:16:33 +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=\"e2tYywpQ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1707830193;\n\tbh=fOCbSKOvzvqQbjz7ul1wcAppxrVWot4cyZyEvr7t7Eo=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=e2tYywpQwM8M1Wti+aGtHYDXKrSlOFJU29h20deZ2h2uJdS1as/NycgqpeM1MJviH\n\tM/codsWY28IQJqaKY2QP+ICzE574UzvBINxRhQGaYWgsjnhj2hzFl5ABG/JaII6Fyl\n\t2Azx1bPBCl6PgLdocrAHNU0YGgNMIINZEeUgHxnU=","Date":"Tue, 13 Feb 2024 14:16:33 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>","Subject":"Re: [PATCH 5/5] libcamera: rkisp1: Remove RkISP1FrameInfo","Message-ID":"<viwrjfk2tqxp3csfrmv4jjq2zlmcsllgq2ymwqhrxphbcpbmcl@qlqn6yj63kpn>","References":"<20240212153532.179283-1-dan.scally@ideasonboard.com>\n\t<20240212153532.179283-6-dan.scally@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20240212153532.179283-6-dan.scally@ideasonboard.com>","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":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]