From patchwork Thu Dec 5 20:43:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2396 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DD8E060BCA for ; Thu, 5 Dec 2019 21:41:47 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 546E51BF20A; Thu, 5 Dec 2019 20:41:47 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:41 +0100 Message-Id: <20191205204350.28196-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:48 -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 Thu Dec 5 20:43: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: 2397 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 295776136C for ; Thu, 5 Dec 2019 21:41:50 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 610F11BF206; Thu, 5 Dec 2019 20:41:48 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:42 +0100 Message-Id: <20191205204350.28196-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 02/10] libcamera: controls: Parse 'values' 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: Thu, 05 Dec 2019 20:41:50 -0000 In preparation to add libcamera Camera definition by re-using the control generation framework, augment the gen_controls.py script to support parsing the 'values' yaml tag and generate documentation and definition of possible values associated with a Control or a Property. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/gen-controls.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/libcamera/gen-controls.py b/src/libcamera/gen-controls.py index 940386cc68c8..f86f01f6759b 100755 --- a/src/libcamera/gen-controls.py +++ b/src/libcamera/gen-controls.py @@ -17,10 +17,15 @@ def snake_case(s): def generate_cpp(controls): + value_doc_template = string.Template('''/** + * \\def ${name} + * \\brief ${description} */''') + doc_template = string.Template('''/** * \\var extern const Control<${type}> ${name} ${description} */''') + def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");') ctrls_doc = [] @@ -35,13 +40,27 @@ ${description} description[0] = '\\brief ' + description[0] description = '\n'.join([(line and ' * ' or ' *') + line for line in description]) + try: + values = ctrl['values'] + except KeyError: + values = "" + info = { 'name': name, 'type': ctrl['type'], 'description': description, 'id_name': id_name, + 'values' : values, } + for value in values: + value_info = { + 'name': list(value.keys())[0], + 'value': value['value'], + 'description': value['description'] + } + ctrls_doc.append(value_doc_template.substitute(value_info)) + ctrls_doc.append(doc_template.substitute(info)) ctrls_def.append(def_template.substitute(info)) ctrls_map.append('\t{ ' + id_name + ', &' + name + ' },') @@ -54,6 +73,7 @@ ${description} def generate_h(controls): + value_template = string.Template('''#define ${name} ${value}''') template = string.Template('''extern const Control<${type}> ${name};''') ctrls = [] @@ -66,11 +86,25 @@ def generate_h(controls): ids.append('\t' + id_name + ' = ' + str(id_value) + ',') + try: + values = ctrl['values'] + except KeyError: + values = "" + info = { 'name': name, 'type': ctrl['type'], + 'values' : values, } + for value in values: + value_info = { + 'name': list(value.keys())[0], + 'value': value['value'], + 'description': value['description'] + } + ctrls.append(value_template.substitute(value_info)) + ctrls.append(template.substitute(info)) id_value += 1 From patchwork Thu Dec 5 20:43:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2398 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6E90261CD2 for ; Thu, 5 Dec 2019 21:41:51 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id E19F01BF209; Thu, 5 Dec 2019 20:41:50 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:43 +0100 Message-Id: <20191205204350.28196-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:51 -0000 Re-use the Control generation infrastructure to generate libcamera properties. Introduce three additional files, one that enumerates the properties ids (include/libcamera/property_ids.h) and one the defines Control<> instances, one for each property (src/libcamera/property_ids.cpp) and provide properties definitions in src/libcamera/property_ids.yaml 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..6ab5be83bc49 --- /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 + values: + - CAMERA_LOCATION_FRONT: + value: 0 + description: | + The camera is mounted on the front side of the device, facing the + user + - CAMERA_LOCATION_BACK: + value: 1 + description: | + The camera is mounted on the back facing side of the device + - CAMERA_LOCATION_EXTERNAL: + 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 Thu Dec 5 20:43: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: 2399 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 19EB56136A for ; Thu, 5 Dec 2019 21:41:53 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 5FFB21BF207; Thu, 5 Dec 2019 20:41:52 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:44 +0100 Message-Id: <20191205204350.28196-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:53 -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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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 Thu Dec 5 20:43: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: 2400 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D50D261363 for ; Thu, 5 Dec 2019 21:41:53 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 43C601BF207; Thu, 5 Dec 2019 20:41:53 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:45 +0100 Message-Id: <20191205204350.28196-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:54 -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 Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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 Thu Dec 5 20:43: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: 2401 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ABBBC6136C for ; Thu, 5 Dec 2019 21:41:54 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 02F491BF209; Thu, 5 Dec 2019 20:41:53 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:46 +0100 Message-Id: <20191205204350.28196-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:54 -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 Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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..5c7a73ab0c4e 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 = CAMERA_LOCATION_EXTERNAL; + break; + case V4L2_LOCATION_FRONT: + propertyValue = CAMERA_LOCATION_FRONT; + break; + case V4L2_LOCATION_BACK: + propertyValue = CAMERA_LOCATION_BACK; + break; + default: + LOG(CameraSensor, Error) + << "Unsupported camera location: " << v4l2Location; + return -EINVAL; + } + } else { + propertyValue = CAMERA_LOCATION_FRONT; + } + 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 Thu Dec 5 20:43:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2402 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 92DBF60BCA for ; Thu, 5 Dec 2019 21:41:56 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id DE1A91BF207; Thu, 5 Dec 2019 20:41:54 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:47 +0100 Message-Id: <20191205204350.28196-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:56 -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 Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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 Thu Dec 5 20:43:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2403 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BC0CE6136A for ; Thu, 5 Dec 2019 21:41:57 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 2F1841BF205; Thu, 5 Dec 2019 20:41:56 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:48 +0100 Message-Id: <20191205204350.28196-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:58 -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 Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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..5cbee0feeb96 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 Thu Dec 5 20:43:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2404 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D8C460BCA for ; Thu, 5 Dec 2019 21:41:58 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 043EE1BF205; Thu, 5 Dec 2019 20:41:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:49 +0100 Message-Id: <20191205204350.28196-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:58 -0000 Construct two example static metadata to be reported to the Android framework using the properties reported by the Camera. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- 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..e01c7fb2e541 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 CAMERA_LOCATION_FRONT: + lensFacing = ANDROID_LENS_FACING_FRONT; + break; + case CAMERA_LOCATION_BACK: + lensFacing = ANDROID_LENS_FACING_BACK; + break; + case CAMERA_LOCATION_EXTERNAL: + lensFacing = ANDROID_LENS_FACING_EXTERNAL; + break; + } + } staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1); std::vector lensFocalLenghts = { From patchwork Thu Dec 5 20:43:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2405 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 58BCF61363 for ; Thu, 5 Dec 2019 21:41:59 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id DA7671BF205; Thu, 5 Dec 2019 20:41:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Dec 2019 21:43:50 +0100 Message-Id: <20191205204350.28196-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191205204350.28196-1-jacopo@jmondi.org> References: <20191205204350.28196-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Thu, 05 Dec 2019 20:41:59 -0000 Add the '-p'|'--props' option to the cam application to list the properties of a camera. Signed-off-by: Jacopo Mondi --- src/cam/main.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cam/main.h | 1 + 2 files changed, 61 insertions(+) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index a38cca959aca..7e1eb20d6df7 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 the cameras properties", "props"); 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_) { @@ -309,9 +353,25 @@ int CamApp::run() for (const std::shared_ptr &cam : cm_->cameras()) { std::cout << index << ": " << cam->name() << std::endl; index++; + + const ControlList &properties = cam->properties(); + for (const auto &prop : properties) { + auto it = properties::properties.find(prop.first); + if (it == properties::properties.end()) + continue; + + std::cout << it->second->name() << ": " << + prop.second.get() << "\n"; + } } } + 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', };