From patchwork Fri Aug 21 15:56:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9352 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 2CC69BE175 for ; Fri, 21 Aug 2020 15:57:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 906E96212A; Fri, 21 Aug 2020 17:57:07 +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="MQ5ZW/+V"; dkim-atps=neutral Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E1E2361FE7 for ; Fri, 21 Aug 2020 17:57:05 +0200 (CEST) Received: by mail-wr1-x42a.google.com with SMTP id c15so2378105wrs.11 for ; Fri, 21 Aug 2020 08:57:05 -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=+zKAd8/wMfnxod5O3k1pUZg+x2G0KDNBQY8RY9TNoeo=; b=MQ5ZW/+VRNWqLAUne/S/yWw/D5X1OGh42vH3vuAiL0ZyrJ1dRQ4T1/gm/HBdMJtQa/ +Q6nhZ8oCSLg5vLkEsH5hanU2/WHWwmz4IZ/b4CNAxHD+FFaLYO1/90QBpQ/UKnCNqAm M2iSiqM5/mzVpTBnlXaVJ0+TQ8RMTXwlQkdHKO3Lu3ja6ae1x8wOaP0lrEU9wxWPvtWn yZlYCxA/pG/JFqSMctrwQa0tpSpcM1BHuF6tg2pmSECSU8+HZOFEI7i1VN2ty0tefH// Nr3zp38wRSPKtmU6lvdN8uAj/BTkLCQbczuEK6yxhzjKorz3tg/ZGgCWBxQqW0f/Yp7j r1Sw== 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=+zKAd8/wMfnxod5O3k1pUZg+x2G0KDNBQY8RY9TNoeo=; b=AuoYYOT/BntIj1nJGecNERe9ot1MBzadw3EmaaGlylWvoyOQpSmNaX1RUKh5d9OSn3 MqraYQ/g/Jhfd6R/MajO4K36jTYuFZiWF+trOE6zBGAgSjWGX2QgHTUSjde0XLsbca9j 44VaDEZEDQPugAnLFa1mMn/7ygeP0R9YledHgacIKUjsxGaWbtmjOciOwrAo8aUSEE+Q fT8H7LI4O+720cJQ4hVFBFQLWPfYWBP4pM3jr5zX5M1VPX1pgS8Ws0UvqUCRJJtHxFOI qjp84UisDfZf10Se3im2dewDyoEbMU6AhdhJp5MfFRoJs5bTtIuv1o015p6VGRkODN7a F1ZQ== X-Gm-Message-State: AOAM531zHYpFXx0LhNmkrBzsOdPfaElBYuZIxoOvHVTRmeMW7KzmXv5D dslRAnHx/HZN5KyQn9VJKAXdXUH1Y8srIA== X-Google-Smtp-Source: ABdhPJzArAe64T7jaCLnHKIpBDx00BBl8ATXvFC9QWoHiHIIjvJBjaMxAGCfdKQ9dz43KDymVErRVg== X-Received: by 2002:adf:bb14:: with SMTP id r20mr3266140wrg.366.1598025425192; Fri, 21 Aug 2020 08:57:05 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id l11sm5627385wme.11.2020.08.21.08.57.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 08:57:04 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 21 Aug 2020 16:56:40 +0100 Message-Id: <20200821155641.11839-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200821155641.11839-1-david.plowman@raspberrypi.com> References: <20200821155641.11839-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/5] 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 | 5 +- 3 files changed, 35 insertions(+), 22 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 3747208..0b36d57 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 a3f8438..4f9aa35 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1159,6 +1159,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(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); @@ -1167,7 +1170,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 = {};