From patchwork Thu Dec 10 16:33:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10635 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 ED324BD80A for ; Thu, 10 Dec 2020 16:33:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7272567F75; Thu, 10 Dec 2020 17:33:42 +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="sINuxwAN"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B6D367F6E for ; Thu, 10 Dec 2020 17:33:41 +0100 (CET) Received: by mail-wm1-x334.google.com with SMTP id g185so5959090wmf.3 for ; Thu, 10 Dec 2020 08:33:41 -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=eIR3MVGby/dymFl1XAhYVzklHGNpDFvUa4zqKMvXn+k=; b=sINuxwANNjeRgMIxKVQMwwDHZAvAEtRhR7cGvItcrwtNgap41fVzN3sbyBSWvvyUxo oefcEMr2yxX50CGm9zAGDC4L9dMedXLEit1J8GI6UUtYRc1lehhqKEMBGXEZDTGOgLbs 1D5WOGVAharmC86+6mclKyQLmZvLuiL+kDXFTeS/Q63vo9WKNMwkjv/prFwTQ6mNBZq1 D3zxO+DPLCxNC7apphVy5GjSye34nXKMRmRPpFY29uLogaqlgU00JJgDlAibIdLk7gCU F0rLRvrD+lvSbsC5jMfBwQUdkYd5iKFVVsUsbt1Y4vIYToixLkoBm+OSGU5rGmBdITtD 1E5g== 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=eIR3MVGby/dymFl1XAhYVzklHGNpDFvUa4zqKMvXn+k=; b=Sn00cwyOeBbyCikaZKOAM/w8p/G+LIpa0J1D2XiHLGARsDgK3w6xcFmJrRI9e4Ix9o m6enH80e/udVe+gojRe3KfjyqMW2hFDK+v0qm5ZhS7izDa3ZuU7br0MfRis2f7Ey/yyY +XR9TGzM9wJhlQDkgxnWOX2uq8+7XOLk7Ri6s2hCnSd/FmYTjjfuHzWTf/YjS9/W+YUc iob/+5nVeOhpGw9WaJEwmzd34vcZ8GV3JDOOg/0zf9aREff2+45n5T/iOPr5qu2njyTR ML7d2VddCkO8PyWb4oxb23bQ8g6PRfm5MR0/bjdDhXDZELksT5n0X88lsojMVps0nIyy ispA== X-Gm-Message-State: AOAM532o34jJaNWX9VknsSqnHbX3GMhSvDX7w69h8HpwvHsfIxjHU9v/ Oy2BLeUty9BdrTm3+vCENJ3FNRrtwRF1iQ== X-Google-Smtp-Source: ABdhPJwvKq1wgY+DavL4nOi9E5wSd4M0EWyP7vbeSGoCul6OyzmOrkRYEw7QS7cNBQc1dXpW/eLJyw== X-Received: by 2002:a1c:98c7:: with SMTP id a190mr9100581wme.184.1607618020610; Thu, 10 Dec 2020 08:33:40 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id v7sm9589433wma.26.2020.12.10.08.33.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Dec 2020 08:33:39 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 10 Dec 2020 16:33:35 +0000 Message-Id: <20201210163337.212857-1-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 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 a float 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..5ee31865 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 times 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. Setting both values to 0 resets the + frame duration to the IPA defaults. + + The maximum frame duration provides the absolute limit to the shutter + speed available to the AE algorithm. This limit also overrides any + limits set by the exposure mode (AeExposureMode). Similarly, a manual + ExposureTime value provided by the application may also be clipped by + this limit. + + \sa AeExposureMode + \sa ExposureTime + + \todo Refer to the frame duration limits property to describe how + application-provided values gets clipped. + + 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). + # ---------------------------------------------------------------------------- # Draft controls section From patchwork Thu Dec 10 16:33:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10636 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 0C73EBD80A for ; Thu, 10 Dec 2020 16:33:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D02BA67F7D; Thu, 10 Dec 2020 17:33:44 +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="WG7zfOQN"; 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 A420767F6E for ; Thu, 10 Dec 2020 17:33:42 +0100 (CET) Received: by mail-wr1-x42e.google.com with SMTP id c5so2500590wrp.6 for ; Thu, 10 Dec 2020 08:33:42 -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=S82wh9N4H0J8ZbqVfvUYib/WapQcrvihxBYDQJl5Npc=; b=WG7zfOQNnbH0XpeBU6+A8VZYTiiAwGyIQRfFH+fh5UA7zjeMZ8pbZYrLFWmwhasqix FeV+LgieFRmrIgE5YBxn/oFVnNXLp96qKmc5M3ClgJrvK2wOzcnC5x+I8ATuEWEgCbX9 6KcHbhmkmkhwzjnTsDY6qn0k7xfE/Q3X9kiaPCcKaCuJ/J+IXOp6eeyD78yoMujXk2Pf ektKa78P8T5pSoGzuvxgp04nG3RC56AwlhhHNeWBbyNqu3jscFokRw4h4uvSBa0w/P4w 1YBFkPAEe5D82BLtBVxwTdtLvZQ9Ljj6ADa3KORFvpl8NjxM6Wg0xipbJ2N8gfelzRqB q0bg== 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=S82wh9N4H0J8ZbqVfvUYib/WapQcrvihxBYDQJl5Npc=; b=nxtb5D5ZAU9YZAFHtAiYE/Yuy3aVVevP4ZGRAkbE6rcgbvF8pZ64Z6TYCBG3nQxYnm ENINp6qaE7I8lH+iL9PQ5LF7OFKWHorYq5N/PZXoJmMVDN+UqNlkmHnt7tUZkkf6IMQy rVSShYFboFjGmKm0cNzWvoBh4CGq+qYhVXoAYvQaTMrIIKmTRJ+dagh/G20I2orKu/Sx WSMguGyXMpM1cv8jUhL0dRS82+nCiErXMcP/0YMHMWi32PhhodE4FEcWTNAsYtLeoaRz ZKgkOqHrnQgoJiOfRIpa2GxVblxnxPHMnLKitrtg0eINKZ2gprbOjhOXnj4yFvtfPP4/ JIdQ== X-Gm-Message-State: AOAM531OTqZEx0LlvUzNvr82I3X4kJPJW+xcHTzZlm7w8LpeNYF1tRsm f3aIEO10ysPJl3udvEfeugALGdQOCfQ8sw== X-Google-Smtp-Source: ABdhPJzA242flWHj8eGY1yj9zN/sfYEebUfM8rIL7Bwnc5cxhLB7CccjGyDp/HpqjdQ6A8ss+JLHdA== X-Received: by 2002:a5d:68c9:: with SMTP id p9mr9185026wrw.139.1607618021706; Thu, 10 Dec 2020 08:33:41 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id v7sm9589433wma.26.2020.12.10.08.33.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Dec 2020 08:33:41 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 10 Dec 2020 16:33:36 +0000 Message-Id: <20201210163337.212857-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201210163337.212857-1-naush@raspberrypi.com> References: <20201210163337.212857-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 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 --- 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 | 39 ++++++++++++++++--- .../pipeline/raspberrypi/raspberrypi.cpp | 3 +- 8 files changed, 115 insertions(+), 13 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 01fe5abc..160ca681 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(1.0e3f, 1.0e9f) }, }; } /* 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..52d25f7d 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,15 @@ 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; + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() @@ -882,7 +899,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 +916,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 Thu Dec 10 16:33:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10637 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 A6183BD80A for ; Thu, 10 Dec 2020 16:33:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3044667F6E; Thu, 10 Dec 2020 17:33:45 +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="sLpAbJp9"; dkim-atps=neutral Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 065DF67F72 for ; Thu, 10 Dec 2020 17:33:43 +0100 (CET) Received: by mail-wr1-x42c.google.com with SMTP id a12so6121877wrv.8 for ; Thu, 10 Dec 2020 08:33:43 -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=sLpAbJp9B5X9I48iZo2Wc46nzTljh3MVv3E1hyKYjs5Fi+eysemaxK1pEl9DeanFE9 ekYqb8NuS350S6QZKpErPpBoh0F8x1djg0+gZ7YFkb4u/jT3+0FB+JE/2iPDnxS49zLo PVdKP+hHS74GPM7PS6uZMBs1XDZtuXalaVV1X+Z9TS6eY2YBAaja64MCvqdlH5tgQd6y A08lkybhNsKFyEReLNSn5qKSxnRqH47HRRUbjh8zNVVT0sQPNNBAKgUXwluLzFb2c3/r Ub1Z1MqeMAQzqmRCWHJoQhKgh7F9pJ8mxAX14cRHa2inJkUP/eRrQVGOFxDq943e1iJL Ulfg== 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=HosZ6p4BtriuAsWOMGuJadfMQevaDvgY2zl4H2R3RmwhZsmQN+32hVROEUo73DTQ9b +OqOncgKBdYx8VATw0W2BN++Kwwi2+pZgBmBwTogO6aEzpTUk+3oiY1QFmNgO2y76CSl Biuq2/pVODSUs6mX3qtESSN7tbk17bRnNE/dolXUMK9bEJsb/tPAwiMkvnSx2EJX8l5r OMWm3/kEg+1B1f4vH8L2IN+XDJjyEmTerhEX/U4kxqZEU2F+Fqfd27WQ1vmZJwG84Y50 jCypecD+1nZ5Cyzb8sCAGauYTRPsX7vsvZlw64reVcDxeKW/+M8rgPbMvBTErtCsUu5Y qGeg== X-Gm-Message-State: AOAM531T/mwMcNhEiYtqeTJAUb97DPpWPBRcOdw8Vhwt5UOfbmEmYBaG D2A+kP4xsmPLS57q75k7EpQz12kk+hWSuQ== X-Google-Smtp-Source: ABdhPJyb9wOXAHpS931pM1TgKWB1RTPPv9Xub3ZI0sMCmgKx1EZUcOMkj1Dstfc8uyZPoyN5CMQX+Q== X-Received: by 2002:a5d:6a05:: with SMTP id m5mr9078387wru.96.1607618022506; Thu, 10 Dec 2020 08:33:42 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id v7sm9589433wma.26.2020.12.10.08.33.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Dec 2020 08:33:41 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 10 Dec 2020 16:33:37 +0000 Message-Id: <20201210163337.212857-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201210163337.212857-1-naush@raspberrypi.com> References: <20201210163337.212857-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 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": [