From patchwork Fri Dec 11 15:45:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10648 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com 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 9ACF9BD80A for ; Fri, 11 Dec 2020 15:45:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E458C67FA5; Fri, 11 Dec 2020 16:45:32 +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="XIQaKFbj"; dkim-atps=neutral Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 86D3B67F06 for ; Fri, 11 Dec 2020 16:45:30 +0100 (CET) Received: by mail-wr1-x42b.google.com with SMTP id r7so9490929wrc.5 for ; Fri, 11 Dec 2020 07:45:30 -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:mime-version :content-transfer-encoding; bh=gH8HMYcOquTPDuesHKOTcqJ/C07iagYJVPlUMXZ+2JM=; b=XIQaKFbjJervKr5MKTd08z7SEDAvlrU1Jd2iuIvfPwQklcpbjbVb4cxSF2rnL7YHTP APM2TNTF7jFgyqh5wDQaWS0VGYuzS7lu/dc/2J8W9r3mKgDr2zy8/cISCQtxYTJQckAt 6doHIxEZnkJhITsPHiA4xozTnIaPY6mIzIhRQbqoqjMmO/Vu4ycF+Pp56bcLCqKOiwdQ +AhUAxSRfm5URC4KF6rSk/G01Ry1mkV4n2it+SDxDMW+Y8qwQa0mDxOw0P+6wu5JMMu7 Mwk78csnv/VlmXLHaBoRbho8GO3zdjyWhOHSiqt0hT2cvQebLdnpnByM5rTgrwjCW8DA mmXQ== 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:mime-version :content-transfer-encoding; bh=gH8HMYcOquTPDuesHKOTcqJ/C07iagYJVPlUMXZ+2JM=; b=dfgq7HeMKC5rrEAJKjfTLFID37yTrv0AeX+n+B+NIhOH54BDTSOYFQH2Z+qceMicbj M6JpRkwsGYFxDUF3JkYK7F7KuzEu1af2wf0DLn6jys2DzWvX2RJHsvH3HYF5zNGSFJVJ BBkWKdQOI8tHlSBa0v/uGMa8h0vF9t3ZMUUUo/rW92W85HP3xHFHQGtX7JjIS3svLmXL NV1ztv78GvYeFjZZl62qJP6sFugVvpwhP8qgF2ZsiyxxrsS30W9X+/zNLX8GL65eS2Wz CGokB6y5dZo3IA60+djxoLCOO7RSkipcDo8TKKRooTZONuFLgjRNCKpZOLmcW9wzWItr 9kxw== X-Gm-Message-State: AOAM532jTtHzmwSePoKsQz6o9mHKNzHoqn4/1/7ZYmdThoznDVWCQBLn iy6qqOWWEpq5+CiE1f6z2K/c1hyTIf5mNQ== X-Google-Smtp-Source: ABdhPJxXRpTTMpqUWZ75lnIRORAdDQhKaTUPCR2QNME2WZcLVVdOAUa1JDd4Bi/V29VIXJAKaVQNCw== X-Received: by 2002:adf:eac7:: with SMTP id o7mr14865231wrn.23.1607701529768; Fri, 11 Dec 2020 07:45:29 -0800 (PST) Received: from naushir-VirtualBox.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id 89sm16281248wre.51.2020.12.11.07.45.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Dec 2020 07:45:29 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 11 Dec 2020 15:45:23 +0000 Message-Id: <20201211154525.5141-1-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 Fri Dec 11 15:45:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10649 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com 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 754BBBD80A for ; Fri, 11 Dec 2020 15:45:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 63C5D67FA8; Fri, 11 Dec 2020 16:45:33 +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="l34AJk5J"; dkim-atps=neutral Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9675367F06 for ; Fri, 11 Dec 2020 16:45:31 +0100 (CET) Received: by mail-wm1-x330.google.com with SMTP id k10so7931169wmi.3 for ; Fri, 11 Dec 2020 07:45:31 -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=FdbQE4UdV7QLbRn6INppLQzDh+qIIxZyvGBJJh4uhBU=; b=l34AJk5JWrOBbomlLksCQmjkNtY6whEXJ9KrDttZWoh6crBufcpq+285wTJIRBzJL2 8M9sNN+Y/OfaWw8/cdhTTyXMPvbnbQzs9aOTRwsRJ0gf6xDdGMaWAhURA+H5r0e6TJMU m1qwmEwRsu52avRGsOxj662Sn4SXmxbLMbmTNLM5kPfyfjM+gxx1B+OQjRh32A/GHZ9j DQiPA6ZhUAlG6KOUKYL2L7MfuF6ZQrpIfzoJSAU1voL+jeXojfpN2yPoyNXqov+LIJ8O hBjnnIYNMUkgId6bkXShUkOAEGZ8zd+fVIOXRLykOAS7VX+CTQqIobmjNOPyDu1E1MnB jPFQ== 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=FdbQE4UdV7QLbRn6INppLQzDh+qIIxZyvGBJJh4uhBU=; b=NOQY1lxDekaX7YIOvgrunt1goOt0FA6wgtWMoQHS7tl7AET3BQ7HsQY56lDQKAPQM9 cHVJGQD7fg9zwFxgtOheGaJQUvYaBM8mvIo7xbW0zj9ZyvReIc/37VlLWvXGrIvBt35c XTqOVkt9CV1aLVAzU9EoI5IEHi+yabOwjRoix1y9lIp1nlUqHR8nBX6nj4aKC97w4dRJ pBGejjMRd/fXtKC/rOx5dSJkQ6v/XuFHpg1glYOceQ9bCJoRl1lmJ7c1MdJsB98ekxnF 5kiPTLwxcMxKGYmPrBO74T//ChfNHYF1DQ+b5eeXXF6wI2FkIrMIAMNsfk/Uvw9c1hJ3 cuPg== X-Gm-Message-State: AOAM533++EyWZ3S+ndSdXLfG+sAMT4OuWeuk4XcoH/fv68heHE59ZWuX lbztxm+NUHzPdkK2Ks3HTCRWYY4u7WQCxA== X-Google-Smtp-Source: ABdhPJzqGCG91rO7K487Xyg27+C1/URdaWM013UKw4dDxVY4WBnYop45vZ/ubq+reQxt9Zzgydxl/A== X-Received: by 2002:a7b:c4d5:: with SMTP id g21mr14260200wmk.92.1607701530775; Fri, 11 Dec 2020 07:45:30 -0800 (PST) Received: from naushir-VirtualBox.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id 89sm16281248wre.51.2020.12.11.07.45.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Dec 2020 07:45:30 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 11 Dec 2020 15:45:24 +0000 Message-Id: <20201211154525.5141-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201211154525.5141-1-naush@raspberrypi.com> References: <20201211154525.5141-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 --- 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 | 42 ++++++++++++++++--- .../pipeline/raspberrypi/raspberrypi.cpp | 3 +- 8 files changed, 118 insertions(+), 13 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 c8ac3232..7fd3e7f6 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 dc5d8275..7630c127 100644 --- a/src/ipa/raspberrypi/cam_helper_ov5647.cpp +++ b/src/ipa/raspberrypi/cam_helper_ov5647.cpp @@ -22,6 +22,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; }; /* @@ -30,7 +39,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 60cfdc27..f6d2b543 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) @@ -145,6 +147,9 @@ private: /* LS table allocation passed in from the pipeline handler. */ FileDescriptor lsTableHandle_; void *lsTable_; + + /* Frame duration (1/fps) given in microseconds. */ + double minFrameDuration_, maxFrameDuration_; }; int IPARPi::init(const IPASettings &settings) @@ -266,7 +271,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; @@ -335,6 +341,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); @@ -712,6 +720,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() @@ -882,7 +902,12 @@ 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); + + /* 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); if (unicamCtrls_.find(V4L2_CID_ANALOGUE_GAIN) == unicamCtrls_.end()) { LOG(IPARPI, Error) << "Can't find analogue gain control"; @@ -894,13 +919,20 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) return; } - LOG(IPARPI, Debug) << "Applying AGC Exposure: " << agcStatus->shutter_time - << " (Shutter lines: " << exposureLines << ") Gain: " + 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 2ec1f6e7..13349f31 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1221,7 +1221,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 Fri Dec 11 15:45:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10650 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com 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 730F7BD80A for ; Fri, 11 Dec 2020 15:45:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3D86F67F9E; Fri, 11 Dec 2020 16:45:35 +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="MzcWlMyy"; dkim-atps=neutral Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B47A267FA1 for ; Fri, 11 Dec 2020 16:45:32 +0100 (CET) Received: by mail-wm1-x336.google.com with SMTP id 3so9004695wmg.4 for ; Fri, 11 Dec 2020 07:45:32 -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=MzcWlMyywIqWI9AGbTBhLo4dZRGCAj5WMUbgXR6gNi1O4jN2CGj0rwauA8sxxX5pbM zrDh0eGzi0PSX97M0WxSZZrOV79mwy5qvMPoNS5Izr8O142Cm3W2F0ffk7se1zOZy0Wk L52aqdgUxklxnNX2Z3ZHGiNGB4SRxG2CvFI4fL3A6zimjWhW++dDIDvnLSEFsLt2hAba 9aewvQXAtW6j5Uq6WXtpUVnxze06ctpl42lyKirW9xxIzTUp5lKb9/CEzOlnjkB8Str6 QZsq30ZRKzIem1zGcZaB3PgukadBibsqOf61eE+eD81BSQ9iALvlawkldE5i8oNfyepU raOA== 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=GpyHnEcOK3/TOeQgxWOBJbYwp0DGlUgldfQ3wt+PZr0prDkmPzt/j2wyV/L25BtmpN UsR4X3nZrMt/5F8Ul8MgT2hehIN1E8VtwJVnBZh0xTW1eGVFnjcrgw/kARB/0RGha5T2 pxaVZY/5Mgx8JlhaprrHV4yqhcVx+P16vrJZmo8g+m6C5CHekQrdj4TD0THyhMsQ0zBt GExNKA7iUadj/T6YdDL2hKN6XEqr5yab+/DFyqaWLYU1cPOP39w+iKbKD7DCPAJ59Kbt AjR+DP93QBdeABWsZsMjd/fkg5azwmcMrH0KxYZxKU1GZg3uXLKgMsK1v5s0CpqkYRVI m1aQ== X-Gm-Message-State: AOAM5338S1AMgkOJRFn4FFUpWyIEc+DdqRi8mJJxDbGS8X8K8ZrCXiXW 4Z4R/kXwrUsuOQzbIK8uN9tBVtOCT9zuvg== X-Google-Smtp-Source: ABdhPJxM6JMzUR/ddsqy0dVWfDYz6PKXnQnItfVbWtg0Q1H7PUNLT+LG8T4kKcpGeqkhZM0MiSJ1Gg== X-Received: by 2002:a05:600c:cc:: with SMTP id u12mr14590904wmm.42.1607701532164; Fri, 11 Dec 2020 07:45:32 -0800 (PST) Received: from naushir-VirtualBox.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id 89sm16281248wre.51.2020.12.11.07.45.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Dec 2020 07:45:31 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 11 Dec 2020 15:45:25 +0000 Message-Id: <20201211154525.5141-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201211154525.5141-1-naush@raspberrypi.com> References: <20201211154525.5141-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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": [