From patchwork Fri Aug 28 14:41:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9421 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 68B14BF019 for ; Fri, 28 Aug 2020 14:41:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 30A3C62927; Fri, 28 Aug 2020 16:41:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="qUZNgImn"; dkim-atps=neutral Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 49E0462922 for ; Fri, 28 Aug 2020 16:41:22 +0200 (CEST) Received: by mail-wm1-x342.google.com with SMTP id q9so1162826wmj.2 for ; Fri, 28 Aug 2020 07:41:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lUHJcrqZxYousXRKyn9ExX5bvnUtThtzvf+6uU/OEKI=; b=qUZNgImn+XbouHvmr2MVr25mEVZjtZKyspkpcSoRg7/JpKGzvY9CXjbMHxAotT6mze Uve7aS5rYvzNBi0gE92ulV5q6tJNRtEUQoZBUhZbn8H+sjibnz9q30oo9s7BPiHbI88I 1VXhVgF8mQDIaT75S3csQRMcIWuUb2CejlltoYYsnva177xDEpFJ3Rh1zzKS3Ek3IrCV VCi28GTP8bcRUC3N/+8KqM5ek70kaGfIhosR+8Wd1mLV8TVZGXwXrKeuGr/OYNYizvuo XX0mboFg6YalABqp6MYlDt1z+cnhEu+IHC20rRJQsX5OYrIFI+DrWfO2iP4r3MtUB58h qFFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lUHJcrqZxYousXRKyn9ExX5bvnUtThtzvf+6uU/OEKI=; b=VEn9460lc41RZsERaM8+r0+fMioT6jnEeELmQUOaIc1wfPDh6NDgSxdOsgs99ETs6c fODgtC/OKvBnjqBuEF80Nf5k+yVHfNehdCNlQ4WjM3EcP9mSK0WlfViD2PjAd7XBJdwi RJLuG5wx9QeWmvRYDdj4+EDWbPxcztMj3m+/9b6T7IDcM/xt8ExEGggSqICB0elsPKVJ NPaY6saR6T/36EoEQxTguYYCV9wjgVBI39KUHcL7HiNkX9/fucB6dv9/1UWjkhkYRq2H 4a67y+NLKA83RVcvS9bSNl3NTb9qFC0Zt6oSlUMs3bCsrLd3XXRRGQ3QNP6w8pOKlKls 4j1A== X-Gm-Message-State: AOAM530PyehknIdHvaksRu6VBZGIWJxR5pDjc5AGnaC9fDhrN1L8MCTZ HIdhkYXWWn1EKEscw/PCkBcBO0HwOklIrw== X-Google-Smtp-Source: ABdhPJxyrbLqyp1BeYsRx1+QDzToTIKqi8Xib5cQMIwhi7kelospPaczMkk1lUcIZKQ8B4GsFyyS4g== X-Received: by 2002:a1c:5f06:: with SMTP id t6mr1950945wmb.54.1598625681513; Fri, 28 Aug 2020 07:41:21 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id s12sm2493724wmj.26.2020.08.28.07.41.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2020 07:41:20 -0700 (PDT) From: David Plowman 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 transform through to IPA X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This commit plumbs the user transform from the Raspberry Pi pipeline handler through to the IPA. Note that the transform is actually handled in the sensor (by setting the h/v flip bits), so the IPAs need to understand the orientation of the image they receive. Once in the IPA we add it to the CameraMode description, so that it becomes automatically available to all the individual control algorithms. The IPA configure method has to be reordered just a little so as to fill in the transform in the camera mode before calling SwitchMode. Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/controller/camera_mode.h | 4 ++ src/ipa/raspberrypi/raspberrypi.cpp | 48 +++++++++++-------- .../pipeline/raspberrypi/raspberrypi.cpp | 11 +++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/ipa/raspberrypi/controller/camera_mode.h b/src/ipa/raspberrypi/controller/camera_mode.h index 875bab3..920f11b 100644 --- a/src/ipa/raspberrypi/controller/camera_mode.h +++ b/src/ipa/raspberrypi/controller/camera_mode.h @@ -6,6 +6,8 @@ */ #pragma once +#include + // Description of a "camera mode", holding enough information for control // algorithms to adapt their behaviour to the different modes of the camera, // including binning, scaling, cropping etc. @@ -33,6 +35,8 @@ struct CameraMode { double noise_factor; // line time in nanoseconds double line_length; + // any camera transform *not* reflected already in the camera tuning + libcamera::Transform transform; }; #ifdef __cplusplus diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 4557016..c730326 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -232,6 +232,33 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, /* Re-assemble camera mode using the sensor info. */ setMode(sensorInfo); + /* + * The ipaConfig.data always gives us the user transform first. Note that + * this will always make the LS table pointer (if present) element 1. + */ + mode_.transform = static_cast(ipaConfig.data[0]); + + /* Store the lens shading table pointer and handle if available. */ + if (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) { + /* Remove any previous table, if there was one. */ + if (lsTable_) { + munmap(lsTable_, MAX_LS_GRID_SIZE); + lsTable_ = nullptr; + } + + /* Map the LS table buffer into user space (now element 1). */ + lsTableHandle_ = FileDescriptor(ipaConfig.data[1]); + if (lsTableHandle_.isValid()) { + lsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, lsTableHandle_.fd(), 0); + + if (lsTable_ == MAP_FAILED) { + LOG(IPARPI, Error) << "dmaHeap mmap failure for LS table."; + lsTable_ = nullptr; + } + } + } + /* Pass the camera mode to the CamHelper to setup algorithms. */ helper_->SetCameraMode(mode_); @@ -280,27 +307,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, } lastMode_ = mode_; - - /* Store the lens shading table pointer and handle if available. */ - if (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) { - /* Remove any previous table, if there was one. */ - if (lsTable_) { - munmap(lsTable_, MAX_LS_GRID_SIZE); - lsTable_ = nullptr; - } - - /* Map the LS table buffer into user space. */ - lsTableHandle_ = FileDescriptor(ipaConfig.data[0]); - if (lsTableHandle_.isValid()) { - lsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, lsTableHandle_.fd(), 0); - - if (lsTable_ == MAP_FAILED) { - LOG(IPARPI, Error) << "dmaHeap mmap failure for LS table."; - lsTable_ = nullptr; - } - } - } } void IPARPi::mapBuffers(const std::vector &buffers) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 6ea1432..8d8e249 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -294,7 +294,7 @@ public: void frameStarted(uint32_t sequence); int loadIPA(); - int configureIPA(); + int configureIPA(CameraConfiguration *config); void queueFrameAction(unsigned int frame, const IPAOperationData &action); @@ -793,7 +793,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) crop.y = (sensorFormat.size.height - crop.height) >> 1; data->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop); - ret = data->configureIPA(); + ret = data->configureIPA(config); if (ret) LOG(RPI, Error) << "Failed to configure the IPA: " << ret; @@ -1149,7 +1149,7 @@ int RPiCameraData::loadIPA() return ipa_->init(settings); } -int RPiCameraData::configureIPA() +int RPiCameraData::configureIPA(CameraConfiguration *config) { std::map streamConfig; std::map entityControls; @@ -1171,6 +1171,9 @@ int RPiCameraData::configureIPA() entityControls.emplace(0, unicam_[Unicam::Image].dev()->controls()); entityControls.emplace(1, isp_[Isp::Input].dev()->controls()); + /* Always send the user transform to the IPA. */ + ipaConfig.data = { static_cast(config->transform) }; + /* Allocate the lens shading table via dmaHeap and pass to the IPA. */ if (!lsTable_.isValid()) { lsTable_ = dmaHeap_.alloc("ls_grid", MAX_LS_GRID_SIZE); @@ -1179,7 +1182,7 @@ int RPiCameraData::configureIPA() /* Allow the IPA to mmap the LS table via the file descriptor. */ ipaConfig.operation = RPI_IPA_CONFIG_LS_TABLE; - ipaConfig.data = { static_cast(lsTable_.fd()) }; + ipaConfig.data.push_back(static_cast(lsTable_.fd())); } CameraSensorInfo sensorInfo = {};