From patchwork Fri Apr 8 01:42:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Rauch X-Patchwork-Id: 15656 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 606FDC326D for ; Fri, 8 Apr 2022 01:42:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B4C0D65644; Fri, 8 Apr 2022 03:42:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1649382159; bh=HBsoBIb7NuzDxeK3IuRL0qDvHy/MXk/GFJTpqX85nfo=; 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=FHaOr4RXoeOJT/MVbcKpZgL1AMOFJkkM2R7ImDwI94GhO9Y/jiwcyMeh8c7GwKJUt EkSJcEqDFFyBHYQ9ncfAjCUigG5GhkZObl/p02fRSABCSzFYV83loRf4VMXYgl2GXn Ug0kVcZNRr9OTS7/k6deuireAolw+8HCLlvsGKe3F02OL+OR9M3RBqj5qkR5VjtgJ1 0FdYNk6MnngF7BXydpzuyy8yxch6mj0HLEeVwjlmU1+6dcowb/Z9hSCAuLtBCQPiNx 2MfcK6Rd56JnS92fu5Bc1TzMpSGCDPBjiRYUZi5l7vc9f8SFWBvMC0wVM85rE9sYzI gktD3rC/hAPBw== Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 46F7665642 for ; Fri, 8 Apr 2022 03:42:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=gmx.net header.i=@gmx.net header.b="N35z1Bur"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1649382155; bh=HBsoBIb7NuzDxeK3IuRL0qDvHy/MXk/GFJTpqX85nfo=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=N35z1BurlDgcyMauEKI879zD0pHa5FI9XIRk7d6A/sKQiaFNW/JlH/NlMAY9FJ51V CrklhCBzS1YNGrZ8odAPOv642J9jjO8yPBJZ4Pavo1KyGwsMW2ZSsJKMZVu+mktD5+ gpr5fdYsoPONqpyj98PcEOH7V/NM3dv0DmA6Ebew= 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 1M59C8-1nbXiR3DzY-0018bX; Fri, 08 Apr 2022 03:42:35 +0200 To: libcamera-devel@lists.libcamera.org Date: Fri, 8 Apr 2022 02:42:31 +0100 Message-Id: <20220408014231.231083-5-Rauch.Christian@gmx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220408014231.231083-1-Rauch.Christian@gmx.de> References: <20220408014231.231083-1-Rauch.Christian@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:p3nB75K/LtNqP2MbQdhvfWtz7eLMW/6SqSZiCmKqDlyVTwYruM6 wlosaC7rJEmmCJNwBYEhLtXhnhKcN11nKEmw145YBm/R7Aba+k98qC5HFWOuqKX6c3xlqYf HrMvNeadUpz1N0XzWynbf0Y/pedFHxrODvGWxmWTOI9bSWJJl4FPqOGfxHyCjWcmQ0+niZO nvnvP3tDH3dQbZ5yskJyA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:UwoQ1vf1zLg=:UMSqmFP0wz4qwVG9rC687J pBUH+ukTuQhqsH+BS3JKN2916mfXihL9L3KSX/R9AopU6N+hyAIPHTFTO6lDqWGEUDj2+i1OC W6OMSm3KAYaQ9LcjSmHVlcSa4vL4VZK8/b1zNqU0zzQbW4XzaqdGyqG0UOI5jxA7CBpE2KCZt 24wD1xq3TfVozp9YgCWr30+tApxiMiQ8b/gGi0qH3WwxCDddXziF2WniEkZkHzjznVX++BO4v Bu26EZ9YUfDXSSb2SgrOuaLBeonagJcCS4QEPFDgY4nuLNmp05r0qiFBXlZvcW9xoU/ylzEla MD++onBpg+f3EDzDesVJK0oL3nHcgJWGKDUikSz4dg3ABdCVwz/Sd5yWUDowq1Tjknv+HHa74 JsOvTDqsuim7ReKkmYmLThJAcVzxnWv+Bb6/XWeI436AUYrl0R5PTokCVtnMDcA94lFmy1Krj QUxyjBAX3OP5y/lLMLlnQuaDgy7O7/dSmeP1k1rhQjyUbkLqkCaO+wcG6ZJ9+S1rhqBxyVUgV R3P5JaNCda5/4ezVqCo8Fh9lwDZo4MTMF6WUG4WsxZCshzmZ5Nng1KzlXyzj89O7qf2dcZGv7 pkV5SupwWcrRpCc8ExrBmVDtqLo6pv1cJern37fxde2y7PBRts7vsjG++J0o49fz3+02M9Ao9 FJJHXmuV6baLVEbKtU5D+Z7wndYpl8T9kXtfeLbsIKAQqg8unqpNs2LQZ5PpSJOLtGzhkuAQT aYCRPsIZZkkytIdvO/Wc9Du39ZUbEq2+NDZSspWopWBHWYyez6Nx/ZJ7SYTepbz4wsIxnUK8G JSPM1vS9HfLXKGN/u6mHgJFK+5resKwtKG4TdLA3B5PFFV4MVAu95MTD5ruNpZDrUknR/9x6T CZE9XAskHoOJbbnQOqpMNPM7oKBGFhmzRgAun79ROmjuqY0VOZkT1B7/11pl5rZi4C6DuwjgO orCXjiwsI6UAJTokLcQCtKZWndPqIpe7mBja/YzC7Ruwbed2HOx9S9I/aPpIK3Clk3yFbrdRw jQ0jdagPgvszWwxCtoJEWC+Y2VJunRbK/OyPCGkKe/in08F8mzLjrEH2UtK9xe7aUP2lVelAL QQdVeYyqR3mLnk= Subject: [libcamera-devel] [PATCH v3 4/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 | 6 +++--- src/cam/main.cpp | 4 ++-- src/ipa/raspberrypi/raspberrypi.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 ++++----- .../pipeline/raspberrypi/raspberrypi.cpp | 9 +++++---- src/qcam/dng_writer.cpp | 15 +++++++++------ 6 files changed, 24 insertions(+), 21 deletions(-) -- 2.25.1 diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 665bcac1..57b777e9 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -167,7 +167,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 +373,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 5a5cdf66..93b32e94 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -934,7 +934,7 @@ void IPARPi::returnEmbeddedBuffer(unsigned int bufferId) void IPARPi::prepareISP(const ipa::RPi::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 60e01917..394221cb 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1146,7 +1146,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() @@ -1341,7 +1341,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)) @@ -1442,7 +1442,7 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer) ev.op = ipa::ipu3::EventStatReady; ev.frame = info->id; ev.bufferId = info->statBuffer->cookie(); - ev.frameTimestamp = request->metadata().get(controls::SensorTimestamp); + ev.frameTimestamp = request->metadata().get(controls::SensorTimestamp).value_or(int64_t{}); ev.sensorControls = info->effectiveSensorControls; ipa_->processEvent(ev); } @@ -1477,8 +1477,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 0fa294d4..63d57033 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,8 @@ 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 +2032,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 +2070,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 2fb527d8..030432e3 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); }