{"id":16188,"url":"https://patchwork.libcamera.org/api/1.1/patches/16188/?format=json","web_url":"https://patchwork.libcamera.org/patch/16188/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20220609125830.4325-1-naush@raspberrypi.com>","date":"2022-06-09T12:58:30","name":"[libcamera-devel] pipeline: ipa: raspberrypi: Correctly report available controls","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"345f6f359e181aa27265ff7e70458270227c986d","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/1.1/people/34/?format=json","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/16188/mbox/","series":[{"id":3167,"url":"https://patchwork.libcamera.org/api/1.1/series/3167/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=3167","date":"2022-06-09T12:58:30","name":"[libcamera-devel] pipeline: ipa: raspberrypi: Correctly report available controls","version":1,"mbox":"https://patchwork.libcamera.org/series/3167/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/16188/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/16188/checks/","tags":{},"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 50D90BD161\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  9 Jun 2022 12:58:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6DFE265631;\n\tThu,  9 Jun 2022 14:58:36 +0200 (CEST)","from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com\n\t[IPv6:2a00:1450:4864:20::42d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B31516559A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  9 Jun 2022 14:58:34 +0200 (CEST)","by mail-wr1-x42d.google.com with SMTP id x17so32310915wrg.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 09 Jun 2022 05:58:34 -0700 (PDT)","from naush-laptop.localdomain ([93.93.133.154])\n\tby smtp.gmail.com with ESMTPSA id\n\ti13-20020a05600c354d00b0039c60e33702sm6826395wmq.16.2022.06.09.05.58.33\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 09 Jun 2022 05:58:33 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1654779516;\n\tbh=wxaScBZBf9fu7sZWB18jutT4pDoDMJnabsrdCwiMBzY=;\n\th=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post:\n\tList-Help:List-Subscribe:From:Reply-To:From;\n\tb=T0FK33fu8skvfMHM5sv2N7JFxLX+4KJ5a0Kov9r/7JRADik2G1wdsLYJkML5irmWn\n\tHYdpMrDys8FcEyoZMcOKzkImVYDgjL9GXBXRCfpwrIWNxgwb4b9DFubpgqRONtQFKq\n\tbVb8RQ5DWqhn27hos241eFyo+lYkbyuwOWUph2OjDKQYq8eTAV2BRVOt0IY4ugz0fn\n\t5SlpQ5A3mwxOuxQ55esdXPHUuzAKpxZlHpueDquoDZl6JSyd2X+ao8hrYqhSJR77in\n\t5fjqO/R2uvHPPmoy6X2390qXPOeeVWl/l4UWlgdvILp+J1YhssLudSVuVwzK49zkVn\n\t43zip5ib5dyIg==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=Ok9ouy0Sf8uhWyfQ6c0zvhxPDI8isGrPvBbpQ9sJMIs=;\n\tb=ZGbDNTVNEJ4dNeklz9VyJVEOa9ToymDhN+nA+LMGWmRjGzQ4h5R1UbBq/TwAvFQgGV\n\thodQSzgs7FGDQhEiWeICLk/SSt6UWtIb5zrruH1DKOKIW1zg6adbmsCtSE+tJQXEQBsJ\n\t106JM3cNCEkJ4ce090Qy3B2YS65MyAbJ/NbqfuY6PctObHmuyS0N8JEY6kOHDWuRlfmd\n\tqNdSEfpkAyYJt7sIEQhVvmIitRqa5d5GDVKHwPOLrCUOWMcaH/b06uetrhZ1UjDCeHd1\n\tyA/RKQtNsPfLGSs6vZolpJuZF/VLqTcS/jkS7iP3eg6SRAnZ0YTgUTYz+SqD4YSmZh2I\n\tEkkA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"ZGbDNTVN\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=Ok9ouy0Sf8uhWyfQ6c0zvhxPDI8isGrPvBbpQ9sJMIs=;\n\tb=7qoJzjr+umZR0lqrMuE4xT+tXKic7D7hhf3p669Av6Lj32ZRbyUENLIMpRp4D7djvp\n\t/t0sC0D07Vg2deTDBzDGgKEqNTwRKsE1/HHVIPs5I+kkIYEegYZRq2hP35BkjDHiVOBZ\n\tBX9YvDQEuSeDC202TR9qMLFlCzm/YFJZA3aV+qyH13IJcVhb4/q55/KBnR6RN30ovuLN\n\tXfQeO9PsCW2DXM7aUqhOzRfeWQGHA65JbzUie313VrMloVdzLq/C3qe1gfFRCT55jqcu\n\tYWw9WDorYE0UMv3WIwsaY6E77+bzAPeqbWnfgQoDzUkhxJ9VKhJzX+B87biOnYCanaXD\n\tUJIA==","X-Gm-Message-State":"AOAM531E25EaCbdB8dSkeqpa133jpOizyOjYDjT5UbmM1DjrY87amfis\n\tDR9Pq0N0vpt4pin/BBx98TU5zN8wuXXD4ePc","X-Google-Smtp-Source":"ABdhPJxiMK7kfxE7bH69nKi5fKQNs/vOMpFoFN+/TRtecpEM5MKjajN23SlJopOfczQkG9e7HjTKVg==","X-Received":"by 2002:a5d:598c:0:b0:218:3fe6:40bd with SMTP id\n\tn12-20020a5d598c000000b002183fe640bdmr20853636wri.373.1654779513834; \n\tThu, 09 Jun 2022 05:58:33 -0700 (PDT)","To":"libcamera-devel@lists.libcamera.org","Date":"Thu,  9 Jun 2022 13:58:30 +0100","Message-Id":"<20220609125830.4325-1-naush@raspberrypi.com>","X-Mailer":"git-send-email 2.25.1","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH] pipeline: ipa: raspberrypi: Correctly\n\treport available controls","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>","From":"Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Naushir Patuck <naush@raspberrypi.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The pipeline handler currently advertises a static ControlInfoMap to specify the\navailable controls and their limits. Fix this limitation by having the IPA\npopulate a ControlInfoMap during Camera::Configure() that is then returned from\nthe pipeline handle. This will allow the ExposureTime, AnalogueGain, and\nFrameDurationLimits controls to advertise the correct limits for the programmed\nmode.\n\nNote that with this change, the ControlInfoMap provided by Camera::Controls()\nis only valid after a successful Camera::Configure() call.\n\nSigned-off-by: Naushir Patuck <naush@raspberrypi.com>\n---\n include/libcamera/ipa/raspberrypi.h           | 55 -------------------\n include/libcamera/ipa/raspberrypi.mojom       |  1 +\n src/ipa/raspberrypi/raspberrypi.cpp           | 42 +++++++++++++-\n .../pipeline/raspberrypi/raspberrypi.cpp      |  6 +-\n .../pipeline/raspberrypi/rpi_stream.h         |  1 -\n 5 files changed, 45 insertions(+), 60 deletions(-)\n delete mode 100644 include/libcamera/ipa/raspberrypi.h","diff":"diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h\ndeleted file mode 100644\nindex 6a56b0083b85..000000000000\n--- a/include/libcamera/ipa/raspberrypi.h\n+++ /dev/null\n@@ -1,55 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2019-2020, Raspberry Pi Ltd.\n- *\n- * raspberrypi.h - Image Processing Algorithm interface for Raspberry Pi\n- */\n-\n-#pragma once\n-\n-#include <stdint.h>\n-\n-#include <libcamera/control_ids.h>\n-#include <libcamera/controls.h>\n-\n-#ifndef __DOXYGEN__\n-\n-namespace libcamera {\n-\n-namespace RPi {\n-\n-/*\n- * List of controls handled by the Raspberry Pi IPA\n- *\n- * \\todo This list will need to be built dynamically from the control\n- * algorithms loaded by the json file, once this is supported. At that\n- * point applications should check first whether a control is supported,\n- * and the pipeline handler may be reverted so that it aborts when an\n- * unsupported control is encountered.\n- */\n-static const ControlInfoMap Controls({\n-\t\t{ &controls::AeEnable, ControlInfo(false, true) },\n-\t\t{ &controls::ExposureTime, ControlInfo(0, 999999) },\n-\t\t{ &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) },\n-\t\t{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },\n-\t\t{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },\n-\t\t{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },\n-\t\t{ &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },\n-\t\t{ &controls::AwbEnable, ControlInfo(false, true) },\n-\t\t{ &controls::ColourGains, ControlInfo(0.0f, 32.0f) },\n-\t\t{ &controls::AwbMode, ControlInfo(controls::AwbModeValues) },\n-\t\t{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },\n-\t\t{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },\n-\t\t{ &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },\n-\t\t{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },\n-\t\t{ &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },\n-\t\t{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },\n-\t\t{ &controls::FrameDurationLimits, ControlInfo(INT64_C(1000), INT64_C(1000000000)) },\n-\t\t{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }\n-\t}, controls::controls);\n-\n-} /* namespace RPi */\n-\n-} /* namespace libcamera */\n-\n-#endif /* __DOXYGEN__ */\ndiff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom\nindex a60c3bb43d3c..ed7adebce1b8 100644\n--- a/include/libcamera/ipa/raspberrypi.mojom\n+++ b/include/libcamera/ipa/raspberrypi.mojom\n@@ -40,6 +40,7 @@ struct IPAConfig {\n \n struct IPAConfigResult {\n        float modeSensitivity;\n+       libcamera.ControlInfoMap controlInfo;\n };\n \n struct StartConfig {\ndiff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\nindex 3b126bb5175e..7eb04a24c41e 100644\n--- a/src/ipa/raspberrypi/raspberrypi.cpp\n+++ b/src/ipa/raspberrypi/raspberrypi.cpp\n@@ -24,7 +24,6 @@\n #include <libcamera/framebuffer.h>\n #include <libcamera/ipa/ipa_interface.h>\n #include <libcamera/ipa/ipa_module_info.h>\n-#include <libcamera/ipa/raspberrypi.h>\n #include <libcamera/ipa/raspberrypi_ipa_interface.h>\n #include <libcamera/request.h>\n \n@@ -72,6 +71,28 @@ constexpr Duration defaultMaxFrameDuration = 250.0s;\n  */\n constexpr Duration controllerMinFrameDuration = 1.0s / 30.0;\n \n+/* List of controls handled by the Raspberry Pi IPA */\n+static const ControlInfoMap Controls({\n+\t{ &controls::AeEnable, ControlInfo(false, true) },\n+\t{ &controls::ExposureTime, ControlInfo(0, 999999) },\n+\t{ &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) },\n+\t{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },\n+\t{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },\n+\t{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },\n+\t{ &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },\n+\t{ &controls::AwbEnable, ControlInfo(false, true) },\n+\t{ &controls::ColourGains, ControlInfo(0.0f, 32.0f) },\n+\t{ &controls::AwbMode, ControlInfo(controls::AwbModeValues) },\n+\t{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },\n+\t{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },\n+\t{ &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },\n+\t{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },\n+\t{ &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },\n+\t{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },\n+\t{ &controls::FrameDurationLimits, ControlInfo(INT64_C(1000), INT64_C(1000000000)) },\n+\t{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }\n+}, controls::controls);\n+\n LOG_DEFINE_CATEGORY(IPARPI)\n \n namespace ipa::RPi {\n@@ -421,6 +442,25 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,\n \tASSERT(controls);\n \t*controls = std::move(ctrls);\n \n+\t/*\n+\t * Apply the correct limits to the exposure, gain and frame duration controls\n+\t * based on the current sensor mode.\n+\t */\n+\tresult->controlInfo = Controls;\n+\tconst Duration minSensorFrameDuration = mode_.min_frame_length * mode_.line_length;\n+\tconst Duration maxSensorFrameDuration = mode_.max_frame_length * mode_.line_length;\n+\tresult->controlInfo.at(controls::FrameDurationLimits.id()) =\n+\t\t\tControlInfo(static_cast<int64_t>(minSensorFrameDuration.get<std::micro>()),\n+\t\t\t\t    static_cast<int64_t>(maxSensorFrameDuration.get<std::micro>()));\n+\n+\tresult->controlInfo.at(controls::AnalogueGain.id()) =\n+\t\t\tControlInfo(1.0f, static_cast<float>(helper_->Gain(maxSensorGainCode_)));\n+\n+\tconst uint32_t exposureMin = sensorCtrls_.at(V4L2_CID_EXPOSURE).min().get<int32_t>();\n+\tconst uint32_t exposureMax = sensorCtrls_.at(V4L2_CID_EXPOSURE).max().get<int32_t>();\n+\tresult->controlInfo.at(controls::ExposureTime.id()) =\n+\t\t\tControlInfo(static_cast<int32_t>(helper_->Exposure(exposureMin).get<std::micro>()),\n+\t\t\t\t    static_cast<int32_t>(helper_->Exposure(exposureMax).get<std::micro>()));\n \treturn 0;\n }\n \ndiff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex adc397e8aabd..abb29a8d24b9 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -20,7 +20,6 @@\n #include <libcamera/camera.h>\n #include <libcamera/control_ids.h>\n #include <libcamera/formats.h>\n-#include <libcamera/ipa/raspberrypi.h>\n #include <libcamera/ipa/raspberrypi_ipa_interface.h>\n #include <libcamera/ipa/raspberrypi_ipa_proxy.h>\n #include <libcamera/logging.h>\n@@ -941,6 +940,9 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \t/* Store the mode sensitivity for the application. */\n \tdata->properties_.set(properties::SensorSensitivity, result.modeSensitivity);\n \n+\t/* Register the controls that the Raspberry Pi IPA can handle. */\n+\tdata->controlInfo_ = result.controlInfo;\n+\n \t/* Setup the Video Mux/Bridge entities. */\n \tfor (auto &[device, link] : data->bridgeDevices_) {\n \t\t/*\n@@ -1282,8 +1284,6 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me\n \tdata->delayedCtrls_ = std::make_unique<DelayedControls>(data->sensor_->device(), params);\n \tdata->sensorMetadata_ = sensorConfig.sensorMetadata;\n \n-\t/* Register the controls that the Raspberry Pi IPA can handle. */\n-\tdata->controlInfo_ = RPi::Controls;\n \t/* Initialize the camera properties. */\n \tdata->properties_ = data->sensor_->properties();\n \ndiff --git a/src/libcamera/pipeline/raspberrypi/rpi_stream.h b/src/libcamera/pipeline/raspberrypi/rpi_stream.h\nindex c37f7e82eef6..fe01110019b7 100644\n--- a/src/libcamera/pipeline/raspberrypi/rpi_stream.h\n+++ b/src/libcamera/pipeline/raspberrypi/rpi_stream.h\n@@ -12,7 +12,6 @@\n #include <unordered_map>\n #include <vector>\n \n-#include <libcamera/ipa/raspberrypi.h>\n #include <libcamera/ipa/raspberrypi_ipa_interface.h>\n #include <libcamera/stream.h>\n \n","prefixes":["libcamera-devel"]}