{"id":9421,"url":"https://patchwork.libcamera.org/api/1.1/patches/9421/?format=json","web_url":"https://patchwork.libcamera.org/patch/9421/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200828144110.17303-7-david.plowman@raspberrypi.com>","date":"2020-08-28T14:41:09","name":"[libcamera-devel,v4,6/7] libcamera: raspberrypi: Plumb user transform through to IPA","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"bfbee4f43b6a7a8b18f327f5ab6c6388b3f95587","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/1.1/people/42/?format=json","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/9421/mbox/","series":[{"id":1250,"url":"https://patchwork.libcamera.org/api/1.1/series/1250/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1250","date":"2020-08-28T14:41:03","name":"2D transforms","version":4,"mbox":"https://patchwork.libcamera.org/series/1250/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/9421/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/9421/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 68B14BF019\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 28 Aug 2020 14:41:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 30A3C62927;\n\tFri, 28 Aug 2020 16:41:25 +0200 (CEST)","from mail-wm1-x342.google.com (mail-wm1-x342.google.com\n\t[IPv6:2a00:1450:4864:20::342])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 49E0462922\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 28 Aug 2020 16:41:22 +0200 (CEST)","by mail-wm1-x342.google.com with SMTP id q9so1162826wmj.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 28 Aug 2020 07:41:22 -0700 (PDT)","from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\ts12sm2493724wmj.26.2020.08.28.07.41.20\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 28 Aug 2020 07:41:20 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"qUZNgImn\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=lUHJcrqZxYousXRKyn9ExX5bvnUtThtzvf+6uU/OEKI=;\n\tb=qUZNgImn+XbouHvmr2MVr25mEVZjtZKyspkpcSoRg7/JpKGzvY9CXjbMHxAotT6mze\n\tUve7aS5rYvzNBi0gE92ulV5q6tJNRtEUQoZBUhZbn8H+sjibnz9q30oo9s7BPiHbI88I\n\t1VXhVgF8mQDIaT75S3csQRMcIWuUb2CejlltoYYsnva177xDEpFJ3Rh1zzKS3Ek3IrCV\n\tVCi28GTP8bcRUC3N/+8KqM5ek70kaGfIhosR+8Wd1mLV8TVZGXwXrKeuGr/OYNYizvuo\n\tXX0mboFg6YalABqp6MYlDt1z+cnhEu+IHC20rRJQsX5OYrIFI+DrWfO2iP4r3MtUB58h\n\tqFFg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=lUHJcrqZxYousXRKyn9ExX5bvnUtThtzvf+6uU/OEKI=;\n\tb=VEn9460lc41RZsERaM8+r0+fMioT6jnEeELmQUOaIc1wfPDh6NDgSxdOsgs99ETs6c\n\tfODgtC/OKvBnjqBuEF80Nf5k+yVHfNehdCNlQ4WjM3EcP9mSK0WlfViD2PjAd7XBJdwi\n\tRJLuG5wx9QeWmvRYDdj4+EDWbPxcztMj3m+/9b6T7IDcM/xt8ExEGggSqICB0elsPKVJ\n\tNPaY6saR6T/36EoEQxTguYYCV9wjgVBI39KUHcL7HiNkX9/fucB6dv9/1UWjkhkYRq2H\n\t4a67y+NLKA83RVcvS9bSNl3NTb9qFC0Zt6oSlUMs3bCsrLd3XXRRGQ3QNP6w8pOKlKls\n\t4j1A==","X-Gm-Message-State":"AOAM530PyehknIdHvaksRu6VBZGIWJxR5pDjc5AGnaC9fDhrN1L8MCTZ\n\tHIdhkYXWWn1EKEscw/PCkBcBO0HwOklIrw==","X-Google-Smtp-Source":"ABdhPJxyrbLqyp1BeYsRx1+QDzToTIKqi8Xib5cQMIwhi7kelospPaczMkk1lUcIZKQ8B4GsFyyS4g==","X-Received":"by 2002:a1c:5f06:: with SMTP id t6mr1950945wmb.54.1598625681513; \n\tFri, 28 Aug 2020 07:41:21 -0700 (PDT)","From":"David Plowman <david.plowman@raspberrypi.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Fri, 28 Aug 2020 15:41:09 +0100","Message-Id":"<20200828144110.17303-7-david.plowman@raspberrypi.com>","X-Mailer":"git-send-email 2.20.1","In-Reply-To":"<20200828144110.17303-1-david.plowman@raspberrypi.com>","References":"<20200828144110.17303-1-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Subject":"[libcamera-devel] [PATCH v4 6/7] libcamera: raspberrypi: Plumb user\n\ttransform through to IPA","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>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"This commit plumbs the user transform from the Raspberry Pi pipeline\nhandler through to the IPA. Note that the transform is actually\nhandled in the sensor (by setting the h/v flip bits), so the IPAs need\nto understand the orientation of the image they receive.\n\nOnce in the IPA we add it to the CameraMode description, so that it\nbecomes automatically available to all the individual control\nalgorithms.\n\nThe IPA configure method has to be reordered just a little so as to\nfill in the transform in the camera mode before calling SwitchMode.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/ipa/raspberrypi/controller/camera_mode.h  |  4 ++\n src/ipa/raspberrypi/raspberrypi.cpp           | 48 +++++++++++--------\n .../pipeline/raspberrypi/raspberrypi.cpp      | 11 +++--\n 3 files changed, 38 insertions(+), 25 deletions(-)","diff":"diff --git a/src/ipa/raspberrypi/controller/camera_mode.h b/src/ipa/raspberrypi/controller/camera_mode.h\nindex 875bab3..920f11b 100644\n--- a/src/ipa/raspberrypi/controller/camera_mode.h\n+++ b/src/ipa/raspberrypi/controller/camera_mode.h\n@@ -6,6 +6,8 @@\n  */\n #pragma once\n \n+#include <libcamera/transform.h>\n+\n // Description of a \"camera mode\", holding enough information for control\n // algorithms to adapt their behaviour to the different modes of the camera,\n // including binning, scaling, cropping etc.\n@@ -33,6 +35,8 @@ struct CameraMode {\n \tdouble noise_factor;\n \t// line time in nanoseconds\n \tdouble line_length;\n+\t// any camera transform *not* reflected already in the camera tuning\n+\tlibcamera::Transform transform;\n };\n \n #ifdef __cplusplus\ndiff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\nindex 4557016..c730326 100644\n--- a/src/ipa/raspberrypi/raspberrypi.cpp\n+++ b/src/ipa/raspberrypi/raspberrypi.cpp\n@@ -232,6 +232,33 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,\n \t/* Re-assemble camera mode using the sensor info. */\n \tsetMode(sensorInfo);\n \n+\t/*\n+\t * The ipaConfig.data always gives us the user transform first. Note that\n+\t * this will always make the LS table pointer (if present) element 1.\n+\t */\n+\tmode_.transform = static_cast<libcamera::Transform>(ipaConfig.data[0]);\n+\n+\t/* Store the lens shading table pointer and handle if available. */\n+\tif (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) {\n+\t\t/* Remove any previous table, if there was one. */\n+\t\tif (lsTable_) {\n+\t\t\tmunmap(lsTable_, MAX_LS_GRID_SIZE);\n+\t\t\tlsTable_ = nullptr;\n+\t\t}\n+\n+\t\t/* Map the LS table buffer into user space (now element 1). */\n+\t\tlsTableHandle_ = FileDescriptor(ipaConfig.data[1]);\n+\t\tif (lsTableHandle_.isValid()) {\n+\t\t\tlsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE,\n+\t\t\t\t\tMAP_SHARED, lsTableHandle_.fd(), 0);\n+\n+\t\t\tif (lsTable_ == MAP_FAILED) {\n+\t\t\t\tLOG(IPARPI, Error) << \"dmaHeap mmap failure for LS table.\";\n+\t\t\t\tlsTable_ = nullptr;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n \t/* Pass the camera mode to the CamHelper to setup algorithms. */\n \thelper_->SetCameraMode(mode_);\n \n@@ -280,27 +307,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,\n \t}\n \n \tlastMode_ = mode_;\n-\n-\t/* Store the lens shading table pointer and handle if available. */\n-\tif (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) {\n-\t\t/* Remove any previous table, if there was one. */\n-\t\tif (lsTable_) {\n-\t\t\tmunmap(lsTable_, MAX_LS_GRID_SIZE);\n-\t\t\tlsTable_ = nullptr;\n-\t\t}\n-\n-\t\t/* Map the LS table buffer into user space. */\n-\t\tlsTableHandle_ = FileDescriptor(ipaConfig.data[0]);\n-\t\tif (lsTableHandle_.isValid()) {\n-\t\t\tlsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE,\n-\t\t\t\t\tMAP_SHARED, lsTableHandle_.fd(), 0);\n-\n-\t\t\tif (lsTable_ == MAP_FAILED) {\n-\t\t\t\tLOG(IPARPI, Error) << \"dmaHeap mmap failure for LS table.\";\n-\t\t\t\tlsTable_ = nullptr;\n-\t\t\t}\n-\t\t}\n-\t}\n }\n \n void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)\ndiff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex 6ea1432..8d8e249 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -294,7 +294,7 @@ public:\n \tvoid frameStarted(uint32_t sequence);\n \n \tint loadIPA();\n-\tint configureIPA();\n+\tint configureIPA(CameraConfiguration *config);\n \n \tvoid queueFrameAction(unsigned int frame, const IPAOperationData &action);\n \n@@ -793,7 +793,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \tcrop.y = (sensorFormat.size.height - crop.height) >> 1;\n \tdata->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop);\n \n-\tret = data->configureIPA();\n+\tret = data->configureIPA(config);\n \tif (ret)\n \t\tLOG(RPI, Error) << \"Failed to configure the IPA: \" << ret;\n \n@@ -1149,7 +1149,7 @@ int RPiCameraData::loadIPA()\n \treturn ipa_->init(settings);\n }\n \n-int RPiCameraData::configureIPA()\n+int RPiCameraData::configureIPA(CameraConfiguration *config)\n {\n \tstd::map<unsigned int, IPAStream> streamConfig;\n \tstd::map<unsigned int, const ControlInfoMap &> entityControls;\n@@ -1171,6 +1171,9 @@ int RPiCameraData::configureIPA()\n \tentityControls.emplace(0, unicam_[Unicam::Image].dev()->controls());\n \tentityControls.emplace(1, isp_[Isp::Input].dev()->controls());\n \n+\t/* Always send the user transform to the IPA. */\n+\tipaConfig.data = { static_cast<unsigned int>(config->transform) };\n+\n \t/* Allocate the lens shading table via dmaHeap and pass to the IPA. */\n \tif (!lsTable_.isValid()) {\n \t\tlsTable_ = dmaHeap_.alloc(\"ls_grid\", MAX_LS_GRID_SIZE);\n@@ -1179,7 +1182,7 @@ int RPiCameraData::configureIPA()\n \n \t\t/* Allow the IPA to mmap the LS table via the file descriptor. */\n \t\tipaConfig.operation = RPI_IPA_CONFIG_LS_TABLE;\n-\t\tipaConfig.data = { static_cast<unsigned int>(lsTable_.fd()) };\n+\t\tipaConfig.data.push_back(static_cast<unsigned int>(lsTable_.fd()));\n \t}\n \n \tCameraSensorInfo sensorInfo = {};\n","prefixes":["libcamera-devel","v4","6/7"]}