From patchwork Fri Jun 5 14:10:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3951 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5920061645 for ; Fri, 5 Jun 2020 16:07:13 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from localhost.localdomain (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id F180A20009; Fri, 5 Jun 2020 14:07:12 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Jun 2020 16:10:01 +0200 Message-Id: <20200605141002.49119-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200605141002.49119-1-jacopo@jmondi.org> References: <20200605141002.49119-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 7/8] libcamera: camera_sensor: Initialize frame durations 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-List-Received-Date: Fri, 05 Jun 2020 14:07:13 -0000 Calculate the camera minimum and maximum frame durations, and register the corresponding FrameDurationLimits property with those values. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index b9428175c55e..b144940f047d 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -283,6 +283,80 @@ int CameraSensor::initProperties() propertyValue = 0; properties_.set(properties::Rotation, propertyValue); + /* Frame durations. */ + std::map controlLimits; + std::array controlIds = { + V4L2_CID_VBLANK, + V4L2_CID_HBLANK, + V4L2_CID_PIXEL_RATE + }; + for (uint32_t controlId : controlIds) { + /* + * Make sure the subdevice reports VBLANK, HBLANK and PIXEL_RATE + * controls and collect the control information. + */ + auto it = controls.find(controlId); + if (it == controls.end()) { + LOG(CameraSensor, Error) + << "Camera sensor does not support control " + << controlId; + return -EINVAL; + } + + controlLimits[controlId] = &it->second; + } + + /* + * While the maximum line and frame sizes can be calculated by adding + * each control's maximum supported value to the current configuration, + * the minimum sizes shall be calculated by using the minimum available + * resolution. Get the current and smalles available size then calculate + * the frame durations. + */ + V4L2SubdeviceFormat fmt{}; + int ret = subdev_->getFormat(0, &fmt); + if (ret) + return ret; + const Size ¤tSize = fmt.size; + const Size &minSize = *sizes_.begin(); + + std::vector durations; + int32_t duration; + + /* + * Pixel rate is reported in Hz while frame duration is expressed in + * nanoseconds. Adjust it and calculate the minimum and maximum + * durations. + */ + int64_t pixelRate = controlLimits[V4L2_CID_PIXEL_RATE]->max().get(); + float rate = static_cast(pixelRate) / 1e9F; + + /* Minimum frame duration: higher frame rate. */ + duration = (minSize.width + + controlLimits[V4L2_CID_HBLANK]->min().get()) + * (minSize.height + + controlLimits[V4L2_CID_VBLANK]->min().get()); + duration = static_cast(static_cast(duration) / rate); + durations.push_back(duration); + + pixelRate = controlLimits[V4L2_CID_PIXEL_RATE]->min().get(); + rate = static_cast(pixelRate) / 1e9F; + + /* Maximum frame duration: lower frame rate. */ + duration = (currentSize.width + + controlLimits[V4L2_CID_HBLANK]->max().get()) + * (currentSize.height + + controlLimits[V4L2_CID_VBLANK]->max().get()); + duration = static_cast(static_cast(duration) / rate); + durations.push_back(duration); + + properties_.set(properties::FrameDurationLimits, durations); + + LOG(CameraSensor, Debug) << "Frame durations interval = [" + << durations[0] << " - " + << durations[1] << "]"; + + return 0; } /**