From patchwork Fri Dec 10 11:21:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 15111 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 0B933C3259 for ; Fri, 10 Dec 2021 11:22:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A71996089C; Fri, 10 Dec 2021 12:22:12 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="Oj6PUd0/"; dkim-atps=neutral Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A32056089C for ; Fri, 10 Dec 2021 12:22:08 +0100 (CET) Received: by mail-wr1-x432.google.com with SMTP id u1so14277893wru.13 for ; Fri, 10 Dec 2021 03:22:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2bNStc3f5yx0+9r6cEGZZIEuYgCV35H3PWXSv/otXK8=; b=Oj6PUd0/l6GDhYXP26/dGOCLjmf00nZqBRVB1jprHDW2gXSuh4KPBH5V4QUPHsNwsy T6AaW9OP74Hf2jpfdezD1fBEk3oaZ+O9mi3bt2t2lpsvjk4VtSq7oC4m/M1131UPM9Y3 L3kzMLTAbPmsPYGcGVDWhse9aV5NjNXZA6wX1YtMb0Xn3owUROXLhhv3Rc8LRCdRSJ6V vAQbZK+gvp/TmnM2IZHJYymADx1r+mQfHOMxwLKtXWXCIjs2yWG0wVv9gHlbugkOTx04 Ed2Ci0Do5jVy/LRWHnsQnPMqimYkaoFK6Pi8XNCnkBoHY1QInkO4PXSihLPCmGT8WlOs UhTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2bNStc3f5yx0+9r6cEGZZIEuYgCV35H3PWXSv/otXK8=; b=PKv/+XJy3cT6dbzUTRHgQGgJHu/NlOc4GtAKJ9146p0FnTriDr6BMp3IYa4MISduZF kWW8ZhKDxSJZOoDDPYevWZQqh6FlEIdvEySId47NCiG2xSuGlrPQGYRMGk20NVDMnKHt h4x+1Pg1UwjODw+cfiTqn/zHuWDI3++lPfk9dbJiCRlziI37d6/eDM3oQ6He6TA/uBPG nJ+cQAFlWnn4KTRcAx3t46eO28BJ2NXCoOmwjEje6N26YSNeQjIgkuxQ5gt4vKvmIUxR s24KkqMOJIDInMySU6xXQtrYMvtoMroHcgLt8t2yEy2xYMYE7Kj4uafhBGWaHcWO4hw2 z59Q== X-Gm-Message-State: AOAM531fIiRoDTRJV7V3MXSUthDVarC2VPS+2bH22LeHDIxelzV/GqgD r8RrNLjB6vfPwNeS4p19sH9C4A== X-Google-Smtp-Source: ABdhPJwiWVRpYlhWu5qtQXZi3is+jdND5+Sp9+8jyI78ekDj2M74WPrLZ4WOtc/EhTJNO5FLv0QFvg== X-Received: by 2002:a5d:6886:: with SMTP id h6mr13314127wru.287.1639135328314; Fri, 10 Dec 2021 03:22:08 -0800 (PST) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:e4a2:3070:eea4:e434]) by smtp.gmail.com with ESMTPSA id z18sm2198469wrq.11.2021.12.10.03.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Dec 2021 03:22:07 -0800 (PST) From: David Plowman To: Laurent Pinchart , Kieran Bingham , Hans Verkuil , Tomasz Figa , Jacopo Mondi , Naushir Patuck , libcamera-devel@lists.libcamera.org Date: Fri, 10 Dec 2021 11:21:41 +0000 Message-Id: <20211210112142.18441-8-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211210112142.18441-1-david.plowman@raspberrypi.com> References: <20211210112142.18441-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v11 7/8] libcamera: Add validateColorSpaces to CameraConfiguration class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This function forces raw streams to have the "raw" color space, and also optionally makes all non-raw output streams to share the same color space as some platforms may require this. When sharing color spaces we take the shared value to be the one from the largest of these streams. This choice is ultimately arbitrary, but can be appropriate if smaller output streams are used for image analysis rather than human consumption, when the precise colours may be less important. Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- include/libcamera/camera.h | 10 +++++ src/libcamera/camera.cpp | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index a7759ccb..5bb06584 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -69,6 +70,15 @@ public: protected: CameraConfiguration(); + enum class ColorSpaceFlag { + None, + StreamsShareColorSpace, + }; + + using ColorSpaceFlags = Flags; + + Status validateColorSpaces(ColorSpaceFlags flags = ColorSpaceFlag::None); + std::vector config_; }; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 400a7cf0..5f8533e8 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -14,12 +14,14 @@ #include #include +#include #include #include #include #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_controls.h" +#include "libcamera/internal/formats.h" #include "libcamera/internal/pipeline_handler.h" /** @@ -314,6 +316,84 @@ std::size_t CameraConfiguration::size() const return config_.size(); } +namespace { + +bool isRaw(const PixelFormat &pixFmt) +{ + const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); + return info.isValid() && + info.colourEncoding == PixelFormatInfo::ColourEncodingRAW; +} + +} /* namespace */ + +/** + * \enum CameraConfiguration::ColorSpaceFlag + * \brief Specify the behaviour of validateColorSpaces + * \var CameraConfiguration::ColorSpaceFlag::None + * \brief No extra validation of color spaces is required + * \var CameraConfiguration::ColorSpaceFlag::StreamsShareColorSpace + * \brief Non-raw output streams must share the same color space + */ + +/** + * \typedef CameraConfiguration::ColorSpaceFlags + * \brief A bitwise combination of ColorSpaceFlag values + */ + +/** + * \brief Check the color spaces requested for each stream + * \param[in] flags Flags to control the behaviour of this function + * + * This function performs certain consistency checks on the color spaces of + * the streams and may adjust them so that: + * + * - Any raw streams have the Raw color space + * - If the StreamsShareColorSpace flag is set, all output streams are forced + * to share the same color space (this may be a constraint on some platforms). + * + * It is optional for a pipeline handler to use this function. + * + * \return A CameraConfiguration::Status value that describes the validation + * status. + * \retval CameraConfigutation::Adjusted The configuration has been adjusted + * and is now valid. The color space of some or all of the streams may bave + * benn changed. The caller shall check the color spaces carefully. + * \retval CameraConfiguration::Valid The configuration was already valid and + * hasn't been adjusted. + */ +CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceFlags flags) +{ + Status status = Valid; + + /* + * Set all raw streams to the Raw color space, and make a note of the largest + * non-raw stream with a defined color space (if there is one). + */ + int index = -1; + for (auto [i, cfg] : utils::enumerate(config_)) { + if (isRaw(cfg.pixelFormat) && cfg.colorSpace != ColorSpace::Raw) { + cfg.colorSpace = ColorSpace::Raw; + status = Adjusted; + } else if (cfg.colorSpace && (index == -1 || cfg.size > config_[i].size)) + index = i; + } + + if (index < 0 || !(flags & ColorSpaceFlag::StreamsShareColorSpace)) + return status; + + /* Make all output color spaces the same, if requested. */ + for (auto &cfg : config_) { + if (!isRaw(cfg.pixelFormat) && + cfg.colorSpace != config_[index].colorSpace) { + cfg.colorSpace = config_[index].colorSpace; + status = Adjusted; + } + } + + return status; +} + /** * \var CameraConfiguration::transform * \brief User-specified transform to be applied to the image