From patchwork Mon Dec 9 16:34:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2412 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EC1C960BDB for ; Mon, 9 Dec 2019 17:32:40 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 74F981C0003; Mon, 9 Dec 2019 16:32:40 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:37 +0100 Message-Id: <20191209163446.32381-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 01/10] [TEMP] include: linux: Update v4l2-controls.h X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Dec 2019 16:32:41 -0000 Import a temporary version of the v4l2-controls.h with the newly added definition of V4L2_CID_CAMERA_SENSOR_LOCATION control. This patch should be temporary applied waiting for the newly added control to land in the mainline kernel version. Signed-off-by: Jacopo Mondi --- include/linux/v4l2-controls.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h index ef2ee5b796b4..d18a7749d3f1 100644 --- a/include/linux/v4l2-controls.h +++ b/include/linux/v4l2-controls.h @@ -910,6 +910,13 @@ enum v4l2_auto_focus_range { #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) +#define V4L2_CID_CAMERA_SENSOR_LOCATION (V4L2_CID_CAMERA_CLASS_BASE+34) +#define V4L2_LOCATION_FRONT 0 +#define V4L2_LOCATION_BACK 1 +#define V4L2_LOCATION_EXTERNAL 2 + +#define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35) + /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) From patchwork Mon Dec 9 16:34:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2413 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 89BA760BDB for ; Mon, 9 Dec 2019 17:32:41 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 190E41C0012; Mon, 9 Dec 2019 16:32:40 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:38 +0100 Message-Id: <20191209163446.32381-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 02/10] libcamera: controls: Parse 'enum' in gen-controls.py X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Dec 2019 16:32:41 -0000 In preparation to add libcamera Camera properties definitions by re-using the control generation framework, augment the gen_controls.py script to support parsing the 'enum' yaml tag and generate documentation and definition of possible values associated with a Control or a Property and defined through an enumeration of supported values. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/gen-controls.py | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/libcamera/gen-controls.py b/src/libcamera/gen-controls.py index 940386cc68c8..4a1ee52cdb04 100755 --- a/src/libcamera/gen-controls.py +++ b/src/libcamera/gen-controls.py @@ -17,6 +17,10 @@ def snake_case(s): def generate_cpp(controls): + enum_doc_start_template = string.Template('''/** + * \enum ${name}Values\n * Supported ${name} values\n\n''') + enum_doc_value_template = string.Template(''' * \\var ${name}Values::${value} +${description}\n *\n''') doc_template = string.Template('''/** * \\var extern const Control<${type}> ${name} ${description} @@ -42,6 +46,27 @@ ${description} 'id_name': id_name, } + enum_doc = [] + try: + enum = ctrl['enum'] + enum_doc += enum_doc_start_template.substitute(info) + + for value in enum: + enum_description = value['description'].strip('\n').split('\n') + enum_description[0] = '\\brief ' + enum_description[0] + enum_description = '\n'.join([' * ' + line for line in enum_description]) + value_info = { + 'name' : name, + 'value': list(value.keys())[0], + 'description': enum_description, + } + enum_doc += enum_doc_value_template.substitute(value_info) + enum_doc += " */" + enum_doc = ''.join(enum_doc) + ctrls_doc.append(enum_doc) + except KeyError: + pass + ctrls_doc.append(doc_template.substitute(info)) ctrls_def.append(def_template.substitute(info)) ctrls_map.append('\t{ ' + id_name + ', &' + name + ' },') @@ -54,6 +79,8 @@ ${description} def generate_h(controls): + enum_template_start = string.Template('''enum ${name}Values {''') + enum_value_template = string.Template('''\t${name} = ${value},''') template = string.Template('''extern const Control<${type}> ${name};''') ctrls = [] @@ -71,6 +98,20 @@ def generate_h(controls): 'type': ctrl['type'], } + try: + enum = ctrl['enum'] + ctrls.append(enum_template_start.substitute(info)) + + for value in enum: + value_info = { + 'name': list(value.keys())[0], + 'value': value['value'], + } + ctrls.append(enum_value_template.substitute(value_info)) + ctrls.append("};") + except KeyError: + pass + ctrls.append(template.substitute(info)) id_value += 1 From patchwork Mon Dec 9 16:34:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2414 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2AE2161D5A for ; Mon, 9 Dec 2019 17:32:42 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id AC3091C0007; Mon, 9 Dec 2019 16:32:41 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:39 +0100 Message-Id: <20191209163446.32381-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 03/10] libcamera: properties: Generate libcamera 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-List-Received-Date: Mon, 09 Dec 2019 16:32:43 -0000 Re-use the Control generation infrastructure to generate libcamera properties. Introduce three additional files: - include/libcamera/property_ids.h Defines the properties ids - src/libcamera/property_ids.cpp Defines the properties Control<> instances - src/libcamera/property_ids.yaml Provide properties definitions Signed-off-by: Jacopo Mondi --- include/libcamera/meson.build | 26 +++++++++++------ include/libcamera/property_ids.h.in | 33 ++++++++++++++++++++++ src/libcamera/meson.build | 21 ++++++++------ src/libcamera/property_ids.cpp.in | 43 +++++++++++++++++++++++++++++ src/libcamera/property_ids.yaml | 34 +++++++++++++++++++++++ 5 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 include/libcamera/property_ids.h.in create mode 100644 src/libcamera/property_ids.cpp.in create mode 100644 src/libcamera/property_ids.yaml diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 99abf0609940..25f503660960 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -23,15 +23,23 @@ install_headers(libcamera_api, gen_controls = files('../../src/libcamera/gen-controls.py') -control_ids_h = custom_target('control_ids_h', - input : files('../../src/libcamera/control_ids.yaml', 'control_ids.h.in'), - output : 'control_ids.h', - depend_files : gen_controls, - command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@'], - install : true, - install_dir : join_paths('include', include_dir)) - -libcamera_api += control_ids_h +control_source_files = [ + 'control_ids', + 'property_ids', +] + +control_headers = [] + +foreach header : control_source_files + input_files = files('../../src/libcamera/' + header +'.yaml', header + '.h.in') + control_headers += custom_target(header + '_h', + input : input_files, + output : header + '.h', + depend_files : gen_controls, + command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@'], + install : true, + install_dir : join_paths('include', include_dir)) +endforeach gen_header = files('gen-header.sh') diff --git a/include/libcamera/property_ids.h.in b/include/libcamera/property_ids.h.in new file mode 100644 index 000000000000..62799b3e8c54 --- /dev/null +++ b/include/libcamera/property_ids.h.in @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * property_ids.h : Property ID list + * + * This file is auto-generated. Do not edit. + */ + +#ifndef __LIBCAMERA_PROPERTY_IDS_H__ +#define __LIBCAMERA_PROPERTY_IDS_H__ + +#include + +#include + +namespace libcamera { + +namespace properties { + +enum { +${ids} +}; + +${controls} + +extern const ControlIdMap properties; + +} /* namespace propertiess */ + +} /* namespace libcamera */ + +#endif // __LIBCAMERA_PROPERTY_IDS_H__ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index c4f965bd7413..14aff6e5fc13 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -67,14 +67,19 @@ endif gen_controls = files('gen-controls.py') -control_ids_cpp = custom_target('control_ids_cpp', - input : files('control_ids.yaml', 'control_ids.cpp.in'), - output : 'control_ids.cpp', - depend_files : gen_controls, - command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@']) - -libcamera_sources += control_ids_cpp -libcamera_sources += control_ids_h +control_sources = [] + +foreach source : control_source_files + input_files = files(source +'.yaml', source + '.cpp.in') + control_sources += custom_target(source + '_cpp', + input : input_files, + output : source + '.cpp', + depend_files : gen_controls, + command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@']) +endforeach + +libcamera_sources += control_headers +libcamera_sources += control_sources gen_version = join_paths(meson.source_root(), 'utils', 'gen-version.sh') diff --git a/src/libcamera/property_ids.cpp.in b/src/libcamera/property_ids.cpp.in new file mode 100644 index 000000000000..bfdd823f63b0 --- /dev/null +++ b/src/libcamera/property_ids.cpp.in @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * property_ids.cpp : Property ID list + * + * This file is auto-generated. Do not edit. + */ + +#include + +/** + * \file property_ids.h + * \brief Camera property identifiers + */ + +namespace libcamera { + +/** + * \brief Namespace for libcamera properties + */ +namespace properties { + +${controls_doc} + +#ifndef __DOXYGEN__ +/* + * Keep the properties definitions hidden from doxygen as it incorrectly parses + * them as functions. + */ +${controls_def} +#endif + +/** + * \brief List of all supported libcamera properties + */ +extern const ControlIdMap properties { +${controls_map} +}; + +} /* namespace properties */ + +} /* namespace libcamera */ diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml new file mode 100644 index 000000000000..811c300c6b0a --- /dev/null +++ b/src/libcamera/property_ids.yaml @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2019, Google Inc. +# +%YAML 1.2 +--- +controls: + - Location: + type: int32_t + description: | + Camera mounting location + enum: + - CameraLocationFront: + value: 0 + description: | + The camera is mounted on the front side of the device, facing the + user + - CameraLocationBack: + value: 1 + description: | + The camera is mounted on the back facing side of the device + - CameraLocationExternal: + value: 2 + description: | + The camera is attached to the device in a way that allows it to + move freely + + - Rotation: + type: int32_t + description: | + Camera mounting rotation expressed as counterclockwise rotation degrees + towards the axis perpendicular to the sensor surface and directed away + from it +... From patchwork Mon Dec 9 16:34:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2415 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 09CFA61D48 for ; Mon, 9 Dec 2019 17:32:43 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 4DEB81C0007; Mon, 9 Dec 2019 16:32:42 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:40 +0100 Message-Id: <20191209163446.32381-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 04/10] libcamera: controls: Add default to ControlRange X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Dec 2019 16:32:43 -0000 Augment the the ControlRange class to store the control default value. This is particularly relevant for v4l2 controls used to create Camera properties, which are constructed using immutable video device properties, whose value won't change at runtime. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- include/libcamera/controls.h | 5 ++++- src/libcamera/controls.cpp | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index b1b73367e874..458b84e8fa8c 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -114,10 +114,12 @@ class ControlRange { public: explicit ControlRange(const ControlValue &min = 0, - const ControlValue &max = 0); + const ControlValue &max = 0, + const ControlValue &def = 0); const ControlValue &min() const { return min_; } const ControlValue &max() const { return max_; } + const ControlValue &def() const { return def_; } std::string toString() const; @@ -134,6 +136,7 @@ public: private: ControlValue min_; ControlValue max_; + ControlValue def_; }; using ControlIdMap = std::unordered_map; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 7d8a0e97ee3a..1678d3cba4f3 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -353,14 +353,21 @@ Control::Control(unsigned int id, const char *name) * pipeline handlers to describe the controls they support. */ +/** + * \var ControlRange::def_ + * \brief The control default value + */ + /** * \brief Construct a ControlRange with minimum and maximum range parameters * \param[in] min The control minimum value * \param[in] max The control maximum value + * \param[in] def The control default value */ ControlRange::ControlRange(const ControlValue &min, - const ControlValue &max) - : min_(min), max_(max) + const ControlValue &max, + const ControlValue &def) + : min_(min), max_(max), def_(def) { } @@ -376,6 +383,12 @@ ControlRange::ControlRange(const ControlValue &min, * \return A ControlValue with the maximum value for the control */ +/** + * \fn ControlRange::def() + * \brief Retrieve the default value of the control + * \return A ControlValue with the default value for the control + */ + /** * \brief Provide a string representation of the ControlRange */ From patchwork Mon Dec 9 16:34:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2416 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 037EA61D5A for ; Mon, 9 Dec 2019 17:32:44 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 2A9811C000E; Mon, 9 Dec 2019 16:32:43 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:41 +0100 Message-Id: <20191209163446.32381-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 05/10] libcamera: v4l2_controls: Store default 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-List-Received-Date: Mon, 09 Dec 2019 16:32:44 -0000 Store the default value for V4L2 controls as reported by the kernel when creating ControlRange instances using information coming from v4l2_query_ext_ctrl. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/v4l2_controls.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index b6547a7c627c..7446c3880330 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -121,17 +121,20 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) switch (ctrl.type) { case V4L2_CTRL_TYPE_BOOLEAN: ControlRange::operator=(ControlRange(static_cast(ctrl.minimum), - static_cast(ctrl.maximum))); + static_cast(ctrl.maximum), + static_cast(ctrl.default_value))); break; case V4L2_CTRL_TYPE_INTEGER64: ControlRange::operator=(ControlRange(static_cast(ctrl.minimum), - static_cast(ctrl.maximum))); + static_cast(ctrl.maximum), + static_cast(ctrl.default_value))); break; default: ControlRange::operator=(ControlRange(static_cast(ctrl.minimum), - static_cast(ctrl.maximum))); + static_cast(ctrl.maximum), + static_cast(ctrl.default_value))); break; } } From patchwork Mon Dec 9 16:34:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2417 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0A39F60BFE for ; Mon, 9 Dec 2019 17:32:45 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 2A1ED1C0006; Mon, 9 Dec 2019 16:32:43 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:42 +0100 Message-Id: <20191209163446.32381-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 06/10] libcamera: camera_sensor: Parse 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-List-Received-Date: Mon, 09 Dec 2019 16:32:45 -0000 Parse and collect camera sensor properties by inspecting the associated v4l2 controls. Augment the CameraSensor class with an operation to retrieve the collected properties. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 46 ++++++++++++++++++++++++++- src/libcamera/include/camera_sensor.h | 7 ++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 86f0c772861b..bc8b9e78bc42 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include "formats.h" #include "utils.h" #include "v4l2_subdevice.h" @@ -47,7 +49,7 @@ LOG_DEFINE_CATEGORY(CameraSensor); * Once constructed the instance must be initialized with init(). */ CameraSensor::CameraSensor(const MediaEntity *entity) - : entity_(entity) + : entity_(entity), properties_(properties::properties) { subdev_ = new V4L2Subdevice(entity); } @@ -89,6 +91,42 @@ int CameraSensor::init() if (ret < 0) return ret; + /* Retrieve and store the camera sensor properties. */ + const ControlInfoMap &controls = subdev_->controls(); + int32_t propertyValue; + + /* Camera Location: default is front location. */ + const auto &locationControl = controls.find(V4L2_CID_CAMERA_SENSOR_LOCATION); + if (locationControl != controls.end()) { + int32_t v4l2Location = + locationControl->second.def().get(); + switch (v4l2Location) { + case V4L2_LOCATION_EXTERNAL: + propertyValue = properties::CameraLocationExternal; + break; + case V4L2_LOCATION_FRONT: + propertyValue = properties::CameraLocationFront; + break; + case V4L2_LOCATION_BACK: + propertyValue = properties::CameraLocationBack; + break; + default: + LOG(CameraSensor, Error) + << "Unsupported camera location: " << v4l2Location; + return -EINVAL; + } + } else { + propertyValue = properties::CameraLocationFront; + } + properties_.set(properties::Location, propertyValue); + + /* Camera Rotation: default is 0 degrees. */ + propertyValue = 0; + const auto &rotationControl = controls.find(V4L2_CID_CAMERA_SENSOR_ROTATION); + if (rotationControl != controls.end()) + propertyValue = rotationControl->second.def().get(); + properties_.set(properties::Rotation, propertyValue); + /* Enumerate and cache media bus codes and sizes. */ const ImageFormats formats = subdev_->formats(0); if (formats.isEmpty()) { @@ -284,6 +322,12 @@ int CameraSensor::getControls(ControlList *ctrls) return subdev_->getControls(ctrls); } +/** + * \fn CameraSensor::properties() + * \brief Retrieve the camera sensor properties + * \return The list of camera sensor properties + */ + /** * \brief Write controls to the sensor * \param[in] ctrls The list of controls to write diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index 1fb36a4f4951..99cff98128dc 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -10,14 +10,13 @@ #include #include +#include #include #include "log.h" namespace libcamera { -class ControlInfoMap; -class ControlList; class MediaEntity; class V4L2Subdevice; @@ -47,6 +46,8 @@ public: int getControls(ControlList *ctrls); int setControls(ControlList *ctrls); + const ControlList &properties() const { return properties_; } + protected: std::string logPrefix() const; @@ -56,6 +57,8 @@ private: std::vector mbusCodes_; std::vector sizes_; + + ControlList properties_; }; } /* namespace libcamera */ From patchwork Mon Dec 9 16:34:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2418 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 10F4A60BFE for ; Mon, 9 Dec 2019 17:32:46 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 2F4A21C000D; Mon, 9 Dec 2019 16:32:45 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:43 +0100 Message-Id: <20191209163446.32381-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 07/10] libcamera: pipeline_handler: Add 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-List-Received-Date: Mon, 09 Dec 2019 16:32:46 -0000 Associate to each Camera a ControlList which contains the Camera properties as created by pipeline handlers in the pipeline handler's CameraData and provide an operation to retrieve them. Collect properties from the camera sensor in all pipeline handlers that support one (IPU3, RKISP1 and VIMC). Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/include/pipeline_handler.h | 2 ++ src/libcamera/pipeline/ipu3/ipu3.cpp | 3 +++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +++ src/libcamera/pipeline/vimc.cpp | 4 ++++ src/libcamera/pipeline_handler.cpp | 19 +++++++++++++++++++ 5 files changed, 31 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index a02e6e77dc9c..68761cc473c4 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -43,6 +43,7 @@ public: PipelineHandler *pipe_; std::list queuedRequests_; ControlInfoMap controlInfo_; + ControlList properties_; std::unique_ptr ipa_; private: @@ -64,6 +65,7 @@ public: void unlock(); const ControlInfoMap &controls(Camera *camera); + const ControlList &properties(Camera *camera); virtual CameraConfiguration *generateConfiguration(Camera *camera, const StreamRoles &roles) = 0; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 1c5fccf69428..536a63a30018 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -867,6 +867,9 @@ int PipelineHandlerIPU3::registerCameras() if (ret) continue; + /* Initialize the camera properties. */ + data->properties_ = cio2->sensor_->properties(); + /** * \todo Dynamically assign ImgU and output devices to each * stream and camera; as of now, limit support to two cameras diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 4a583a7a1d7e..e9a70755f4c5 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -888,6 +888,9 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) if (ret) return ret; + /* Initialize the camera properties. */ + data->properties_ = data->sensor_->properties(); + ret = data->loadIPA(); if (ret) return ret; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 06664fed42e7..f043cf55889e 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -454,6 +454,10 @@ int VimcCameraData::init(MediaDevice *media) } controlInfo_ = std::move(ctrls); + + /* Initialize the camera properties. */ + properties_ = sensor_->properties(); + return 0; } diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 4349ca8957e4..a023fa1001f5 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -96,6 +96,14 @@ LOG_DEFINE_CATEGORY(Pipeline) * creating the camera, and shall not be modified afterwards. */ +/** + * \var CameraData::properties_ + * \brief The list of properties supported by the camera + * + * The list of camera properties shall be initialised by the pipeline handler + * when creating the camera, and shall not be modified afterwards. + */ + /** * \var CameraData::ipa_ * \brief The IPA module used by the camera @@ -244,6 +252,17 @@ const ControlInfoMap &PipelineHandler::controls(Camera *camera) return data->controlInfo_; } +/** + * \brief Retrieve the list of properties for a camera + * \param[in] camera The camera + * \return A ControlList of properties supported by \a camera + */ +const ControlList &PipelineHandler::properties(Camera *camera) +{ + CameraData *data = cameraData(camera); + return data->properties_; +} + /** * \fn PipelineHandler::generateConfiguration() * \brief Generate a camera configuration for a specified camera From patchwork Mon Dec 9 16:34:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2419 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 14E9E60BFE for ; Mon, 9 Dec 2019 17:32:47 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 32EFA1C000C; Mon, 9 Dec 2019 16:32:46 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:44 +0100 Message-Id: <20191209163446.32381-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 08/10] libcamera: camera: Add 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-List-Received-Date: Mon, 09 Dec 2019 16:32:47 -0000 Add a method to the Camera class to retrieve the Camera properties registered by the pipeline handler. While at it, reword the Camera::controls() operation documentation to specify that the camera control information are constant during the camera lifetime not their value, while the camera properties value are the actually static information. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- include/libcamera/camera.h | 1 + src/libcamera/camera.cpp | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index ef6a37bb142c..72d5d62cc902 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -85,6 +85,7 @@ public: int release(); const ControlInfoMap &controls(); + const ControlList &properties(); const std::set &streams() const; std::unique_ptr generateConfiguration(const StreamRoles &roles); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index e810fb725d81..afc401c65fec 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -551,7 +551,8 @@ int Camera::release() /** * \brief Retrieve the list of controls supported by the camera * - * Camera controls remain constant through the lifetime of the camera. + * The list of controls supported by the camera and their associated + * constraints remain constant through the lifetime of the Camera object. * * \return A ControlInfoMap listing the controls supported by the camera */ @@ -560,6 +561,19 @@ const ControlInfoMap &Camera::controls() return pipe_->controls(this); } +/** + * \brief Retrieve the list of properties of the camera + * + * Camera properties are static information that describe the capabilities of + * the camera. They remain constant through the lifetime of the Camera object. + * + * \return A ControlList of properties supported by the camera + */ +const ControlList &Camera::properties() +{ + return pipe_->properties(this); +} + /** * \brief Retrieve all the camera's stream information * From patchwork Mon Dec 9 16:34:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2420 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DD6B460BFE for ; Mon, 9 Dec 2019 17:32:47 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 3A6231C000D; Mon, 9 Dec 2019 16:32:47 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:45 +0100 Message-Id: <20191209163446.32381-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 09/10] android: camera_device: Use Camera properties for static Metadata X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Dec 2019 16:32:48 -0000 Construct two example static metadata to be reported to the Android framework using the properties reported by the Camera. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 065e0292e186..f434ea2020bd 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -7,6 +7,9 @@ #include "camera_device.h" +#include +#include + #include "log.h" #include "utils.h" @@ -97,6 +100,8 @@ camera_metadata_t *CameraDevice::getStaticMetadata() if (staticMetadata_) return staticMetadata_->get(); + const ControlList &properties = camera_->properties(); + /* * The here reported metadata are enough to implement a basic capture * example application, but a real camera implementation will require @@ -261,9 +266,15 @@ camera_metadata_t *CameraDevice::getStaticMetadata() staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, &exposureTimeRange, 2); + /* + * Android reports orientation as clockwise correction, while libcamera + * uses counter-clockwise. + */ int32_t orientation = 0; - staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, - &orientation, 1); + if (properties.contains(properties::Rotation)) + orientation = (360 - properties.get(properties::Rotation)) + % 360; + staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation, 1); std::vector testPatterModes = { ANDROID_SENSOR_TEST_PATTERN_MODE_OFF, @@ -310,6 +321,20 @@ camera_metadata_t *CameraDevice::getStaticMetadata() lensApertures.size()); uint8_t lensFacing = ANDROID_LENS_FACING_FRONT; + if (properties.contains(properties::Location)) { + int32_t location = properties.get(properties::Location); + switch (location) { + case properties::CameraLocationFront: + lensFacing = ANDROID_LENS_FACING_FRONT; + break; + case properties::CameraLocationBack: + lensFacing = ANDROID_LENS_FACING_BACK; + break; + case properties::CameraLocationExternal: + lensFacing = ANDROID_LENS_FACING_EXTERNAL; + break; + } + } staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1); std::vector lensFocalLenghts = { From patchwork Mon Dec 9 16:34:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2421 Return-Path: Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C97461D5A for ; Mon, 9 Dec 2019 17:32:48 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 0D8611C000E; Mon, 9 Dec 2019 16:32:47 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 9 Dec 2019 17:34:46 +0100 Message-Id: <20191209163446.32381-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191209163446.32381-1-jacopo@jmondi.org> References: <20191209163446.32381-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/10] cam: Add option to list 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-List-Received-Date: Mon, 09 Dec 2019 16:32:48 -0000 Add the '-p'|'--list-properties' option to the cam application to list the properties of a camera. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/cam/main.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cam/main.h | 1 + 2 files changed, 51 insertions(+) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index a38cca959aca..41aedea3ab17 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "capture.h" #include "event_loop.h" @@ -36,6 +37,7 @@ public: private: int parseOptions(int argc, char *argv[]); int prepareConfig(); + int listProperties(); int infoConfiguration(); int run(); @@ -180,6 +182,7 @@ int CamApp::parseOptions(int argc, char *argv[]) parser.addOption(OptInfo, OptionNone, "Display information about stream(s)", "info"); parser.addOption(OptList, OptionNone, "List all cameras", "list"); + parser.addOption(OptProps, OptionNone, "List cameras properties", "list-properties"); options_ = parser.parse(argc, argv); if (!options_.valid()) @@ -268,6 +271,47 @@ int CamApp::prepareConfig() return 0; } +int CamApp::listProperties() +{ + if (!camera_) { + std::cout << "Cannot list properties without a camera" + << std::endl; + return -EINVAL; + } + + const ControlList &properties = camera_->properties(); + for (const auto &prop : properties) { + unsigned int id = prop.first; + const auto &ctrlId = properties::properties.find(id); + const ControlId *ctrl = ctrlId->second; + const ControlValue &value = prop.second; + + std::cout << "Property: " << ctrl->name() << " = "; + + switch (ctrl->type()) { + case ControlTypeBool: { + bool val = value.get(); + std::cout << (val ? "True" : "False") << std::endl; + break; + } + case ControlTypeInteger32: { + int32_t val = value.get(); + std::cout << val << std::endl; + break; + } + case ControlTypeInteger64: { + int64_t val = value.get(); + std::cout << val << std::endl; + break; + } + default: + break; + } + } + + return 0; +} + int CamApp::infoConfiguration() { if (!config_) { @@ -312,6 +356,12 @@ int CamApp::run() } } + if (options_.isSet(OptProps)) { + ret = listProperties(); + if (ret) + return ret; + } + if (options_.isSet(OptInfo)) { ret = infoConfiguration(); if (ret) diff --git a/src/cam/main.h b/src/cam/main.h index 0997476bb335..afcad4353b7d 100644 --- a/src/cam/main.h +++ b/src/cam/main.h @@ -14,6 +14,7 @@ enum { OptHelp = 'h', OptInfo = 'I', OptList = 'l', + OptProps = 'p', OptStream = 's', };