From patchwork Fri Sep 15 13:06:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19032 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 F2244BE080 for ; Fri, 15 Sep 2023 13:15:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3C37362918; Fri, 15 Sep 2023 15:15:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783743; bh=XngVIR/K3WSLnbRrQQG66G+y0Xl6BXECCKJIZEWF6jY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=J8FJoY4GWz6WLgoDL3tvLI4A33jucioajAy/4BuWMY0gOXkMZTvvkHs4BQHtR5ibu OGEC0zol634pO5n3VXUFkDKac6LqyMUWZ4PF8AQBDyJGsNkTLnC1XQuMUG/0B3Cj5I bJRnr+bIZojreUvQdm2xJhTXJ79syPYnqPxZUjjX0Z7m6TZC60Fl+56yKuFIFqYpK6 Wehs9PO75rndrwZBfLP5hGsk9rW3rsbGe7TfMU1nVYTclcQvgt7SAmMVDqnz4Gg+Rp rMF1W2ylSZzhTByhD0TASRG7jVh2qwoL2SsHmt+7aT5g7jlLFkASxoWqL9ImXkLzPk WW9IZips9a47w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 76A62628EC for ; Fri, 15 Sep 2023 15:07:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iLqXbaFY"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BCA6012AE; Fri, 15 Sep 2023 15:05:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783135; bh=XngVIR/K3WSLnbRrQQG66G+y0Xl6BXECCKJIZEWF6jY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iLqXbaFYHGxBkrBo+Bc8lh1unhQw+V6lpj0YNLVFxrdAhqwOc8l1P3cgd/5hsAPdf OEzaIIObFnR4b8obJsgrjcIx8K0HFGO6cTNVMOUkNsoOXOLOi3ifHxJaGp16PIBWHJ yQK27RvzAUOXTZFKMbnTNfKdO3uff5kruj+gho40= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:39 +0200 Message-ID: <20230915130650.35691-2-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 X-Mailman-Approved-At: Fri, 15 Sep 2023 15:15:42 +0200 Subject: [libcamera-devel] [PATCH v3 01/12] documentation: Introduce Camera Sensor Model 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Introduce a documentation page about the 'camera sensor model' implemented by libcamera. The camera sensor model serves to provide to applications a reference description of the processing steps that take place in a camera sensor in order to precisely control the sensor configuration through the forthcoming SensorConfiguration class. Signed-off-by: Jacopo Mondi Reviewed-by: Naushir Patuck Reviewed-by: Kieran Bingham --- Documentation/binning.png | Bin 0 -> 66004 bytes Documentation/camera-sensor-model.png | Bin 0 -> 74270 bytes Documentation/camera-sensor-model.rst | 198 ++++++++++++++++++++++++++ Documentation/index.rst | 1 + Documentation/meson.build | 1 + Documentation/skipping.png | Bin 0 -> 67218 bytes 6 files changed, 200 insertions(+) create mode 100644 Documentation/binning.png create mode 100644 Documentation/camera-sensor-model.png create mode 100644 Documentation/camera-sensor-model.rst create mode 100644 Documentation/skipping.png GIT binary patch literal 67218 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 MjgmzgBU06W0dN~+0{{R3 literal 0 HcmV?d00001 diff --git a/Documentation/binning.png b/Documentation/binning.png new file mode 100644 index 0000000000000000000000000000000000000000..b91dd92f76061a20490a66e23affa79948767d51 GIT binary patch literal 66004 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%0DfS`-YC;;S{u&^HN?B4}B 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 literal 0 HcmV?d00001 diff --git a/Documentation/camera-sensor-model.png b/Documentation/camera-sensor-model.png new file mode 100644 index 0000000000000000000000000000000000000000..24cc6fd28af1b9056315d1f32cb7232f5f7677e0 GIT binary patch literal 74270 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 Lens driver requirements Python Bindings + Camera Sensor Model diff --git a/Documentation/meson.build b/Documentation/meson.build index b2a5bf15e6ea..7c1502592baa 100644 --- a/Documentation/meson.build +++ b/Documentation/meson.build @@ -63,6 +63,7 @@ endif if sphinx.found() docs_sources = [ + 'camera-sensor-model.rst', 'coding-style.rst', 'conf.py', 'contributing.rst', diff --git a/Documentation/skipping.png b/Documentation/skipping.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ff2268da01d9508349a1c3faf822554a823da9 From patchwork Fri Sep 15 13:06:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19021 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 A48B4BD160 for ; Fri, 15 Sep 2023 13:07:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4212462919; Fri, 15 Sep 2023 15:07:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783230; bh=3Z/xmkYMA96biaHBFTCUKtvbTDfV1i7xuqt8j4mp4jI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=T/7GxT3Rq1zsQn/8zQs9ss/Pr1qkHjSmmwFHqKzwTIraGAjd7yKe8zws1ap8AxMeZ pSTlXB9TTKuw/hCEbsftsdGVdGe5SBrvz3OxaH089m/uPiKtPL54CpXGau04fUrPup ds2hGyD4DX5oaUeVMQi/tXrNLAF5TpE9XFflemrvjq50Iazp4JPd/v8m7JJkKX7UXu kz5DQWHNYNF5kgDIcPh2sDiycmVcKAIWb5MYrLMval4BoDHC+LPpW4SzP4t59ltxBZ B708Ery5h8oF76Bdna9gbnOSZB9eiWXABW0zqraRIkvDLBfZhmNpx/tgxslER72VW7 Oq6EcKZgkxtaQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E255962919 for ; Fri, 15 Sep 2023 15:07:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="IeiXm+rs"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6ED6C9A8; Fri, 15 Sep 2023 15:05:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783135; bh=3Z/xmkYMA96biaHBFTCUKtvbTDfV1i7xuqt8j4mp4jI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IeiXm+rs4+R4N1nwd8QMlsABiR7Vbn4subo7WQEM9dSrvgOJh0955GZZ8teEM2gg2 XwEAMcqXnl6gFXBJZmTyu5m9Gf95fUKvVYbdicZxuEoV1GQN6OjIGRssuXfZdZHkoR zrHO4aNFc5FE65yohf12GzZWPU433/5haRXv3Yx4= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:40 +0200 Message-ID: <20230915130650.35691-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 02/12] libcamera: camera: Introduce SensorConfiguration 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Introduce SensorConfiguration in the libcamera API. The SensorConfiguration is part of the CameraConfiguration class and allows applications to control the sensor settings. Signed-off-by: Jacopo Mondi Reviewed-by: Naushir Patuck Reviewed-by: Kieran Bingham --- include/libcamera/camera.h | 43 +++++++++ src/libcamera/camera.cpp | 185 +++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 004bc89455f5..b2aa8d467feb 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,47 @@ class FrameBufferAllocator; class PipelineHandler; class Request; +class SensorConfiguration +{ +public: + unsigned int bitDepth = 0; + + Rectangle analogCrop; + + struct { + unsigned int binX = 1; + unsigned int binY = 1; + } binning; + + struct { + unsigned int xOddInc = 1; + unsigned int xEvenInc = 1; + unsigned int yOddInc = 1; + unsigned int yEvenInc = 1; + } skipping; + + Size outputSize; + + bool valid() const + { + return validate() != Invalid; + } + + explicit operator bool() const + { + return validate() == Populated; + } + +private: + enum Status { + Unpopulated, + Populated, + Invalid, + }; + + Status validate() const; +}; + class CameraConfiguration { public: @@ -66,6 +108,7 @@ public: bool empty() const; std::size_t size() const; + SensorConfiguration sensorConfig; Transform transform; protected: diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 0eecee766f00..f497a35c90fb 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -97,6 +97,21 @@ * implemented in the above order at the hardware level. The libcamera pipeline * handlers translate the pipeline model to the real hardware configuration. * + * \subsection camera-sensor-mode Camera Sensor Model + * + * libcamera allows applications to control the configuration of the camera + * sensor, particularly it allows to control the frame geometry and frame + * delivery rate of the sensor. + * + * The camera sensor configuration applies to all streams produced by a camera + * from the same image source. + * + * More details about the camera sensor model implemented by libcamera are + * available in the libcamera camera-sensor-model documentation page. + * + * The sensor configuration is specified by applications by populating the + * CameraConfiguration::sensorConfig class member. + * * \subsection digital-zoom Digital Zoom * * Digital zoom is implemented as a combination of the cropping and scaling @@ -111,6 +126,166 @@ namespace libcamera { LOG_DECLARE_CATEGORY(Camera) +/** + * \class SensorConfiguration + * \brief Camera sensor configuration + * + * The SensorConfiguration class collects parameters to control the operations + * of the camera sensor, accordingly to the abstract camera sensor model + * implemented by libcamera. + * + * \todo Applications shall fully populate all fields of the + * CameraConfiguration::sensorConfig class members before validating the + * CameraConfiguration. If the SensorConfiguration is not fully populated, or if + * any of its parameters cannot be applied to the sensor in use, the + * CameraConfiguration validation process will fail and return + * CameraConfiguration::Status::Invalid. + * + * Applications that populate the SensorConfiguration class members are + * expected to be highly-specialized applications that know what sensor + * they are operating with and what parameters are valid for the sensor in use. + * + * A detailed description of the abstract camera sensor model implemented by + * libcamera and the description of its configuration parameters is available + * in the libcamera documentation camera-sensor-model file. + */ + +/** + * \enum SensorConfiguration::Status + * \brief The sensor configuration validation status + */ + +/** + * \var SensorConfiguration::bitDepth + * \brief The sensor image format bit depth + * + * The number of bits (resolution) used to represent a pixel sample. + */ + +/** + * \var SensorConfiguration::analogCrop + * \brief The analog crop rectangle + * + * The selected portion of the active pixel array used to produce the image + * frame. + */ + +/** + * \var SensorConfiguration::binning + * \brief Sensor binning configuration + * + * Refer to the camera-sensor-model documentation for an accurate description + * of the binning operations. Disabled by default. + */ + +/** + * \var SensorConfiguration::binX + * \brief Horizontal binning factor + * + * The horizontal binning factor. Default to 1. + */ + +/** + * \var SensorConfiguration::binY + * \brief Vertical binning factor + * + * The vertical binning factor. Default to 1. + */ + +/** + * \var SensorConfiguration::skipping + * \brief The sensor skipping configuration + * + * Refer to the camera-sensor-model documentation for an accurate description + * of the skipping operations. + * + * If no skipping is performed, all the structure fields should be + * set to 1. Disabled by default. + */ + +/** + * \var SensorConfiguration::xOddInc + * \brief Horizontal increment for odd rows. Default to 1. + */ + +/** + * \var SensorConfiguration::xEvenInc + * \brief Horizontal increment for even rows. Default to 1. + */ + +/** + * \var SensorConfiguration::yOddInc + * \brief Vertical increment for odd columns. Default to 1. + */ + +/** + * \var SensorConfiguration::yEvenInc + * \brief Vertical increment for even columns. Default to 1. + */ + +/** + * \var SensorConfiguration::outputSize + * \brief The frame output (visible) size + * + * The size of the data frame as received by the host processor. + */ + +/** + * \fn SensorConfiguration::valid() const + * \brief Validate the SensorConfiguration + * + * Validate the sensor configuration. + * + * \todo A sensor configuration is valid (or well-formed) if it's either + * completely un-populated or fully populated. For now allow applications to + * populate the bitDepth and the outputSize only. + * + * \return True if the SensorConfiguration is either fully populated or + * un-populated, false otherwise + */ + +/** + * \fn SensorConfiguration::operator bool() const + * \brief Test if a SensorConfiguration is fully populated + * \return True if the SensorConfiguration is fully populated + */ + +/** + * \brief Validate the sensor configuration + * + * \todo A sensor configuration is valid (or well-formed) if it's either + * completely un-populated or fully populated. For now allow applications to + * populate the bitDepth and the outputSize only. + * + * \return The sensor configuration status + * \retval Unpopulated The sensor configuration is fully unpopulated + * \retval Populated The sensor configuration is fully populated + * \retval Invalid The sensor configuration is invalid (not fully populated + * and not fully unpopulated) + */ +SensorConfiguration::Status SensorConfiguration::validate() const +{ + if (bitDepth && binning.binX && binning.binY && + skipping.xOddInc && skipping.yOddInc && + skipping.xEvenInc && skipping.yEvenInc && + !outputSize.isNull()) + return Populated; + + /* + * By default the binning and skipping factors are initialized to 1, but + * a zero-initialized SensorConfiguration is considered unpopulated + * as well. + */ + if (!bitDepth && + binning.binX <= 1 && binning.binY <= 1 && + skipping.xOddInc <= 1 && skipping.yOddInc <= 1 && + skipping.xEvenInc <= 1 && skipping.yEvenInc <= 1 && + outputSize.isNull()) + return Unpopulated; + + return Invalid; +} + /** * \class CameraConfiguration * \brief Hold configuration for streams of the camera @@ -391,6 +566,16 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF return status; } +/** + * \var CameraConfiguration::sensorConfig + * \brief The camera sensor configuration + * + * The sensorConfig field allows control of the configuration of the camera + * sensor. Refer to the camera-sensor-model documentation and to the + * SensorConfiguration class documentation for details about the sensor + * configuration process. + */ + /** * \var CameraConfiguration::transform * \brief User-specified transform to be applied to the image From patchwork Fri Sep 15 13:06:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19022 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 81723BD160 for ; Fri, 15 Sep 2023 13:07:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3618162924; Fri, 15 Sep 2023 15:07:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783234; bh=t04UmGisZTTgoEcMdwJ8q9eBiTCywSmfIlvIh/JVtJk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=AJuvwpdl0SJ5ewrLXJegOfc6etmWFmxsHjrlRwll8KEC83WObm8g8kH09qeH24B2d i/avCpa8jqlDyb4L1lXSrlMmOiDCqP3DTfqgp1Z4YcD+ClaGUs1oY2UjW/JnelPoHY vieCziZ1BTzJAgUzvNgpYYXGb4iPKES+zrGyEXjtZd1ANCImEDdes7t+9Gmo5NLG+p 9Yi8ZGTqEGJm9JUEl5y2KBLrZobkwGPPzWJiyCn2hU607y4Vhn1m09cgP4ZdbXvzIO /cRB6SF0DTz9YhryUfkSMTtzMl2OS+aelBkISFhw+1l0b/bBwT0W5GBkIHXgfAHW8B Sp93zzhoPbBLg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5BCC76291A for ; Fri, 15 Sep 2023 15:07:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UKqxAlD+"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DB959208C; Fri, 15 Sep 2023 15:05:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783136; bh=t04UmGisZTTgoEcMdwJ8q9eBiTCywSmfIlvIh/JVtJk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UKqxAlD+ca+IkaPjnyKo4mrpBR2bB2lnLcNVlRXc8pHRr0GcI5bR8sHjqdmHLlsmY wNGZktZ9FKZAzrjLuASrJd+pJ+a224Rl67n1aczCVxWE7D3JDDLJDteZSw09+EgXNg GoXAN46jUX5tkMZJH2B7y35RYvIfxixz8yq4V4zI= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:41 +0200 Message-ID: <20230915130650.35691-4-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 03/12] libcamera: camera_sensor: Support SensorConfiguration 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a class function to the CameraSensor class to apply a full configuration to the sensor. The configuration shall be fully populated and shall apply without modifications to the sensor. Signed-off-by: Jacopo Mondi Reviewed-by: Naushir Patuck Reviewed-by: Kieran Bingham --- include/libcamera/internal/camera_sensor.h | 5 ++ src/libcamera/camera_sensor.cpp | 86 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 02c77ab037da..06791c3c6425 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -29,6 +29,7 @@ namespace libcamera { class BayerFormat; class CameraLens; class MediaEntity; +class SensorConfiguration; struct CameraSensorProperties; @@ -58,6 +59,10 @@ public: Transform transform = Transform::Identity); int tryFormat(V4L2SubdeviceFormat *format) const; + int applyConfiguration(const SensorConfiguration &config, + Transform transform = Transform::Identity, + V4L2SubdeviceFormat *sensorFormat = nullptr); + const ControlInfoMap &controls() const; ControlList getControls(const std::vector &ids); int setControls(ControlList *ctrls); diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index f3a5aa37149f..d453f81bc548 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -822,6 +823,91 @@ int CameraSensor::tryFormat(V4L2SubdeviceFormat *format) const V4L2Subdevice::Whence::TryFormat); } +/** + * \brief Apply a sensor configuration to the camera sensor + * \param[in] config The sensor configuration + * \param[in] transform The transform to be applied on the sensor. + * Defaults to Identity + * \param[out] sensorFormat Optional output parameter where the format + * actually applied to the sensor is returned to the caller + * + * Apply to the camera sensor the configuration \a config. + * + * \todo The configuration shall be fully populated and if any of the fields + * specified cannot be applied exactly, an error code is returned. + * + * \return 0 if \a config is applied to the camera sensor, a negative error code + * otherwise + */ +int CameraSensor::applyConfiguration(const SensorConfiguration &config, + Transform transform, + V4L2SubdeviceFormat *sensorFormat) +{ + if (!config) { + LOG(CameraSensor, Error) << "Invalid sensor configuration"; + return -EINVAL; + } + + std::vector filteredCodes; + std::copy_if(mbusCodes_.begin(), mbusCodes_.end(), + std::back_inserter(filteredCodes), + [&config](unsigned int mbusCode) { + BayerFormat bayer = BayerFormat::fromMbusCode(mbusCode); + if (bayer.bitDepth == config.bitDepth) + return true; + return false; + }); + if (filteredCodes.empty()) { + LOG(CameraSensor, Error) + << "Cannot find any format with bit depth " + << config.bitDepth; + return -EINVAL; + } + + /* + * Compute the sensor's data frame size by applying the cropping + * rectangle, subsampling and output crop to the sensor's pixel array + * size. + * + * \todo The actual size computation is for now ignored and only the + * output size is considered. This implies that resolutions obtained + * with two different cropping/subsampling will look identical and + * only the first found one will be considered. + */ + V4L2SubdeviceFormat subdevFormat = {}; + for (unsigned int code : filteredCodes) { + for (const Size &size : sizes(code)) { + if (size.width != config.outputSize.width || + size.height != config.outputSize.height) + continue; + + subdevFormat.mbus_code = code; + subdevFormat.size = size; + break; + } + } + if (!subdevFormat.mbus_code) { + LOG(CameraSensor, Error) << "Invalid output size in sensor configuration"; + return -EINVAL; + } + + int ret = setFormat(&subdevFormat, transform); + if (ret) + return ret; + + /* + * Return to the caller the format actually applied to the sensor. + * This is relevant if transform has changed the bayer pattern order. + */ + if (sensorFormat) + *sensorFormat = subdevFormat; + + /* \todo Handle AnalogCrop. Most sensors do not support set_selection */ + /* \todo Handle scaling in the digital domain. */ + + return 0; +} + /** * \brief Retrieve the supported V4L2 controls and their information * From patchwork Fri Sep 15 13:06:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19023 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 7CFF3C3260 for ; Fri, 15 Sep 2023 13:07:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B3AE362931; Fri, 15 Sep 2023 15:07:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783234; bh=diqPr+bOZt2J1Lky0enY1fCvxe9+SzbQzvAlh0xf60A=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=OPlJbQpG06RnwcT5JxtyNEbGgcaP89Zvr7XfOI+KfgflvmehCOiyzmhTqYYbZZ3Wz kZUXFZHoJE07V5zmTMUgkXEq1Py75YK562EIwjAlJOd4UoJlo0Gkh91/o/6c0q6PL2 OBVv2qVtT2/iijbkz5N3aFrt7mjx7zDGh2V37GBnYIPTlpJJFdkC5ywjQP1Y4yZw8/ FjFUOKh4DZZ/K+YUU4aKr47zm4XM5sXRDmoN+SOceb5SS21/8YOOxKbK13km48nVVa IoA61yECV0+cAnE02HDUjKEEaliJ0rzNAohUHnzTdfcAgQUXMkSF+AWpcEjZD5Me3W 8XyGmzGXH2t9g== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C51D762916 for ; Fri, 15 Sep 2023 15:07:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VI4XnSRM"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5238F2D14; Fri, 15 Sep 2023 15:05:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783136; bh=diqPr+bOZt2J1Lky0enY1fCvxe9+SzbQzvAlh0xf60A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VI4XnSRMPhVWcIWuKzrquz02NsrIfel4vYG3RaANJPXOD69nxaEi+n2XYkMaWglRt +1gK1fCV7DScjbHxN8ujmy5dDlBwHSVbIwnc1g36ysMOsrjK7IUG/acw8nGByzlStH buzcfscOuva97Z3KmoUexWOL4IhCvG61V+5wfCwI= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:42 +0200 Message-ID: <20230915130650.35691-5-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 04/12] libcamera: rpi: Handle SensorConfiguration 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Handle the SensorConfiguration provided by the application in the pipeline validate() and configure() call chains. During validation, first make sure SensorConfiguration is valid, then handle it to compute the sensor format. For the VC4 platform where the RAW stream follows the sensor's configuration adjust the RAW stream configuration to match the sensor configuration. Reviewed-by: Naushir Patuck Reviewed-by: Kieran Bingham Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 62 ++++++++++++++++--- .../pipeline/rpi/common/pipeline_base.h | 4 +- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 28 ++++++++- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 51fa1bbf9aa9..dff4164a5f02 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -180,6 +180,11 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() if (config_.empty()) return Invalid; + if (!sensorConfig.valid()) { + LOG(RPI, Error) << "Invalid sensor configuration request"; + return Invalid; + } + status = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace); /* @@ -207,19 +212,43 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() std::sort(outStreams.begin(), outStreams.end(), [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); - /* Compute the sensor configuration. */ - unsigned int bitDepth = defaultRawBitDepth; - if (!rawStreams.empty()) { + /* Compute the sensor's format then do any platform specific fixups. */ + unsigned int bitDepth; + Size sensorSize; + + if (sensorConfig) { + /* Use the application provided sensor configuration. */ + bitDepth = sensorConfig.bitDepth; + sensorSize = sensorConfig.outputSize; + } else if (!rawStreams.empty()) { + /* Use the RAW stream format and size. */ BayerFormat bayerFormat = BayerFormat::fromPixelFormat(rawStreams[0].cfg->pixelFormat); bitDepth = bayerFormat.bitDepth; + sensorSize = rawStreams[0].cfg->size; + } else { + bitDepth = defaultRawBitDepth; + sensorSize = outStreams[0].cfg->size; } - sensorFormat_ = data_->findBestFormat(rawStreams.empty() ? outStreams[0].cfg->size - : rawStreams[0].cfg->size, - bitDepth); + sensorFormat_ = data_->findBestFormat(sensorSize, bitDepth); + + /* + * If a sensor configuration has been requested, it should apply + * without modifications. + */ + if (sensorConfig) { + BayerFormat bayer = BayerFormat::fromMbusCode(sensorFormat_.mbus_code); + + if (bayer.bitDepth != sensorConfig.bitDepth || + sensorFormat_.size != sensorConfig.outputSize) { + LOG(RPI, Error) << "Invalid sensor configuration: " + << "bitDepth/size mismatch"; + return Invalid; + } + } /* Do any platform specific fixups. */ - status = data_->platformValidate(rawStreams, outStreams); + status = data_->platformValidate(this, rawStreams, outStreams); if (status == Invalid) return Invalid; @@ -467,12 +496,25 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) std::sort(ispStreams.begin(), ispStreams.end(), [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); - /* Apply the format on the sensor with any cached transform. */ + /* + * Apply the format on the sensor with any cached transform. + * + * If the application has provided a sensor configuration apply it + * instead of just applying a format. + */ const RPiCameraConfiguration *rpiConfig = static_cast(config); - V4L2SubdeviceFormat sensorFormat = rpiConfig->sensorFormat_; + V4L2SubdeviceFormat sensorFormat; - ret = data->sensor_->setFormat(&sensorFormat, rpiConfig->combinedTransform_); + if (rpiConfig->sensorConfig) { + ret = data->sensor_->applyConfiguration(rpiConfig->sensorConfig, + rpiConfig->combinedTransform_, + &sensorFormat); + } else { + sensorFormat = rpiConfig->sensorFormat_; + ret = data->sensor_->setFormat(&sensorFormat, + rpiConfig->combinedTransform_); + } if (ret) return ret; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index dbabc61ea48c..81b2b7d2f4d1 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -42,6 +42,7 @@ namespace RPi { /* Map of mbus codes to supported sizes reported by the sensor. */ using SensorFormats = std::map>; +class RPiCameraConfiguration; class CameraData : public Camera::Private { public: @@ -72,7 +73,8 @@ public: V4L2VideoDevice *dev; }; - virtual CameraConfiguration::Status platformValidate(std::vector &rawStreams, + virtual CameraConfiguration::Status platformValidate(RPiCameraConfiguration *rpiConfig, + std::vector &rawStreams, std::vector &outStreams) const = 0; virtual int platformConfigure(const V4L2SubdeviceFormat &sensorFormat, std::optional packing, diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 018cf4881d0e..2670eb8c4bbc 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -65,7 +65,8 @@ public: { } - CameraConfiguration::Status platformValidate(std::vector &rawStreams, + CameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig, + std::vector &rawStreams, std::vector &outStreams) const override; int platformPipelineConfigure(const std::unique_ptr &root) override; @@ -394,7 +395,8 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer return 0; } -CameraConfiguration::Status Vc4CameraData::platformValidate(std::vector &rawStreams, +CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig, + std::vector &rawStreams, std::vector &outStreams) const { CameraConfiguration::Status status = CameraConfiguration::Status::Valid; @@ -405,9 +407,27 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(std::vectorsensorFormat_.mbus_code); + + /* Handle flips to make sure to match the RAW stream format. */ + if (flipsAlterBayerOrder_) + rawBayer = rawBayer.transform(rpiConfig->combinedTransform_); + PixelFormat rawFormat = rawBayer.toPixelFormat(); + + if (rawStream->pixelFormat != rawFormat || + rawStream->size != rpiConfig->sensorFormat_.size) { + rawStream->pixelFormat = rawFormat; + rawStream->size = rpiConfig->sensorFormat_.size; + + status = CameraConfiguration::Adjusted; + } + } + /* * For the two ISP outputs, one stream must be equal or smaller than the * other in all dimensions. @@ -417,6 +437,8 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(std::vectorsize.width, outStreams[0].cfg->size.width); size.height = std::min(outStreams[i].cfg->size.height, From patchwork Fri Sep 15 13:06:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19024 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 821E1BD160 for ; Fri, 15 Sep 2023 13:07:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 874046292A; Fri, 15 Sep 2023 15:07:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783235; bh=RZhYEj/pzFsYZ1EdPil8Y7m2aIi45fZLApt+gcqLs9I=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=e5y5WoNcf+ZD1PqG3zRnIiGeEwisE3QqJDbxGvra9l4KV9XQLNChB95n+gIfx8DU4 5P66tC/+BKtvhVHVXXZ7lG7MVPaQsYw0Jhj1GHvznFxbPmxd+fcgI2lAdCu6SgIm07 8dTg4pNtLTaNFOvimJv5KYHMykO//JsRGiBrMMJSZLPJykAdUElAZe4fjhL/TxZti6 hW7XKGhsr5BrPKAuLe8+dOUhw66Gx4s6h5oywDQanxcE6bDIYTtdvcmqw/cCH12rOs PNk3BKu7YBZlRh5bk4ADq7XsvVZ9kJRTBSyAtBIXPwar+8einU7yYpZ+/9EvC6tUG+ g0LVpXm3cVXvw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 360B062918 for ; Fri, 15 Sep 2023 15:07:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="KciLzndu"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BCD3C9A8; Fri, 15 Sep 2023 15:05:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783137; bh=RZhYEj/pzFsYZ1EdPil8Y7m2aIi45fZLApt+gcqLs9I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KciLzndu+TN4h/c2nUjv5JfkXjqM2HQ0XN+1FKmpuU907T6E9VoHLunG30EU/0pC2 nm4qTFnLw0D6nRNl9ms2m+mIrixKntmPim50bqZlRyGp88f1UMyG6k5LnL0oubzwnl 5l7XRXVhcDqMP5FJEWslJppX1DlP1wTvj9yIsn60= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:43 +0200 Message-ID: <20230915130650.35691-6-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 05/12] libcamera: rpi: Allow platformValidate() to adjust format strides 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Propagate any changes to the format stride done by platformValidate(). The stride value may be adjusted for performace reasons. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index dff4164a5f02..2d787f4b99ed 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -305,6 +305,17 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() V4L2DeviceFormat format; format.fourcc = out.dev->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; + + /* + * platformValidate may have worked out the correct stride so we + * must pass it in. This also needs the planesCount to be set + * correctly or the stride will be ignored. + */ + const PixelFormat &pixFormat = format.fourcc.toPixelFormat(); + const PixelFormatInfo &info = PixelFormatInfo::info(pixFormat); + format.planesCount = info.numPlanes(); + format.planes[0].bpl = cfg.stride; + /* We want to send the associated YCbCr info through to the driver. */ format.colorSpace = yuvColorSpace_; From patchwork Fri Sep 15 13:06:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19025 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 62198C32B0 for ; Fri, 15 Sep 2023 13:07:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9A7F462924; Fri, 15 Sep 2023 15:07:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783236; bh=w9AusMuCSjpYZIrUzlAUxsdXUujTwmIu5v1OblYSQOc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=KBbDtBwz48j+G0qMEgFDbwUqSqWh4tQlx+CnMBR2REIfr4lY3G0ljjDZXhgHjHtj2 Lqhwiwq5P6OWWatK9yAwdZRL9h3NbOoRuAK3TzgoHoSuwjJ1I+ddhbRkb8xyCPDVoS Z5GwrP0tWK8jsRtIB9GPItyqIrdtyBsnazCYxcpaxKrkDEIYqOIKbVK/XtLVXJwiEA Yw0qh9P4ynDEwReipPSmy/zcjgz5infBzPz8TmZinuQmWl/MOMoeJETjGeZJzwB7T6 NIzvBFfIOxoguG1M6Bq1o/7zTd3oozcWAsSQg6x4ksDpNnIEcVNzVQ8HquDWFr+lQU ierpDjaMaJopw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8AF2462921 for ; Fri, 15 Sep 2023 15:07:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cVomdQVI"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2A0A612AE; Fri, 15 Sep 2023 15:05:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783137; bh=w9AusMuCSjpYZIrUzlAUxsdXUujTwmIu5v1OblYSQOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cVomdQVI96m+P9sy9vWbMX7BcqAQMv4HtkzG16YARtr7c2cHIgKTq5xa92+5Zk1p5 GS2dKpwznA3mUB0FiHPg4NJdSGmBb+gJevNTW37cNOvYr/THX3TU9gbyOsVw3Y5nlN kRQPqzerxn79ANPSjLaoIA0EJ5qb81y/tk9cRRWs= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:44 +0200 Message-ID: <20230915130650.35691-7-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 06/12] libcamera: rpi: Fix wrong comment indentation 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The closing line of a comment block was aligned with spaces and not tabs. Fix it. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/libcamera/pipeline/rpi/common/pipeline_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 81b2b7d2f4d1..3e7c487fb0bf 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -273,7 +273,7 @@ private: * Store the colour spaces that all our streams will have. RGB format streams * will have the same colorspace as YUV streams, with YCbCr field cleared and * range set to full. - */ + */ std::optional yuvColorSpace_; std::optional rgbColorSpace_; }; From patchwork Fri Sep 15 13:06:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19026 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 2F07FC32B1 for ; Fri, 15 Sep 2023 13:07:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 501B462918; Fri, 15 Sep 2023 15:07:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783237; bh=Bjqt1BC/qeXCOGnSbabt151Jc4j/SYVO0ZOFPLYMUaA=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=ckc1enNV+OZAjVK1Rati5N1jqwWC8kuBZhMbQ5Fvwwcwo3akSyif6Y9JcGDmOuBqo 59/ckBAkQ+m5KOP0n1CtdnAX1M0mKdkHnyFOl5mqsoPbl7jiTnfl5xxY81RDl1JGdq IyiHD8GHx4TnRRh8jYiiODNYjSoPdi/He5SSFr0qYI3J8OwuQkVXhkkLt9VF9KUV6a tlmKgXHkuSpmViux5MpVR7pg+ike7gtoD1ib7VRWjju7dAW27RWeTKsuZ254qXKE8Z Ss/7rAN3UBiDzyCCyJW5VX2xy+NP/y2SPKkZf81eruW7DbdjCU1NNFv7uDGhcsCyiS 9BCRm1I7QTyVQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0692462927 for ; Fri, 15 Sep 2023 15:07:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="B5PtuB+V"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8A128208C; Fri, 15 Sep 2023 15:05:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783137; bh=Bjqt1BC/qeXCOGnSbabt151Jc4j/SYVO0ZOFPLYMUaA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B5PtuB+V+yhQV6srnLGvMPkaJ4ely480w2B+xCZ9cKSpddeMRD+2T316FUgmdsPDJ cinbcRO4czHeR/EPuwI7hE9T95/4RZY+Fg6F0d/PmhcjEAGF4FXhKKKDpNhd1nKHAF +Ah9iKZfhhFUxXNTc4OJ8ptN6KTxX6wo1cXQSEFc= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:45 +0200 Message-ID: <20230915130650.35691-8-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 07/12] libcamera: rpi: Make isRaw/isYuv/isRgb static functions 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Move the existing isRaw()/isYuv()/isRgb()into a static function of PipelineHandlerBase. This will allow then to be shared with the pipeline handler derived class. Signed-off-by: Naushir Patuck Signed-off-by: Jacopo Mondi Reviewed-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 52 +++++++++---------- .../pipeline/rpi/common/pipeline_base.h | 4 ++ 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 2d787f4b99ed..d8e1ebc106af 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -37,12 +37,6 @@ namespace { constexpr unsigned int defaultRawBitDepth = 12; -bool isRaw(const PixelFormat &pixFmt) -{ - /* This test works for both Bayer and raw mono formats. */ - return BayerFormat::fromPixelFormat(pixFmt).isValid(); -} - PixelFormat mbusCodeToPixelFormat(unsigned int mbus_code, BayerFormat::Packing packingReq) { @@ -91,22 +85,6 @@ std::optional findValidColorSpace(const ColorSpace &colourSpace) return std::nullopt; } -bool isRgb(const PixelFormat &pixFmt) -{ - const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); - return info.colourEncoding == PixelFormatInfo::ColourEncodingRGB; -} - -bool isYuv(const PixelFormat &pixFmt) -{ - /* The code below would return true for raw mono streams, so weed those out first. */ - if (isRaw(pixFmt)) - return false; - - const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); - return info.colourEncoding == PixelFormatInfo::ColourEncodingYUV; -} - } /* namespace */ /* @@ -129,7 +107,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validateColorSpaces([[maybe_ for (auto cfg : config_) { /* First fix up raw streams to have the "raw" colour space. */ - if (isRaw(cfg.pixelFormat)) { + if (PipelineHandlerBase::isRaw(cfg.pixelFormat)) { /* If there was no value here, that doesn't count as "adjusted". */ if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw) status = Adjusted; @@ -156,13 +134,13 @@ CameraConfiguration::Status RPiCameraConfiguration::validateColorSpaces([[maybe_ if (cfg.colorSpace == ColorSpace::Raw) continue; - if (isYuv(cfg.pixelFormat) && cfg.colorSpace != yuvColorSpace_) { + if (PipelineHandlerBase::isYuv(cfg.pixelFormat) && cfg.colorSpace != yuvColorSpace_) { /* Again, no value means "not adjusted". */ if (cfg.colorSpace) status = Adjusted; cfg.colorSpace = yuvColorSpace_; } - if (isRgb(cfg.pixelFormat) && cfg.colorSpace != rgbColorSpace_) { + if (PipelineHandlerBase::isRgb(cfg.pixelFormat) && cfg.colorSpace != rgbColorSpace_) { /* Be nice, and let the YUV version count as non-adjusted too. */ if (cfg.colorSpace && cfg.colorSpace != yuvColorSpace_) status = Adjusted; @@ -199,7 +177,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() std::vector rawStreams, outStreams; for (const auto &[index, cfg] : utils::enumerate(config_)) { - if (isRaw(cfg.pixelFormat)) + if (PipelineHandlerBase::isRaw(cfg.pixelFormat)) rawStreams.emplace_back(index, &cfg); else outStreams.emplace_back(index, &cfg); @@ -347,6 +325,28 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() return status; } +bool PipelineHandlerBase::isRgb(const PixelFormat &pixFmt) +{ + const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); + return info.colourEncoding == PixelFormatInfo::ColourEncodingRGB; +} + +bool PipelineHandlerBase::isYuv(const PixelFormat &pixFmt) +{ + /* The code below would return true for raw mono streams, so weed those out first. */ + if (PipelineHandlerBase::isRaw(pixFmt)) + return false; + + const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); + return info.colourEncoding == PixelFormatInfo::ColourEncodingYUV; +} + +bool PipelineHandlerBase::isRaw(const PixelFormat &pixFmt) +{ + /* This test works for both Bayer and raw mono formats. */ + return BayerFormat::fromPixelFormat(pixFmt).isValid(); +} + V4L2DeviceFormat PipelineHandlerBase::toV4L2DeviceFormat(const V4L2VideoDevice *dev, const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 3e7c487fb0bf..135b74392140 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -213,6 +213,10 @@ public: { } + static bool isRgb(const PixelFormat &pixFmt); + static bool isYuv(const PixelFormat &pixFmt); + static bool isRaw(const PixelFormat &pixFmt); + static V4L2DeviceFormat toV4L2DeviceFormat(const V4L2VideoDevice *dev, const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq); From patchwork Fri Sep 15 13:06:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19027 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 D077EC3260 for ; Fri, 15 Sep 2023 13:07:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2A87E6293A; Fri, 15 Sep 2023 15:07:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783238; bh=BLmSo05O9D/oTNRavJ4KE9mPpSeGRwlq9uxNQmydyJY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=h9d5XcfMhOOEU/gTc/ChFsZKpdXZ6DZI6U4BynLmo0TNqb/SNt9XPDFgPqmbx+cVm V+zzkjnupe0CvT21l0ie0US6rRRxdOiKk05swGbwRIug/xa6AKdzF27KjeLCeGBeDa TCDoItIdv/H8FAT3zAXA0RXu+Av+EMw5qhXF81HubS8GKZyZaInXUT3OLvsf0yOYVo 2LUq2aiS1IRij7fHcXWArZ2OvOYNQA8rHFjvJ82NI5vqBBg4BCiW/yU8cTtKbgbmKw sOLiBN23/FI4ezxguhFdZBzOd2oezmNepcAcO+tC3dl9gjX8XpP29jQX6GxEyjN9gF 3RUzrf4xSaSwg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D564628EC for ; Fri, 15 Sep 2023 15:07:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MikrQn/p"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ED26712AE; Fri, 15 Sep 2023 15:05:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783138; bh=BLmSo05O9D/oTNRavJ4KE9mPpSeGRwlq9uxNQmydyJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MikrQn/pjGmxXJMZ/YOAde0ApoXuLg/EW0LPRBtoc1KrivnVJ26jQy+MaZkIz/JCh ww7c16DC7zQL4dTgchjhisuBedJaBVTpb7zetoiube/QSiFBrDPsllHbER4KtJIGRM Eu5arnGrc/htz/hms0TuwrNI6UHj8rz9I54oeGFg= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:46 +0200 Message-ID: <20230915130650.35691-9-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 08/12] libcamera: rpi: Cache rawStreams and outStreams 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Currently, the stream configuration is stored in two vectors, rawStreams and outStreams for convenience. However, these vectors are constructed in both platformValidate() and platformConfigure(). This change caches these vectors in the RPiCameraConfiguration class to construct them only once in platformValidate(). Pass a pointer to the current configuration to platformValidate() and platformConfigure() so that they can access the streams vectors. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 50 +++++++------------ .../pipeline/rpi/common/pipeline_base.h | 42 ++++++++-------- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 20 ++++---- 3 files changed, 48 insertions(+), 64 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index d8e1ebc106af..0aa0c3a0fc7d 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -175,19 +175,21 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() if (transform != requestedTransform) status = Adjusted; - std::vector rawStreams, outStreams; + rawStreams_.clear(); + outStreams_.clear(); + for (const auto &[index, cfg] : utils::enumerate(config_)) { if (PipelineHandlerBase::isRaw(cfg.pixelFormat)) - rawStreams.emplace_back(index, &cfg); + rawStreams_.emplace_back(index, &cfg); else - outStreams.emplace_back(index, &cfg); + outStreams_.emplace_back(index, &cfg); } /* Sort the streams so the highest resolution is first. */ - std::sort(rawStreams.begin(), rawStreams.end(), + std::sort(rawStreams_.begin(), rawStreams_.end(), [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); - std::sort(outStreams.begin(), outStreams.end(), + std::sort(outStreams_.begin(), outStreams_.end(), [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); /* Compute the sensor's format then do any platform specific fixups. */ @@ -198,14 +200,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() /* Use the application provided sensor configuration. */ bitDepth = sensorConfig.bitDepth; sensorSize = sensorConfig.outputSize; - } else if (!rawStreams.empty()) { + } else if (!rawStreams_.empty()) { /* Use the RAW stream format and size. */ - BayerFormat bayerFormat = BayerFormat::fromPixelFormat(rawStreams[0].cfg->pixelFormat); + BayerFormat bayerFormat = BayerFormat::fromPixelFormat(rawStreams_[0].cfg->pixelFormat); bitDepth = bayerFormat.bitDepth; - sensorSize = rawStreams[0].cfg->size; + sensorSize = rawStreams_[0].cfg->size; } else { bitDepth = defaultRawBitDepth; - sensorSize = outStreams[0].cfg->size; + sensorSize = outStreams_[0].cfg->size; } sensorFormat_ = data_->findBestFormat(sensorSize, bitDepth); @@ -226,12 +228,12 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() } /* Do any platform specific fixups. */ - status = data_->platformValidate(this, rawStreams, outStreams); + status = data_->platformValidate(this); if (status == Invalid) return Invalid; /* Further fixups on the RAW streams. */ - for (auto &raw : rawStreams) { + for (auto &raw : rawStreams_) { StreamConfiguration &cfg = config_.at(raw.index); V4L2DeviceFormat rawFormat; @@ -269,7 +271,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() } /* Further fixups on the ISP output streams. */ - for (auto &out : outStreams) { + for (auto &out : outStreams_) { StreamConfiguration &cfg = config_.at(out.index); PixelFormat &cfgPixFmt = cfg.pixelFormat; V4L2VideoDevice::Formats fmts = out.dev->formats(); @@ -489,24 +491,6 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) for (auto const stream : data->streams_) stream->clearFlags(StreamFlag::External); - std::vector rawStreams, ispStreams; - - for (unsigned i = 0; i < config->size(); i++) { - StreamConfiguration *cfg = &config->at(i); - - if (isRaw(cfg->pixelFormat)) - rawStreams.emplace_back(i, cfg); - else - ispStreams.emplace_back(i, cfg); - } - - /* Sort the streams so the highest resolution is first. */ - std::sort(rawStreams.begin(), rawStreams.end(), - [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); - - std::sort(ispStreams.begin(), ispStreams.end(), - [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; }); - /* * Apply the format on the sensor with any cached transform. * @@ -531,9 +515,9 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) /* Use the user requested packing/bit-depth. */ std::optional packing; - if (!rawStreams.empty()) { + if (!rpiConfig->rawStreams_.empty()) { BayerFormat bayerFormat = - BayerFormat::fromPixelFormat(rawStreams[0].cfg->pixelFormat); + BayerFormat::fromPixelFormat(rpiConfig->rawStreams_[0].cfg->pixelFormat); packing = bayerFormat.packing; } @@ -541,7 +525,7 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) * Platform specific internal stream configuration. This also assigns * external streams which get configured below. */ - ret = data->platformConfigure(sensorFormat, packing, rawStreams, ispStreams); + ret = data->platformConfigure(sensorFormat, packing, rpiConfig); if (ret) return ret; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 135b74392140..1a3a13dbb6cf 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -57,29 +57,10 @@ public: { } - struct StreamParams { - StreamParams() - : index(0), cfg(nullptr), dev(nullptr) - { - } - - StreamParams(unsigned int index_, StreamConfiguration *cfg_) - : index(index_), cfg(cfg_), dev(nullptr) - { - } - - unsigned int index; - StreamConfiguration *cfg; - V4L2VideoDevice *dev; - }; - - virtual CameraConfiguration::Status platformValidate(RPiCameraConfiguration *rpiConfig, - std::vector &rawStreams, - std::vector &outStreams) const = 0; + virtual CameraConfiguration::Status platformValidate(RPiCameraConfiguration *rpiConfig) const = 0; virtual int platformConfigure(const V4L2SubdeviceFormat &sensorFormat, std::optional packing, - std::vector &rawStreams, - std::vector &outStreams) = 0; + const RPiCameraConfiguration *rpiConfig) = 0; virtual void platformStart() = 0; virtual void platformStop() = 0; @@ -270,6 +251,25 @@ public: /* The sensor format computed in validate() */ V4L2SubdeviceFormat sensorFormat_; + struct StreamParams { + StreamParams() + : index(0), cfg(nullptr), dev(nullptr) + { + } + + StreamParams(unsigned int index_, StreamConfiguration *cfg_) + : index(index_), cfg(cfg_), dev(nullptr) + { + } + + unsigned int index; + StreamConfiguration *cfg; + V4L2VideoDevice *dev; + }; + + std::vector rawStreams_; + std::vector outStreams_; + private: const CameraData *data_; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 2670eb8c4bbc..2308577a613b 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -25,6 +25,7 @@ namespace libcamera { LOG_DECLARE_CATEGORY(RPI) using StreamFlag = RPi::Stream::StreamFlag; +using StreamParams = RPi::RPiCameraConfiguration::StreamParams; namespace { @@ -65,9 +66,7 @@ public: { } - CameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig, - std::vector &rawStreams, - std::vector &outStreams) const override; + CameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override; int platformPipelineConfigure(const std::unique_ptr &root) override; @@ -118,8 +117,7 @@ private: int platformConfigure(const V4L2SubdeviceFormat &sensorFormat, std::optional packing, - std::vector &rawStreams, - std::vector &outStreams) override; + const RPi::RPiCameraConfiguration *rpiConfig) override; int platformConfigureIpa(ipa::RPi::ConfigParams ¶ms) override; int platformInitIpa([[maybe_unused]] ipa::RPi::InitParams ¶ms) override @@ -395,10 +393,11 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr &camer return 0; } -CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig, - std::vector &rawStreams, - std::vector &outStreams) const +CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const { + std::vector &rawStreams = rpiConfig->rawStreams_; + std::vector &outStreams = rpiConfig->outStreams_; + CameraConfiguration::Status status = CameraConfiguration::Status::Valid; /* Can only output 1 RAW stream, or 2 YUV/RGB streams. */ @@ -503,9 +502,10 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr & int Vc4CameraData::platformConfigure(const V4L2SubdeviceFormat &sensorFormat, std::optional packing, - std::vector &rawStreams, - std::vector &outStreams) + const RPi::RPiCameraConfiguration *rpiConfig) { + const std::vector &rawStreams = rpiConfig->rawStreams_; + const std::vector &outStreams = rpiConfig->outStreams_; int ret; if (!packing) From patchwork Fri Sep 15 13:06:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19028 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 8F90EC32B2 for ; Fri, 15 Sep 2023 13:07:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3FD536292C; Fri, 15 Sep 2023 15:07:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783239; bh=PtshK3Pj861tS2DXW6ssL2SOgjz+CtZH76Y5B/BzOOE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=kHkLGId8/VDleMiBf5rJ5CXb5pwdc3G3pyT3PEPe73jJVWjuga6+sxDQxbyldLrA6 eQDRbMZXdIMuMlaOkOTWDMyupdrUl4eBuYmaMSTNMeXnDV7xRpd5da7Oz4FBa5xAAa I4oymmg8hklM9XpmJFIxlRE4LkSZVPHHxbQusvxoRb9wlWIkL9SeT8qQQgX6cqB/Wp hE0lIIrCh8viiGYjVJhwvzQPC8nIMqZJON8IEqrSHMtT0zCsicA+bBHr3GSdGEcJHt w+K+GwY0WdmcAMyYxuW8srk664/UE8h/3yljECYgFOmUWVrl7wWGQI/33Y7jl+BRhs uoVkQxnhlrfqA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C1BD962911 for ; Fri, 15 Sep 2023 15:07:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gIIOdFkf"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 596292D14; Fri, 15 Sep 2023 15:05:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783138; bh=PtshK3Pj861tS2DXW6ssL2SOgjz+CtZH76Y5B/BzOOE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gIIOdFkfM8Q45l0hyBOjbxLFj3B0nDp5TrN9wRvSgA0ll63b7KaL+vhdZ8EioVDui Oa6DJEr85z73Ml6qPbxQMzjjqUS0yyNN9euaqf9VJUwbWqf3FFpy1wrQcHhKWJL2zc vxXUopyGpwCGL9lH9OALu2qrtH/r++Zt7KwUj8Go= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:47 +0200 Message-ID: <20230915130650.35691-10-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 09/12] libcamera: rpi: Add some helpers to PipelineHandlerBase 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Add a helper updateStreamConfig() that updates the format related fields in a StreamConfiguration from a given V4L2DeviceFormat structure. Add and override to the toV4L2DeviceFormat() helper that returns a V4L2DeviceFormat structure populated from the format related fields in a StreamConfiguration. Both these helper functions will be used in a future commit to simplify the Raspberry Pi pipeline handler configuration/validation code. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 47 +++++++++++++++++++ .../pipeline/rpi/common/pipeline_base.h | 4 ++ 2 files changed, 51 insertions(+) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 0aa0c3a0fc7d..b523d560420a 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -349,6 +349,53 @@ bool PipelineHandlerBase::isRaw(const PixelFormat &pixFmt) return BayerFormat::fromPixelFormat(pixFmt).isValid(); } +/* + * Adjust a StreamConfiguration fields to match a video device format. + * Returns true if the StreamConfiguration has been adjusted. + */ +bool PipelineHandlerBase::updateStreamConfig(StreamConfiguration *stream, + const V4L2DeviceFormat &format) +{ + const PixelFormat &pixFormat = format.fourcc.toPixelFormat(); + bool adjusted = false; + + if (stream->pixelFormat != pixFormat || stream->size != format.size) { + stream->pixelFormat = pixFormat; + stream->size = format.size; + adjusted = true; + } + + if (stream->colorSpace != format.colorSpace) { + stream->colorSpace = format.colorSpace; + adjusted = true; + LOG(RPI, Debug) + << "Color space changed from " + << ColorSpace::toString(stream->colorSpace) << " to " + << ColorSpace::toString(format.colorSpace); + } + + stream->stride = format.planes[0].bpl; + stream->frameSize = format.planes[0].size; + + return adjusted; +} + +/* + * Populate and return a video device format using a StreamConfiguration. */ +V4L2DeviceFormat PipelineHandlerBase::toV4L2DeviceFormat(const V4L2VideoDevice *dev, + const StreamConfiguration *stream) +{ + V4L2DeviceFormat deviceFormat; + + const PixelFormatInfo &info = PixelFormatInfo::info(stream->pixelFormat); + deviceFormat.planesCount = info.numPlanes(); + deviceFormat.fourcc = dev->toV4L2PixelFormat(stream->pixelFormat); + deviceFormat.size = stream->size; + deviceFormat.colorSpace = stream->colorSpace; + + return deviceFormat; +} + V4L2DeviceFormat PipelineHandlerBase::toV4L2DeviceFormat(const V4L2VideoDevice *dev, const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 1a3a13dbb6cf..491c5e98c4a1 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -198,6 +198,10 @@ public: static bool isYuv(const PixelFormat &pixFmt); static bool isRaw(const PixelFormat &pixFmt); + static bool updateStreamConfig(StreamConfiguration *stream, + const V4L2DeviceFormat &format); + static V4L2DeviceFormat toV4L2DeviceFormat(const V4L2VideoDevice *dev, + const StreamConfiguration *stream); static V4L2DeviceFormat toV4L2DeviceFormat(const V4L2VideoDevice *dev, const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq); From patchwork Fri Sep 15 13:06:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19029 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 4372BBD160 for ; Fri, 15 Sep 2023 13:07:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D4E5962925; Fri, 15 Sep 2023 15:07:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783240; bh=iLQ8LBHmiC3945zZsyxvl/bmfpMvg4wmJfLfordAR+I=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=O9I4lwUaFkC0F9/nwDEXjpe4NNqosSmtXKckAtoD3fXYhVeJxXQPi4f0xI0Yd3ZSV gG/jgdG+r1N/AK2AKSRakoUaNM/6PE4hgvJuY1XSB5r5tFDD08ExXE9YM+0pc2dujB lrYuv3ToyRegd7MNxghyTM9p/g8de6fF1zDb4hllBWuD1VgIa5i9EjyjuXgT97vLI1 yzHsf/2+7nOc0qSidvnOx6Sf4Vx6WuHCVwmmUpeEViBOpKieFxVksGwuF0nP3yGBhO BJN/I70Aco+b1h6DD9OKDpxqzLSH2scGAUxq3gA14jSd+TmQiznkmJn0GPcUWvrQOL zVqy4xgcUoY0w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2D4FF6291C for ; Fri, 15 Sep 2023 15:07:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vtXD1oCH"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BA109208C; Fri, 15 Sep 2023 15:05:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783139; bh=iLQ8LBHmiC3945zZsyxvl/bmfpMvg4wmJfLfordAR+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vtXD1oCH4SAffQSKc1HYGGxDlIkmd+2XBg2Vf/kQcNkj0enNDHHkyJYqc0WHUHsbl oWnJ4hZ/GxVpgGd3uPKvHKaiXZSwpvVBdmFR+9LE5NfBd8NcrnTa6WG1uq03XiPuqt 0TrkHuuQXdjx7mpA4rT3jUPw8SGKQPsc1OTEo39g= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:48 +0200 Message-ID: <20230915130650.35691-11-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/12] libcamera: rpi: Simplify validate() and configure() for RAW streams 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck This commit simplifies the validate() and configure() calls in the pipeline handler in a number of ways: - Only pass the RPiCameraConfiguration structure into platformValidate() and platformConfigure(). - Determine the V4L2DeviceFormat structure fields for all streams in validate(), cache them and reuse in configure() instead of re-generating this structure multiple times. - Use the recently added updateStreamConfig() and toV4L2DeviceFormat() helpers to populate fields in the V4L2DeviceFormat and StreamConfiguration structures to reduce code duplication. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 48 +++++-------------- .../pipeline/rpi/common/pipeline_base.h | 5 +- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 35 ++++++++------ 3 files changed, 34 insertions(+), 54 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index b523d560420a..d83811801460 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -234,16 +234,10 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() /* Further fixups on the RAW streams. */ for (auto &raw : rawStreams_) { - StreamConfiguration &cfg = config_.at(raw.index); - - V4L2DeviceFormat rawFormat; - rawFormat.fourcc = raw.dev->toV4L2PixelFormat(cfg.pixelFormat); - rawFormat.size = cfg.size; - rawFormat.colorSpace = cfg.colorSpace; - - int ret = raw.dev->tryFormat(&rawFormat); + int ret = raw.dev->tryFormat(&raw.format); if (ret) return Invalid; + /* * Some sensors change their Bayer order when they are h-flipped * or v-flipped, according to the transform. If this one does, we @@ -251,23 +245,15 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * Note how we must fetch the "native" (i.e. untransformed) Bayer * order, because the sensor may currently be flipped! */ - V4L2PixelFormat fourcc = rawFormat.fourcc; + BayerFormat bayer = BayerFormat::fromPixelFormat(raw.cfg->pixelFormat); if (data_->flipsAlterBayerOrder_) { - BayerFormat bayer = BayerFormat::fromV4L2PixelFormat(fourcc); bayer.order = data_->nativeBayerOrder_; bayer = bayer.transform(combinedTransform_); - fourcc = bayer.toV4L2PixelFormat(); } + raw.cfg->pixelFormat = bayer.toPixelFormat(); - PixelFormat inputPixFormat = fourcc.toPixelFormat(); - if (raw.cfg->size != rawFormat.size || raw.cfg->pixelFormat != inputPixFormat) { - raw.cfg->size = rawFormat.size; - raw.cfg->pixelFormat = inputPixFormat; + if (RPi::PipelineHandlerBase::updateStreamConfig(raw.cfg, raw.format)) status = Adjusted; - } - - raw.cfg->stride = rawFormat.planes[0].bpl; - raw.cfg->frameSize = rawFormat.planes[0].size; } /* Further fixups on the ISP output streams. */ @@ -544,35 +530,25 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) * If the application has provided a sensor configuration apply it * instead of just applying a format. */ - const RPiCameraConfiguration *rpiConfig = - static_cast(config); - V4L2SubdeviceFormat sensorFormat; + RPiCameraConfiguration *rpiConfig = static_cast(config); + V4L2SubdeviceFormat *sensorFormat = &rpiConfig->sensorFormat_; if (rpiConfig->sensorConfig) { ret = data->sensor_->applyConfiguration(rpiConfig->sensorConfig, rpiConfig->combinedTransform_, - &sensorFormat); + sensorFormat); } else { - sensorFormat = rpiConfig->sensorFormat_; - ret = data->sensor_->setFormat(&sensorFormat, + ret = data->sensor_->setFormat(sensorFormat, rpiConfig->combinedTransform_); } if (ret) return ret; - /* Use the user requested packing/bit-depth. */ - std::optional packing; - if (!rpiConfig->rawStreams_.empty()) { - BayerFormat bayerFormat = - BayerFormat::fromPixelFormat(rpiConfig->rawStreams_[0].cfg->pixelFormat); - packing = bayerFormat.packing; - } - /* * Platform specific internal stream configuration. This also assigns * external streams which get configured below. */ - ret = data->platformConfigure(sensorFormat, packing, rpiConfig); + ret = data->platformConfigure(rpiConfig); if (ret) return ret; @@ -636,11 +612,11 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) */ link->setEnabled(true); const MediaPad *sinkPad = link->sink(); - ret = device->setFormat(sinkPad->index(), &sensorFormat); + ret = device->setFormat(sinkPad->index(), sensorFormat); if (ret) { LOG(RPI, Error) << "Failed to set format on " << device->entity()->name() << " pad " << sinkPad->index() - << " with format " << sensorFormat + << " with format " << *sensorFormat << ": " << ret; return ret; } diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 491c5e98c4a1..0c4a59b7f590 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -58,9 +58,7 @@ public: } virtual CameraConfiguration::Status platformValidate(RPiCameraConfiguration *rpiConfig) const = 0; - virtual int platformConfigure(const V4L2SubdeviceFormat &sensorFormat, - std::optional packing, - const RPiCameraConfiguration *rpiConfig) = 0; + virtual int platformConfigure(const RPiCameraConfiguration *rpiConfig) = 0; virtual void platformStart() = 0; virtual void platformStop() = 0; @@ -269,6 +267,7 @@ public: unsigned int index; StreamConfiguration *cfg; V4L2VideoDevice *dev; + V4L2DeviceFormat format; }; std::vector rawStreams_; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 2308577a613b..1a03c88d7ee3 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -115,9 +115,7 @@ private: isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &ispCrop_); } - int platformConfigure(const V4L2SubdeviceFormat &sensorFormat, - std::optional packing, - const RPi::RPiCameraConfiguration *rpiConfig) override; + int platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig) override; int platformConfigureIpa(ipa::RPi::ConfigParams ¶ms) override; int platformInitIpa([[maybe_unused]] ipa::RPi::InitParams ¶ms) override @@ -416,6 +414,9 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig /* Handle flips to make sure to match the RAW stream format. */ if (flipsAlterBayerOrder_) rawBayer = rawBayer.transform(rpiConfig->combinedTransform_); + + /* Apply the user requested packing. */ + rawBayer.packing = BayerFormat::fromPixelFormat(rawStream->pixelFormat).packing; PixelFormat rawFormat = rawBayer.toPixelFormat(); if (rawStream->pixelFormat != rawFormat || @@ -425,6 +426,9 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig status = CameraConfiguration::Adjusted; } + + rawStreams[0].format = + RPi::PipelineHandlerBase::toV4L2DeviceFormat(unicam_[Unicam::Image].dev(), rawStream); } /* @@ -500,23 +504,14 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr & return 0; } -int Vc4CameraData::platformConfigure(const V4L2SubdeviceFormat &sensorFormat, - std::optional packing, - const RPi::RPiCameraConfiguration *rpiConfig) +int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig) { const std::vector &rawStreams = rpiConfig->rawStreams_; const std::vector &outStreams = rpiConfig->outStreams_; int ret; - if (!packing) - packing = BayerFormat::Packing::CSI2; - V4L2VideoDevice *unicam = unicam_[Unicam::Image].dev(); - V4L2DeviceFormat unicamFormat = RPi::PipelineHandlerBase::toV4L2DeviceFormat(unicam, sensorFormat, *packing); - - ret = unicam->setFormat(&unicamFormat); - if (ret) - return ret; + V4L2DeviceFormat unicamFormat; /* * See which streams are requested, and route the user @@ -525,14 +520,24 @@ int Vc4CameraData::platformConfigure(const V4L2SubdeviceFormat &sensorFormat, if (!rawStreams.empty()) { rawStreams[0].cfg->setStream(&unicam_[Unicam::Image]); unicam_[Unicam::Image].setFlags(StreamFlag::External); + unicamFormat = rawStreams[0].format; + } else { + unicamFormat = + RPi::PipelineHandlerBase::toV4L2DeviceFormat(unicam, + rpiConfig->sensorFormat_, + BayerFormat::Packing::CSI2); } + ret = unicam->setFormat(&unicamFormat); + if (ret) + return ret; + ret = isp_[Isp::Input].dev()->setFormat(&unicamFormat); if (ret) return ret; LOG(RPI, Info) << "Sensor: " << sensor_->id() - << " - Selected sensor format: " << sensorFormat + << " - Selected sensor format: " << rpiConfig->sensorFormat_ << " - Selected unicam format: " << unicamFormat; /* Use a sensible small default size if no output streams are configured. */ From patchwork Fri Sep 15 13:06:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19031 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 4F4C7C32B3 for ; Fri, 15 Sep 2023 13:07:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DCA7162939; Fri, 15 Sep 2023 15:07:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783241; bh=HdX7fPUe7yjplSewSAS8Lj7uy5T/cMNB0e+BsE0aDiM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=QHNTVxVXhPwskDgFo3GgXTE7T9W8QmetON1dMqxIMgE2/QBsfBtOl8fbR8MZaalWI eJdB7CyUfuhB719+3BJrjK6B6ja4nbDYLwujwz3PjaJKc+o7ZC67adX8yAWB1bqq2C bSlEG5wjoMtyq+jbE/HUYW/kqkZnfNCRLN8BtiAKk/qvXQ26rsSOQVkaat4/e156l3 W8nSmyGqgog2ZkSM6aU8FPkXOko7buve9HIYf83yjAIlwpFEdKF3l13z2+XUKYp2kj Ic56BAuSIva2YJM+gZW5+aIkoiGhA5TEjCQC89rIGS6V9iXJHe44GvoSjihUgCbxx/ r0gjrLfwAbb9g== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8FA1562925 for ; Fri, 15 Sep 2023 15:07:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gPfiVsNW"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2704E12AE; Fri, 15 Sep 2023 15:05:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783139; bh=HdX7fPUe7yjplSewSAS8Lj7uy5T/cMNB0e+BsE0aDiM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gPfiVsNW4xPEUD2kHTt+i6aUPykkUQrMOyJcK6TCnNrSDiwXQjyQxvBHKysM8JuAH 2OfCE+ah0j4ZOOOT0BWhhH3u4gVzGAD+maWl+EZzH+38KbFfd5mLTtp4ZCNsX56g7B kZ4TM4HAMMktArkLcswn3URN0B7yM//JUNWxcHvA= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:49 +0200 Message-ID: <20230915130650.35691-12-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 11/12] libcamera: rpi: Change default stream formats 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Switch to XRGB8888 as a default Viewfinder role output format, and YUV420 as a default output format for everything else. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index d83811801460..0de91123ee50 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -264,7 +264,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() if (fmts.find(out.dev->toV4L2PixelFormat(cfgPixFmt)) == fmts.end()) { /* If we cannot find a native format, use a default one. */ - cfgPixFmt = formats::NV12; + cfgPixFmt = formats::YUV420; status = Adjusted; } @@ -427,7 +427,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, SpanispFormats(); - pixelFormat = formats::NV12; + pixelFormat = formats::YUV420; /* * Still image codecs usually expect the sYCC color space. * Even RGB codecs will be fine as the RGB we get with the @@ -461,7 +461,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, SpanispFormats(); - pixelFormat = formats::ARGB8888; + pixelFormat = formats::XRGB8888; colorSpace = ColorSpace::Sycc; size = { 800, 600 }; bufferCount = 4; From patchwork Fri Sep 15 13:06:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19030 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 A3A13C32B0 for ; Fri, 15 Sep 2023 13:07:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 65AF46292F; Fri, 15 Sep 2023 15:07:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694783241; bh=t05fFLPiScMNjDYmygJ5MwL6tWEYKYUaHsg2TlIfDeY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=N/r4kDjYC9qBrWtkk/93oMI2VGFCp4L3/ZjNcta4SvE9xTWBqFQ0oqqbRhebQiENT naB5vPo9owUR8JktJ0aZjTs/eyb6OfwLRTYgdV7Xiijxi7uk3iCfzKA8+E1SXs3BjY 3jDTcXla2Hqtov+6vTC0d0y0kLShi87hZtyAlId2rH1x1opYANWj08xzXAduKFMnav aJCNsGOTpA8k9N7xizvZ6Vq+188DNTWaXDBYyY8Hp+LfiaBTiCZrwCNhCpHpU7N8B5 GHBFXwKJsoZSAFQK6XD3rbbqWEFzV8euROTj9QBfWbkjwHshrGVqEukpbAbEGucAxq qK05khYxi68SA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EE3F362928 for ; Fri, 15 Sep 2023 15:07:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MDXXHnRO"; dkim-atps=neutral Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 896A62F6C; Fri, 15 Sep 2023 15:05:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1694783139; bh=t05fFLPiScMNjDYmygJ5MwL6tWEYKYUaHsg2TlIfDeY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MDXXHnROG/E5ttB4RGuQvj1SRoIogwuia5tevmA91cQfCKgkMANTPXDHZeLhlijtc ZV2PU+5MosT+HCGlmeIzAj/wn1sDSG1KTizVMLrPW7spymZ1h0w4dQRGpoTWh+mvjC UrA0g/aYlPuxh9buEqCVOGNl2gB67efkRsZNUijA= To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 15:06:50 +0200 Message-ID: <20230915130650.35691-13-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> References: <20230915130650.35691-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 12/12] libcamera: rpi: Simplify validate() and configure() for YUV/RGB streams 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck This commit simplifies the validate() and configure() calls in the pipeline handler in a number of ways: - Determine the V4L2DeviceFormat structure fields for all streams in validate(), cache them and reuse in configure() instead of re-generating this structure multiple times. - Remove setting a default pixel format in validate(), this code patch will not be used. - Use the recently added updateStreamConfig() and toV4L2DeviceFormat() helpers to populate fields in the V4L2DeviceFormat and StreamConfiguration structures to reduce code duplication. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- .../pipeline/rpi/common/pipeline_base.cpp | 49 ++++--------------- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 15 ++---- 2 files changed, 12 insertions(+), 52 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 0de91123ee50..51d54e57ceaf 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -258,56 +258,25 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() /* Further fixups on the ISP output streams. */ for (auto &out : outStreams_) { - StreamConfiguration &cfg = config_.at(out.index); - PixelFormat &cfgPixFmt = cfg.pixelFormat; - V4L2VideoDevice::Formats fmts = out.dev->formats(); - - if (fmts.find(out.dev->toV4L2PixelFormat(cfgPixFmt)) == fmts.end()) { - /* If we cannot find a native format, use a default one. */ - cfgPixFmt = formats::YUV420; - status = Adjusted; - } - - V4L2DeviceFormat format; - format.fourcc = out.dev->toV4L2PixelFormat(cfg.pixelFormat); - format.size = cfg.size; /* - * platformValidate may have worked out the correct stride so we - * must pass it in. This also needs the planesCount to be set - * correctly or the stride will be ignored. + * We want to send the associated YCbCr info through to the driver. + * + * But for RGB streams, the YCbCr info gets overwritten on the way back + * so we must check against what the stream cfg says, not what we actually + * requested (which carefully included the YCbCr info)! */ - const PixelFormat &pixFormat = format.fourcc.toPixelFormat(); - const PixelFormatInfo &info = PixelFormatInfo::info(pixFormat); - format.planesCount = info.numPlanes(); - format.planes[0].bpl = cfg.stride; - - /* We want to send the associated YCbCr info through to the driver. */ - format.colorSpace = yuvColorSpace_; + out.format.colorSpace = yuvColorSpace_; LOG(RPI, Debug) - << "Try color space " << ColorSpace::toString(cfg.colorSpace); + << "Try color space " << ColorSpace::toString(out.cfg->colorSpace); - int ret = out.dev->tryFormat(&format); + int ret = out.dev->tryFormat(&out.format); if (ret) return Invalid; - /* - * But for RGB streams, the YCbCr info gets overwritten on the way back - * so we must check against what the stream cfg says, not what we actually - * requested (which carefully included the YCbCr info)! - */ - if (cfg.colorSpace != format.colorSpace) { + if (RPi::PipelineHandlerBase::updateStreamConfig(out.cfg, out.format)) status = Adjusted; - LOG(RPI, Debug) - << "Color space changed from " - << ColorSpace::toString(cfg.colorSpace) << " to " - << ColorSpace::toString(format.colorSpace); - } - - cfg.colorSpace = format.colorSpace; - cfg.stride = format.planes[0].bpl; - cfg.frameSize = format.planes[0].size; } return status; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 1a03c88d7ee3..a1813ba65725 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -457,6 +457,8 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig * have that fixed up in the code above. */ outStreams[i].dev = isp_[i == 0 ? Isp::Output0 : Isp::Output1].dev(); + + outStreams[i].format = RPi::PipelineHandlerBase::toV4L2DeviceFormat(outStreams[i].dev, outStreams[i].cfg); } return status; @@ -549,11 +551,7 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi /* The largest resolution gets routed to the ISP Output 0 node. */ RPi::Stream *stream = i == 0 ? &isp_[Isp::Output0] : &isp_[Isp::Output1]; - - V4L2PixelFormat fourcc = stream->dev()->toV4L2PixelFormat(cfg->pixelFormat); - format.size = cfg->size; - format.fourcc = fourcc; - format.colorSpace = cfg->colorSpace; + format = outStreams[i].format; LOG(RPI, Debug) << "Setting " << stream->name() << " to " << format; @@ -562,13 +560,6 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi if (ret) return -EINVAL; - if (format.size != cfg->size || format.fourcc != fourcc) { - LOG(RPI, Error) - << "Failed to set requested format on " << stream->name() - << ", returned " << format; - return -EINVAL; - } - LOG(RPI, Debug) << "Stream " << stream->name() << " has color space " << ColorSpace::toString(cfg->colorSpace);