From patchwork Sun Sep 15 14:33:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Cl=C3=A1udio_Paulo?= X-Patchwork-Id: 21270 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 00675C324C for ; Sun, 15 Sep 2024 14:33:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EC825634F5; Sun, 15 Sep 2024 16:33:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=makewise.pt header.i=@makewise.pt header.b="jcxCOPD7"; dkim=pass (1024-bit key; unprotected) header.d=amazonses.com header.i=@amazonses.com header.b="dmktEO45"; dkim-atps=neutral Received: from a7-10.smtp-out.eu-west-1.amazonses.com (a7-10.smtp-out.eu-west-1.amazonses.com [54.240.7.10]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 72F29634F4 for ; Sun, 15 Sep 2024 16:33:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=4ymqmigrodjwq5luewph2eedidgwlpqq; d=makewise.pt; t=1726410802; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type:Content-Transfer-Encoding; bh=um5wbCeILzvMYQA1uSzoz2yUh5ugb3K+i3jCeJ8Ayjw=; b=jcxCOPD7oxFY3nWWWNLsvxNq+GeSiSJmfRIu9B4uuIhPrBpk7HSAmb3VRczZNFe2 wJPAlg6tOXgdchaXshjPfyhWj/PvF5J3KzJQrlhg0+g9fNgwuPlTDKz4W6NxbX2m3gP GqNI6aIKYkCAXRMR0HNnfH8OUJas/G6WZLGJiXAEKP2G7r4b3jgEQGJdBQMZ9akmxMo puScsjUFBoko4E+RDa7VuSdKpzZ8XwzgecjivR0y3kO1ZAoCVwmhRd+P7LySBDkdyH3 zdImBpi/1v9Uuex6+HN2yScsS/B8O0ePsFVqTP34hYh6CT8sQYBmc2aef/axDHEAOOM OC/WXb6ZYA== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=uku4taia5b5tsbglxyj6zym32efj7xqv; d=amazonses.com; t=1726410802; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type:Content-Transfer-Encoding:Feedback-ID; bh=um5wbCeILzvMYQA1uSzoz2yUh5ugb3K+i3jCeJ8Ayjw=; b=dmktEO456h+OrhgQ53cnKemDufo1p8btDLhe6Yk5f3BgKrdxDNU8YpJaVFVP+ia1 cIXYUWW3hKwwbhpWrXXltHHslWGseui1T0vLCKWCOEdnBmR9sm6dXVlNgEXKs/c6HJQ ncRGbS12krOtIn4XN4sy8QCVn6D6yKSsUU6FeZY0= From: =?utf-8?q?Cl=C3=A1udio_Paulo?= To: libcamera-devel@lists.libcamera.org Cc: =?utf-8?q?Cl=C3=A1udio_Paulo?= Subject: [PATCH v4] libcamera: pipeline: uvcvideo: Retrieve v4l2 device control information Date: Sun, 15 Sep 2024 14:33:22 +0000 Message-ID: <01020191f61a4608-322d1924-5c78-4e1e-93fc-a8d715af8c83-000000@eu-west-1.amazonses.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Feedback-ID: ::1.eu-west-1.z8xjvhxVxUk+kM5mx7i/KMS/a2avhcAXFe/noI67NVQ=:AmazonSES X-SES-Outgoing: 2024.09.15-54.240.7.10 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" Populate frame metadata by using V4L2Device::getControls() to get the values for all supported controls on each frame. Signed-off-by: Cláudio Paulo --- Fixed similar issues raised in review of a distinct patch. src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 106 ++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 6b32fa18..e89884db 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -750,10 +750,112 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info, void UVCCameraData::bufferReady(FrameBuffer *buffer) { Request *request = buffer->request(); + ControlList *metadata = &request->metadata(); /* \todo Use the UVC metadata to calculate a more precise timestamp */ - request->metadata().set(controls::SensorTimestamp, - buffer->metadata().timestamp); + metadata->set(controls::SensorTimestamp, buffer->metadata().timestamp); + + /* Retrieve control as reported by the device. */ + std::vector ids; + for (const auto &[controlId, _] : video_->controls()) { + switch (uint32_t cid = controlId->id()) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_EXPOSURE_AUTO: + case V4L2_CID_EXPOSURE_ABSOLUTE: + case V4L2_CID_GAIN: + case V4L2_CID_FOCUS_ABSOLUTE: + case V4L2_CID_FOCUS_AUTO: + ids.push_back(cid); + break; + default:; + } + } + + /* + * See UVCCameraData::addControl() for explanations of the different + * value mappings. + */ + ControlList deviceControls = video_->getControls(ids); + for (const auto &[cid, value] : deviceControls) { + ControlInfo v4l2Info = video_->controls().at(cid); + + int32_t min = -1, def = -1, max = -1; + if (v4l2Info.min().type() == ControlTypeInteger32) + min = v4l2Info.min().get(); + if (v4l2Info.min().type() == ControlTypeInteger32) + def = v4l2Info.def().get(); + if (v4l2Info.min().type() == ControlTypeInteger32) + max = v4l2Info.max().get(); + + switch (cid) { + case V4L2_CID_BRIGHTNESS: { + float scale = std::max(max - def, def - min); + + float fvalue = (value.get() - def) / scale; + metadata->set(controls::Brightness, fvalue); + break; + } + + case V4L2_CID_GAIN: + case V4L2_CID_CONTRAST: { + float m = (4.0f - 1.0f) / (max - def); + float p = 1.0f - m * def; + + if (m * min + p < 0.5f) { + m = (1.0f - 0.5f) / (def - min); + p = 1.0f - m * def; + } + + float fvalue = m * value.get() + p; + if (cid == V4L2_CID_GAIN) + metadata->set(controls::AnalogueGain, fvalue); + else if (cid == V4L2_CID_CONTRAST) + metadata->set(controls::Contrast, fvalue); + break; + } + + case V4L2_CID_SATURATION: { + float scale = def - min; + + float fvalue = (value.get() - min) / scale; + metadata->set(controls::Saturation, fvalue); + break; + } + + case V4L2_CID_EXPOSURE_AUTO: { + bool bvalue = value.get() != V4L2_EXPOSURE_MANUAL; + metadata->set(controls::AeEnable, bvalue); + break; + } + + case V4L2_CID_EXPOSURE_ABSOLUTE: { + int32_t ivalue = value.get() * 100; + metadata->set(controls::ExposureTime, ivalue); + break; + } + + case V4L2_CID_FOCUS_ABSOLUTE: { + float focusedAt50Cm = 0.15f * (max - min); + float scale = 2.0f / focusedAt50Cm; + + float fvalue = (value.get() - min) * scale; + metadata->set(controls::LensPosition, fvalue); + break; + } + + case V4L2_CID_FOCUS_AUTO: { + uint32_t ivalue = value.get() == 0 + ? controls::AfModeManual + : controls::AfModeContinuous; + metadata->set(controls::AfMode, ivalue); + break; + } + + default:; + } + } pipe()->completeBuffer(request, buffer); pipe()->completeRequest(request);