From patchwork Mon Jun 27 16:27:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16382 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 DAF0DBD808 for ; Mon, 27 Jun 2022 16:27:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A4D796563F; Mon, 27 Jun 2022 18:27:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347263; bh=BQg10bEAKgUSKfipvpBAEs5RYtA/MK+zNLgmgMgBYV0=; 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=kjZbMM83lNmyHIrdzxLAw0S9+LkbrSwggOBnqA+ZgHQKYyTZRLJpv3V8/TTL3sDUX +0uppi5c4087DOHYVnP8GL1NXtRzYTROTUCWsK5UBdcOw0nz6mIkX1txmtYdIAomgN xvSrLLITJtN6e1zZdYkLPR9d36mRAoNg/AudZNi564MJEPx3ps9AxL26WrTgwVBV8W mhHunbzINIzzvXpVnK4HhbVoQJBuIk6S2pIGHhtuOZWfXZmt2JVxGpYFzzQ35rgetz iqv1vfcAWWKuchr54seti5ny2GLrMLLxOMpPJyQvE46jAw3GU10JBzVKh/XDaPFyBK DOM0URqzLqpEA== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C1EAC65636 for ; Mon, 27 Jun 2022 18:27:40 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 8A1222000C; Mon, 27 Jun 2022 16:27:39 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:18 +0200 Message-Id: <20220627162732.33160-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/15] libcamera: control_ids: Add 'internal' argument 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add to the gen-controls.py script an optional argument '--internal' that allows to specify if the generated file targets public or internal controls. Add two new tags to the .cpp.in and .h.in templates to specify the correct inclusion path and the correct namespace. Internal controls will be introduced in the next patch. Signed-off-by: Jacopo Mondi --- include/libcamera/control_ids.h.in | 6 +++--- src/libcamera/control_ids.cpp.in | 12 ++++++------ utils/gen-controls.py | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in index 0718a8886f6c..410cfb643a0b 100644 --- a/include/libcamera/control_ids.h.in +++ b/include/libcamera/control_ids.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * control_ids.h - Control ID list + * ${include_prefix}control_ids.h - Control ID list * * This file is auto-generated. Do not edit. */ @@ -16,7 +16,7 @@ namespace libcamera { -namespace controls { +namespace controls${namespace_extension} { enum { ${ids} @@ -32,6 +32,6 @@ ${draft_controls} } /* namespace draft */ -} /* namespace controls */ +} /* namespace controls${namespace_extension} */ } /* namespace libcamera */ diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in index 5fb1c2c30558..e7e1080e9324 100644 --- a/src/libcamera/control_ids.cpp.in +++ b/src/libcamera/control_ids.cpp.in @@ -2,17 +2,17 @@ /* * Copyright (C) 2019, Google Inc. * - * control_ids.cpp : Control ID list + * ${include_prefix}control_ids.cpp : Control ID list * * This file is auto-generated. Do not edit. */ -#include +#include #include /** - * \file control_ids.h - * \brief Camera control identifiers + * \file libcamera/${include_prefix}control_ids.h + * \brief Control identifiers */ namespace libcamera { @@ -20,7 +20,7 @@ namespace libcamera { /** * \brief Namespace for libcamera controls */ -namespace controls { +namespace controls${namespace_extension} { ${controls_doc} @@ -57,6 +57,6 @@ extern const ControlIdMap controls { ${controls_map} }; -} /* namespace controls */ +} /* namespace controls${namespace_extension} */ } /* namespace libcamera */ diff --git a/utils/gen-controls.py b/utils/gen-controls.py index 3f99b5e2ba7d..978179f63858 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -188,6 +188,17 @@ def fill_template(template, data): return template.substitute(data) +def handle_internal_arg(internal, data): + + if internal: + data["namespace_extension"] = "::internal" + data["include_prefix"] = "internal/" + return + + data["namespace_extension"] = "" + data["include_prefix"] = "" + + def main(argv): # Parse command line arguments @@ -198,6 +209,7 @@ def main(argv): help='Input file name.') parser.add_argument('template', type=str, help='Template file name.') + parser.add_argument('--internal', type=bool, default=False) args = parser.parse_args(argv[1:]) data = open(args.input, 'rb').read() @@ -210,6 +222,8 @@ def main(argv): else: raise RuntimeError('Unknown template type') + handle_internal_arg(args.internal, data) + data = fill_template(args.template, data) if args.output: From patchwork Mon Jun 27 16:27:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16383 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 C9E67BD808 for ; Mon, 27 Jun 2022 16:27:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D73E665642; Mon, 27 Jun 2022 18:27:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347265; bh=Td3krTJJg9DQJdNUDwUHGq6oqQPqRHLo3sYlLNOUw9g=; 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=lmewknPpO/cGzbCO/pmH4z2+tk+iuZdD1x1EflR1zXtbfRoSctjDg8SLukQ9ZkxBI 3FYbKg1xCOJA8UT9t/oquDEjw/WtA6AxBtxeLGFFxvjINyCZsVh1TT9FdfdH/oDiFG bFqvnqXfi922FlkH2ijZ1F53tgbAnmBGMVZMJmUwgDRX8PhZX3RkT5Z/5c6tjdjx91 Xroa9oqaKpAxPLnOpY7EK/vPv1u6AyoxbHXjenzfW6xvqCsEIsnmkHmxCSi8YQyrlx KdDceKtHsqiSRSNfCuut/FY5ehsMQ2QwsZLXXCm5W7S8mqFCZmeKbfK3BmCyt/nrTh /R7YbJId67oEw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C074D6059B for ; Mon, 27 Jun 2022 18:27:41 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id BA89B20008; Mon, 27 Jun 2022 16:27:40 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:19 +0200 Message-Id: <20220627162732.33160-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/15] libcamera: control_ids: Separate the id numerical space 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Separate the internal and public control id numerical space by placing the internal controls at offset 0x1000. Signed-off-by: Jacopo Mondi Reviewed-by: Jean-Michel Hautbois --- utils/gen-controls.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/utils/gen-controls.py b/utils/gen-controls.py index 978179f63858..63e888546277 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -118,7 +118,7 @@ ${description} } -def generate_h(controls): +def generate_h(internal, controls): enum_template_start = string.Template('''enum ${name}Enum {''') enum_value_template = string.Template('''\t${name} = ${value},''') enum_values_template = string.Template('''extern const std::array ${name}Values;''') @@ -133,7 +133,11 @@ def generate_h(controls): name, ctrl = ctrl.popitem() id_name = snake_case(name).upper() - ids.append('\t' + id_name + ' = ' + str(id_value) + ',') + # Separate the internal and public controls id space + if internal: + ids.append('\t' + id_name + ' = ' + "0x1000 | " + str(id_value) + ',') + else: + ids.append('\t' + id_name + ' = ' + str(id_value) + ',') ctrl_type = ctrl['type'] if ctrl_type == 'string': @@ -218,7 +222,7 @@ def main(argv): if args.template.endswith('.cpp.in'): data = generate_cpp(controls) elif args.template.endswith('.h.in'): - data = generate_h(controls) + data = generate_h(args.internal, controls) else: raise RuntimeError('Unknown template type') From patchwork Mon Jun 27 16:27:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16384 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 3D56CBD808 for ; Mon, 27 Jun 2022 16:27:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1904A6563A; Mon, 27 Jun 2022 18:27:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347266; bh=rfTtBwtUgSj9o+bJBAFXhooGsYV+I+gwNmqLZ6anrjI=; 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=W9tMASKV9lvqZSO1YiORjVcqI5vx/nliLaPC3iR3yqS/vuC1sorOFLIQGc8om+b3s zW1MlOTqCoxwW62qTN23+s6I0zeNWUy2esz3OOQkg7qHOgrkXkGtMBw6E1+mEdUG0h AgM09PDqds3Dhfu6E/G65gxna7mQkbyTm88hh/Sj+1NFCGZWj+xPt8rJhZJ65QKDaB XLTvPEhrOOHIMumNSDRT1SkLyleUY6L2mpfhGMcVe1cjp805kXvpzeRTxN6IHiaJLH mmYYsjmYsp6g3OxiHhe1CK5e5A12Qkw5uradX4cqaU/9VsT0Lpq8b5rhvAv79xNBCS lc5Ussoz7YYfw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EA0ED6059B for ; Mon, 27 Jun 2022 18:27:42 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 02D8E20008; Mon, 27 Jun 2022 16:27:41 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:20 +0200 Message-Id: <20220627162732.33160-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/15] libcamera: Introduce internal controls 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Introduce the enumeration of internal controls in internal_control_ids.yaml. The list of controls currently defines 4 draft controls which mirror the definition of the V4L2 control they map to. Plumb in the build system the command to generate the definition of internal controls by re-using the same mechanism used for public controls to make it easy to extend it to also handle internal properties in future. Signed-off-by: Jacopo Mondi Reviewed-by: Jean-Michel Hautbois --- include/libcamera/internal/meson.build | 15 +++++++ src/libcamera/internal_control_ids.yaml | 54 +++++++++++++++++++++++++ src/libcamera/meson.build | 17 ++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/libcamera/internal_control_ids.yaml diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 7a780d48ee57..1559c3c368c4 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -9,6 +9,21 @@ libcamera_tracepoint_header = custom_target( command: [gen_tracepoints_header, '@OUTPUT@', '@INPUT@'], ) +# Generate the list of internal controls identifiers +internal_control_source_files = ['control_ids'] + +libcamera_internal_control_headers = [] + +foreach header : internal_control_source_files + input_files = files('../../../src/libcamera/internal_' + header +'.yaml',\ + '../' + header + '.h.in') + libcamera_internal_control_headers += custom_target( + 'internal_' + header + '_h', + input : input_files, + output : header + '.h', + command : [gen_controls, '--internal=True','-o', '@OUTPUT@', '@INPUT@']) +endforeach + libcamera_internal_headers = files([ 'bayer_format.h', 'byte_stream_buffer.h', diff --git a/src/libcamera/internal_control_ids.yaml b/src/libcamera/internal_control_ids.yaml new file mode 100644 index 000000000000..e69e0d30657c --- /dev/null +++ b/src/libcamera/internal_control_ids.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2022, Google Inc. +# +%YAML 1.2 +--- +# Enumeration of internal libcamera controls +# Not exposed to application, for library use only + +controls: + + # ---------------------------------------------------------------------------- + # Draft controls section + + - VBlank: + type: int32_t + draft: true + description: | + Vertical blanking. The idle period after every frame during which no + image data is produced. The unit of vertical blanking is a line. Every + line has length of the image width plus horizontal blanking at the pixel + rate defined by V4L2_CID_PIXEL_RATE control in the same sub-device. + + Currently identical to V4L2_CID_VBLANK. + + - HBlank: + type: int32_t + draft: true + description: | + Horizontal blanking. The idle period after every line of image data + during which no image data is produced. The unit of horizontal blanking + is pixels. + + Currently identical to V4L2_CID_HBLANK. + + - SensorAnalogueGain: + type: int32_t + draft: true + description: | + Analogue gain is gain affecting all colour components in the pixel + matrix. The gain operation is performed in the analogue domain before + A/D conversion + + Currently identical to V4L2_CID_ANALOGUE_GAIN. + + - SensorExposure: + type: int32_t + draft: true + description: | + Exposure time, expressed in frame lines. + + Currently identical to V4L2_CID_EXPOSURE. + +... diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index b57bee7ef6ca..89fdf347c708 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -52,6 +52,7 @@ libcamera_sources = files([ libcamera_sources += libcamera_public_headers libcamera_sources += libcamera_generated_ipa_headers libcamera_sources += libcamera_tracepoint_header +libcamera_sources += libcamera_internal_control_headers includes = [ libcamera_includes, @@ -99,6 +100,7 @@ if not libyaml.found() libyaml = libyaml_wrap.dependency('yaml') endif +# Generate control_ids.cpp and property_ids.cpp control_sources = [] foreach source : control_source_files @@ -111,6 +113,21 @@ endforeach libcamera_sources += control_sources +# Generate internal_control_ids.cpp +internal_control_source_files = ['control_ids'] +internal_control_sources = [] + +foreach source : internal_control_source_files + input_files = files('internal_' + source +'.yaml', source + '.cpp.in') + internal_control_sources += custom_target('internal_' + source + '_cpp', + input : input_files, + output : 'internal_' + source + '.cpp', + command : [gen_controls, '--internal=True',\ + '-o', '@OUTPUT@',\ + '@INPUT@']) +endforeach +libcamera_sources += internal_control_sources + gen_version = meson.project_source_root() / 'utils' / 'gen-version.sh' # Use vcs_tag() and not configure_file() or run_command(), to ensure that the From patchwork Mon Jun 27 16:27:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16385 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 B1565BD808 for ; Mon, 27 Jun 2022 16:27:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ADA8865649; Mon, 27 Jun 2022 18:27:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347267; bh=zDe4M49TC5p06UHt+KurRaCJqiyk+cq+1bpvCuMHd/4=; 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=YJz3nvyU8krlLxdW9kNil8tFHmv4c0QasZF7UFGcmwd/9hJUw5dKPBSo+IDGZRb+k uB+l67y/0JcSitHiCvMDT94DgULHxeprDCBCmcaO3LCAnkkeRyBSbulkmFHvNhPKNP qrIobWpSagXrUFhs1vpa4CYF+xrSdPFKJjYQPy0ezMgGrH5BsYMAvG3WheRUYa4MVX LUqZf9SJ9AD7Bk0IOT0GhpoWMvW6t9e6Yb2sWRi1nfJ2KKLCDmSBOUdsBmQF9E6N4u 8alt3zwzJx+/+O3TnZw3bt+guDA5o6CdukaUn2qB93Q6yx+w7XKJpXO/zbxhlCkzmU Ff6XkfmSsfZUw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D05EB65641 for ; Mon, 27 Jun 2022 18:27:43 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 3308320008; Mon, 27 Jun 2022 16:27:42 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:21 +0200 Message-Id: <20220627162732.33160-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/15] libcamera: camera_sensor_properties: Add sensor delays 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add to the camera sensor properties a map of control identifiers to their latencies. Some camera sensor controls take a variable number of frames to take effect, hence they should be set in advance. The newly introduced map records that information as a property of the camera sensor class. Signed-off-by: Jacopo Mondi --- .../internal/camera_sensor_properties.h | 2 ++ src/libcamera/camera_sensor_properties.cpp | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/libcamera/internal/camera_sensor_properties.h b/include/libcamera/internal/camera_sensor_properties.h index 1ee3cb994106..868b992196de 100644 --- a/include/libcamera/internal/camera_sensor_properties.h +++ b/include/libcamera/internal/camera_sensor_properties.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -20,6 +21,7 @@ struct CameraSensorProperties { Size unitCellSize; std::map testPatternModes; + std::unordered_map sensorDelays; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera_sensor_properties.cpp b/src/libcamera/camera_sensor_properties.cpp index e5f27f06eb1d..5ff28eb04b9f 100644 --- a/src/libcamera/camera_sensor_properties.cpp +++ b/src/libcamera/camera_sensor_properties.cpp @@ -13,6 +13,8 @@ #include +#include + /** * \file camera_sensor_properties.h * \brief Database of camera sensor properties @@ -41,6 +43,10 @@ LOG_DEFINE_CATEGORY(CameraSensorProperties) * \brief Map that associates the TestPattern control value with the indexes of * the corresponding sensor test pattern modes as returned by * V4L2_CID_TEST_PATTERN. + * + * \var CameraSensorProperties::sensorDelays + * \brief Map that associates control identifiers with their latencies, + * expressed in frame periods. */ /** @@ -69,6 +75,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen * 9: "Resolution Pattern" */ }, + .sensorDelays = { }, } }, { "imx219", { .unitCellSize = { 1120, 1120 }, @@ -79,6 +86,11 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, { controls::draft::TestPatternModePn9, 4 }, }, + .sensorDelays = { + { &controls::internal::FrameDuration, 2 }, + { &controls::internal::ExposureTime, 2 }, + { &controls::internal::draft::SensorAnalogueGain, 1 }, + }, } }, { "imx258", { .unitCellSize = { 1120, 1120 }, @@ -89,18 +101,26 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, { controls::draft::TestPatternModePn9, 4 }, }, + .sensorDelays = { }, } }, { "imx290", { .unitCellSize = { 2900, 2900 }, .testPatternModes = {}, + .sensorDelays = { + { &controls::internal::FrameDuration, 2 }, + { &controls::internal::ExposureTime, 2 }, + { &controls::internal::draft::SensorAnalogueGain, 2 }, + }, } }, { "imx296", { .unitCellSize = { 3450, 3450 }, .testPatternModes = {}, + .sensorDelays = { }, } }, { "imx477", { .unitCellSize = { 1550, 1550 }, .testPatternModes = {}, + .sensorDelays = { }, } }, { "ov2740", { .unitCellSize = { 1400, 1400 }, @@ -108,6 +128,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeOff, 0 }, { controls::draft::TestPatternModeColorBars, 1}, }, + .sensorDelays = { }, } }, { "ov5640", { .unitCellSize = { 1400, 1400 }, @@ -115,10 +136,16 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeOff, 0 }, { controls::draft::TestPatternModeColorBars, 1 }, }, + .sensorDelays = { }, } }, { "ov5647", { .unitCellSize = { 1400, 1400 }, .testPatternModes = {}, + .sensorDelays = { + { &controls::internal::FrameDuration, 2 }, + { &controls::internal::ExposureTime, 2 }, + { &controls::internal::draft::SensorAnalogueGain, 2 }, + }, } }, { "ov5670", { .unitCellSize = { 1120, 1120 }, @@ -126,6 +153,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeOff, 0 }, { controls::draft::TestPatternModeColorBars, 1 }, }, + .sensorDelays = { }, } }, { "ov5675", { .unitCellSize = { 1120, 1120 }, @@ -133,6 +161,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeOff, 0 }, { controls::draft::TestPatternModeColorBars, 1 }, }, + .sensorDelays = { }, } }, { "ov5693", { .unitCellSize = { 1400, 1400 }, @@ -145,6 +174,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen * Rolling Bar". */ }, + .sensorDelays = { }, } }, { "ov8865", { .unitCellSize = { 1400, 1400 }, @@ -159,6 +189,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen * 5: "Color squares with rolling bar" */ }, + .sensorDelays = { }, } }, { "ov13858", { .unitCellSize = { 1120, 1120 }, @@ -166,6 +197,7 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen { controls::draft::TestPatternModeOff, 0 }, { controls::draft::TestPatternModeColorBars, 1 }, }, + .sensorDelays = { }, } }, }; From patchwork Mon Jun 27 16:27:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16386 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 81502BD808 for ; Mon, 27 Jun 2022 16:27:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 324BF6564C; Mon, 27 Jun 2022 18:27:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347271; bh=ckO0WIZjO53QzzWM6jMDukqqxc2tn5erdfG9AVHU+UY=; 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=SoqgSVxUvAhzQr86geLRVRaowKvbud6plNRZYOyQW+u5VNFD0ZDhZMZYFszkxQiV8 yBpG9opEWemMT5gzvImatCelFF0M58Zr0n+vSYxvPDhQCRHp4VQJKcmllCpFOM3Zx5 tTNYjui8XNIg0nGD2rP3GkSNzpVPKk24AiJOYaYxkAU/isHy3mRpk6vWoSaqRoMLB0 jYHKmhGt4dom+cvi8Z8TnDxE6Y8qfBZsOc0ipatDDGtJbMJZYXWaMhbFDHgJHB4aI5 pyWTBG3FaCvUhuZetoQHK+HfvYapAWvgqCOxQZaKHGmjaI0YStDFIqy1/c5MiObM6F T+SgKHFCpkx2Q== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CDE0D65639 for ; Mon, 27 Jun 2022 18:27:44 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 0D35B20009; Mon, 27 Jun 2022 16:27:43 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:22 +0200 Message-Id: <20220627162732.33160-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/15] libcamera: camera_sensor: Retrieve sensor delays 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a function to the CameraSensor to retrieve the SensorDelay map that associate controls to their latencies. If such information is not provided, return a reference to an empty map. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 4 +++ src/libcamera/camera_sensor.cpp | 30 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index b9f4d7867854..0359d4609517 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -34,6 +35,8 @@ struct CameraSensorProperties; class CameraSensor : protected Loggable { public: + using SensorDelays = std::unordered_map; + explicit CameraSensor(const MediaEntity *entity); ~CameraSensor(); @@ -45,6 +48,7 @@ public: const std::vector &mbusCodes() const { return mbusCodes_; } std::vector sizes(unsigned int mbusCode) const; Size resolution() const; + const SensorDelays &sensorDelays(); const std::vector &testPatternModes() const { return testPatternModes_; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index d055c16a4885..5cd33e904174 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -47,6 +47,14 @@ LOG_DEFINE_CATEGORY(CameraSensor) * devices as the needs arise. */ +/** + * \typedef CameraSensor::SensorDelays + * \brief Camera sensor controls delays + * + * Type to represent a map of camera sensor controls associated with their + * latencies, expressed in frame periods. + */ + /** * \brief Construct a CameraSensor * \param[in] entity The media entity backing the camera sensor @@ -561,6 +569,28 @@ Size CameraSensor::resolution() const return std::min(sizes_.back(), activeArea_.size()); } +/** + * \brief Retrieve the map of latencies associated with camera controls + * + * Retrieve the SensorDelays map that associates camera controls with + * their latencies. + * + * If a camera sensor does not provide such information an empty map is + * returned. + * + * \return A map of controls associated with their latencies or an empty map + * if no sensor delays are available. + */ +const CameraSensor::SensorDelays &CameraSensor::sensorDelays() +{ + static SensorDelays emptyDelays{}; + + if (!staticProps_) + return emptyDelays; + + return staticProps_->sensorDelays; +} + /** * \fn CameraSensor::testPatternModes() * \brief Retrieve all the supported test pattern modes of the camera sensor From patchwork Mon Jun 27 16:27:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16387 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 D1BBBBD808 for ; Mon, 27 Jun 2022 16:27:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 55EDC65645; Mon, 27 Jun 2022 18:27:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347272; bh=DTtd03qxnOavgVCgD4PzR0t9PU2WvibBUcL0Q4807Ro=; 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=N+ulLedzUIpoIPbgIBzCvOxSA7IagkQWfH3nClsV0PJIGvJOjAdBVPh9s8pz6DAlE vGU7kB2Euxukgds5DIVy9tDLwPsjVihiJqvscJlxLVv6S32QE1QCWiHQYCPSk3eP5H Cr1PFx201vr/rUXHaQtC48vq5gRXBW4+qwIneq/FHK0mTJTXSQQma/AY9+gvxElYye vrygXjZCja1ZwTo0H/lydzNiWt+HGRw9CZ8v3iYjauopHv/Pn1KwBHbn2rP1KL4vbJ pXqKu9sOWlL74kjQyJNaV5jEWb1OEkY1QtD2us2xfaMHzgKzCBJY4ZVM3dLaYWL1n0 zv+NUSOgUZ62Q== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 39ACF65644 for ; Mon, 27 Jun 2022 18:27:46 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 315F220009; Mon, 27 Jun 2022 16:27:44 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:23 +0200 Message-Id: <20220627162732.33160-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/15] libcamera: ipu3: Initialize DelayedControls with camera properties 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the sensor control delays as reported by the camera sensor properties map to intialize delayed controls for the IPU3 platform. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 30 ++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index b7dda282faab..19d022c584ed 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1127,13 +1127,31 @@ int PipelineHandlerIPU3::registerCameras() continue; /* - * \todo Read delay values from the sensor itself or from a - * a sensor database. For now use generic values taken from - * the Raspberry Pi and listed as 'generic values'. + * Get the sensor delays and validate the required controls + * are reported. */ - std::unordered_map params = { - { V4L2_CID_ANALOGUE_GAIN, { 1, false } }, - { V4L2_CID_EXPOSURE, { 2, false } }, + const CameraSensor::SensorDelays &sensorDelays = cio2->sensor()->sensorDelays(); + if (!sensorDelays.count(&controls::internal::ExposureTime) || + !sensorDelays.count(&controls::internal::draft::SensorAnalogueGain)) { + LOG(IPU3, Error) << "Missing sensor control delays"; + return -ENODEV; + } + + const std::unordered_map params{ + { + V4L2_CID_ANALOGUE_GAIN, + { + sensorDelays.at(&controls::internal::draft::SensorAnalogueGain), + false, + }, + }, + { + V4L2_CID_EXPOSURE, + { + sensorDelays.at(&controls::internal::ExposureTime), + false, + }, + }, }; data->delayedCtrls_ = From patchwork Mon Jun 27 16:27:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16388 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 58E74BD808 for ; Mon, 27 Jun 2022 16:27:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E191865641; Mon, 27 Jun 2022 18:27:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347274; bh=NAA+viX/0qEteDTwxXnIhouPLrgCWAhkeOlKxIY0x8w=; 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=JpEGg3qkm8KpCewgbFkE6JmHuc4j3ApU4M3ZCo+ehmjtwmsO36Qunlt1Ax0DVrjLs AiRKJYrSrKQxegNNcPSCQ0WuJFawbaINaaUAIhTy0I6MkpecLx+d2ftpFYdiBvkY/b xTmdINfzMs1ZMLy7zxJvSUnNEFuttY9ls9ZCYgnScXXy/0v7k5XAi1nvBI2lITWx+A 6d2ja0Pu3Imdno7gkHn8nj8m+vMbkobVvSamyFxxQCyzZ7MWf7LBqGisDLCSWShyNW rDXSvtNM25zJMLIbIJuIxuzAQ8QWfXJg0MS5OKiqUWpKM7LgegpVR7GolfAplzuOZP 59JRVFJ+pepkw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B0CC65641 for ; Mon, 27 Jun 2022 18:27:47 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6DBF72000B; Mon, 27 Jun 2022 16:27:46 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:24 +0200 Message-Id: <20220627162732.33160-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/15] libcamera: camera_sensor: Rename the control interface 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The control interface of the CameraSensor class operates on V4L2 controls. To prepare to move the CameraSensor interface to use libcamera::internal controls, rename the existing interface to be the 'v4l2' control interface, to allow users to transition to the new interface gradually. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 6 +++--- src/libcamera/camera_sensor.cpp | 14 +++++++------- src/libcamera/pipeline/ipu3/ipu3.cpp | 10 +++++----- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 14 +++++++------- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/vimc/vimc.cpp | 8 ++++---- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 0359d4609517..0bed6e679840 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -59,9 +59,9 @@ public: const Size &size) const; int setFormat(V4L2SubdeviceFormat *format); - const ControlInfoMap &controls() const; - ControlList getControls(const std::vector &ids); - int setControls(ControlList *ctrls); + const ControlInfoMap &v4l2Controls() const; + ControlList getV4L2Controls(const std::vector &ids); + int setV4L2Controls(ControlList *ctrls); V4L2Subdevice *device() { return subdev_.get(); } diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 5cd33e904174..e3354530380c 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -335,8 +335,8 @@ void CameraSensor::initStaticProperties() void CameraSensor::initTestPatternModes() { - const auto &v4l2TestPattern = controls().find(V4L2_CID_TEST_PATTERN); - if (v4l2TestPattern == controls().end()) { + const auto &v4l2TestPattern = v4l2Controls().find(V4L2_CID_TEST_PATTERN); + if (v4l2TestPattern == v4l2Controls().end()) { LOG(CameraSensor, Debug) << "V4L2_CID_TEST_PATTERN is not supported"; return; } @@ -637,10 +637,10 @@ int CameraSensor::applyTestPatternMode(controls::draft::TestPatternModeEnum mode LOG(CameraSensor, Debug) << "Apply test pattern mode " << mode; int32_t index = staticProps_->testPatternModes.at(mode); - ControlList ctrls{ controls() }; + ControlList ctrls{ v4l2Controls() }; ctrls.set(V4L2_CID_TEST_PATTERN, index); - int ret = setControls(&ctrls); + int ret = setV4L2Controls(&ctrls); if (ret) return ret; @@ -766,7 +766,7 @@ int CameraSensor::setFormat(V4L2SubdeviceFormat *format) * * \return A map of the V4L2 controls supported by the sensor */ -const ControlInfoMap &CameraSensor::controls() const +const ControlInfoMap &CameraSensor::v4l2Controls() const { return subdev_->controls(); } @@ -789,7 +789,7 @@ const ControlInfoMap &CameraSensor::controls() const * \return The control values in a ControlList on success, or an empty list on * error */ -ControlList CameraSensor::getControls(const std::vector &ids) +ControlList CameraSensor::getV4L2Controls(const std::vector &ids) { return subdev_->getControls(ids); } @@ -819,7 +819,7 @@ ControlList CameraSensor::getControls(const std::vector &ids) * \retval -EINVAL One of the control is not supported or not accessible * \retval i The index of the control that failed */ -int CameraSensor::setControls(ControlList *ctrls) +int CameraSensor::setV4L2Controls(ControlList *ctrls) { return subdev_->setControls(ctrls); } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 19d022c584ed..28442756b184 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -581,7 +581,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) * the sensor and user transform. */ if (data->supportsFlips_) { - ControlList sensorCtrls(cio2->sensor()->controls()); + ControlList sensorCtrls(cio2->sensor()->v4l2Controls()); sensorCtrls.set(V4L2_CID_HFLIP, static_cast(!!(config->combinedTransform_ & Transform::HFlip))); @@ -589,7 +589,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) static_cast(!!(config->combinedTransform_ & Transform::VFlip))); - ret = cio2->sensor()->setControls(&sensorCtrls); + ret = cio2->sensor()->setV4L2Controls(&sensorCtrls); if (ret) return ret; } @@ -662,7 +662,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } ipa::ipu3::IPAConfigInfo configInfo; - configInfo.sensorControls = data->cio2_.sensor()->controls(); + configInfo.sensorControls = data->cio2_.sensor()->v4l2Controls(); CameraLens *lens = data->cio2_.sensor()->focusLens(); if (lens) @@ -1175,7 +1175,7 @@ int PipelineHandlerIPU3::registerCameras() LOG(IPU3, Warning) << "Invalid rotation of " << rotation << " degrees: ignoring"; - ControlList ctrls = cio2->sensor()->getControls({ V4L2_CID_HFLIP }); + ControlList ctrls = cio2->sensor()->getV4L2Controls({ V4L2_CID_HFLIP }); if (!ctrls.empty()) /* We assume the sensor supports VFLIP too. */ data->supportsFlips_ = true; @@ -1263,7 +1263,7 @@ int IPU3CameraData::loadIPA() return ret; ret = ipa_->init(IPASettings{ "", sensor->model() }, sensorInfo, - sensor->controls(), &ipaControls_); + sensor->v4l2Controls(), &ipaControls_); if (ret) { LOG(IPU3, Error) << "Failed to initialise the IPU3 IPA"; return ret; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index adc397e8aabd..782eb9ef20e8 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1292,8 +1292,8 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me * sensor of the colour gains. It is defined to be a linear gain where * the default value represents a gain of exactly one. */ - auto it = data->sensor_->controls().find(V4L2_CID_NOTIFY_GAINS); - if (it != data->sensor_->controls().end()) + auto it = data->sensor_->v4l2Controls().find(V4L2_CID_NOTIFY_GAINS); + if (it != data->sensor_->v4l2Controls().end()) data->notifyGainsUnity_ = it->second.def().get(); /* @@ -1554,7 +1554,7 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config, ipa::RPi::IPA } } - entityControls.emplace(0, sensor_->controls()); + entityControls.emplace(0, sensor_->v4l2Controls()); entityControls.emplace(1, isp_[Isp::Input].dev()->controls()); /* Always send the user transform to the IPA. */ @@ -1708,7 +1708,7 @@ void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList & if (notifyGainsUnity_ && controls.contains(libcamera::controls::ColourGains)) { libcamera::Span colourGains = controls.get(libcamera::controls::ColourGains); /* The control wants linear gains in the order B, Gb, Gr, R. */ - ControlList ctrls(sensor_->controls()); + ControlList ctrls(sensor_->v4l2Controls()); std::array gains{ static_cast(colourGains[1] * *notifyGainsUnity_), *notifyGainsUnity_, @@ -1717,7 +1717,7 @@ void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList & }; ctrls.set(V4L2_CID_NOTIFY_GAINS, Span{ gains }); - sensor_->setControls(&ctrls); + sensor_->setV4L2Controls(&ctrls); } state_ = State::IpaComplete; @@ -1789,10 +1789,10 @@ void RPiCameraData::setSensorControls(ControlList &controls) ControlList vblank_ctrl; vblank_ctrl.set(V4L2_CID_VBLANK, controls.get(V4L2_CID_VBLANK)); - sensor_->setControls(&vblank_ctrl); + sensor_->setV4L2Controls(&vblank_ctrl); } - sensor_->setControls(&controls); + sensor_->setV4L2Controls(&controls); } void RPiCameraData::unicamTimeout() diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 7cf36524ccc4..997f72500675 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -652,7 +652,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) } std::map entityControls; - entityControls.emplace(0, data->sensor_->controls()); + entityControls.emplace(0, data->sensor_->v4l2Controls()); ret = data->ipa_->configure(sensorInfo, streamConfig, entityControls); if (ret) { diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 3379ac5cd47d..2991306ca9d8 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -307,7 +307,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) std::forward_as_tuple(cfg.pixelFormat, cfg.size)); std::map entityControls; - entityControls.emplace(0, data->sensor_->controls()); + entityControls.emplace(0, data->sensor_->v4l2Controls()); IPACameraSensorInfo sensorInfo; data->sensor_->sensorInfo(&sensorInfo); @@ -376,7 +376,7 @@ void PipelineHandlerVimc::stopDevice(Camera *camera) int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request) { - ControlList controls(data->sensor_->controls()); + ControlList controls(data->sensor_->v4l2Controls()); for (auto it : request->controls()) { unsigned int id = it.first; @@ -405,7 +405,7 @@ int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request) << "Setting control " << utils::hex(ctrl.first) << " to " << ctrl.second.toString(); - int ret = data->sensor_->setControls(&controls); + int ret = data->sensor_->setV4L2Controls(&controls); if (ret) { LOG(VIMC, Error) << "Failed to set controls: " << ret; return ret < 0 ? ret : -EINVAL; @@ -530,7 +530,7 @@ int VimcCameraData::init() } /* Initialise the supported controls. */ - const ControlInfoMap &controls = sensor_->controls(); + const ControlInfoMap &controls = sensor_->v4l2Controls(); ControlInfoMap::Map ctrls; for (const auto &ctrl : controls) { From patchwork Mon Jun 27 16:27:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16389 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 F2F64BD808 for ; Mon, 27 Jun 2022 16:27:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 73DEF6563E; Mon, 27 Jun 2022 18:27:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347275; bh=y2h0WznafB5q+/INu0P7L8XWOVslu0KaZmIrAPC07d8=; 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=uae3sTqwbQTLni+zWNlJhbNGGs/8xRa6Q+9w5EjoFw4ZOE9w5Ks6X1oJssXUNGeLz 4q2khufbN8WsEY+fUDbykp29ElCzld2iyhKp9nOiElD3IjQ251GTHGTX6Tc2hQezHd 5ZNoJlyJozkv87GIJKWhI1q3onki2qpjuJVj2l5/nVukFrGjszfvnzcFuFQ4GIAoul 4rRGxHbZdas3azcbFWJoOgh1rdvvKQRncWkAIyABNeC7LET5mYTY7NZpR8CuFWAVG4 rWZEpsTD9ZiHiUzKbKn5HnC5zT80Mw9sWXWPlwF51JrgVslxBQtLVZYnRynW2lMszW 8XmlfDuXujAzA== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 392B465636 for ; Mon, 27 Jun 2022 18:27:48 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6E62420009; Mon, 27 Jun 2022 16:27:47 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:25 +0200 Message-Id: <20220627162732.33160-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/15] libcamera: camera_sensor: Initialize controls 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Initialize the control interface of the CameraSensor class by registering the control limits for controls::internal::ExposureTime, controls::internal::FrameDuration and controls::internal::draft::SensorAnalogueGain. Update the CameraSensor controls in the CameraSensor::updateControlInfo() function after having updated the subdevice V4L2 controls. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 3 + src/libcamera/camera_sensor.cpp | 89 ++++++++++++++++++++++ src/libcamera/internal_control_ids.yaml | 10 +++ 3 files changed, 102 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 0bed6e679840..c71f93f230d1 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -66,6 +66,7 @@ public: V4L2Subdevice *device() { return subdev_.get(); } const ControlList &properties() const { return properties_; } + const ControlInfoMap &controls() const { return controls_; } int sensorInfo(IPACameraSensorInfo *info) const; void updateControlInfo(); @@ -84,6 +85,7 @@ private: void initStaticProperties(); void initTestPatternModes(); int initProperties(); + int updateControls(); int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); int discoverAncillaryDevices(); @@ -107,6 +109,7 @@ private: const BayerFormat *bayerFormat_; ControlList properties_; + ControlInfoMap controls_; std::unique_ptr focusLens_; }; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index e3354530380c..82e51272cccc 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -22,6 +22,7 @@ #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor_properties.h" +#include "libcamera/internal/control_ids.h" #include "libcamera/internal/formats.h" #include "libcamera/internal/sysfs.h" @@ -180,6 +181,10 @@ int CameraSensor::init() if (ret) return ret; + ret = updateControls(); + if (ret) + return ret; + ret = discoverAncillaryDevices(); if (ret) return ret; @@ -455,6 +460,83 @@ int CameraSensor::initProperties() return 0; } +int CameraSensor::updateControls() +{ + if (!bayerFormat_) + return 0; + + ControlInfoMap::Map controlsMap; + + /* The subdev driver has been validate already, the controls are there! */ + ControlList subdevControls = subdev_->getControls({ V4L2_CID_PIXEL_RATE, + V4L2_CID_HBLANK, + V4L2_CID_VBLANK }); + uint64_t pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get(); + uint32_t hblank = subdevControls.get(V4L2_CID_HBLANK).get(); + + /* Assume the sensor has a single source pad #0. */ + V4L2SubdeviceFormat subdevFormat; + subdev_->getFormat(0, &subdevFormat); + + const ControlInfoMap &subdevControlsInfo = subdev_->controls(); + + /* + * Compute controls::ExposureTime limits by using line length and pixel + * rate converted to microseconds. Use the V4L2_CID_EXPOSURE control to + * get exposure min, max and default and convert it from lines to + * microseconds. + */ + uint32_t lineLength = subdevFormat.size.width + hblank; + double lineDuration = lineLength / (pixelRate / 1000000.0F); + auto &[expId, v4l2Exposure] = *subdevControlsInfo.find(V4L2_CID_EXPOSURE); + int32_t minExposure = v4l2Exposure.min().get() * lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * lineDuration; + + controlsMap[&controls::internal::ExposureTime] = + ControlInfo(minExposure, maxExposure, defExposure); + + /* + * Compute the frame duration limits. + * + * The frame length is computed assuming a fixed line length combined + * with the vertical frame sizes. + */ + auto &[vblankId, v4l2VBlank] = *subdevControlsInfo.find(V4L2_CID_VBLANK); + std::array frameHeights{ + v4l2VBlank.min().get() + subdevFormat.size.height, + v4l2VBlank.max().get() + subdevFormat.size.height, + v4l2VBlank.def().get() + subdevFormat.size.height, + }; + + std::array frameDurations; + for (unsigned int i = 0; i < frameHeights.size(); ++i) { + uint64_t frameSize = lineLength * frameHeights[i]; + frameDurations[i] = frameSize / (pixelRate / 1000000.0F); + } + + controlsMap[&controls::internal::FrameDuration] = + ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]); + + /* + * For analogue gain collect the raw V4L2 control values which express + * the gain codes as seen from the sensor and need to be translated + * on the IPA side. + * + * \todo Translate it by using a CameraSensorHelper. + */ + auto &[gainId, v4l2AGain] = *subdevControlsInfo.find(V4L2_CID_ANALOGUE_GAIN); + controlsMap[&controls::internal::draft::SensorAnalogueGain] = + ControlInfo(v4l2AGain.min().get(), + v4l2AGain.max().get(), + v4l2AGain.def().get()); + + controls_ = ControlInfoMap(std::move(controlsMap), + controls::internal::controls); + + return 0; +} + /** * \brief Check for and initialise any ancillary devices * @@ -837,6 +919,12 @@ int CameraSensor::setV4L2Controls(ControlList *ctrls) * \return The list of camera sensor properties */ +/** + * \fn CameraSensor::controls() + * \brief Retrieve the map of the camera sensor controls limits + * \return The map of camera sensor control information + */ + /** * \brief Assemble and return the camera sensor info * \param[out] info The camera sensor info @@ -932,6 +1020,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const void CameraSensor::updateControlInfo() { subdev_->updateControlInfo(); + updateControls(); } /** diff --git a/src/libcamera/internal_control_ids.yaml b/src/libcamera/internal_control_ids.yaml index e69e0d30657c..c6e6bd111cf7 100644 --- a/src/libcamera/internal_control_ids.yaml +++ b/src/libcamera/internal_control_ids.yaml @@ -9,6 +9,16 @@ controls: + - ExposureTime: + type: int32_t + description: | + The sensor exposure time in milliseconds. + + - FrameDuration: + type: int64_t + description: | + The sensor frame duration time in milliseconds. + # ---------------------------------------------------------------------------- # Draft controls section From patchwork Mon Jun 27 16:27:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16390 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 66E50BD808 for ; Mon, 27 Jun 2022 16:27:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DA4496563B; Mon, 27 Jun 2022 18:27:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347277; bh=YRcrjHMXZIwdFvwX6ssq+Ra4PbFZJC596koAMpw3dT8=; 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=h3SR8HqED7QDJzxyKY6sZQCj7VWa+Y7LPs/wE+Zu17ORfjyEUMAhEkQDxw32BQUGU V19k92WDVsPBoGiKMSIrN+TEvQGU5YK7yCiNd3mQRj94BC8DJqT1RUYXKsvYdxewJS klk1ac2SqPTwvH9OGO1v6MewO6+HwqqPLWwCcf72/NO/0wsoTee5dUbk3e5cJvfnkv W1Ry1EuYeIltWvXysDgr/v1et+1BvvXDQ+/QyVGagiCyfyOJ5xAMhNKbCHNAt4mNCX yJj2yz3OXx7c23JB1pbE2bim7TI765mL5pkEHwwj5KLRFCRMMwN+d8FGdionaM+/eT AgQcjAufLu15w== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 483C26563E for ; Mon, 27 Jun 2022 18:27:49 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 8435520009; Mon, 27 Jun 2022 16:27:48 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:26 +0200 Message-Id: <20220627162732.33160-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/15] libcamera: control_serializer: Support internal controls 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The control serializer class uses tags to identify which ControlIdMap to use to de-serialize a ControlList. Add a value for internal controls to the ipa_controls_id_map_type enumeration and use it to identify lists of internal controls. Signed-off-by: Jacopo Mondi --- include/libcamera/ipa/ipa_controls.h | 1 + src/libcamera/control_serializer.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/libcamera/ipa/ipa_controls.h b/include/libcamera/ipa/ipa_controls.h index e5da1946ce1d..609e28197f50 100644 --- a/include/libcamera/ipa/ipa_controls.h +++ b/include/libcamera/ipa/ipa_controls.h @@ -20,6 +20,7 @@ extern "C" { enum ipa_controls_id_map_type { IPA_CONTROL_ID_MAP_CONTROLS, IPA_CONTROL_ID_MAP_PROPERTIES, + IPA_CONTROL_ID_MAP_INTERNAL_CONTROLS, IPA_CONTROL_ID_MAP_V4L2, }; diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index e87d23625ed2..c5b691a981a2 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -21,6 +21,7 @@ #include #include "libcamera/internal/byte_stream_buffer.h" +#include "libcamera/internal/control_ids.h" /** * \file control_serializer.h @@ -335,6 +336,8 @@ int ControlSerializer::serialize(const ControlList &list, idMapType = IPA_CONTROL_ID_MAP_CONTROLS; else if (idmap == &properties::properties) idMapType = IPA_CONTROL_ID_MAP_PROPERTIES; + else if (idmap == &controls::internal::controls) + idMapType = IPA_CONTROL_ID_MAP_INTERNAL_CONTROLS; else idMapType = IPA_CONTROL_ID_MAP_V4L2; @@ -461,6 +464,9 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & case IPA_CONTROL_ID_MAP_PROPERTIES: idMap = &properties::properties; break; + case IPA_CONTROL_ID_MAP_INTERNAL_CONTROLS: + idMap = &controls::internal::controls; + break; case IPA_CONTROL_ID_MAP_V4L2: controlIdMaps_.emplace_back(std::make_unique()); localIdMap = controlIdMaps_.back().get(); From patchwork Mon Jun 27 16:27:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16391 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 52A46BD808 for ; Mon, 27 Jun 2022 16:27:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CAA0565653; Mon, 27 Jun 2022 18:27:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347279; bh=kOEVtb1pxIg4nalpzYb9LbdT3uzPqrarMrdtPenImMU=; 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=aY4+VdEswtT9JEd3fBJ7BOCcSYKcpqVwG9D0Yjn3JCDrtNHYEc7eSITRCtMEBxKS4 sLb/eXL8Uo/SNVWa7D0N1539zNPVbPAtU0BMZk+15KjsaUKwKGpIaFUmsKx14rMnlD WXqiCX3t60EMLgaQvGjYoiilgZKAXQOhhtbwXh7eYa2YfGLRn0N7//9yxE5bpVKvOu IqlIFhjwKJnw9pLQ/z8abPrdYa7Gzky06hOn5EZSy38jVnMuAcXXbOXase9tVWZl8u muXiJ4JtR5KoA2tKxBoHEj6CDw5r1KIyCVlYcCG2luUiGHA0LIboyWAm+QQfP9PgCp tvd9K9lpzdvDw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EEC86564C for ; Mon, 27 Jun 2022 18:27:50 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 82A7620009; Mon, 27 Jun 2022 16:27:49 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:27 +0200 Message-Id: <20220627162732.33160-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/15] libcamera: ipu3: Initialize Camera controls in the PH 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently the map of V4L2 controls collected from the sensor is passed to the IPA module which initializes Camera controls by inspecting the sensor control values. As the CameraSensor class translates V4L2 controls into libcamera::internal controls, the Camera controls can be initialized directly in the pipeline handler, without sending them to the IPA which receives all the information it needs using the CameraSensorInfo. Remove from the IPA interface the list of V4L2 controls from the sensor sent to the IPA as it is not used anymore and initialize Camera controls in the pipeline directly. Signed-off-by: Jacopo Mondi --- include/libcamera/ipa/ipu3.mojom | 7 +-- src/ipa/ipu3/ipu3.cpp | 87 ++-------------------------- src/libcamera/pipeline/ipu3/ipu3.cpp | 37 +++++++----- 3 files changed, 31 insertions(+), 100 deletions(-) diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom index d1b1c6b867da..5818cd3a6846 100644 --- a/include/libcamera/ipa/ipu3.mojom +++ b/include/libcamera/ipa/ipu3.mojom @@ -18,14 +18,13 @@ struct IPAConfigInfo { interface IPAIPU3Interface { init(libcamera.IPASettings settings, - libcamera.IPACameraSensorInfo sensorInfo, - libcamera.ControlInfoMap sensorControls) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + libcamera.IPACameraSensorInfo sensorInfo) + => (int32 ret); start() => (int32 ret); stop(); configure(IPAConfigInfo configInfo) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + => (int32 ret); mapBuffers(array buffers); unmapBuffers(array ids); diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 2f6bb672f7bb..7e8bf0feee8a 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -28,6 +28,7 @@ #include #include +#include "libcamera/internal/control_ids.h" #include "libcamera/internal/mapped_framebuffer.h" #include "algorithms/af.h" @@ -132,15 +133,12 @@ class IPAIPU3 : public IPAIPU3Interface { public: int init(const IPASettings &settings, - const IPACameraSensorInfo &sensorInfo, - const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) override; + const IPACameraSensorInfo &sensorInfo) override; int start() override; void stop() override; - int configure(const IPAConfigInfo &configInfo, - ControlInfoMap *ipaControls) override; + int configure(const IPAConfigInfo &configInfo) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; @@ -151,9 +149,6 @@ public: const uint32_t bufferId, const ControlList &sensorControls) override; private: - void updateControls(const IPACameraSensorInfo &sensorInfo, - const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls); void updateSessionConfiguration(const ControlInfoMap &sensorControls); bool validateSensorControls(); @@ -208,68 +203,6 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls) context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); } -/** - * \brief Compute camera controls using the sensor information and the sensor - * V4L2 controls - * - * Some of the camera controls are computed by the pipeline handler, some others - * by the IPA module which is in charge of handling, for example, the exposure - * time and the frame duration. - * - * This function computes: - * - controls::ExposureTime - * - controls::FrameDurationLimits - */ -void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, - const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) -{ - ControlInfoMap::Map controls{}; - double lineDuration = context_.configuration.sensor.lineDuration.get(); - - /* - * Compute exposure time limits by using line length and pixel rate - * converted to microseconds. Use the V4L2_CID_EXPOSURE control to get - * exposure min, max and default and convert it from lines to - * microseconds. - */ - const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get() * lineDuration; - int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; - int32_t defExposure = v4l2Exposure.def().get() * lineDuration; - controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, - defExposure); - - /* - * Compute the frame duration limits. - * - * The frame length is computed assuming a fixed line length combined - * with the vertical frame sizes. - */ - const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second; - uint32_t hblank = v4l2HBlank.def().get(); - uint32_t lineLength = sensorInfo.outputSize.width + hblank; - - const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second; - std::array frameHeights{ - v4l2VBlank.min().get() + sensorInfo.outputSize.height, - v4l2VBlank.max().get() + sensorInfo.outputSize.height, - v4l2VBlank.def().get() + sensorInfo.outputSize.height, - }; - - std::array frameDurations; - for (unsigned int i = 0; i < frameHeights.size(); ++i) { - uint64_t frameSize = lineLength * frameHeights[i]; - frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); - } - - controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], - frameDurations[1], - frameDurations[2]); - - *ipaControls = ControlInfoMap(std::move(controls), controls::controls); -} - /** * \brief Validate that the sensor controls mandatory for the IPA exists */ @@ -300,9 +233,7 @@ bool IPAIPU3::validateSensorControls() * them in the \a ipaControls output parameter. */ int IPAIPU3::init(const IPASettings &settings, - const IPACameraSensorInfo &sensorInfo, - const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) + const IPACameraSensorInfo &sensorInfo) { camHelper_ = CameraSensorHelperFactory::create(settings.sensorModel); if (camHelper_ == nullptr) { @@ -323,9 +254,6 @@ int IPAIPU3::init(const IPASettings &settings, algorithms_.push_back(std::make_unique()); algorithms_.push_back(std::make_unique()); - /* Initialize controls. */ - updateControls(sensorInfo, sensorControls, ipaControls); - return 0; } @@ -423,7 +351,6 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) * \brief Configure the IPU3 IPA * \param[in] configInfo The IPA configuration data, received from the pipeline * handler - * \param[in] ipaControls The IPA controls to update * * Calculate the best grid for the statistics based on the pipeline handler BDS * output, and parse the minimum and maximum exposure and analogue gain control @@ -434,8 +361,7 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) * All algorithm modules are called to allow them to prepare the * \a IPASessionConfiguration structure for the \a IPAContext. */ -int IPAIPU3::configure(const IPAConfigInfo &configInfo, - ControlInfoMap *ipaControls) +int IPAIPU3::configure(const IPAConfigInfo &configInfo) { if (configInfo.sensorControls.empty()) { LOG(IPAIPU3, Error) << "No sensor controls provided"; @@ -464,9 +390,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo, return -EINVAL; } - /* Update the camera controls using the new sensor settings. */ - updateControls(sensorInfo_, sensorCtrls_, ipaControls); - /* Update the IPASessionConfiguration using the sensor settings. */ updateSessionConfiguration(sensorCtrls_); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 28442756b184..815530dd640b 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -26,6 +26,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor.h" +#include "libcamera/internal/control_ids.h" #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/framebuffer.h" @@ -84,8 +85,6 @@ public: /* Requests queued to the CIO2 device but not yet processed by the ImgU. */ std::queue processingRequests_; - ControlInfoMap ipaControls_; - private: void metadataReady(unsigned int id, const ControlList &metadata); void paramsBufferReady(unsigned int id); @@ -672,7 +671,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) configInfo.bdsOutputSize = config->imguConfig().bds; configInfo.iif = config->imguConfig().iif; - ret = data->ipa_->configure(configInfo, &data->ipaControls_); + ret = data->ipa_->configure(configInfo); if (ret) { LOG(IPU3, Error) << "Failed to configure IPA: " << strerror(-ret); @@ -950,9 +949,6 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) * Initialize the camera controls by calculating controls which the pipeline * is reponsible for and merge them with the controls computed by the IPA. * - * This function needs data->ipaControls_ to be initialized by the IPA init() - * function at camera creation time. Always call this function after IPA init(). - * * \return 0 on success or a negative error code otherwise */ int PipelineHandlerIPU3::initControls(IPU3CameraData *data) @@ -982,9 +978,6 @@ int PipelineHandlerIPU3::initControls(IPU3CameraData *data) * Compute the camera controls by calculating controls which the pipeline * is reponsible for and merge them with the controls computed by the IPA. * - * This function needs data->ipaControls_ to be refreshed when a new - * configuration is applied to the camera by the IPA configure() function. - * * Always call this function after IPA configure() to make sure to have a * properly refreshed IPA controls list. * @@ -1063,9 +1056,26 @@ int PipelineHandlerIPU3::updateControls(IPU3CameraData *data) controls[&controls::ScalerCrop] = ControlInfo(minCrop, maxCrop, maxCrop); - /* Add the IPA registered controls to list of camera controls. */ - for (const auto &ipaControl : data->ipaControls_) - controls[ipaControl.first] = ipaControl.second; + /* Translate the sensor controls to Camera controls. */ + const ControlInfoMap &sensorControls = sensor->controls(); + + /* Exposure time is reported directly from the sensor control limits. */ + if (sensorControls.count(&controls::internal::ExposureTime)) { + auto &[id, info] = *sensorControls.find(&controls::internal::ExposureTime); + + controls[&controls::ExposureTime] = ControlInfo(info.min().get(), + info.max().get(), + info.def().get()); + } + + /* Frame duration is reported directly from the sensor control limits. */ + if (sensorControls.count(&controls::internal::FrameDuration)) { + auto &[id, info] = *sensorControls.find(&controls::internal::FrameDuration); + + controls[&controls::FrameDurationLimits] = ControlInfo(info.min().get(), + info.max().get(), + info.def().get()); + } data->controlInfo_ = ControlInfoMap(std::move(controls), controls::controls); @@ -1262,8 +1272,7 @@ int IPU3CameraData::loadIPA() if (ret) return ret; - ret = ipa_->init(IPASettings{ "", sensor->model() }, sensorInfo, - sensor->v4l2Controls(), &ipaControls_); + ret = ipa_->init(IPASettings{ "", sensor->model() }, sensorInfo); if (ret) { LOG(IPU3, Error) << "Failed to initialise the IPU3 IPA"; return ret; From patchwork Mon Jun 27 16:27:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16392 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 96E5DBD808 for ; Mon, 27 Jun 2022 16:28:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2C83D6563A; Mon, 27 Jun 2022 18:28:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347280; bh=0CFR/QE0UmHxV/v04KGzFbyK814o/lukdYYX8q5xPDA=; 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=GClNktlvW+XcVqBAVdp/kv29B4D/DOCZHSY6Wx+NHLhToXfLpsjz2Ks33uG9wXfri HQ5lBOjgo/V7YUih0AlGmq7S0V+/B+d3csPcxUp4ITNduZrWID0/vJNzTO1/5IU8xJ MzObH4Eh4Erdbs7tiwDMe7hxccACSOxIheGvcg1HgCDME0hug0FvYkGRZr2IXAemXB bhp47pkJf7l2G/p5w/LG2B8wwAtW0CRG+fzvNLOXPjQkNed0VCoid4HpF/Aqqv2JRO tY0JFNYjXpJSfQP0CrXA2keA5jynGiL3zAkwpwTe40WfwTjCcg7jHZ5mZio7qdIXFH uMViQl0MFLx/g== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D5506563F for ; Mon, 27 Jun 2022 18:27:51 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id C32D220004; Mon, 27 Jun 2022 16:27:50 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:28 +0200 Message-Id: <20220627162732.33160-12-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/15] libcamera: IPACameraSensorInfo: Add VBLANK 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPA modules need the V4L2_CID_VBLANK value to calculate the total frame size for the current sensor configuration. In order to prepare removing usage of V4L2_CID_VBLANK in IPA modules, add the vblank value to the IPACameraSensorInfo structure. Signed-off-by: Jacopo Mondi --- include/libcamera/ipa/core.mojom | 6 ++++++ src/libcamera/camera_sensor.cpp | 1 + 2 files changed, 7 insertions(+) diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom index 74f3339e56f2..d122fb7add4d 100644 --- a/include/libcamera/ipa/core.mojom +++ b/include/libcamera/ipa/core.mojom @@ -178,6 +178,11 @@ module libcamera; * The total line length in pixel clock periods, including blanking. */ +/** + * \var IPACameraSensorInfo::vblank + * \brief The vertical blanking, expressed in number of lines + */ + /** * \var IPACameraSensorInfo::minFrameLength * \brief The minimum allowable frame length in units of lines @@ -218,6 +223,7 @@ struct IPACameraSensorInfo { uint64 pixelRate; uint32 lineLength; + uint32 vblank; uint32 minFrameLength; uint32 maxFrameLength; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 82e51272cccc..e8db9da84e6a 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -1004,6 +1004,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const int32_t hblank = ctrls.get(V4L2_CID_HBLANK).get(); info->lineLength = info->outputSize.width + hblank; info->pixelRate = ctrls.get(V4L2_CID_PIXEL_RATE).get(); + info->vblank = ctrls.get(V4L2_CID_VBLANK).get(); const ControlInfo vblank = ctrls.infoMap()->at(V4L2_CID_VBLANK); info->minFrameLength = info->outputSize.height + vblank.min().get(); From patchwork Mon Jun 27 16:27:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16393 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 C67BEBD808 for ; Mon, 27 Jun 2022 16:28:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7C62265659; Mon, 27 Jun 2022 18:28:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347282; bh=G5D9fOHWCM9PZClxjpkw4/6UIxce7BP82fLdpzG/XbE=; 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=WytnHA9OjvJRq08/lbM2ZWuRaG6sOmS2kpOusVhJ/ag3IH1pqMx3+eyBAxCPNQ2L3 bzVs8FEQ8wtBAJceDj5POVQW2o81YlQSRt6T+UubSCfmrihQ10QyfeHUa5CLYkiPP1 OJel7IhwHizfkb486NtWZoQyvwfI4FcozSJkuPmlVb8RwdEC992v2Bobx0rnjs2wEL y6O51fyoDjyBDaKEqjHRJsJfwPn/LB6s89SlZwuR9scadMFFG7TQz8Wx+KgTwx7wk/ YVhykYoXrZ7ozWAS2QyVRpV9w5M4xL7UQTWXYig4rrJK8ddNMqv5yaEsF0eY7wERiv EL/1NXbQ3PsPQ== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7752C65648 for ; Mon, 27 Jun 2022 18:27:52 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id BA53720004; Mon, 27 Jun 2022 16:27:51 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:29 +0200 Message-Id: <20220627162732.33160-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/15] libcamera: ipa: Use the current VBLANK value 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPU3 IPA module uses the default value from the V4L2_CID_VBLANK control to compute the total frame size in processStatsBuffer(). Most drivers update the VBLANK control limits when a new format is applied and assign to the default the current control value. As this is not required by the API specification, and the VBLANK default value can be different than its current value, use the actual control value as now available from the IPACameraSensorInfo structure. Signed-off-by: Jacopo Mondi --- src/ipa/ipu3/ipa_context.cpp | 4 ++-- src/ipa/ipu3/ipa_context.h | 2 +- src/ipa/ipu3/ipu3.cpp | 15 ++++++++------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 13cdb835ef7f..06fdf2a1efc7 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -126,8 +126,8 @@ namespace libcamera::ipa::ipu3 { * \var IPASessionConfiguration::sensor.lineDuration * \brief Line duration in microseconds * - * \var IPASessionConfiguration::sensor.defVBlank - * \brief The default vblank value of the sensor + * \var IPASessionConfiguration::sensor.vBlank + * \brief The vertical blanking expressed in number of lines */ /** diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 42e11141d3a1..a5b878ab7792 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -43,7 +43,7 @@ struct IPASessionConfiguration { } agc; struct { - int32_t defVBlank; + int32_t vBlank; utils::Duration lineDuration; } sensor; }; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 7e8bf0feee8a..3efbc84c4ef1 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -149,7 +149,7 @@ public: const uint32_t bufferId, const ControlList &sensorControls) override; private: - void updateSessionConfiguration(const ControlInfoMap &sensorControls); + void updateSessionConfiguration(const IPAConfigInfo &info); bool validateSensorControls(); @@ -177,10 +177,12 @@ private: * \brief Compute IPASessionConfiguration using the sensor information and the * sensor V4L2 controls */ -void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls) +void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) { - const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second; - context_.configuration.sensor.defVBlank = vBlank.def().get(); + const IPACameraSensorInfo &sensorInfo = info.sensorInfo; + context_.configuration.sensor.vBlank = sensorInfo.vblank; + + const ControlInfoMap &sensorControls = info.sensorControls; const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; int32_t minExposure = v4l2Exposure.min().get(); @@ -391,7 +393,7 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) } /* Update the IPASessionConfiguration using the sensor settings. */ - updateSessionConfiguration(sensorCtrls_); + updateSessionConfiguration(configInfo); for (auto const &algo : algorithms_) { int ret = algo->configure(context_, configInfo); @@ -501,7 +503,7 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, frameContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get()); double lineDuration = context_.configuration.sensor.lineDuration.get(); - int32_t vBlank = context_.configuration.sensor.defVBlank; + int32_t vBlank = context_.configuration.sensor.vBlank; ControlList ctrls(controls::controls); for (auto const &algo : algorithms_) @@ -509,7 +511,6 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, setControls(frame); - /* \todo Use VBlank value calculated from each frame exposure. */ int64_t frameDuration = (vBlank + sensorInfo_.outputSize.height) * lineDuration; ctrls.set(controls::FrameDuration, frameDuration); From patchwork Mon Jun 27 16:27:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16394 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 E8455BD808 for ; Mon, 27 Jun 2022 16:28:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 85E4965648; Mon, 27 Jun 2022 18:28:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347283; bh=FuSvLWC6rEDGiyWw4GH9+mSsVBs1AMYnTSQKdxD+VlI=; 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=prIp1BM5lgzrUZhsYMTK0HWB3eQslrmzMC00t6i+45uLIcTvR7cQoo898orP3TJM1 OxpPKU9yFfYcBk62VJD+t2P72JpVAE54Wahcgb+7MktylnByUTqhekrUKzbK5R4HSQ qNvxyytkVzNg8yVW/ZxXWb98uBSfYeBvx6usAWTPVxNOUwSZrxj/EZUb2K77s2Gfae LV0P/sDAK+j45LJ9acVsVHDZRWbsQansVnP/k3fVRCqv3xGdW0LtVQh+cdlmVmxWFv xF9MecBdvOdRN1ECIzPFqp2EgcOeccxydVAUn67WCFZpOuSbur9NuBVOcy5s1Esx4w ZSLC7nPlvzezA== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7984265640 for ; Mon, 27 Jun 2022 18:27:53 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9AA8320004; Mon, 27 Jun 2022 16:27:52 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:30 +0200 Message-Id: <20220627162732.33160-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/15] libcamera: ipu3: ipa: Use an updated lineDuration 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPA module computes the lineDuration value in the init() function only, and uses it when processing statistics to recompute the shutter duration. As the lineDuration varies when a new mode is applied to the sensor, computing it once at IPA initialization time is not enough. Re-calculate the line duration value at IPA configure() time to make sure the module always uses an updated value. Signed-off-by: Jacopo Mondi --- include/libcamera/ipa/ipu3.mojom | 3 +-- src/ipa/ipu3/ipu3.cpp | 9 ++++----- src/libcamera/pipeline/ipu3/ipu3.cpp | 7 +------ 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom index 5818cd3a6846..64fe65fdd5fc 100644 --- a/include/libcamera/ipa/ipu3.mojom +++ b/include/libcamera/ipa/ipu3.mojom @@ -17,8 +17,7 @@ struct IPAConfigInfo { }; interface IPAIPU3Interface { - init(libcamera.IPASettings settings, - libcamera.IPACameraSensorInfo sensorInfo) + init(libcamera.IPASettings settings) => (int32 ret); start() => (int32 ret); stop(); diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 3efbc84c4ef1..1f80a10bc48d 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -132,8 +132,7 @@ namespace ipa::ipu3 { class IPAIPU3 : public IPAIPU3Interface { public: - int init(const IPASettings &settings, - const IPACameraSensorInfo &sensorInfo) override; + int init(const IPASettings &settings) override; int start() override; void stop() override; @@ -181,6 +180,8 @@ void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) { const IPACameraSensorInfo &sensorInfo = info.sensorInfo; context_.configuration.sensor.vBlank = sensorInfo.vblank; + context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s + / sensorInfo.pixelRate; const ControlInfoMap &sensorControls = info.sensorControls; @@ -234,8 +235,7 @@ bool IPAIPU3::validateSensorControls() * handler, computes the limits of the controls it handles and returns * them in the \a ipaControls output parameter. */ -int IPAIPU3::init(const IPASettings &settings, - const IPACameraSensorInfo &sensorInfo) +int IPAIPU3::init(const IPASettings &settings) { camHelper_ = CameraSensorHelperFactory::create(settings.sensorModel); if (camHelper_ == nullptr) { @@ -247,7 +247,6 @@ int IPAIPU3::init(const IPASettings &settings, /* Clean context */ context_.configuration = {}; - context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; /* Construct our Algorithms */ algorithms_.push_back(std::make_unique()); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 815530dd640b..44e65d9f2d46 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1267,12 +1267,7 @@ int IPU3CameraData::loadIPA() if (ret) return ret; - IPACameraSensorInfo sensorInfo{}; - ret = sensor->sensorInfo(&sensorInfo); - if (ret) - return ret; - - ret = ipa_->init(IPASettings{ "", sensor->model() }, sensorInfo); + ret = ipa_->init(IPASettings{ "", sensor->model() }); if (ret) { LOG(IPU3, Error) << "Failed to initialise the IPU3 IPA"; return ret; From patchwork Mon Jun 27 16:27:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16395 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 33D79BD808 for ; Mon, 27 Jun 2022 16:28:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C2BA26564F; Mon, 27 Jun 2022 18:28:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347284; bh=xWarKmTw0az9pmRqeB1pNq0yAC4/im7vDuKrVEzDcl4=; 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=fMpii3qcE/qhqGM+2rVfYpFZKBxvAz8zYFgQAtJ4njbLzUZt5BYbTnxl9g5chE31l PA9lmxuPs9Wt5dtwMRaCTGp29G8NOslxMHYopgGI9hb49p+ZbV2pkMdTFyAhBzkmiU 8M1veIfJ/WKHTH4pR2qL4Vsoo3fB521GqNNvRTc6/AaivWUd0QF+4EpoifjhxjiQNI IIsVN8LvjX2cOFjyMy2IWl8UDnR7zGMzqVBhQyn9n5QdSqV8b6lUf66uk2904BpZSX 3ptZd/qYnjhmS99azCRRPfe1XJvL1pRBc0k8EvBTekuHTmZnD4ws7B7lrj8ZI7s0Y5 KYrsVA7MTJG/g== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EE5D65635 for ; Mon, 27 Jun 2022 18:27:54 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id B172B20004; Mon, 27 Jun 2022 16:27:53 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:31 +0200 Message-Id: <20220627162732.33160-15-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 14/15] ipa: ipu3: Configure IPA with libcamera controls 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Pass to the IPA configure() function the list of libcamera controls::internal controls in place of sending to the IPA the raw V4L2 control values. As the controls::internal::ExposureTime is already expressed in micro-seconds, there's not need to multiply by the line duration. AnalogueGain still requires translation using the CameraSensorHelper class. While at it, rationalize the sequence of operations IPA::configure() to: - check the validity of the configuration - update the session configuration - configure algorithm - assign class member variables Signed-off-by: Jacopo Mondi --- src/ipa/ipu3/ipu3.cpp | 67 ++++++++++++---------------- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 1f80a10bc48d..b67ff1948bc2 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -150,7 +150,7 @@ public: private: void updateSessionConfiguration(const IPAConfigInfo &info); - bool validateSensorControls(); + bool validateConfiguration(const IPAConfigInfo &config); void setControls(unsigned int frame); void calculateBdsGrid(const Size &bdsOutputSize); @@ -183,16 +183,6 @@ void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; - const ControlInfoMap &sensorControls = info.sensorControls; - - const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get(); - int32_t maxExposure = v4l2Exposure.max().get(); - - const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second; - int32_t minGain = v4l2Gain.min().get(); - int32_t maxGain = v4l2Gain.max().get(); - /* * When the AGC computes the new exposure values for a frame, it needs * to know the limits for shutter speed and analogue gain. @@ -200,8 +190,16 @@ void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) * * \todo take VBLANK into account for maximum shutter speed */ - context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration; - context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration; + const ControlInfoMap &sensorControls = info.sensorControls; + + const auto &[expId, exposure] = *sensorControls.find(&controls::internal::ExposureTime); + context_.configuration.agc.minShutterSpeed = exposure.min().get() * 1.0us; + context_.configuration.agc.maxShutterSpeed = exposure.max().get() * 1.0us; + + const auto &[gainId, gain] = *sensorControls.find(&controls::internal::draft::SensorAnalogueGain); + int32_t minGain = gain.min().get(); + int32_t maxGain = gain.max().get(); + context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); } @@ -209,18 +207,18 @@ void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) /** * \brief Validate that the sensor controls mandatory for the IPA exists */ -bool IPAIPU3::validateSensorControls() +bool IPAIPU3::validateConfiguration(const IPAConfigInfo &config) { - static const uint32_t ctrls[] = { - V4L2_CID_ANALOGUE_GAIN, - V4L2_CID_EXPOSURE, - V4L2_CID_VBLANK, + static constexpr std::array ctrls = { + &controls::internal::ExposureTime, + &controls::internal::FrameDuration, + &controls::internal::draft::SensorAnalogueGain, }; - for (auto c : ctrls) { - if (sensorCtrls_.find(c) == sensorCtrls_.end()) { + for (const ControlId *c : ctrls) { + if (config.sensorControls.find(c) == config.sensorControls.end()) { LOG(IPAIPU3, Error) << "Unable to find sensor control " - << utils::hex(c); + << c->name(); return false; } } @@ -369,30 +367,19 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return -ENODATA; } - sensorInfo_ = configInfo.sensorInfo; - - lensCtrls_ = configInfo.lensControls; - - /* - * Compute the sensor V4L2 controls to be used by the algorithms and - * to be set on the sensor. - */ - sensorCtrls_ = configInfo.sensorControls; - - calculateBdsGrid(configInfo.bdsOutputSize); + if (!validateConfiguration(configInfo)) { + LOG(IPAIPU3, Error) << "Sensor control validation failed."; + return -EINVAL; + } /* Clean IPAActiveState at each reconfiguration. */ context_.activeState = {}; IPAFrameContext initFrameContext; context_.frameContexts.fill(initFrameContext); - if (!validateSensorControls()) { - LOG(IPAIPU3, Error) << "Sensor control validation failed."; - return -EINVAL; - } - - /* Update the IPASessionConfiguration using the sensor settings. */ + /* Update the IPA configuration using the new settings. */ updateSessionConfiguration(configInfo); + calculateBdsGrid(configInfo.bdsOutputSize); for (auto const &algo : algorithms_) { int ret = algo->configure(context_, configInfo); @@ -400,6 +387,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } + sensorInfo_ = configInfo.sensorInfo; + lensCtrls_ = configInfo.lensControls; + sensorCtrls_ = configInfo.sensorControls; + return 0; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 44e65d9f2d46..8bf51411581a 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -661,7 +661,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } ipa::ipu3::IPAConfigInfo configInfo; - configInfo.sensorControls = data->cio2_.sensor()->v4l2Controls(); + configInfo.sensorControls = data->cio2_.sensor()->controls(); CameraLens *lens = data->cio2_.sensor()->focusLens(); if (lens) From patchwork Mon Jun 27 16:27:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16396 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 9B996BD808 for ; Mon, 27 Jun 2022 16:28:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0C23D65649; Mon, 27 Jun 2022 18:28:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347286; bh=P9aa6O5zAz3cqNS1dxpJn9f54hgJ61tTUiMnkK+R99U=; 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=X9/OdMiA0wxKeZAWPs+JYM+ulTDATiBmqLtXeRPpInPMwB7QrPFN3Y3HZ4O3UZH82 YJ1xv10uS9wakIWiyqF2lFHM1Fm5TxhOmB4nLv7dB0ZsRS7kbzIAjTaTUUGhEt55OZ la00oRSmzkzPibBbNP0OzQ4WNPp2CzmoXCCc6nf+rHYB7KEzfRHcKURPhnqfqMWPpu AyQ+Sbl83ryJJVbsVsFjmVcvnnM5z232ACrt0aK1pTNZGqIjTCAUYEVcQF093d/DI3 +pFWkNwkzTKoE9byW0Ys2i0HYffBy3gB7vjOWOqwmxUXoNAse/8nQiQJYYI4ZlU79A dETL5pKLbK8kw== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B4D0965650 for ; Mon, 27 Jun 2022 18:27:55 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 0B57C20008; Mon, 27 Jun 2022 16:27:54 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:32 +0200 Message-Id: <20220627162732.33160-16-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 15/15] ipa: ipu3: Rework IPAIPU3::processStatsBuffer() 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Before removing V4L2 controls from the IPAIPU3::processStatsBuffer() interface, rationalize the existing code a bit. 1) we have a context_.configuration which collects the per-capture session configuration data. At the same time the sensor and lens controls info are kept in class member variables. Move all per-capture session parameters to context_.configuration 2) IPAIPU3::setControls() operates on the active state, which is implicitly retrieved from the global context. Pass it explicitely to make it clear. 3) Now that we have the full IPACameraSensorInfo in the current context remove vblank from IPASessionConfiguration::sensor as it can be retrieved from IPASessionConfiguration::sensor.info. 4) Rationalize the code of IPAIPU3::processStatsBuffer() to organize it in a logical flow of operations: - Update the per-frame context with the sensor's controls values - Map the stats buffer - Run algorithms with the the per-frame context and stats - setControls() using the active state as computed by algorithms - Populate the metadata buffer Signed-off-by: Jacopo Mondi --- src/ipa/ipu3/ipa_context.cpp | 14 ++++++- src/ipa/ipu3/ipa_context.h | 9 ++++- src/ipa/ipu3/ipu3.cpp | 73 +++++++++++++++++++----------------- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 06fdf2a1efc7..f09d061e2d19 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -126,8 +126,18 @@ namespace libcamera::ipa::ipu3 { * \var IPASessionConfiguration::sensor.lineDuration * \brief Line duration in microseconds * - * \var IPASessionConfiguration::sensor.vBlank - * \brief The vertical blanking expressed in number of lines + * \var IPASessionConfiguration::sensor.info + * \brief The IPACameraSensorInfo valid for the session + * + * \var IPASessionConfiguration::sensor.controls + * \brief The ControlInfoMap of camera sensor control limits valid for the + * session + * + * \var IPASessionConfiguration::lens + * \brief Lens-specific configuration of the IPA + * + * \var IPASessionConfiguration::lens.controls + * \brief The ControlInfoMap of lens control limits valid for the session */ /** diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index a5b878ab7792..35baa17e8708 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -17,6 +17,8 @@ #include #include +#include + namespace libcamera { namespace ipa::ipu3 { @@ -43,9 +45,14 @@ struct IPASessionConfiguration { } agc; struct { - int32_t vBlank; utils::Duration lineDuration; + ControlInfoMap controls; + IPACameraSensorInfo info; } sensor; + + struct { + ControlInfoMap controls; + } lens; }; struct IPAActiveState { diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index b67ff1948bc2..791c03e5a2d3 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -152,16 +152,11 @@ private: bool validateConfiguration(const IPAConfigInfo &config); - void setControls(unsigned int frame); + void setControls(unsigned int frame, const IPAActiveState &state); void calculateBdsGrid(const Size &bdsOutputSize); std::map buffers_; - ControlInfoMap sensorCtrls_; - ControlInfoMap lensCtrls_; - - IPACameraSensorInfo sensorInfo_; - /* Interface to the Camera Helper */ std::unique_ptr camHelper_; @@ -179,7 +174,6 @@ private: void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) { const IPACameraSensorInfo &sensorInfo = info.sensorInfo; - context_.configuration.sensor.vBlank = sensorInfo.vblank; context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; @@ -202,6 +196,11 @@ void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info) context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); + + /* Store the sensor and lens configuration in the current session. */ + context_.configuration.sensor.info = info.sensorInfo; + context_.configuration.sensor.controls = info.sensorControls; + context_.configuration.lens.controls = info.lensControls; } /** @@ -265,7 +264,7 @@ int IPAIPU3::start() * Set the sensors V4L2 controls before the first frame to ensure that * we have an expected and known configuration from the start. */ - setControls(0); + setControls(0, context_.activeState); return 0; } @@ -387,9 +386,9 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } - sensorInfo_ = configInfo.sensorInfo; - lensCtrls_ = configInfo.lensControls; - sensorCtrls_ = configInfo.sensorControls; + context_.configuration.sensor.controls = configInfo.sensorControls; + context_.configuration.sensor.info = configInfo.sensorInfo; + context_.configuration.lens.controls = configInfo.lensControls; return 0; } @@ -480,35 +479,39 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, return; } - Span mem = it->second.planes()[0]; - const ipu3_uapi_stats_3a *stats = - reinterpret_cast(mem.data()); - + /* + * Update the per-frame context storing the sensor exposure and + * gain for later use by algorithms. + */ IPAFrameContext &frameContext = context_.frameContexts[frame % kMaxFrameContexts]; - if (frameContext.frame != frame) LOG(IPAIPU3, Warning) << "Frame " << frame << " does not match its frame context"; frameContext.sensor.exposure = sensorControls.get(V4L2_CID_EXPOSURE).get(); frameContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get()); - double lineDuration = context_.configuration.sensor.lineDuration.get(); - int32_t vBlank = context_.configuration.sensor.vBlank; - ControlList ctrls(controls::controls); - + /* Run algorithms on the statistics and per-frame context. */ + Span mem = it->second.planes()[0]; + const ipu3_uapi_stats_3a *stats = + reinterpret_cast(mem.data()); for (auto const &algo : algorithms_) algo->process(context_, &frameContext, stats); - setControls(frame); + /* Set sensor controls using the newly computed values. */ + setControls(frame, context_.activeState); - int64_t frameDuration = (vBlank + sensorInfo_.outputSize.height) * lineDuration; - ctrls.set(controls::FrameDuration, frameDuration); + /* Prepare metadata for the frame. */ + const IPASessionConfiguration &ipaConfig = context_.configuration; + const IPACameraSensorInfo &sensorInfo = ipaConfig.sensor.info; + double lineDuration = ipaConfig.sensor.lineDuration.get(); + int64_t frameDuration = (sensorInfo.vblank + sensorInfo.outputSize.height) * lineDuration; - ctrls.set(controls::AnalogueGain, frameContext.sensor.gain); + ControlList metadata(controls::controls); - ctrls.set(controls::ColourTemperature, context_.activeState.awb.temperatureK); - - ctrls.set(controls::ExposureTime, frameContext.sensor.exposure * lineDuration); + metadata.set(controls::FrameDuration, frameDuration); + metadata.set(controls::AnalogueGain, frameContext.sensor.gain); + metadata.set(controls::ColourTemperature, context_.activeState.awb.temperatureK); + metadata.set(controls::ExposureTime, frameContext.sensor.exposure * lineDuration); /* * \todo The Metadata provides a path to getting extended data @@ -518,7 +521,7 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame, * likely want to avoid putting platform specific metadata in. */ - metadataReady.emit(frame, ctrls); + metadataReady.emit(frame, metadata); } /** @@ -538,22 +541,24 @@ void IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls) /** * \brief Handle sensor controls for a given \a frame number * \param[in] frame The frame on which the sensor controls should be set + * \param[in] state The IPA active state which contains the control values as + * computed by the algorithms * * Send the desired sensor control values to the pipeline handler to request * that they are applied on the camera sensor. */ -void IPAIPU3::setControls(unsigned int frame) +void IPAIPU3::setControls(unsigned int frame, const IPAActiveState &state) { - int32_t exposure = context_.activeState.agc.exposure; - int32_t gain = camHelper_->gainCode(context_.activeState.agc.gain); + int32_t exposure = state.agc.exposure; + int32_t gain = camHelper_->gainCode(state.agc.gain); - ControlList ctrls(sensorCtrls_); + ControlList ctrls(controls::controls); ctrls.set(V4L2_CID_EXPOSURE, exposure); ctrls.set(V4L2_CID_ANALOGUE_GAIN, gain); - ControlList lensCtrls(lensCtrls_); + ControlList lensCtrls(controls::controls); lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, - static_cast(context_.activeState.af.focus)); + static_cast(state.af.focus)); setSensorControls.emit(frame, ctrls, lensCtrls); }