From patchwork Thu Apr 23 19:04:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3507 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EC6062E45 for ; Thu, 23 Apr 2020 21:05:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="uHicGSgg"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0F63B4F7; Thu, 23 Apr 2020 21:05:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1587668702; bh=x8za8beMjIMY2dG8Ib7RxjJV2l6PoWdqzBtlPbVXS4k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uHicGSggJl4VJqfJzqm505GUv6mQERjl9zYJsfnp2tOpCSD7RzexDIcIW9w130aa0 k53QJqBcKQB/KJn4zU+Fs+Bpwri1MAtjNDozvuzMuKIj/UbIXBDGPq/GOmlxTy1bSt CyWbuQbPHp3uGxBE77wOiqr35aGtfCxr9tPVD+zk= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 23 Apr 2020 22:04:43 +0300 Message-Id: <20200423190443.31510-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200423173613.GI6196@pendragon.ideasonboard.com> References: <20200423173613.GI6196@pendragon.ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3.1 2/5] libcamera: pipeline: uvcvideo: Update exposure/gain ctrls set with new units 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: Thu, 23 Apr 2020 19:05:03 -0000 From: Naushir Patuck The ExposureTime control now uses units of 1 micro-second, and UVC uses units of 100 micro-seconds. Correctly map the values before setting V4L2_CID_EXPOSURE_ABSOLUTE on the V4L2 device. The AnalogueGain control now uses floats to allow fractional gain values. Since UVC has no explicit gain units, map the default gain value to 1.0 and linearly map to the requested value. Signed-off-by: Naushir Patuck Signed-off-by: Laurent Pinchart --- Changes since v3: - Round the gain value to the nearest integer when converting from float - Use float values for the gain range --- Hi Naush, I realized there were two issues in the previous version of the patch: - The gain was always rounded down, preventing my sine wave gain test from reaching the maximum value as I never hit the case where sin(w*t) was exactly equal to 1.0. - The gain control info was reported as int32_t values, when the control is of type float. This was reported by an error message in ControlInfoMap::generateIdmap() which I initially missed, wondering why the gain was not applied. This new version fixes both issues. The conversion from int32_t to float for the range may not be very nice, but I propose addressing that separately on top if we deem it necessary. src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 28 +++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index d7df95e4519a..09176b4e0d17 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -253,9 +253,22 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request) controls.set(V4L2_CID_SATURATION, value); } else if (id == controls::ExposureTime) { controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast(1)); - controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value); + /* + * controls::ExposureTime is in units of 1 us, and UVC + * expects V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 us. + */ + controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, + value.get() / 100); } else if (id == controls::AnalogueGain) { - controls.set(V4L2_CID_GAIN, value); + /* + * controls::AnalogueGain is specified as an absolute + * multiplier for all RGB samples. Map this multiplier + * in a linear way such that 1.0 -> default gain + * of the V4L2_CID_GAIN control on the uvcvideo device. + */ + const ControlInfo &gainInfo = controls.infoMap()->at(V4L2_CID_GAIN); + int32_t gain = lroundf(value.get() * gainInfo.def().get()); + controls.set(V4L2_CID_GAIN, gain); } } @@ -350,7 +363,7 @@ int UVCCameraData::init(MediaEntity *entity) ControlInfoMap::Map ctrls; for (const auto &ctrl : controls) { - const ControlInfo &info = ctrl.second; + ControlInfo info = ctrl.second; const ControlId *id; switch (ctrl.first->id()) { @@ -368,6 +381,15 @@ int UVCCameraData::init(MediaEntity *entity) break; case V4L2_CID_GAIN: id = &controls::AnalogueGain; + /* + * AnalogueGain is a float control, convert the type of + * the range. + */ + info = ControlInfo{ + { static_cast(info.min().get()) }, + { static_cast(info.max().get()) }, + { static_cast(info.def().get()) } + }; break; default: continue;