[{"id":12037,"web_url":"https://patchwork.libcamera.org/comment/12037/","msgid":"<20200819020527.GO2360@pendragon.ideasonboard.com>","date":"2020-08-19T02:05:27","subject":"Re: [libcamera-devel] [PATCH v2 3/5] libcamera: raspberrypi: Set\n\tcamera flips correctly from user transform","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nThank you for the patch.\n\nOn Thu, Aug 06, 2020 at 05:36:37PM +0100, David Plowman wrote:\n> The Raspberry Pi pipeline handler allows all transforms except those\n> involving a transpose. The user transform is combined with any\n> inherent rotation of the camera, and the camera's H and V flip bits\n> are set accordingly.\n> ---\n>  .../pipeline/raspberrypi/raspberrypi.cpp      | 20 +++++++++++++++----\n>  1 file changed, 16 insertions(+), 4 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> index 236aa5c..9d183e3 100644\n> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> @@ -324,6 +324,8 @@ public:\n>  \tuint32_t expectedSequence_;\n>  \tbool sensorMetadata_;\n>  \n> +\tTransform transform_;\n> +\n>  \t/*\n>  \t * All the functions in this class are called from a single calling\n>  \t * thread. So, we do not need to have any mutex to protect access to any\n> @@ -400,8 +402,9 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n>  \tif (config_.empty())\n>  \t\treturn Invalid;\n>  \n> -\tif (transform != Transform::Identity) {\n> -\t\ttransform = Transform::Identity;\n> +\t/* We cannot do Transforms with a transpose in them. */\n> +\tif (!!(transform & Transform::Transpose)) {\n> +\t\ttransform = transform ^ Transform::Transpose;\n\nI wonder if we should define a ~ operator to be able to write\n\n\t\ttransform = transform & ~Transform::Transpose;\n\nAnd maybe also making the following possible ?\n\n\t\ttransform &= ~Transform::Transpose;\n\n>  \t\tstatus = Adjusted;\n>  \t}\n>  \n> @@ -610,6 +613,9 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n>  \tfor (auto const stream : data->streams_)\n>  \t\tstream->reset();\n>  \n> +\t/* We will want to know the transform requested by the application. */\n> +\tdata->transform_ = config->transform;\n> +\n>  \tSize maxSize, sensorSize;\n>  \tunsigned int maxIndex = 0;\n>  \tbool rawStream = false;\n> @@ -1174,8 +1180,14 @@ int RPiCameraData::configureIPA()\n>  \t\t/* Configure the H/V flip controls based on the sensor rotation. */\n>  \t\tControlList ctrls(unicam_[Unicam::Image].dev()->controls());\n>  \t\tint32_t rotation = sensor_->properties().get(properties::Rotation);\n> -\t\tctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!rotation));\n> -\t\tctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!rotation));\n> +\t\tbool success;\n> +\t\tTransform combined = transform_ * transformFromRotation(rotation, &success);\n> +\t\tif (!success) {\n> +\t\t\tLOG(RPI, Error) << \"Invalid rotation: \" << rotation;\n> +\t\t\treturn -EINVAL;\n> +\t\t}\n> +\t\tctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!(combined & Transform::HFlip)));\n> +\t\tctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!(combined & Transform::VFlip)));\n\nShouldn't this code guard against a 90° or 270° rotation ? Actually,\nthinking about it, what if the sensor is mounted with a 90° rotation,\nand the user is fine with that ? How should we combine that with the\nuser transform to make it possible to capture images ?\n\n>  \t\tunicam_[Unicam::Image].dev()->setControls(&ctrls);\n>  \t}\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E2C75BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 19 Aug 2020 02:05:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 41DC061E0E;\n\tWed, 19 Aug 2020 04:05:47 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8116E60384\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 19 Aug 2020 04:05:45 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 070F729E;\n\tWed, 19 Aug 2020 04:05:44 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"RCu5KCGc\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1597802745;\n\tbh=JLE//c9hR747HkXEfP1DvbmKNJQtJdgPb95b/zndtNc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=RCu5KCGcMI7ehjbNbtR/LrPF7AjzMuWc/19LCXORGQvUugJzGZ5YaV5sdJGoQsH99\n\tyzrajDtfO77PX4hSlZs0APBDLrbVce3b8sXELk2WUvXZpwGX6SsnvweZn9WxFV+Wbk\n\tawaFnApKRUL2fOC0vz/u7T1Ll6IgpbmT3C5QeBUo=","Date":"Wed, 19 Aug 2020 05:05:27 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<20200819020527.GO2360@pendragon.ideasonboard.com>","References":"<20200806163639.12971-1-david.plowman@raspberrypi.com>\n\t<20200806163639.12971-4-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200806163639.12971-4-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH v2 3/5] libcamera: raspberrypi: Set\n\tcamera flips correctly from user transform","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]