From patchwork Wed Apr 27 22:30:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Rauch X-Patchwork-Id: 15738 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 697D8C3256 for ; Wed, 27 Apr 2022 22:30:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C07956564B; Thu, 28 Apr 2022 00:30:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1651098611; bh=8Z/TQf7DbNeFmtw2DOYLxNoW8vSdLF3ml0tv0nfJknA=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XSuIlLkxtHmAAI7U+BxiOGXJz9/IaFDcpaPZNJTWkIolW4tmMc2tBwBrHog/ymXT2 V5ex7ZJzZWnUavu8ECAfWYwfONuDhEOZhUcZfN+LyDID6HsN8maFlnZCa3vOr6ifdS Nqu3SyLAhwIxd4Ih3iO1S9M7GRRRmiAZeHT/13GNeBg/AQa9Y/HzdzP81RuGC5xpoq dEV25B57FGptZ5lrTenYNfbj93gBEbibedf07lMvayF9/JN6a13S0Lg5QImYP8bl01 dGcD0QIaaTjHpfBXneEjjOkovKrWx66aKGowMKcOLe15zUKh3cum5ygvnEP+zniwVc +VeCYvtG6mBBw== Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3F3BF6563F for ; Thu, 28 Apr 2022 00:30:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=gmx.net header.i=@gmx.net header.b="VxCjHSTo"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1651098607; bh=8Z/TQf7DbNeFmtw2DOYLxNoW8vSdLF3ml0tv0nfJknA=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=VxCjHSToxaw9QrfJBzU0NXRuXOD9z+AAEMTTEGctMbNiQ66COVVRLHraFZKC1znc5 IGqqXm6x0oyePPe0PxuRKLiVkUMOKP+PJaW3pdbSrkno2nixl2bdheBz5S/TSQRCOb tsrXc+2b76iSmYzTDbIVGaGkcSEq7wj7WFqM+7Kg= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([92.10.251.63]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MOA3F-1nU7de1G0X-00OWv5; Thu, 28 Apr 2022 00:30:07 +0200 To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Apr 2022 23:30:01 +0100 Message-Id: <20220427223004.115381-2-Rauch.Christian@gmx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220427223004.115381-1-Rauch.Christian@gmx.de> References: <20220427223004.115381-1-Rauch.Christian@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:X73hD7rLAxVCFz2KfUez6VvMFNcTAbSK1GPiL3MmS8mhPIuzBBQ +S7kAuYVaQNm8brJS1gt5EQ13pi279cL7yyqpcaFFWQDopzZJeySSK+VfeJ2VDaE8BsV4Hk v/hDc1MZq0zXC/KTCTnb1U/FW6GwhbJ+/vfOM8jH62RA3zJZUNylSaaktbqG20XtGltDLV7 VR5PI1ytbHAlRNtCd1SqQ== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:Tk73K1bVSIE=:BwJwK6ocYcWZaNSe6YAIOV RDvdVvL4Pi2akUvxAi1EUCJqfayTWvXrV/qrSZjSnsHOxRLUFqcypzc/tWIeiLsR3M9VWLW6a 7bKFiPxKRFJXNMycbdQFnQh0ZN0x29wh8EUJPiUrBm9+Tj5cDoQ+418vV+Di/BW6F6Hqorf4J O7bReyPZ1yPicrrd8jZif5OUFUOAlfNPd0OB6Me2LASPK+CTZDHPRBQuyMyA8y40CBscCRwRz 1cgy08a0d3nnkVFH4qI2r3WuD8GN1HJ9kcRqyJXueuf8VpbB0kdoSaeWQcDdwJFiOWphKozSl em05CN4KQ7jjxqS6oQnhB85YNReSFFynm7zYk+sLklCRI9mKC5tDxM/Qi9ABtO4vwhd1oYw8i R8LqK7GhEo0NnmsnA35UTBFTJp0aT6ML+PMsCoSnjwssYKTl/mCO6G9xV3sGEmRew9HTPIKzh JNXw/Jw8HUdqXy/ZKReVKddrBvCS/8gn3CVu66jR+8d2p0lDJoJ1AepmAMnNi/mR44okCl2Ap dF66ffUCaQOc/IKK02MbrM8c/1CSz9HSsEMzNC/g4LAV1NL5/5kWIF4UGib5FEH+uy/MgIXD5 eKTiDDgIeOsZEKnYHGpPazCeTAxXO+Q41Sac0KV7DqRjau8r7gdguQOm8cv6gZ/P3sLgikc8v vy9Um3HnM/bhpW/oBwBreZA66rnwsy08poYOflRhJPevWLGAjEaYi4i+qKl1o2Pql+gd40TFG fHTzkjEMCy2AprCFN4LcyjrGvQSqZL2sCcpYW/f1WrX0iU8sS8k+rOYy9DAJQWTFxT+bomZsR auWh3tqJ4tZZXiZfBX7gqDow1OD+4++BvfPFlpbX7lE62pK6Ks/FXZYQDyoEjJPjL9ldOoCZS i5ACBl0oUR5yN3EJZ2YO9p/YEcYVlGKXFd/5/T6qyCSgnO4kgZWRVGox6CJQsxF/cSslZJw/C BxynP/rpDo7br7yGTOzAENsOrS8WzrOhw2n8QR+EJCX/l49bVB6oaU/PtfZxBY39MpdmKBbtH KDzSbF9Wx0pOjBQ36e27lGTAhjckSAxjpucyUS5O7kyirySo+rvRoEM7AqXRsax8LFsFxHuzw Z/cdD9DCQ9XjJc= Subject: [libcamera-devel] [PATCH v4 1/4] use std::optional to handle invalid control values 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: Christian Rauch via libcamera-devel From: Christian Rauch Reply-To: Christian Rauch Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Previously, ControlList::get() would use default constructed objects to indicate that a ControlList does not have the requested Control. This has several disadvantages: 1) It requires types to be default constructible, 2) it does not differentiate between a default constructed object and an object that happens to have the same state as a default constructed object. std::optional additionally stores the information if the object is valid or not, and therefore is more expressive than a default constructed object. Signed-off-by: Christian Rauch --- include/libcamera/controls.h | 7 ++++--- src/cam/main.cpp | 4 ++-- src/ipa/raspberrypi/raspberrypi.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 ++++----- .../pipeline/raspberrypi/raspberrypi.cpp | 10 ++++++---- src/qcam/dng_writer.cpp | 15 +++++++++------ 6 files changed, 26 insertions(+), 21 deletions(-) -- 2.34.1 diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 665bcac1..363e7809 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,7 @@ public: using V = typename T::value_type; const V *value = reinterpret_cast(data().data()); - return { value, numElements_ }; + return T{ value, numElements_ }; } #ifndef __DOXYGEN__ @@ -373,11 +374,11 @@ public: bool contains(unsigned int id) const; template - T get(const Control &ctrl) const + std::optional get(const Control &ctrl) const { const ControlValue *val = find(ctrl.id()); if (!val) - return T{}; + return std::nullopt; return val->get(); } diff --git a/src/cam/main.cpp b/src/cam/main.cpp index c7f664b9..853a78ed 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -293,7 +293,7 @@ std::string CamApp::cameraName(const Camera *camera) * is only used if the location isn't present or is set to External. */ if (props.contains(properties::Location)) { - switch (props.get(properties::Location)) { + switch (props.get(properties::Location).value_or(int32_t{})) { case properties::CameraLocationFront: addModel = false; name = "Internal front camera "; @@ -313,7 +313,7 @@ std::string CamApp::cameraName(const Camera *camera) * If the camera location is not availble use the camera model * to build the camera name. */ - name = "'" + props.get(properties::Model) + "' "; + name = "'" + props.get(properties::Model).value_or(std::string{}) + "' "; } name += "(" + camera->id() + ")"; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 5efd051b..bf54f64f 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -936,7 +936,7 @@ void IPARPi::returnEmbeddedBuffer(unsigned int bufferId) void IPARPi::prepareISP(const ISPConfig &data) { - int64_t frameTimestamp = data.controls.get(controls::SensorTimestamp); + int64_t frameTimestamp = data.controls.get(controls::SensorTimestamp).value_or(int64_t{}); RPiController::Metadata lastMetadata; Span embeddedBuffer; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index fd989e61..1e9e5081 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1145,7 +1145,7 @@ int PipelineHandlerIPU3::registerCameras() /* Convert the sensor rotation to a transformation */ int32_t rotation = 0; if (data->properties_.contains(properties::Rotation)) - rotation = data->properties_.get(properties::Rotation); + rotation = data->properties_.get(properties::Rotation).value_or(int32_t{}); else LOG(IPU3, Warning) << "Rotation control not exposed by " << cio2->sensor()->id() @@ -1331,7 +1331,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) request->metadata().set(controls::draft::PipelineDepth, 3); /* \todo Actually apply the scaler crop region to the ImgU. */ if (request->controls().contains(controls::ScalerCrop)) - cropRegion_ = request->controls().get(controls::ScalerCrop); + cropRegion_ = request->controls().get(controls::ScalerCrop).value_or(Rectangle{}); request->metadata().set(controls::ScalerCrop, cropRegion_); if (frameInfos_.tryComplete(info)) @@ -1424,7 +1424,7 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer) return; } - ipa_->processStatsBuffer(info->id, request->metadata().get(controls::SensorTimestamp), + ipa_->processStatsBuffer(info->id, request->metadata().get(controls::SensorTimestamp).value_or(int64_t{}), info->statBuffer->cookie(), info->effectiveSensorControls); } @@ -1458,8 +1458,7 @@ void IPU3CameraData::frameStart(uint32_t sequence) if (!request->controls().contains(controls::draft::TestPatternMode)) return; - const int32_t testPatternMode = request->controls().get( - controls::draft::TestPatternMode); + const int32_t testPatternMode = request->controls().get(controls::draft::TestPatternMode).value_or(int32_t{}); int ret = cio2_.sensor()->setTestPatternMode( static_cast(testPatternMode)); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index acc0beca..ce86ba45 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -365,7 +365,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * error means the platform can never run. Let's just print a warning * and continue regardless; the rotation is effectively set to zero. */ - int32_t rotation = data_->sensor_->properties().get(properties::Rotation); + int32_t rotation = data_->sensor_->properties().get(properties::Rotation).value_or(int32_t{}); bool success; Transform rotationTransform = transformFromRotation(rotation, &success); if (!success) @@ -1696,7 +1696,9 @@ void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList & * V4L2_CID_NOTIFY_GAINS control (which means notifyGainsUnity_ is set). */ if (notifyGainsUnity_ && controls.contains(libcamera::controls::ColourGains)) { - libcamera::Span colourGains = controls.get(libcamera::controls::ColourGains); + libcamera::Span colourGains = + controls.get(libcamera::controls::ColourGains).\ + value_or(libcamera::Span({ 0, 0 })); /* The control wants linear gains in the order B, Gb, Gr, R. */ ControlList ctrls(sensor_->controls()); std::array gains{ @@ -2031,7 +2033,7 @@ Rectangle RPiCameraData::scaleIspCrop(const Rectangle &ispCrop) const void RPiCameraData::applyScalerCrop(const ControlList &controls) { if (controls.contains(controls::ScalerCrop)) { - Rectangle nativeCrop = controls.get(controls::ScalerCrop); + Rectangle nativeCrop = controls.get(controls::ScalerCrop).value_or(Rectangle{}); if (!nativeCrop.width || !nativeCrop.height) nativeCrop = { 0, 0, 1, 1 }; @@ -2069,7 +2071,7 @@ void RPiCameraData::fillRequestMetadata(const ControlList &bufferControls, Request *request) { request->metadata().set(controls::SensorTimestamp, - bufferControls.get(controls::SensorTimestamp)); + bufferControls.get(controls::SensorTimestamp).value_or(int64_t{})); request->metadata().set(controls::ScalerCrop, scalerCrop_); } diff --git a/src/qcam/dng_writer.cpp b/src/qcam/dng_writer.cpp index 34c8df5a..e119ca52 100644 --- a/src/qcam/dng_writer.cpp +++ b/src/qcam/dng_writer.cpp @@ -392,7 +392,7 @@ int DNGWriter::write(const char *filename, const Camera *camera, TIFFSetField(tif, TIFFTAG_MAKE, "libcamera"); if (cameraProperties.contains(properties::Model)) { - std::string model = cameraProperties.get(properties::Model); + std::string model = cameraProperties.get(properties::Model).value_or(std::string{}); TIFFSetField(tif, TIFFTAG_MODEL, model.c_str()); /* \todo set TIFFTAG_UNIQUECAMERAMODEL. */ } @@ -438,7 +438,8 @@ int DNGWriter::write(const char *filename, const Camera *camera, const double eps = 1e-2; if (metadata.contains(controls::ColourGains)) { - Span const &colourGains = metadata.get(controls::ColourGains); + Span const &colourGains = + metadata.get(controls::ColourGains).value_or(libcamera::Span({ 0, 0 })); if (colourGains[0] > eps && colourGains[1] > eps) { wbGain = Matrix3d::diag(colourGains[0], 1, colourGains[1]); neutral[0] = 1.0 / colourGains[0]; /* red */ @@ -446,7 +447,8 @@ int DNGWriter::write(const char *filename, const Camera *camera, } } if (metadata.contains(controls::ColourCorrectionMatrix)) { - Span const &coeffs = metadata.get(controls::ColourCorrectionMatrix); + Span const &coeffs = + metadata.get(controls::ColourCorrectionMatrix).value_or(Span({ 0, 0, 0, 0, 0, 0, 0, 0, 0 })); Matrix3d ccmSupplied(coeffs); if (ccmSupplied.determinant() > eps) ccm = ccmSupplied; @@ -515,7 +517,8 @@ int DNGWriter::write(const char *filename, const Camera *camera, uint32_t whiteLevel = (1 << info->bitsPerSample) - 1; if (metadata.contains(controls::SensorBlackLevels)) { - Span levels = metadata.get(controls::SensorBlackLevels); + Span levels = + metadata.get(controls::SensorBlackLevels).value_or(Span({ 0, 0, 0, 0 })); /* * The black levels control is specified in R, Gr, Gb, B order. @@ -593,13 +596,13 @@ int DNGWriter::write(const char *filename, const Camera *camera, TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, strTime); if (metadata.contains(controls::AnalogueGain)) { - float gain = metadata.get(controls::AnalogueGain); + float gain = metadata.get(controls::AnalogueGain).value_or(float{}); uint16_t iso = std::min(std::max(gain * 100, 0.0f), 65535.0f); TIFFSetField(tif, EXIFTAG_ISOSPEEDRATINGS, 1, &iso); } if (metadata.contains(controls::ExposureTime)) { - float exposureTime = metadata.get(controls::ExposureTime) / 1e6; + float exposureTime = metadata.get(controls::ExposureTime).value_or(float{}) / 1e6; TIFFSetField(tif, EXIFTAG_EXPOSURETIME, exposureTime); }