From patchwork Mon Nov 21 15:44:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 17824 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 8F789BE08B for ; Mon, 21 Nov 2022 15:44:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CEE806331F; Mon, 21 Nov 2022 16:44:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669045470; bh=ElKufu7CMYATkuoiRAVdVvcfz+UvtRZPr92j7IB7HfU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=31PEPtlXqQctIGSD+8bZHipmGItUUAD7/zitxH+Im/qWkhV2QXnpHhuzHn/WJQA55 IMoNx6d40sJ8S+XQP+vYHE2sMqIXnokpO0ut9JgLFGqo0abaBrySyd1Yk7L3umcF0J 1HKURnun3CR54pCbj3yTTFB9eHgaZ3nstsR2hZhdP49Dl/xg4JdGs+/i55JQ42HVv6 pP4cBXNMtDPIGoBd+MsG8M5rLwYVuzWFhhh5BAVSP67+LbpHWOsNusv+vgCkEaAOUE sEssguG+WR4BAIHtlfJxExketGLbaeDgGUr6yaGLIMhnkK0Nfs8gvaM7EwQqRYXPBR W/3bwQIuo963g== Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A429963311 for ; Mon, 21 Nov 2022 16:44:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="tm44CIB5"; dkim-atps=neutral Received: by mail-wm1-x329.google.com with SMTP id i64-20020a1c3b43000000b003d016c21100so3479843wma.3 for ; Mon, 21 Nov 2022 07:44:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=eZWGHVFGF7J1lGK7ZZU9Tff95PuQzoZ9l1symSVcbtA=; b=tm44CIB5IuCJuH5JD4u3iC+a2vOmjVZzqqhFHovCFdHF+byGhy7GhRDhvCd5coCo2y yghgLci/H+r0ARvKOrVV/Fv2xyBbN6OVOaH1yNavbt5zRyvfEQubciGioNist5rBIvIt OPzcG8wG48i2mCVjE7Ik8MDo3Y+qr1zqF9xsGYRF2Ek7nbr2PiIhHY2XwPOEcN4vb/Gp Ks42gaA43bFnSjKvZ4uYjkUP+nmWdKR6TC8JWKDm5UETQwbsrIPbLS0+V+cAyRyEBvSC SfLDo1FHc3ueOJ7UKJlP0Am/GfdxHqnOA+nZt22Lm80+htn0PTH4JQ7geIlJeXKRgabz vXKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eZWGHVFGF7J1lGK7ZZU9Tff95PuQzoZ9l1symSVcbtA=; b=cNYgYRMpaat5ZFtUagYhrccyWqQs+TpNRv6M/PrcF3qPr3RKUUeEoDiXp4Aygy++Km gzLznCU6oZikh6Yn6RMrA7dJO1kChkWtvMXVqxNtaVvKNLFQgwCRuK4Le1f8sR6YeKl0 2WZM9aWFIRM/bBTr+CaHXt+iogxcH++eHoAzM1mM+WGlZkAEOErhDszQpl15Vr65PBAU bpsRLIsLoUkVDjUCiGA/6kY5hEoWI7j4mJqCzy5Dun5wxghDO2LNpTDFe+UoJx78sEKx 1DkKtnYldfqPo3Hj5CWwuesXf7VqzdVK0F9dHzX6RKg5o6XHGtRZ7lB3ZAkNuxmsp5Jg uC7g== X-Gm-Message-State: ANoB5pk9V7YRXsz2NxVpMHTasNzoWcJsWeVxo9/A32voIqspg449WyVn /wsNT00bkadZ477R6s8azjgG8QPRfBBSXw== X-Google-Smtp-Source: AA0mqf4g+bJ9A7Bu9fHMTfU+RU7RDJdrH9LAK5p5kYo9tyBC9HIbRFfsJmJzxaAaoGpOpxozx4zqPw== X-Received: by 2002:a7b:ce8c:0:b0:3cf:8b2d:8cbc with SMTP id q12-20020a7bce8c000000b003cf8b2d8cbcmr2279440wmj.89.1669045467956; Mon, 21 Nov 2022 07:44:27 -0800 (PST) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:e4a2:3070:eea4:e434]) by smtp.gmail.com with ESMTPSA id t11-20020adff60b000000b0022e035a4e93sm11742257wrp.87.2022.11.21.07.44.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Nov 2022 07:44:27 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Mon, 21 Nov 2022 15:44:18 +0000 Message-Id: <20221121154421.11732-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221121154421.11732-1-david.plowman@raspberrypi.com> References: <20221121154421.11732-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/5] libcamera: camera_sensor: Do not clear camera flips when listing formats 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-Patchwork-Original-From: David Plowman via libcamera-devel From: David Plowman Reply-To: David Plowman Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Previously the code used to clear the camnera's h and v flip bits when enumerating the supported formats so as to obtain any Bayer formats in the sensor's native (untransformed) orientation. However this fails when the camera is already in use elsewhere. Instead, we query the current state of the flip bits and transform the formats - which we obtain in their flipped orientation - back into their native orientation to be stored. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 49 ++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 572a313a..cbac9e78 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -19,6 +19,8 @@ #include +#include + #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor_properties.h" @@ -108,18 +110,45 @@ int CameraSensor::init() return ret; /* - * Clear any flips to be sure we get the "native" Bayer order. This is - * harmless for sensors where the flips don't affect the Bayer order. + * We want to get the native mbus codes for the sensor, without any flips. + * We can't clear any flips here, so we have to read the current values + * (if the flip controls exist), decide whether they actually modify any + * output Bayer pattern, and finally undo their effect on the formats. + * + * First, check if the flip controls exist and if so read them. */ - ControlList ctrls(subdev_->controls()); - if (subdev_->controls().find(V4L2_CID_HFLIP) != subdev_->controls().end()) - ctrls.set(V4L2_CID_HFLIP, 0); - if (subdev_->controls().find(V4L2_CID_VFLIP) != subdev_->controls().end()) - ctrls.set(V4L2_CID_VFLIP, 0); - subdev_->setControls(&ctrls); + std::vector flipCtrlIds; + const struct v4l2_query_ext_ctrl *hflipInfo = subdev_->controlInfo(V4L2_CID_HFLIP); + const struct v4l2_query_ext_ctrl *vflipInfo = subdev_->controlInfo(V4L2_CID_VFLIP); + if (hflipInfo) + flipCtrlIds.push_back(V4L2_CID_HFLIP); + if (vflipInfo) + flipCtrlIds.push_back(V4L2_CID_VFLIP); + ControlList flipCtrls = subdev_->getControls(flipCtrlIds); + + /* Now construct a transform that would undo any flips. */ + Transform transform = Transform::Identity; + if (hflipInfo && flipCtrls.get(V4L2_CID_HFLIP).get() && + (hflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT)) + transform |= Transform::HFlip; + if (vflipInfo && flipCtrls.get(V4L2_CID_VFLIP).get() && + (vflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT)) + transform |= Transform::VFlip; + + /* Finally get the formats, and apply the transform to the mbus codes. */ + auto formats = subdev_->formats(pad_); + for (const auto &format : formats) { + unsigned int mbusCode = format.first; + BayerFormat bayerFormat = BayerFormat::fromMbusCode(mbusCode); + + if (bayerFormat.isValid()) + mbusCode = bayerFormat.transform(transform).toMbusCode(); + + if (mbusCode) + formats_[mbusCode] = std::move(format.second); + } /* Enumerate, sort and cache media bus codes and sizes. */ - formats_ = subdev_->formats(pad_); if (formats_.empty()) { LOG(CameraSensor, Error) << "No image format found"; return -EINVAL; @@ -189,7 +218,7 @@ int CameraSensor::init() * \todo The control API ought to have a flag to specify if a control * is read-only which could be used below. */ - const ControlInfo hblank = ctrls.infoMap()->at(V4L2_CID_HBLANK); + const ControlInfo hblank = subdev_->controls().at(V4L2_CID_HBLANK); const int32_t hblankMin = hblank.min().get(); const int32_t hblankMax = hblank.max().get();