From patchwork Wed Sep 20 15:19:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 19061 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 14159BE080 for ; Wed, 20 Sep 2023 15:19:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BE16661EA6; Wed, 20 Sep 2023 17:19:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1695223188; bh=cLqnvuCYesf4LzJla4naO3hwhosEhFW4p3wRdVojALI=; 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=3DR+2wvXRfguEjrIHIZqU9qXhI9QVn06OHBbTUnRMu/QQykWrU57zj4YxkXdl34tm xbw51pLKJNSXEBcDIrbcWugx2pVMLrunet+Ys+b96NAlyEx54sWE/LPWGVlLbkKQoI 2bGAV5O31xcQQHNCIZWr0FzAW05BjVrD816qqGPcqYGdyBZrBAhJNjgadCaWkIQhkA HX3ZG540uX9YhGScOAMs9UynkqAS/ccWYAex7vQ7UXB7VSweSK+YdZg2ZXSSfBD7Zv MZ0RtLmkKE7SNoyK9Uq+u1+jS7cnN25QfeZlCLq1WPs3ONoUOPZhhJUiZG5D0FwhFq iuvSbuMijGyAw== Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3226A60388 for ; Wed, 20 Sep 2023 17:19:47 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="YDWvHaz0"; dkim-atps=neutral Received: by mail-lj1-x231.google.com with SMTP id 38308e7fff4ca-2bfed7c4e6dso74010521fa.1 for ; Wed, 20 Sep 2023 08:19:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695223186; x=1695827986; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=S2brHV0UWTwGPZcCBUIQTOIhY0SvitvKrOiswkeZSYM=; b=YDWvHaz0JSrd7T+MqALPO0tNhH0iFvtpJabF9F0iPycvxtUyW8FRPngr7oV+tSMjLC onkGZEqh5vwtrpvXCrn9mOlwMOEf41GIbET6Mwkij11n4v2tUHmdBxWJf4vvh6s3rkIZ BawSigaGQf8fRwVRSaDway/+Meqgi4Kta+jdi7KM09UhenpFsEvERexUANjNPEVb0FU1 7CA2E9E1OajEUq8IjKcDmSbpTrF5BGtRZSYiOLxqop+vuTrVOocA3PGZHpZ9cywadDm4 /+2c+HHrL1OyhIXLGpd2qJgCIZjtMcVdn9OOxdtVgCA8gyvNdy8iet+k+0VNoZrfwI0T HXwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695223186; x=1695827986; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S2brHV0UWTwGPZcCBUIQTOIhY0SvitvKrOiswkeZSYM=; b=T1zRNSbfG9j0Gu42FqKMxufNuoFSm1b3EdolSq6i2y6AM1PNA6Lcdyw20Kki0GvbgD sGX0St0DX9EVXLYYrMrr+jiswvZACTr4M5yHBcB30jxZQkq255iGEczIp3bPeFmKSHdw yT7v9CBoJusFTwOSx5gEz5WxTdRtA3QmaxGEaEuHjTycCnFPUpDQgEzC18vspspFU2Gr xsJp3wU0IxQoGeTjJD8dU2l4j4Zyk1RguBH8eLTP1khKA0DAWibFRRzlAQSVd1uPo9T9 fWlSBOueDEeQnoADJiFiLsZEjHMnrLksA3Sjlko8NW+MDjxtVkh5Fro6rTO5hXLWWXZ8 Rz7g== X-Gm-Message-State: AOJu0YwdbV5doXGn5B4IB3iOEjfte4KrEwdBYzkaNKh9FpF2HL0+VnGo QlKi67VMMLWoJ14EIKV25QtC85zn7DF0JdJvYCc= X-Google-Smtp-Source: AGHT+IEF+FEJkbw1jq88NkFQsQPsdpcU6O8fNJZEhOG7JbdxBrJxI8MuXKNkVkQ7QLZf6P7A0s7TIA== X-Received: by 2002:a2e:878d:0:b0:2bf:ec8e:97c9 with SMTP id n13-20020a2e878d000000b002bfec8e97c9mr2348057lji.17.1695223186569; Wed, 20 Sep 2023 08:19:46 -0700 (PDT) Received: from Lat-5310.. ([87.116.162.81]) by smtp.gmail.com with ESMTPSA id h24-20020a170906829800b009ae0042e48bsm5376736ejx.5.2023.09.20.08.19.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 08:19:46 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Sep 2023 18:19:18 +0300 Message-Id: <20230920151921.31273-2-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230920151921.31273-1-andrey.konovalov@linaro.org> References: <20230920151921.31273-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/4] libcamera: converter: a few fixes to ConverterFactoryBase documentation 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: Andrey Konovalov via libcamera-devel From: Andrey Konovalov Reply-To: Andrey Konovalov Cc: jacopo.mondi@ideasonboard.com, bryan.odonoghue@linaro.org, srinivas.kandagatla@linaro.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Andrey Konovalov --- src/libcamera/converter.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp index fa0f1ec8..466f8421 100644 --- a/src/libcamera/converter.cpp +++ b/src/libcamera/converter.cpp @@ -199,16 +199,18 @@ ConverterFactoryBase::ConverterFactoryBase(const std::string name, std::initiali /** * \fn ConverterFactoryBase::compatibles() - * \return The names compatibles + * \return The compatibles */ /** - * \brief Create an instance of the converter corresponding to a named factory - * \param[in] media Name of the factory + * \brief Create an instance of the converter corresponding to the media device + * \param[in] media the media device to create the converter for * * \return A unique pointer to a new instance of the converter subclass - * corresponding to the named factory or one of its alias. Otherwise a null - * pointer if no such factory exists + * corresponding to the media device. The converter is created by the factory + * the name or the alias of which equals to the media device driver name. + * If the media device driver name doesn't match anything a null pointer is + * returned. */ std::unique_ptr ConverterFactoryBase::create(MediaDevice *media) { @@ -236,10 +238,11 @@ std::unique_ptr ConverterFactoryBase::create(MediaDevice *media) } /** - * \brief Add a converter class to the registry + * \brief Add a converter factory to the registry * \param[in] factory Factory to use to construct the converter class * - * The caller is responsible to guarantee the uniqueness of the converter name. + * The caller is responsible to guarantee the uniqueness of the converter + * factory name. */ void ConverterFactoryBase::registerType(ConverterFactoryBase *factory) { From patchwork Wed Sep 20 15:19:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 19062 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 97E5BBE080 for ; Wed, 20 Sep 2023 15:19:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 42E3F6294A; Wed, 20 Sep 2023 17:19:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1695223191; bh=2Njc0O7Ob11wQMCP+v1HytL2/9nJoKyaxnVb/jvHmfg=; 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=QhzD/HGig1H/Cf7vGHYBf6br3hIaqoRINKnqsHhWd7TxSUwPHgRkn30ijiOBtTise sIiljWKF3ZFYlF50msUqv83LA7SZVE1L2Jzyn1WCpav/CnlFaDUXzUNQVKo1/G/GFh 9yYT5mvT/nMdZgGEWL+hapD/UkzE0mTPypXF+ZHcuoIu+YgPouan3JhUFpDXKYDZ/t jhK5iZeBUZdGVn2CqRCB4xRc63Jbxkf/rFCAe0+ytVajl6KkpD5usjHWtR8soAS57C i9YWbO0jzEzQ9e5aW55zFMv5K4g8nbm0G9EcBJCyxCxouf4YRVndevJY9Hm3veUw/y +SWuq0qDWznWw== Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8B4B160388 for ; Wed, 20 Sep 2023 17:19:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="FueLl9o+"; dkim-atps=neutral Received: by mail-ej1-x62d.google.com with SMTP id a640c23a62f3a-9ae2cc4d17eso253302166b.1 for ; Wed, 20 Sep 2023 08:19:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695223189; x=1695827989; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=G2NSitUIDldnJJ4gfjSXMsL6xctreIOQIZGGhC40Bg8=; b=FueLl9o+/N1flf2eAKoPGKyzUWRF3ZhgaTMh+5nN4RsoDU80mkpIEffmOqZFjnGl0Z SRGfZfpaniO3s64jy8xh2QaUh/lmedrFRlxR2iqfeytQoYFwIgG232WCIEIQedlwa2Zr ScANqUg7bGgzpblkb5rNDVL1/hYWM5qPg06QslqaWayLmTTlvQ0x4yQzsi8wpiXBu+3W rcfPyoJ70cgT8WOalvwjYVjhkN5KfAPu0reihdBwLIkEsNlsy9Jkjlx0ykZDP2pyk688 EOGsBmdYevfcySMl5D0PmkULgtdeG5EEB36mGntAU0sWjBiVXhAkNkoHdGdTUjJMwivQ rFrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695223189; x=1695827989; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G2NSitUIDldnJJ4gfjSXMsL6xctreIOQIZGGhC40Bg8=; b=KY1hnmdAVyjy5g4B/tFqqzZU3mZAEnaGRg1CaOZzZnlJL/KfqsmVEw7XF7pyXen6lX j6+CKKLFXzwyUI200uofpx0nrSEe9zKyKYje0Tvvwy+LmxpElQJuk/gq93j1os2O7KTi Zmxa+W21ppy0WBrdgHZdQZ1BbWivFlqZwDOVzpb5HKnF8LlptJeu6C7sIqXVzl/V+wV9 0N8Y6bTwygDvkMYfAT1LXge88w9E1VHW4IqCBG3FDCHG6IPN1jLnJNSNDhuP10lPXEnm FF4/EutpRkJXfcQOyzk4W5s+RRru1nE2NUAO/Da8DkMUr46OpZKcm+kw8x8Z5yw/Y3qf dqIQ== X-Gm-Message-State: AOJu0YzWJIbC7N99KgB0r9x4n2RggYa4bDcWd4xBZztbbyHx8jECL778 H6WUdyal3gjbcnVP4wgBzjf/MXoej2qE6JnT0YI= X-Google-Smtp-Source: AGHT+IE2yHFzE7K0dLQIlqXKpFP1T9/giIIdTYwlTsnZp4hiB06RWm2LyfhVb1R2RSvGiil0w3GdqA== X-Received: by 2002:a17:906:1d2:b0:9a1:cbe4:d029 with SMTP id 18-20020a17090601d200b009a1cbe4d029mr2283360ejj.74.1695223189052; Wed, 20 Sep 2023 08:19:49 -0700 (PDT) Received: from Lat-5310.. ([87.116.162.81]) by smtp.gmail.com with ESMTPSA id h24-20020a170906829800b009ae0042e48bsm5376736ejx.5.2023.09.20.08.19.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 08:19:48 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Sep 2023 18:19:19 +0300 Message-Id: <20230920151921.31273-3-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230920151921.31273-1-andrey.konovalov@linaro.org> References: <20230920151921.31273-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/4] libcamera: converter: make using MediaDevice optional for the Converter 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: Andrey Konovalov via libcamera-devel From: Andrey Konovalov Reply-To: Andrey Konovalov Cc: jacopo.mondi@ideasonboard.com, bryan.odonoghue@linaro.org, srinivas.kandagatla@linaro.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Make Converter a bit more generic by making pointer to MediaDevice an optional argument for Converter::Converter(), ConverterFactoryBase::create(), ConverterFactoryBase::createInstance(), and ConverterFactory::createInstance() functions. Instead of the MediaDevice driver name, use a generic string to match against the convertor factory name and its compatibles list. For MediaDevice based converters this string will be the MediaDevice driver name as before. Signed-off-by: Andrey Konovalov --- include/libcamera/internal/converter.h | 9 ++-- src/libcamera/converter.cpp | 53 ++++++++++++++---------- src/libcamera/pipeline/simple/simple.cpp | 33 +++++++++++---- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h index 834ec5ab..d0c70296 100644 --- a/include/libcamera/internal/converter.h +++ b/include/libcamera/internal/converter.h @@ -2,6 +2,7 @@ /* * Copyright (C) 2020, Laurent Pinchart * Copyright 2022 NXP + * Copyright 2023, Linaro Ltd * * converter.h - Generic format converter interface */ @@ -31,7 +32,7 @@ struct StreamConfiguration; class Converter { public: - Converter(MediaDevice *media); + Converter(MediaDevice *media = nullptr); virtual ~Converter(); virtual int loadConfiguration(const std::string &filename) = 0; @@ -72,7 +73,7 @@ public: const std::vector &compatibles() const { return compatibles_; } - static std::unique_ptr create(MediaDevice *media); + static std::unique_ptr create(std::string name, MediaDevice *media = nullptr); static std::vector &factories(); static std::vector names(); @@ -81,7 +82,7 @@ private: static void registerType(ConverterFactoryBase *factory); - virtual std::unique_ptr createInstance(MediaDevice *media) const = 0; + virtual std::unique_ptr createInstance(MediaDevice *media = nullptr) const = 0; std::string name_; std::vector compatibles_; @@ -96,7 +97,7 @@ public: { } - std::unique_ptr createInstance(MediaDevice *media) const override + std::unique_ptr createInstance(MediaDevice *media = nullptr) const override { return std::make_unique<_Converter>(media); } diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp index 466f8421..5070eabc 100644 --- a/src/libcamera/converter.cpp +++ b/src/libcamera/converter.cpp @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright 2022 NXP + * Copyright 2023 Linaro Ltd * * converter.cpp - Generic format converter interface */ @@ -13,8 +14,6 @@ #include "libcamera/internal/media_device.h" -#include "linux/media.h" - /** * \file internal/converter.h * \brief Abstract converter @@ -38,26 +37,28 @@ LOG_DEFINE_CATEGORY(Converter) /** * \brief Construct a Converter instance - * \param[in] media The media device implementing the converter + * \param[in] media The media device implementing the converter (optional) * * This searches for the entity implementing the data streaming function in the * media graph entities and use its device node as the converter device node. */ Converter::Converter(MediaDevice *media) { - const std::vector &entities = media->entities(); - auto it = std::find_if(entities.begin(), entities.end(), - [](MediaEntity *entity) { - return entity->function() == MEDIA_ENT_F_IO_V4L; - }); - if (it == entities.end()) { - LOG(Converter, Error) - << "No entity suitable for implementing a converter in " - << media->driver() << " entities list."; - return; + if (media) { + const std::vector &entities = media->entities(); + auto it = std::find_if(entities.begin(), entities.end(), + [](MediaEntity *entity) { + return entity->function() == MEDIA_ENT_F_IO_V4L; + }); + if (it == entities.end()) { + LOG(Converter, Error) + << "No entity suitable for implementing a converter in " + << media->driver() << " entities list."; + return; + } + + deviceNode_ = (*it)->deviceNode(); } - - deviceNode_ = (*it)->deviceNode(); } Converter::~Converter() @@ -162,7 +163,8 @@ Converter::~Converter() /** * \fn Converter::deviceNode() * \brief The converter device node attribute accessor - * \return The converter device node string + * \return The converter device node string. If there is no device node for + * the converter returnes an empty string. */ /** @@ -203,8 +205,13 @@ ConverterFactoryBase::ConverterFactoryBase(const std::string name, std::initiali */ /** - * \brief Create an instance of the converter corresponding to the media device - * \param[in] media the media device to create the converter for + * \brief Create an instance of the converter corresponding to the converter + * name + * \param[in] name the name of the converter to create + * \param[in] media the media device to create the converter for (optional) + * + * The converter \a name must match the name of the converter factory, or one + * of its compatibles. * * \return A unique pointer to a new instance of the converter subclass * corresponding to the media device. The converter is created by the factory @@ -212,22 +219,22 @@ ConverterFactoryBase::ConverterFactoryBase(const std::string name, std::initiali * If the media device driver name doesn't match anything a null pointer is * returned. */ -std::unique_ptr ConverterFactoryBase::create(MediaDevice *media) +std::unique_ptr ConverterFactoryBase::create(std::string name, MediaDevice *media) { const std::vector &factories = ConverterFactoryBase::factories(); for (const ConverterFactoryBase *factory : factories) { const std::vector &compatibles = factory->compatibles(); - auto it = std::find(compatibles.begin(), compatibles.end(), media->driver()); + auto it = std::find(compatibles.begin(), compatibles.end(), name); - if (it == compatibles.end() && media->driver() != factory->name_) + if (it == compatibles.end() && name != factory->name_) continue; LOG(Converter, Debug) << "Creating converter from " << factory->name_ << " factory with " - << (it == compatibles.end() ? "no" : media->driver()) << " alias."; + << (it == compatibles.end() ? "no" : name) << " alias."; std::unique_ptr converter = factory->createInstance(media); if (converter->isValid()) @@ -318,7 +325,7 @@ std::vector &ConverterFactoryBase::factories() /** * \fn ConverterFactory::createInstance() const * \brief Create an instance of the Converter corresponding to the factory - * \param[in] media Media device pointer + * \param[in] media Media device pointer (optional) * \return A unique pointer to a newly constructed instance of the Converter * subclass corresponding to the factory */ diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 05ba76bc..3f1b523a 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -178,20 +178,26 @@ LOG_DEFINE_CATEGORY(SimplePipeline) class SimplePipelineHandler; +enum class ConverterFlag { + NoFlag = 0, + MediaDevice = (1 << 0), +}; +using ConverterFlags = Flags; + struct SimplePipelineInfo { const char *driver; /* * Each converter in the list contains the name * and the number of streams it supports. */ - std::vector> converters; + std::vector> converters; }; namespace { static const SimplePipelineInfo supportedDevices[] = { { "dcmipp", {} }, - { "imx7-csi", { { "pxp", 1 } } }, + { "imx7-csi", { { ConverterFlag::MediaDevice, "pxp", 1 } } }, { "j721e-csi2rx", {} }, { "mxc-isi", {} }, { "qcom-camss", {} }, @@ -330,6 +336,7 @@ public: V4L2VideoDevice *video(const MediaEntity *entity); V4L2Subdevice *subdev(const MediaEntity *entity); + const char *converterName() { return converterName_; } MediaDevice *converter() { return converter_; } protected: @@ -358,6 +365,7 @@ private: MediaDevice *media_; std::map entities_; + const char *converterName_; MediaDevice *converter_; }; @@ -496,8 +504,10 @@ int SimpleCameraData::init() /* Open the converter, if any. */ MediaDevice *converter = pipe->converter(); - if (converter) { - converter_ = ConverterFactoryBase::create(converter); + const char *converterName = pipe->converterName(); + if (converterName) { + LOG(SimplePipeline, Info) << "Creating converter '" << converterName << "'"; + converter_ = ConverterFactoryBase::create(std::string(converterName), converter); if (!converter_) { LOG(SimplePipeline, Warning) << "Failed to create converter, disabling format conversion"; @@ -1409,10 +1419,17 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) if (!media_) return false; - for (const auto &[name, streams] : info->converters) { - DeviceMatch converterMatch(name); - converter_ = acquireMediaDevice(enumerator, converterMatch); - if (converter_) { + for (const auto &[flags, name, streams] : info->converters) { + if (flags & ConverterFlag::MediaDevice) { + DeviceMatch converterMatch(name); + converter_ = acquireMediaDevice(enumerator, converterMatch); + if (converter_) { + converterName_ = name; + numStreams = streams; + break; + } + } else { + converterName_ = name; numStreams = streams; break; } From patchwork Wed Sep 20 15:19:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 19063 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 2F7B9BE080 for ; Wed, 20 Sep 2023 15:19:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF37262949; Wed, 20 Sep 2023 17:19:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1695223193; bh=4eJtoJQZ1Ft0e3FzoISPW1xfhliKRyqmXV3zEncH4hc=; 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=ZokY0Hj9MSpjVeJIGjrUetlLumJCmp7vC/hCs3IHq6Cvd6J2guvefE/KqBX9XZRCf XU4opNC8eODfQUD4LQxRJ+UdARDXR+BhXyPnKEQ6g7GF2Qy2P5chNOlBYHidrjQqhq Z2r6BnjGsvExi0BzJMwfaJQklUMze3AKp/n4QsjekotzakT89ns3/C7H3pOkSyxPvT SH+BV7oWyAWaN8x8odCErG960VPn00eRBxW/XQgwivBhY50s/kOV10MKLcVXdYleTO A3jFQE084bae34w+/TeNHEy1wbHstg5CmXpG5xXqgCTwqxhey/rDMNXqYrI/D0ooB/ ssOIlTrY5PLng== Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6292962947 for ; Wed, 20 Sep 2023 17:19:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="UdjSt4jW"; dkim-atps=neutral Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-9a645e54806so888061966b.0 for ; Wed, 20 Sep 2023 08:19:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695223192; x=1695827992; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RZY5U+ROeuG8Ewb9apD40CBzc+Y9kANtrGRRLQoZKL8=; b=UdjSt4jWp7h94xiMKbv6RvaAvnL/6eVAu5X8H2gOetfdL87cQGUdgcJQ8Z3aPpCqAX Xo1w7sLqtKewtAGcr/7ngutg11X1gTozjRrxQN1ladvtb1++c8W1LaQ+bD945qWJDIlG dJPKwHmegYcSh9s3llmR3ndaKPQ5RK8+UETxAgu04UxUEr9xZX+316bIPw/HuXS6/V4r PG050rupxtiw0YezfC/evmUFLjlsm0zW0wKg/xYxGb978jD4HaPb3mJaW/LVEeX6spWa jQqG69c5aqp+22pvAJJr94aurYVCQPvPzdelnmiyM59kABNnaTcD9lzjxluYXK4v3GXM GdTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695223192; x=1695827992; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RZY5U+ROeuG8Ewb9apD40CBzc+Y9kANtrGRRLQoZKL8=; b=kZsRTC1xsTy1rhOFji6Mz9zcbWu9lpUclmavkczOwYw0zf+ed9rVHa7TdA8QhjNd5C g0CGHPzKOElbSP2gNaVoMIZPywIwoWoHqDWtLyKDB4A+m9W2+gldYDXtmWux8KDupo3T JChxMzpjJTW9AjZnOvhVUB+8D634cf1GK9kRAZLpaNhisSQCd24RT7oekwVBRYKpO57U xpoteFUrNSXnfKTU9zalFOG7RjiuiomnPsyfTNA0QeCIUbO2Xg98M4cYkMRgZV8Ts2+r 1g4Hv/h0YXqmpJ6Jok3bzOiGsBFelpK19iCnJxnpJYbhGGFKPin2j2Gf+6zgcioKZFF+ r4uQ== X-Gm-Message-State: AOJu0YxpdYas4/0AkNaJwOMYvcyxywnDsUFXTXQ9U2XZg7qKF1RtgfCB NXVqDoGuw06109FfZQMPt23F6guK9Aun8xRKqr8= X-Google-Smtp-Source: AGHT+IFapLl9XNU3YxMFD0P2EGl8uKpP3vv70J88F7enBENvj54f2k/cH75vTIyISxcT9bfnaqfmwA== X-Received: by 2002:a17:906:31da:b0:9ae:424b:a92c with SMTP id f26-20020a17090631da00b009ae424ba92cmr2710024ejf.50.1695223191990; Wed, 20 Sep 2023 08:19:51 -0700 (PDT) Received: from Lat-5310.. ([87.116.162.81]) by smtp.gmail.com with ESMTPSA id h24-20020a170906829800b009ae0042e48bsm5376736ejx.5.2023.09.20.08.19.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 08:19:51 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Sep 2023 18:19:20 +0300 Message-Id: <20230920151921.31273-4-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230920151921.31273-1-andrey.konovalov@linaro.org> References: <20230920151921.31273-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 3/4] libcamera: converter: add software converter 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: Andrey Konovalov via libcamera-devel From: Andrey Konovalov Reply-To: Andrey Konovalov Cc: jacopo.mondi@ideasonboard.com, bryan.odonoghue@linaro.org, srinivas.kandagatla@linaro.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the Converter interface to implement bilinear Bayer demosaic filtering and very simple AWB on CPU. The only output format currently supported is RGB888. Signed-off-by: Andrey Konovalov --- .../internal/converter/converter_softw.h | 90 ++++ .../libcamera/internal/converter/meson.build | 1 + src/libcamera/converter/converter_softw.cpp | 410 ++++++++++++++++++ src/libcamera/converter/meson.build | 3 +- 4 files changed, 503 insertions(+), 1 deletion(-) create mode 100644 include/libcamera/internal/converter/converter_softw.h create mode 100644 src/libcamera/converter/converter_softw.cpp diff --git a/include/libcamera/internal/converter/converter_softw.h b/include/libcamera/internal/converter/converter_softw.h new file mode 100644 index 00000000..eff9d6b2 --- /dev/null +++ b/include/libcamera/internal/converter/converter_softw.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * converter_softw.h - interface of software converter (runs 100% on CPU) + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "libcamera/internal/converter.h" + +namespace libcamera { + +class FrameBuffer; +class MediaDevice; +class Size; +class SizeRange; +struct StreamConfiguration; + +class SwConverter : public Converter +{ +public: + SwConverter([[maybe_unused]] MediaDevice *media) + : Converter() {} + + int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } + bool isValid() const { return true; } + + std::vector formats(PixelFormat input); + SizeRange sizes(const Size &input); + + std::tuple + strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size); + + int configure(const StreamConfiguration &inputCfg, + const std::vector> &outputCfg); + int exportBuffers(unsigned int ouput, unsigned int count, + std::vector> *buffers); + + void process(FrameBuffer *input, FrameBuffer *output); + int start(); + void stop(); + + int queueBuffers(FrameBuffer *input, + const std::map &outputs); + +private: + class Isp : public Object + { + public: + Isp(SwConverter *converter) + : converter_(converter) {} + + int configure(const StreamConfiguration &inputCfg, + const StreamConfiguration &outputCfg); + int exportBuffers(unsigned int count, + std::vector> *buffers); + void process(FrameBuffer *input, FrameBuffer *output); + int start(); + void stop(); + + private: + void debayer(uint8_t *dst, const uint8_t *src); + + SwConverter *converter_; + + Thread thread_; + + unsigned int width_; + unsigned int height_; + unsigned int stride_; + Point red_shift_; + + unsigned long rNumerat_, rDenomin_; /* red gain for AWB */ + unsigned long bNumerat_, bDenomin_; /* blue gain for AWB */ + unsigned long gNumerat_, gDenomin_; /* green gain for AWB */ + }; + + std::unique_ptr isp_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/converter/meson.build b/include/libcamera/internal/converter/meson.build index 891e79e7..843a0483 100644 --- a/include/libcamera/internal/converter/meson.build +++ b/include/libcamera/internal/converter/meson.build @@ -1,5 +1,6 @@ # SPDX-License-Identifier: CC0-1.0 libcamera_internal_headers += files([ + 'converter_softw.h', 'converter_v4l2_m2m.h', ]) diff --git a/src/libcamera/converter/converter_softw.cpp b/src/libcamera/converter/converter_softw.cpp new file mode 100644 index 00000000..ad7e6f3d --- /dev/null +++ b/src/libcamera/converter/converter_softw.cpp @@ -0,0 +1,410 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * converter_softw.h - interface of software converter (runs 100% on CPU) + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "libcamera/internal/bayer_format.h" +#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" + +#include "libcamera/internal/converter/converter_softw.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(Converter) + +std::vector SwConverter::formats(PixelFormat input) +{ + std::vector pixelFormats; + BayerFormat inputFormat = BayerFormat::fromPixelFormat(input); + + /* Only RAW10P is currently supported */ + if (inputFormat.bitDepth == 10 && inputFormat.packing == BayerFormat::Packing::CSI2) + pixelFormats.push_back(formats::RGB888); + + if (pixelFormats.empty()) + LOG(Converter, Info) + << "Unsupported input format " << input.toString(); + + return pixelFormats; +} + +SizeRange SwConverter::sizes(const Size &input) +{ + if (input.width < 2 || input.height < 2) { + LOG(Converter, Error) + << "Input format size too small: " << input.toString(); + return {}; + } + + return SizeRange(Size(input.width - 2, input.height - 2)); +} + +std::tuple +SwConverter::strideAndFrameSize(const PixelFormat &pixelFormat, + const Size &size) +{ + /* Only RGB888 output is currently supported */ + if (pixelFormat == formats::RGB888) { + int stride = size.width * 3; + return std::make_tuple(stride, stride * (size.height)); + } + + return std::make_tuple(0, 0); +} + +int SwConverter::configure(const StreamConfiguration &inputCfg, + const std::vector> &outputCfgs) +{ + if (outputCfgs.size() != 1) { + LOG(Converter, Error) + << "Unsupported number of output streams: " + << outputCfgs.size(); + return -EINVAL; + } + + isp_ = std::make_unique(this); + + return isp_->configure(inputCfg, outputCfgs[0]); +} + +int SwConverter::Isp::configure(const StreamConfiguration &inputCfg, + const StreamConfiguration &outputCfg) +{ + BayerFormat bayerFormat = + BayerFormat::fromPixelFormat(inputCfg.pixelFormat); + width_ = inputCfg.size.width; + height_ = inputCfg.size.height; + stride_ = inputCfg.stride; + + if (bayerFormat.bitDepth != 10 || + bayerFormat.packing != BayerFormat::Packing::CSI2 || + width_ < 2 || height_ < 2) { + LOG(Converter, Error) << "Input format " + << inputCfg.size << "-" + << inputCfg.pixelFormat + << "not supported"; + return -EINVAL; + } + + switch (bayerFormat.order) { + case BayerFormat::BGGR: + red_shift_ = Point(0, 0); + break; + case BayerFormat::GBRG: + red_shift_ = Point(1, 0); + break; + case BayerFormat::GRBG: + red_shift_ = Point(0, 1); + break; + case BayerFormat::RGGB: + default: + red_shift_ = Point(1, 1); + break; + } + + if (outputCfg.size.width != width_ - 2 || + outputCfg.size.height != height_ - 2 || + outputCfg.stride != (width_ - 2) * 3 || + outputCfg.pixelFormat != formats::RGB888) { + LOG(Converter, Error) + << "Output format not supported"; + return -EINVAL; + } + + LOG(Converter, Info) << "SwConverter configuration: " + << inputCfg.size << "-" << inputCfg.pixelFormat + << " -> " + << outputCfg.size << "-" << outputCfg.pixelFormat; + + /* set r/g/b gains to 1.0 until frame data collected */ + rNumerat_ = rDenomin_ = 1; + bNumerat_ = bDenomin_ = 1; + gNumerat_ = gDenomin_ = 1; + + return 0; +} + +int SwConverter::exportBuffers(unsigned int output, unsigned int count, + std::vector> *buffers) +{ + /* single output for now */ + if (output >= 1) + return -EINVAL; + + return isp_->exportBuffers(count, buffers); +} + +int SwConverter::Isp::exportBuffers(unsigned int count, + std::vector> *buffers) +{ + /* V4L2_PIX_FMT_BGR24 aka 'BGR3' for output: */ + unsigned int bufSize = (height_ - 2) * (width_ - 2) * 3; + + for (unsigned int i = 0; i < count; i++) { + std::string name = "frame-" + std::to_string(i); + + const int ispFd = memfd_create(name.c_str(), 0); + int ret = ftruncate(ispFd, bufSize); + if (ret < 0) { + LOG(Converter, Error) << "ftruncate() for memfd failed " + << strerror(-ret); + return ret; + } + + FrameBuffer::Plane outPlane; + outPlane.fd = SharedFD(std::move(ispFd)); + outPlane.offset = 0; + outPlane.length = bufSize; + + std::vector planes{ outPlane }; + buffers->emplace_back(std::make_unique(std::move(planes))); + } + + return count; +} + +int SwConverter::Isp::start() +{ + moveToThread(&thread_); + thread_.start(); + return 0; +} + +void SwConverter::Isp::stop() +{ + thread_.exit(); + thread_.wait(); +} + +int SwConverter::start() +{ + return isp_->start(); +} + +void SwConverter::stop() +{ + return isp_->stop(); +} + +int SwConverter::queueBuffers(FrameBuffer *input, + const std::map &outputs) +{ + unsigned int mask = 0; + + /* + * Validate the outputs as a sanity check: at least one output is + * required, all outputs must reference a valid stream and no two + * outputs can reference the same stream. + */ + if (outputs.empty()) + return -EINVAL; + + for (auto [index, buffer] : outputs) { + if (!buffer) + return -EINVAL; + if (index >= 1) /* only single stream atm */ + return -EINVAL; + if (mask & (1 << index)) + return -EINVAL; + + mask |= 1 << index; + } + + process(input, outputs.at(0)); + + return 0; +} + +void SwConverter::process(FrameBuffer *input, FrameBuffer *output) +{ + isp_->invokeMethod(&SwConverter::Isp::process, + ConnectionTypeQueued, input, output); +} + +void SwConverter::Isp::process(FrameBuffer *input, FrameBuffer *output) +{ + /* Copy metadata from the input buffer */ + FrameMetadata &metadata = output->_d()->metadata(); + metadata.status = input->metadata().status; + metadata.sequence = input->metadata().sequence; + metadata.timestamp = input->metadata().timestamp; + + MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read); + MappedFrameBuffer out(output, MappedFrameBuffer::MapFlag::Write); + if (!in.isValid() || !out.isValid()) { + LOG(Converter, Error) << "mmap-ing buffer(s) failed"; + metadata.status = FrameMetadata::FrameError; + converter_->outputBufferReady.emit(output); + converter_->inputBufferReady.emit(input); + return; + } + + debayer(out.planes()[0].data(), in.planes()[0].data()); + metadata.planes()[0].bytesused = out.planes()[0].size(); + + converter_->outputBufferReady.emit(output); + converter_->inputBufferReady.emit(input); +} + +void SwConverter::Isp::debayer(uint8_t *dst, const uint8_t *src) +{ + /* RAW10P input format is assumed */ + + /* output buffer is in BGR24 format and is of (width-2)*(height-2) */ + + int w_out = width_ - 2; + int h_out = height_ - 2; + + unsigned long sumR = 0; + unsigned long sumB = 0; + unsigned long sumG = 0; + + for (int y = 0; y < h_out; y++) { + const uint8_t *pin_base = src + (y + 1) * stride_; + uint8_t *pout = dst + y * w_out * 3; + int phase_y = (y + red_shift_.y) % 2; + + for (int x = 0; x < w_out; x++) { + int phase_x = (x + red_shift_.x) % 2; + int phase = 2 * phase_y + phase_x; + + /* x part of the offset in the input buffer: */ + int x_m1 = x + x / 4; /* offset for (x-1) */ + int x_0 = x + 1 + (x + 1) / 4; /* offset for x */ + int x_p1 = x + 2 + (x + 2) / 4; /* offset for (x+1) */ + /* the colour component value to write to the output */ + unsigned val; + + switch (phase) { + case 0: /* at R pixel */ + /* blue: ((-1,-1)+(1,-1)+(-1,1)+(1,1)) / 4 */ + val = ( *(pin_base + x_m1 - stride_) + + *(pin_base + x_p1 - stride_) + + *(pin_base + x_m1 + stride_) + + *(pin_base + x_p1 + stride_) ) >> 2; + val = val * bNumerat_ / bDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* green: ((0,-1)+(-1,0)+(1,0)+(0,1)) / 4 */ + val = ( *(pin_base + x_0 - stride_) + + *(pin_base + x_p1) + + *(pin_base + x_m1) + + *(pin_base + x_0 + stride_) ) >> 2; + val = val * gNumerat_ / gDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* red: (0,0) */ + val = *(pin_base + x_0); + sumR += val; + val = val * rNumerat_ / rDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + break; + case 1: /* at Gr pixel */ + /* blue: ((0,-1) + (0,1)) / 2 */ + val = ( *(pin_base + x_0 - stride_) + + *(pin_base + x_0 + stride_) ) >> 1; + val = val * bNumerat_ / bDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* green: (0,0) */ + val = *(pin_base + x_0); + sumG += val; + val = val * gNumerat_ / gDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* red: ((-1,0) + (1,0)) / 2 */ + val = ( *(pin_base + x_m1) + + *(pin_base + x_p1) ) >> 1; + val = val * rNumerat_ / rDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + break; + case 2: /* at Gb pixel */ + /* blue: ((-1,0) + (1,0)) / 2 */ + val = ( *(pin_base + x_m1) + + *(pin_base + x_p1) ) >> 1; + val = val * bNumerat_ / bDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* green: (0,0) */ + val = *(pin_base + x_0); + sumG += val; + val = val * gNumerat_ / gDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* red: ((0,-1) + (0,1)) / 2 */ + val = ( *(pin_base + x_0 - stride_) + + *(pin_base + x_0 + stride_) ) >> 1; + val = val * rNumerat_ / rDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + break; + default: /* at B pixel */ + /* blue: (0,0) */ + val = *(pin_base + x_0); + sumB += val; + val = val * bNumerat_ / bDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* green: ((0,-1)+(-1,0)+(1,0)+(0,1)) / 4 */ + val = ( *(pin_base + x_0 - stride_) + + *(pin_base + x_p1) + + *(pin_base + x_m1) + + *(pin_base + x_0 + stride_) ) >> 2; + val = val * gNumerat_ / gDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + /* red: ((-1,-1)+(1,-1)+(-1,1)+(1,1)) / 4 */ + val = ( *(pin_base + x_m1 - stride_) + + *(pin_base + x_p1 - stride_) + + *(pin_base + x_m1 + stride_) + + *(pin_base + x_p1 + stride_) ) >> 2; + val = val * rNumerat_ / rDenomin_; + *pout++ = (uint8_t)std::min(val, 0xffU); + } + } + } + + /* calculate red and blue gains for simple AWB */ + LOG(Converter, Debug) << "sumR = " << sumR + << ", sumB = " << sumB << ", sumG = " << sumG; + + sumG /= 2; /* the number of G pixels is twice as big vs R and B ones */ + + /* normalize red, blue, and green sums to fit into 22-bit value */ + unsigned long fRed = sumR / 0x400000; + unsigned long fBlue = sumB / 0x400000; + unsigned long fGreen = sumG / 0x400000; + unsigned long fNorm = std::max({ 1UL, fRed, fBlue, fGreen }); + sumR /= fNorm; + sumB /= fNorm; + sumG /= fNorm; + + LOG(Converter, Debug) << "fNorm = " << fNorm; + LOG(Converter, Debug) << "Normalized: sumR = " << sumR + << ", sumB= " << sumB << ", sumG = " << sumG; + + /* make sure red/blue gains never exceed approximately 256 */ + unsigned long minDenom; + rNumerat_ = (sumR + sumB + sumG) / 3; + minDenom = rNumerat_ / 0x100; + rDenomin_ = std::max(minDenom, sumR); + bNumerat_ = rNumerat_; + bDenomin_ = std::max(minDenom, sumB); + gNumerat_ = rNumerat_; + gDenomin_ = std::max(minDenom, sumG); + + LOG(Converter, Debug) << "rGain = [ " + << rNumerat_ << " / " << rDenomin_ + << " ], bGain = [ " << bNumerat_ << " / " << bDenomin_ + << " ], gGain = [ " << gNumerat_ << " / " << gDenomin_ + << " (minDenom = " << minDenom << ")"; +} + +static std::initializer_list compatibles = {}; + +REGISTER_CONVERTER("linaro-sw-converter", SwConverter, compatibles) + +} /* namespace libcamera */ diff --git a/src/libcamera/converter/meson.build b/src/libcamera/converter/meson.build index 2aa72fe4..1f1e0ea4 100644 --- a/src/libcamera/converter/meson.build +++ b/src/libcamera/converter/meson.build @@ -1,5 +1,6 @@ # SPDX-License-Identifier: CC0-1.0 libcamera_sources += files([ - 'converter_v4l2_m2m.cpp' + 'converter_softw.cpp', + 'converter_v4l2_m2m.cpp', ]) From patchwork Wed Sep 20 15:19:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 19064 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 AE8B8BE080 for ; Wed, 20 Sep 2023 15:19:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6850762951; Wed, 20 Sep 2023 17:19:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1695223197; bh=Qscjn3q0oPf6D31A4hGqTKItxrQ9hcOQaYNNv4/xHV8=; 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=jJkMFqER8eNfLrQzRsVNAhID1X7I505U7VBEt1MoqPR1CGJGRIMGyYI8gpJRoMBzf p1LttXiMt0npgHqv2/YyVPHE96TkkcObeg/ikohOBqmdVtEMtyvL+UHeu9yDCmscCh So6O6SNHmpReb2n9gB4Cv73ixW+tf7Jm1DiA0ZEGy/muJ4rkebNHupoile3WWYj3ue 52m/205M1S++98ZrBK6NVawX1gcei4D86k4swUHAngzWoK2tbgEFLrQfcKA3QCNIVK qba69Bt+HD1WnzmPnfkma494uRDUMaqkVCPzcqdswOVv8uiECg0wd1Jt34wIlzpwsH WhxsvRo//hJlQ== Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8162162945 for ; Wed, 20 Sep 2023 17:19:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="SRuVJbdv"; dkim-atps=neutral Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-9ad810be221so927845366b.2 for ; Wed, 20 Sep 2023 08:19:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695223196; x=1695827996; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2PigZEVZ9MknM95i+59mfvk6dA+sT3p9TjF0DYjWRTc=; b=SRuVJbdvoF95eGWeaW2GFyWirrH3UTvRP634a5meDuZ9pBRCnwX+Ly6CYKT4Yghe3J dOZ9XIvOM819RpFOb9qZRyDs9j2HWZGlIJHPUsFITAVWJwAqiCrLbuR+EQNLCofO0P0J Gh4oONpMlOKeikM+EPnbYswXvvN03PCgSIGUQgPfYly8TceDzJzk4MZDQqiCxnXdeaCC lVHftt4GtjBBXqfrdwXcnw/cLQUeNwiNXiG9o1nQZmbpMPmpo0MAJuAiNXGwG8AMzBFm EkmE9Olmcni5S2MLbI3SgVuiPuMIkttUi6w9HtJHVLv7EEfWrcQnawOQtddBjWzRZpRL 74kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695223196; x=1695827996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2PigZEVZ9MknM95i+59mfvk6dA+sT3p9TjF0DYjWRTc=; b=T++XQ1Rlg8f5hp1+v92ZCMytI7rGxs0/so7fajyuQo5fGFhSnxx24Sw0dDHUqrZuuo uH7Tz5hfwTnm0zOhi1UMPPd3djifd3Wqg6t6iOQiqzVp3AfIEmPk9hYQ1XUp0v3znygN pMedH1Nm2Z1HcZF7uXNxRl/bPMV6Q2gGJeeBi2kVf633+QvzV1IZG7Uq2aTb1KM+Mk1o Ph+6w8f7qOHzBeAvGvdsr0+8+eGGbXT88nQhhHToyI2JHMGkpNEzidZU6NB4E0pEgPp6 Q8FgFoKIhK1nVRQEihVOdVYvKg8hqwWjuwsDNhE1Wj7jBTzf113GeTQjh4WWZG+C4cWa Sxag== X-Gm-Message-State: AOJu0YwWUynXAwDcZspK38QjQMd2GzkND24+eTwtjTzM8rzLEiCj3rTd /pUFHcAlAM3qaSq84Mn/RXfiOROZ3K1WtXJWdd0= X-Google-Smtp-Source: AGHT+IGnniqV2uyMUXI1Q+eQpCby9vGTBqB9UJYpUdG5yKzPVgZf4rxOQ/4dtawZzeHDcCuDrVighw== X-Received: by 2002:a17:906:196:b0:9ad:df85:97ae with SMTP id 22-20020a170906019600b009addf8597aemr2438588ejb.66.1695223195677; Wed, 20 Sep 2023 08:19:55 -0700 (PDT) Received: from Lat-5310.. ([87.116.162.81]) by smtp.gmail.com with ESMTPSA id h24-20020a170906829800b009ae0042e48bsm5376736ejx.5.2023.09.20.08.19.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 08:19:55 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Sep 2023 18:19:21 +0300 Message-Id: <20230920151921.31273-5-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230920151921.31273-1-andrey.konovalov@linaro.org> References: <20230920151921.31273-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 4/4] libcamera: pipeline: simple: enable software converter for qcom-camss 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: Andrey Konovalov via libcamera-devel From: Andrey Konovalov Reply-To: Andrey Konovalov Cc: jacopo.mondi@ideasonboard.com, bryan.odonoghue@linaro.org, srinivas.kandagatla@linaro.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Andrey Konovalov --- src/libcamera/pipeline/simple/simple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 3f1b523a..27b2a835 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -200,7 +200,7 @@ static const SimplePipelineInfo supportedDevices[] = { { "imx7-csi", { { ConverterFlag::MediaDevice, "pxp", 1 } } }, { "j721e-csi2rx", {} }, { "mxc-isi", {} }, - { "qcom-camss", {} }, + { "qcom-camss", { { ConverterFlag::NoFlag, "linaro-sw-converter", 1 } } }, { "sun6i-csi", {} }, };