From patchwork Wed Dec 16 11:22:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10671 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 24CFAC0F1A for ; Wed, 16 Dec 2020 11:22:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CB95561592; Wed, 16 Dec 2020 12:22:08 +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="IOivdRXh"; dkim-atps=neutral Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 36CD96158A for ; Wed, 16 Dec 2020 12:22:07 +0100 (CET) Received: by mail-wr1-x42f.google.com with SMTP id q18so15295586wrn.1 for ; Wed, 16 Dec 2020 03:22:07 -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=gH8HMYcOquTPDuesHKOTcqJ/C07iagYJVPlUMXZ+2JM=; b=IOivdRXhvi+CfuYbzXoDtzCtn/eEwFUm1ea8BcfaR/UDKkz7/LGsFJ0mjIp3HzXBvC j/2MHMQO7qS3Lk2QLF+J1lDTiz9ollB8eNu8gdqUD0ZesNBgVwgd4GzkTYkC6BIzjRiC sZJnxkbsblpiFZWzFU49A1JggsSH9rPThw3UGZxXJgv0HM03SOSaJTM7FKT6eqN4HuEe EbOTAgn9R5R+i/01PYTylESsu/N9/34C90nl6kxtZ0YcPzQXQOna9ushfNPosaxJjelL 72FwmgRC11LqC/kttjEbAjNj2Hhsu3b2tbstwd7VSnesXms97KLKDeEtOuGZHsLwsP9b uM2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gH8HMYcOquTPDuesHKOTcqJ/C07iagYJVPlUMXZ+2JM=; b=k2LZSV41hXpBgih8TK7EaOJMPsT2r6OkJhpBxzEOSOWwBMsFuhHfvaQyJylXUlFxQC mzHKO2XVNbjFX1nkU9DAmRBylJ+MXMkGp6lY6jes0SvStd3GKIzpYo9H4If9ltZYokC+ u3v3XCHH1ob+BG7E5PEFhRLfQhJ2FDVcXWURoawd4TvdsZVbkhBceSnWNarmKTCSvjQu aM1AWY0e8JUOKz2upmHA8/hhCb7cdp2AbDk2KBEUjctk+JS4M5LKPByKMPBMGsKTwCXG l6KDrR0nvNERt/9c4kj51Hl9GvcyrVyBtZWTMz0x6POgdtqtoNYf1sOWY/SMRvsF7xkS G8+g== X-Gm-Message-State: AOAM531Es5M1r4wDYebhA0NeuyRnYR86xfDTuMvRpZv8xyhCoW58VG+n 6ZdJeiweUPR8tVGTvzmCOaZz2KFrvbBQ/g== X-Google-Smtp-Source: ABdhPJw9YzNpIttlUosdOQnIxTlB0Zo2q+3RU4AhUD48JqI8Njt6tVgsN1B/D0N8CzcC/qmLctgOqw== X-Received: by 2002:a5d:6902:: with SMTP id t2mr37733385wru.214.1608117726590; Wed, 16 Dec 2020 03:22:06 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id l8sm2766941wrb.73.2020.12.16.03.22.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Dec 2020 03:22:05 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Dec 2020 11:22:00 +0000 Message-Id: <20201216112202.5063-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201216112202.5063-1-naush@raspberrypi.com> References: <20201216112202.5063-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 1/3] libcamera: controls: Add frame duration control 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" Add an int64_t array control (controls::FrameDurations) to specify the minimum and maximum (in that order) frame duration to be used by the camera sensor. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi --- src/libcamera/control_ids.yaml | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml index 6d6f0fee..43a7cfb7 100644 --- a/src/libcamera/control_ids.yaml +++ b/src/libcamera/control_ids.yaml @@ -306,6 +306,46 @@ controls: maximum valid value is given by the properties::ScalerCropMaximum property, and the two can be used to implement digital zoom. + - FrameDurations: + type: int64_t + description: | + The minimum and maximum (in that order) frame duration, + expressed in micro-seconds. + + When provided by applications, the control specifies the sensor frame + duration interval the pipeline has to use. This could also limit the + largest exposure time the sensor can use. For example, if a maximum + frame duration of 33ms is requested (corresponding to 30 frames per + second), the sensor will not be able to raise the exposure time above + 33ms. A fixed frame duration is achieved by setting the minimum and + maximum values to be the same. + + The maximum frame duration provides the absolute limit to the shutter + speed computed by the AE algorithm and it overrides any exposure mode + setting specified with controls::AeExposureMode. Similarly, when a + manual exposure time is set through controls::ExposureTime, it also + gets clipped to the limits set by this control. + + \sa AeExposureMode + \sa ExposureTime + + \todo Refer to the frame duration limits property to describe how + application-provided values gets clipped and reset. + + When reported by pipelines, the control expresses the duration of the + sensor frame used to produce streams part of the completed Request. + The minimum and maximum values shall then be the same, as the sensor + frame duration is a fixed parameter. The sensor frame duration is one + of the parameter that defines the capture frame rate but it does not + alone provide enough information to fully calculate it as it does not + account for pipeline processing delays. + + \todo Define how to calculate the capture frame rate by + defining controls to report additional delays introduced by + the capture pipeline or post-processing stages (ie JPEG + conversion, frame scaling). + size: [2] + # ---------------------------------------------------------------------------- # Draft controls section From patchwork Wed Dec 16 11:22:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10672 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 66B88C0F1A for ; Wed, 16 Dec 2020 11:22:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 30F9E6158F; Wed, 16 Dec 2020 12:22:11 +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="BtA6aOAS"; dkim-atps=neutral Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A38E4600FD for ; Wed, 16 Dec 2020 12:22:08 +0100 (CET) Received: by mail-wr1-x431.google.com with SMTP id c5so19162498wrp.6 for ; Wed, 16 Dec 2020 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=BMt5KV7r4poEgH+RCRyU9BmNO7pGD1K6371O8qsEwRM=; b=BtA6aOASPjoyzlTCDwQYZjuEjz07pY3QXuveGTZgf2OeOnY++IPxRIVxHdhC3E02Is aPfVXv1rMmGP4RZEXdLrYMdBtKAg7n3W6UamUpJVeyvEegpId3i15R3f1bqhEx77Fidl laPOSrva4RslrAUkmK5WjBt2ruJHuHPk+j4ym7+t0Sg3WY7+g/N1pnKZTC3Zc7stnWM0 VoBqJoeMEtVVXzAB9aWj7m78pHSwXb0EZ3OBKtcBQU2lRNT/A+1HSK0HCJG7FXjRmi/z vm2J/ZI8MwY6CxYCi9tHA3V/luB29+Jo/tc9p9LGqSR+QcSnSgeJ8arovDgYyLqVuPa9 5dbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BMt5KV7r4poEgH+RCRyU9BmNO7pGD1K6371O8qsEwRM=; b=F2IOFqXEmka1jGAkYfNaFAfi7l3Jfz5L/mYBRWJt03cEvTuD/urkCxVcg1gJ5GhGKu zerunBc9cghvZJ2rYYL75kOsRqTCeLcUz9TepES7ILgcCDSNLicWTRrbC2KxFN2cxpa6 /dPZoXCA1NLC4u1axjrIvbq9CFarDoHfxMyETa8n1yHthODAYaONGCaTsXK4io5QbkDY M/ztYpUEp+9U78AmNHELiUJcQCZKKaX5mXEdjOwViVvZYMSoarXMgT/Lzz9HxoIU4p2D YjFCb3UAbZGpkRLTA/pGt9x2P+MKgP51V8oZA5MMhNR2BhoTHIHJTmXaDnnr4IoRciFv cE5g== X-Gm-Message-State: AOAM531kNe/WkRF9zv7xEkWPeHZ6gMWvAmSM2iYHeS69AwSnc6fle1Jk J/vAoMAiBLeFrLr+fudxWAk7y9aaz6mkhg== X-Google-Smtp-Source: ABdhPJy9qnw4JC84VH8/1Amjl2Aj7ZjVRrVeO+aJTOuy+LVP0xN8lpxCwQEDVPaVmxUbtadhEWs/IQ== X-Received: by 2002:adf:9124:: with SMTP id j33mr35886033wrj.376.1608117727796; Wed, 16 Dec 2020 03:22:07 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id l8sm2766941wrb.73.2020.12.16.03.22.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Dec 2020 03:22:06 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Dec 2020 11:22:01 +0000 Message-Id: <20201216112202.5063-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201216112202.5063-1-naush@raspberrypi.com> References: <20201216112202.5063-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 2/3] libcamera: raspberrypi: Add control of sensor vblanking 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" Add support for setting V4L2_CID_VBLANK appropriately when setting V4L2_CID_EXPOSURE. This will allow adaptive framerates during viewfinder use cases (e.g. when the exposure time goes above 33ms, we can reduce the framerate to lower than 30fps). The minimum and maximum frame durations are provided via libcamera controls, and will prioritise exposure time limits over any AGC request. V4L2_CID_VBLANK is controlled through the staggered writer, just like the exposure and gain controls. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/cam_helper.cpp | 35 ++++++++++++++- src/ipa/raspberrypi/cam_helper.hpp | 15 ++++++- src/ipa/raspberrypi/cam_helper_imx219.cpp | 13 +++++- src/ipa/raspberrypi/cam_helper_imx477.cpp | 11 ++++- src/ipa/raspberrypi/cam_helper_ov5647.cpp | 11 ++++- src/ipa/raspberrypi/raspberrypi.cpp | 45 ++++++++++++++++--- .../pipeline/raspberrypi/raspberrypi.cpp | 3 +- 8 files changed, 120 insertions(+), 14 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 01fe5abc..1de36039 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -65,6 +65,7 @@ static const ControlInfoMap Controls = { { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) }, { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) }, { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) }, + { &controls::FrameDurations, ControlInfo(1000, 1000000000) }, }; } /* namespace RPi */ diff --git a/src/ipa/raspberrypi/cam_helper.cpp b/src/ipa/raspberrypi/cam_helper.cpp index 6efa0d7f..018c17b9 100644 --- a/src/ipa/raspberrypi/cam_helper.cpp +++ b/src/ipa/raspberrypi/cam_helper.cpp @@ -34,8 +34,10 @@ CamHelper *CamHelper::Create(std::string const &cam_name) return nullptr; } -CamHelper::CamHelper(MdParser *parser) - : parser_(parser), initialized_(false) +CamHelper::CamHelper(MdParser *parser, unsigned int maxFrameLength, + unsigned int frameIntegrationDiff) + : parser_(parser), initialized_(false), maxFrameLength_(maxFrameLength), + frameIntegrationDiff_(frameIntegrationDiff) { } @@ -56,6 +58,35 @@ double CamHelper::Exposure(uint32_t exposure_lines) const return exposure_lines * mode_.line_length / 1000.0; } +uint32_t CamHelper::GetVBlanking(double &exposure, double minFrameDuration, + double maxFrameDuration) const +{ + uint32_t frameLengthMin, frameLengthMax, vblank; + uint32_t exposureLines = ExposureLines(exposure); + + assert(initialized_); + + /* + * Clip frame length by the frame duration range and the maximum allowable + * value in the sensor, given by maxFrameLength_. + */ + frameLengthMin = std::clamp(1e3 * minFrameDuration / mode_.line_length, + mode_.height, maxFrameLength_); + frameLengthMax = std::clamp(1e3 * maxFrameDuration / mode_.line_length, + mode_.height, maxFrameLength_); + /* + * Limit the exposure to the maximum frame duration requested, and + * re-calculate if it has been clipped. + */ + exposureLines = std::min(frameLengthMax - frameIntegrationDiff_, exposureLines); + exposure = Exposure(exposureLines); + + /* Limit the vblank to the range allowed by the frame length limits. */ + vblank = std::clamp(exposureLines + frameIntegrationDiff_, + frameLengthMin, frameLengthMax) - mode_.height; + return vblank; +} + void CamHelper::SetCameraMode(const CameraMode &mode) { mode_ = mode; diff --git a/src/ipa/raspberrypi/cam_helper.hpp b/src/ipa/raspberrypi/cam_helper.hpp index 044c2866..b1739a57 100644 --- a/src/ipa/raspberrypi/cam_helper.hpp +++ b/src/ipa/raspberrypi/cam_helper.hpp @@ -62,12 +62,15 @@ class CamHelper { public: static CamHelper *Create(std::string const &cam_name); - CamHelper(MdParser *parser); + CamHelper(MdParser *parser, unsigned int maxFrameLength, + unsigned int frameIntegrationDiff); virtual ~CamHelper(); void SetCameraMode(const CameraMode &mode); MdParser &Parser() const { return *parser_; } uint32_t ExposureLines(double exposure_us) const; double Exposure(uint32_t exposure_lines) const; // in us + virtual uint32_t GetVBlanking(double &exposure_us, double minFrameDuration, + double maxFrameDuration) const; virtual uint32_t GainCode(double gain) const = 0; virtual double Gain(uint32_t gain_code) const = 0; virtual void GetDelays(int &exposure_delay, int &gain_delay) const; @@ -76,10 +79,20 @@ public: virtual unsigned int HideFramesModeSwitch() const; virtual unsigned int MistrustFramesStartup() const; virtual unsigned int MistrustFramesModeSwitch() const; + protected: MdParser *parser_; CameraMode mode_; + +private: bool initialized_; + /* Largest possible frame length, in units of lines. */ + unsigned int maxFrameLength_; + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + unsigned int frameIntegrationDiff_; }; // This is for registering camera helpers with the system, so that the diff --git a/src/ipa/raspberrypi/cam_helper_imx219.cpp b/src/ipa/raspberrypi/cam_helper_imx219.cpp index db8ab879..8688ec09 100644 --- a/src/ipa/raspberrypi/cam_helper_imx219.cpp +++ b/src/ipa/raspberrypi/cam_helper_imx219.cpp @@ -49,13 +49,22 @@ public: double Gain(uint32_t gain_code) const override; unsigned int MistrustFramesModeSwitch() const override; bool SensorEmbeddedDataPresent() const override; + +private: + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + static constexpr int frameIntegrationDiff = 4; + /* Largest possible frame length, in units of lines. */ + static constexpr int maxFrameLength = 0xffff; }; CamHelperImx219::CamHelperImx219() #if ENABLE_EMBEDDED_DATA - : CamHelper(new MdParserImx219()) + : CamHelper(new MdParserImx219(), maxFrameLength, frameIntegrationDiff) #else - : CamHelper(new MdParserRPi()) + : CamHelper(new MdParserRPi(), maxFrameLength, frameIntegrationDiff) #endif { } diff --git a/src/ipa/raspberrypi/cam_helper_imx477.cpp b/src/ipa/raspberrypi/cam_helper_imx477.cpp index 0e896ac7..53961310 100644 --- a/src/ipa/raspberrypi/cam_helper_imx477.cpp +++ b/src/ipa/raspberrypi/cam_helper_imx477.cpp @@ -38,10 +38,19 @@ public: uint32_t GainCode(double gain) const override; double Gain(uint32_t gain_code) const override; bool SensorEmbeddedDataPresent() const override; + +private: + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + static constexpr int frameIntegrationDiff = 22; + /* Largest possible frame length, in units of lines. */ + static constexpr int maxFrameLength = 0xffdc; }; CamHelperImx477::CamHelperImx477() - : CamHelper(new MdParserImx477()) + : CamHelper(new MdParserImx477(), maxFrameLength, frameIntegrationDiff) { } diff --git a/src/ipa/raspberrypi/cam_helper_ov5647.cpp b/src/ipa/raspberrypi/cam_helper_ov5647.cpp index 0b841cd1..2bd8a754 100644 --- a/src/ipa/raspberrypi/cam_helper_ov5647.cpp +++ b/src/ipa/raspberrypi/cam_helper_ov5647.cpp @@ -23,6 +23,15 @@ public: unsigned int HideFramesModeSwitch() const override; unsigned int MistrustFramesStartup() const override; unsigned int MistrustFramesModeSwitch() const override; + +private: + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + static constexpr int frameIntegrationDiff = 4; + /* Largest possible frame length, in units of lines. */ + static constexpr int maxFrameLength = 0xffff; }; /* @@ -31,7 +40,7 @@ public: */ CamHelperOv5647::CamHelperOv5647() - : CamHelper(new MdParserRPi()) + : CamHelper(new MdParserRPi(), maxFrameLength, frameIntegrationDiff) { } diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index d087b07e..e1fe35f5 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -58,6 +58,8 @@ namespace libcamera { /* Configure the sensor with these values initially. */ constexpr double DefaultAnalogueGain = 1.0; constexpr unsigned int DefaultExposureTime = 20000; +constexpr double defaultMinFrameDuration = 1e6 / 30.0; +constexpr double defaultMaxFrameDuration = 1e6 / 0.01; LOG_DEFINE_CATEGORY(IPARPI) @@ -150,6 +152,9 @@ private: /* Distinguish the first camera start from others. */ bool firstStart_; + + /* Frame duration (1/fps) given in microseconds. */ + double minFrameDuration_, maxFrameDuration_; }; int IPARPi::init(const IPASettings &settings) @@ -332,7 +337,8 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, sensorMetadata = helper_->SensorEmbeddedDataPresent(); result->data.push_back(gainDelay); - result->data.push_back(exposureDelay); + result->data.push_back(exposureDelay); /* FOR EXPOSURE ctrl */ + result->data.push_back(exposureDelay); /* For VBLANK ctrl */ result->data.push_back(sensorMetadata); result->operation |= RPi::IPA_CONFIG_STAGGERED_WRITE; @@ -382,6 +388,8 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, AgcStatus agcStatus; agcStatus.shutter_time = DefaultExposureTime; agcStatus.analogue_gain = DefaultAnalogueGain; + minFrameDuration_ = defaultMinFrameDuration; + maxFrameDuration_ = defaultMaxFrameDuration; applyAGC(&agcStatus, ctrls); result->controls.emplace_back(ctrls); @@ -524,7 +532,8 @@ bool IPARPi::validateSensorControls() { static const uint32_t ctrls[] = { V4L2_CID_ANALOGUE_GAIN, - V4L2_CID_EXPOSURE + V4L2_CID_EXPOSURE, + V4L2_CID_VBLANK }; for (auto c : ctrls) { @@ -804,6 +813,18 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::FRAME_DURATIONS: { + auto frameDurations = ctrl.second.get>(); + + /* This will be applied once AGC recalculations occur. */ + minFrameDuration_ = frameDurations[0] ? frameDurations[0] : defaultMinFrameDuration; + maxFrameDuration_ = frameDurations[1] ? frameDurations[1] : defaultMaxFrameDuration; + libcameraMetadata_.set(controls::FrameDurations, + { static_cast(minFrameDuration_), + static_cast(maxFrameDuration_) }); + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() @@ -962,15 +983,27 @@ void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) { int32_t gainCode = helper_->GainCode(agcStatus->analogue_gain); - int32_t exposureLines = helper_->ExposureLines(agcStatus->shutter_time); - LOG(IPARPI, Debug) << "Applying AGC Exposure: " << agcStatus->shutter_time - << " (Shutter lines: " << exposureLines << ") Gain: " + /* GetVBlanking might clip exposure time to the fps limits. */ + double exposure = agcStatus->shutter_time; + int32_t vblanking = helper_->GetVBlanking(exposure, minFrameDuration_, + maxFrameDuration_); + int32_t exposureLines = helper_->ExposureLines(exposure); + + LOG(IPARPI, Debug) << "Applying AGC Exposure: " << exposure + << " (Shutter lines: " << exposureLines << ", AGC requested " + << agcStatus->shutter_time << ") Gain: " << agcStatus->analogue_gain << " (Gain Code: " << gainCode << ")"; - ctrls.set(V4L2_CID_ANALOGUE_GAIN, gainCode); + /* + * Due to the behavior of V4L2, the current value of VBLANK could clip the + * exposure time without us knowing. The next time though this function should + * clip exposure correctly. + */ + ctrls.set(V4L2_CID_VBLANK, vblanking); ctrls.set(V4L2_CID_EXPOSURE, exposureLines); + ctrls.set(V4L2_CID_ANALOGUE_GAIN, gainCode); } void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 7a5f5881..252cab64 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1233,7 +1233,8 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config) if (!staggeredCtrl_) { staggeredCtrl_.init(unicam_[Unicam::Image].dev(), { { V4L2_CID_ANALOGUE_GAIN, result.data[resultIdx++] }, - { V4L2_CID_EXPOSURE, result.data[resultIdx++] } }); + { V4L2_CID_EXPOSURE, result.data[resultIdx++] }, + { V4L2_CID_VBLANK, result.data[resultIdx++] } }); sensorMetadata_ = result.data[resultIdx++]; } } From patchwork Wed Dec 16 11:22:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10673 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 67A9EC0F1A for ; Wed, 16 Dec 2020 11:22:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 38E3461599; Wed, 16 Dec 2020 12:22:13 +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="lOGrdZJW"; dkim-atps=neutral Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 212236158D for ; Wed, 16 Dec 2020 12:22:09 +0100 (CET) Received: by mail-wr1-x42e.google.com with SMTP id 91so22801508wrj.7 for ; Wed, 16 Dec 2020 03:22:09 -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=UivwIO3ktu5j2EoxINYFa7ri9ABorkJNi+C3XacBQ4A=; b=lOGrdZJW/F6BZs4geYFq5bpz5qJHGDM8WV1dZOQRpcX3nO0zWNeS2o1UKfumXcj+Kr jGu4ZrrIYjC6jDxxmsGjmOidm3wf8qnxOPtSDaxN3T5RkRUtJPR/H3hz5jB6uGZgfQ0q sZuhzMuBSqidMJ3SVAdCeASsuA8afqBhNm6onJuJVnuhhd4cRqyX3KOnrjeoD76Uqybz fkp8ugdds6fhF2ttdtJRq12WMyW2XozbqXSnybYfsIBdS1MeUaI7N0fyfoE3O8ozKurS 86MJxpTWxgmdIHnoyPMdZvKhqdK1CL8rCMMg1rTJqlYzAVgU69M62o4bkV6YX4wxgstz 1Aqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UivwIO3ktu5j2EoxINYFa7ri9ABorkJNi+C3XacBQ4A=; b=Ydy4kOXngmM05GzDLZbqGWrGQv7h7Ky9ifkd89q2GBr4N6wZE/Ei2UTTPMO9KrhXlS vpfGVZF6rG+U6nv3Px7sVhIJLmTYYslF3vPsl0KAWzVZO/OJE4NOWNIba2y/4cvMozry h8hBkYA4IlHxHbbm3n8QfFpiSY3loRepZKdtLFaErKtR5S6l1Ab1Q37RSNJvHxeW0t4D GwrBzL/ZbAAnq7LRArERT75GIPbLWTfNHDkGDcZJobQA85b4QDa8uXf9FAZNpO5zZ1K5 dTfCiKbBpvVyLihdTFGtAkNKZ95DlE1cT2SzWgm3FewSONbINSgfSppmfRmqXCAl/aKI Bddg== X-Gm-Message-State: AOAM533E+4bzvQfd3x6sczsjKUPNuIh4phuvtcJKXQNEGszLd1RGVd4l 3DA2Kd5cjmH0+SeT+fKVjnZhYR6sJZeoug== X-Google-Smtp-Source: ABdhPJzI/ySLgw5bB3ro74CnE5ctXt3PsG91yUeN8y/5kNPHXHW5DNI3gCu80zqWISLY+CCkVDCleQ== X-Received: by 2002:a5d:5146:: with SMTP id u6mr6572514wrt.46.1608117728578; Wed, 16 Dec 2020 03:22:08 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id l8sm2766941wrb.73.2020.12.16.03.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Dec 2020 03:22:08 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Dec 2020 11:22:02 +0000 Message-Id: <20201216112202.5063-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201216112202.5063-1-naush@raspberrypi.com> References: <20201216112202.5063-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 3/3] ipa: raspberrypi: config: Update shutter speeds for imx219/477 and ov5647 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" Set the maximum shutter speed for the normal exposure profile to 66ms. Set the maximum shutter speed for the sport exposure profile to 33ms. Add a long exposure profile to allow shutter speeds of up to 120ms. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman --- src/ipa/raspberrypi/data/imx219.json | 15 +++++++++++++-- src/ipa/raspberrypi/data/imx477.json | 15 +++++++++++++-- src/ipa/raspberrypi/data/ov5647.json | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/ipa/raspberrypi/data/imx219.json b/src/ipa/raspberrypi/data/imx219.json index 212f8b9a..1ec338be 100644 --- a/src/ipa/raspberrypi/data/imx219.json +++ b/src/ipa/raspberrypi/data/imx219.json @@ -133,7 +133,7 @@ { "shutter": [ - 100, 10000, 30000, 30000, 30000 + 100, 10000, 30000, 60000, 66666 ], "gain": [ @@ -144,7 +144,18 @@ { "shutter": [ - 100, 5000, 10000, 20000, 30000 + 100, 5000, 10000, 20000, 33333 + ], + "gain": + [ + 1.0, 2.0, 4.0, 6.0, 6.0 + ] + }, + "long": + { + "shutter": + [ + 100, 10000, 30000, 60000, 120000 ], "gain": [ diff --git a/src/ipa/raspberrypi/data/imx477.json b/src/ipa/raspberrypi/data/imx477.json index 12fe2f41..9bee3f16 100644 --- a/src/ipa/raspberrypi/data/imx477.json +++ b/src/ipa/raspberrypi/data/imx477.json @@ -133,7 +133,7 @@ { "shutter": [ - 100, 10000, 30000, 60000, 120000 + 100, 10000, 30000, 60000, 66666 ], "gain": [ @@ -144,7 +144,18 @@ { "shutter": [ - 100, 5000, 10000, 20000, 120000 + 100, 5000, 10000, 20000, 33333 + ], + "gain": + [ + 1.0, 2.0, 4.0, 6.0, 6.0 + ] + }, + "long": + { + "shutter": + [ + 100, 10000, 30000, 60000, 120000 ], "gain": [ diff --git a/src/ipa/raspberrypi/data/ov5647.json b/src/ipa/raspberrypi/data/ov5647.json index 3d8a7c8f..1a354f7c 100644 --- a/src/ipa/raspberrypi/data/ov5647.json +++ b/src/ipa/raspberrypi/data/ov5647.json @@ -133,7 +133,7 @@ { "shutter": [ - 100, 10000, 30000, 30000, 30000 + 100, 10000, 30000, 60000, 66666 ], "gain": [ @@ -144,7 +144,18 @@ { "shutter": [ - 100, 5000, 10000, 20000, 30000 + 100, 5000, 10000, 20000, 33333 + ], + "gain": + [ + 1.0, 2.0, 4.0, 6.0, 6.0 + ] + }, + "long": + { + "shutter": + [ + 100, 10000, 30000, 60000, 120000 ], "gain": [