From patchwork Fri Mar 6 15:59:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2973 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CF628627C3 for ; Fri, 6 Mar 2020 17:00:11 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4F510312; Fri, 6 Mar 2020 17:00:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510411; bh=77mglneyalJTHCteM/+9YUWLuxIGGb77FpOhSbG0xQw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aSA/FseUTa0ED1M++KJjHi+krdRfTEPEUIFSFV/UxNsJLuZqRfnRi1UfqiXPLNSmy L9rmYbLaw6z5ZHY++P5dgeOqcob1McwIzAOTn9WZjI4LnlWqJo2QWbI1k08FkrHmF6 5Gx7ir6R/fKtuQf6APAWRwtKyhoKd8XqkKhGXr2E= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:31 +0200 Message-Id: <20200306160002.30549-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 01/32] libcamera: Add a C++20-compliant std::span<> implementation 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: Fri, 06 Mar 2020 16:00:12 -0000 From: Jacopo Mondi C++20 will contain a std::span<> class that provides view over a contiguous sequence of objects, the storage of which is owned by some other object. Add a compatible implementation to the utils namespace. This will be used to implement array controls. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Acked-by: Kieran Bingham --- Changes since v1: - Drop span.cpp --- Documentation/Doxyfile.in | 3 +- include/libcamera/meson.build | 1 + include/libcamera/span.h | 417 ++++++++++++++++++++++++++++++++++ 3 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 include/libcamera/span.h diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index beeaf6d3cf48..d5ba5c4e3b80 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -840,7 +840,8 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = @TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \ +EXCLUDE = @TOP_SRCDIR@/include/libcamera/span.h \ + @TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \ @TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_sysfs.h \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_udev.h \ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index f58c02d2cf35..f47c583cbbc0 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -14,6 +14,7 @@ libcamera_api = files([ 'pixelformats.h', 'request.h', 'signal.h', + 'span.h', 'stream.h', 'timer.h', ]) diff --git a/include/libcamera/span.h b/include/libcamera/span.h new file mode 100644 index 000000000000..513ddb432405 --- /dev/null +++ b/include/libcamera/span.h @@ -0,0 +1,417 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * span.h - C++20 std::span<> implementation for C++11 + */ + +#ifndef __LIBCAMERA_SPAN_H__ +#define __LIBCAMERA_SPAN_H__ + +#include +#include +#include +#include +#include + +namespace libcamera { + +static constexpr std::size_t dynamic_extent = std::numeric_limits::max(); + +template +class Span; + +namespace details { + +template +struct is_array : public std::false_type { +}; + +template +struct is_array> : public std::true_type { +}; + +template +struct is_span : public std::false_type { +}; + +template +struct is_span> : public std::true_type { +}; + +} /* namespace details */ + +namespace utils { + +template +constexpr auto size(const C &c) -> decltype(c.size()) +{ + return c.size(); +} + +template +constexpr auto data(const C &c) -> decltype(c.data()) +{ + return c.data(); +} + +template +constexpr auto data(C &c) -> decltype(c.data()) +{ + return c.data(); +} + +template +constexpr T *data(T (&array)[N]) noexcept +{ + return array; +} + +template +struct tuple_element; + +template +struct tuple_element> { + using type = T; +}; + +template +struct tuple_size; + +template +struct tuple_size> : public std::integral_constant { +}; + +template +struct tuple_size>; + +} /* namespace utils */ + +template +class Span +{ +public: + using element_type = T; + using value_type = typename std::remove_cv_t; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using pointer = T *; + using const_pointer = const T *; + using reference = T &; + using const_reference = const T &; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static constexpr std::size_t extent = Extent; + + template> + constexpr Span() noexcept + : data_(nullptr) + { + } + + constexpr Span(pointer ptr, size_type count) + : data_(ptr) + { + } + + constexpr Span(pointer first, pointer last) + : data_(first) + { + } + + template + constexpr Span(element_type (&arr)[N], + std::enable_if_t (*)[], + element_type (*)[]>::value && + N == Extent, + std::nullptr_t> = nullptr) noexcept + : data_(arr) + { + } + + template + constexpr Span(std::array &arr, + std::enable_if_t (*)[], + element_type (*)[]>::value && + N == Extent, + std::nullptr_t> = nullptr) noexcept + : data_(arr.data()) + { + } + + template + constexpr Span(const std::array &arr, + std::enable_if_t (*)[], + element_type (*)[]>::value && + N == Extent, + std::nullptr_t> = nullptr) noexcept + : data_(arr.data()) + { + } + + template + constexpr Span(Container &cont, + std::enable_if_t::value && + !details::is_array::value && + !std::is_array::value && + std::is_convertible (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) + : data_(utils::data(cont)) + { + } + + template + constexpr Span(const Container &cont, + std::enable_if_t::value && + !details::is_array::value && + !std::is_array::value && + std::is_convertible (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) + : data_(utils::data(cont)) + { + static_assert(utils::size(cont) == Extent, "Size mismatch"); + } + + template + constexpr Span(const Span &s, + std::enable_if_t::value && + N == Extent, + std::nullptr_t> = nullptr) noexcept + : data_(s.data()) + { + } + + constexpr Span(const Span &other) noexcept = default; + + constexpr Span &operator=(const Span &other) noexcept + { + data_ = other.data_; + return *this; + } + + constexpr iterator begin() const { return data(); } + constexpr const_iterator cbegin() const { return begin(); } + constexpr iterator end() const { return data() + size(); } + constexpr const_iterator cend() const { return end(); } + constexpr reverse_iterator rbegin() const { return reverse_iterator(data() + size() - 1); } + constexpr const_reverse_iterator crbegin() const { return rbegin(); } + constexpr reverse_iterator rend() const { return reverse_iterator(data() - 1); } + constexpr const_reverse_iterator crend() const { return rend(); } + + constexpr reference front() const { return *data(); } + constexpr reference back() const { return *(data() + size() - 1); } + constexpr reference operator[](size_type idx) const { return data()[idx]; } + constexpr pointer data() const noexcept { return data_; } + + constexpr size_type size() const noexcept { return Extent; } + constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); } + constexpr bool empty() const noexcept { return size() == 0; } + + template + constexpr Span first() const + { + static_assert(Count <= Extent, "Count larger than size"); + return { data(), Count }; + } + + constexpr Span first(std::size_t Count) const + { + return { data(), Count }; + } + + template + constexpr Span last() const + { + static_assert(Count <= Extent, "Count larger than size"); + return { data() + size() - Count, Count }; + } + + constexpr Span last(std::size_t Count) const + { + return { data() + size() - Count, Count }; + } + + template + constexpr Span subspan() const + { + static_assert(Offset <= Extent, "Offset larger than size"); + static_assert(Count == dynamic_extent || Count + Offset <= Extent, + "Offset + Count larger than size"); + return { data() + Offset, Count == dynamic_extent ? size() - Offset : Count }; + } + + constexpr Span + subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const + { + return { data() + Offset, Count == dynamic_extent ? size() - Offset : Count }; + } + +private: + pointer data_; +}; + +template +class Span +{ +public: + using element_type = T; + using value_type = typename std::remove_cv_t; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using pointer = T *; + using const_pointer = const T *; + using reference = T &; + using const_reference = const T &; + using iterator = T *; + using const_iterator = const T *; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static constexpr std::size_t extent = dynamic_extent; + + constexpr Span() noexcept + : data_(nullptr), size_(0) + { + } + + constexpr Span(pointer ptr, size_type count) + : data_(ptr), size_(count) + { + } + + constexpr Span(pointer first, pointer last) + : data_(first), size_(last - first) + { + } + + template + constexpr Span(element_type (&arr)[N], + std::enable_if_t (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) noexcept + : data_(arr), size_(N) + { + } + + template + constexpr Span(std::array &arr, + std::enable_if_t (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) noexcept + : data_(utils::data(arr)), size_(N) + { + } + + template + constexpr Span(const std::array &arr) noexcept + : data_(utils::data(arr)), size_(N) + { + } + + template + constexpr Span(Container &cont, + std::enable_if_t::value && + !details::is_array::value && + !std::is_array::value && + std::is_convertible (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) + : data_(utils::data(cont)), size_(utils::size(cont)) + { + } + + template + constexpr Span(const Container &cont, + std::enable_if_t::value && + !details::is_array::value && + !std::is_array::value && + std::is_convertible (*)[], + element_type (*)[]>::value, + std::nullptr_t> = nullptr) + : data_(utils::data(cont)), size_(utils::size(cont)) + { + } + + template + constexpr Span(const Span &s, + std::enable_if_t::value, + std::nullptr_t> = nullptr) noexcept + : data_(s.data()), size_(s.size()) + { + } + + constexpr Span(const Span &other) noexcept = default; + + constexpr Span &operator=(const Span &other) noexcept + { + data_ = other.data_; + size_ = other.size_; + return *this; + } + + constexpr iterator begin() const { return data(); } + constexpr const_iterator cbegin() const { return begin(); } + constexpr iterator end() const { return data() + size(); } + constexpr const_iterator cend() const { return end(); } + constexpr reverse_iterator rbegin() const { return reverse_iterator(data() + size() - 1); } + constexpr const_reverse_iterator crbegin() const { return rbegin(); } + constexpr reverse_iterator rend() const { return reverse_iterator(data() - 1); } + constexpr const_reverse_iterator crend() const { return rend(); } + + constexpr reference front() const { return *data(); } + constexpr reference back() const { return *(data() + size() - 1); } + constexpr reference operator[](size_type idx) const { return data()[idx]; } + constexpr pointer data() const noexcept { return data_; } + + constexpr size_type size() const noexcept { return size_; } + constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); } + constexpr bool empty() const noexcept { return size() == 0; } + + template + constexpr Span first() const + { + return { data(), Count }; + } + + constexpr Span first(std::size_t Count) const + { + return { data(), Count }; + } + + template + constexpr Span last() const + { + return { data() + size() - Count, Count }; + } + + constexpr Span last(std::size_t Count) const + { + return { data() + size() - Count, Count }; + } + + template + constexpr Span subspan() const + { + return { data() + Offset, Count == dynamic_extent ? size() - Offset : Count }; + } + + constexpr Span + subspan(std::size_t Offset, std::size_t Count = dynamic_extent) const + { + return { data() + Offset, Count == dynamic_extent ? size() - Offset : Count }; + } + +private: + pointer data_; + size_type size_; +}; + +}; /* namespace libcamera */ + +#endif /* __LIBCAMERA_SPAN_H__ */ From patchwork Fri Mar 6 15:59:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2974 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B836627C3 for ; Fri, 6 Mar 2020 17:00:12 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B7DAE24B for ; Fri, 6 Mar 2020 17:00:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510411; bh=cXCBpWnkjaFxc9D83cak3df0VDZgS7qi/C6fGDl3R9c=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oVrjLPi23SJRozmyruMzy1RxPRaN0SRCFZKi5GUu6QzdI7SiJGlVFszhk7t28w5SF sk92HmhU377JLq2cduTWbNfzu63Xr36QI94w0VvDjPDHiPkGZyVixjuKcw0jDWJ+aK 5g3fs5MovcsP0xPjcv6QaFd9UiNPB6XZzT9jdW4w= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:32 +0200 Message-Id: <20200306160002.30549-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 02/32] test: Add Span test 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: Fri, 06 Mar 2020 16:00:12 -0000 Add a compile-only test that exercises the whole Span API, as template functions are not fully compile-tested when the file is parsed. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Moved the test to the public libcamera tests - Include libcamera/span.h first to ensure the header is self-contained --- test/meson.build | 1 + test/span.cpp | 181 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 test/span.cpp diff --git a/test/meson.build b/test/meson.build index daaa1aac926d..8ab58ac15a2a 100644 --- a/test/meson.build +++ b/test/meson.build @@ -17,6 +17,7 @@ public_tests = [ ['geometry', 'geometry.cpp'], ['list-cameras', 'list-cameras.cpp'], ['signal', 'signal.cpp'], + ['span', 'span.cpp'], ] internal_tests = [ diff --git a/test/span.cpp b/test/span.cpp new file mode 100644 index 000000000000..69f0732e8027 --- /dev/null +++ b/test/span.cpp @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * span.cpp - Span tests + */ + +/* + * Include first to ensure the header is self-contained, as there's no span.cpp + * in libcamera. + */ +#include + +#include +#include +#include + +#include "test.h" + +using namespace std; +using namespace libcamera; + +class SpanTest : public Test +{ +protected: + int run() + { + int i[4]{ 1, 2, 3, 4 }; + std::array a{ 1, 2, 3, 4 }; + const std::array ca{ 1, 2, 3, 4 }; + std::vector v{ 1, 2, 3, 4 }; + const std::vector cv{ 1, 2, 3, 4 }; + + /* + * Compile-test construction and usage of spans with static + * extent. Commented-out tests are expected not to compile, or + * to generate undefined behaviour. + */ + + Span{}; + /* Span{}; */ + + Span{ &i[0], 4 }; + Span{ &i[0], &i[3] }; + + Span{ i }; + /* Span{ i }; */ + /* Span{ i }; */ + + Span{ a }; + Span{ a }; + /* Span{ a }; */ + /* Span{ a }; */ + + Span{ ca }; + /* Span{ ca }; */ + /* Span{ ca }; */ + /* Span{ ca }; */ + + Span{ v }; + Span{ v }; + /* Span{ v }; */ + + Span{ v }; + /* Span{ v }; */ + /* Span{ v }; */ + + Span staticSpan{ i }; + Span{ staticSpan }; + Span{ staticSpan }; + /* Span{ staticSpan }; */ + + staticSpan = Span{ v }; + + staticSpan.begin(); + staticSpan.cbegin(); + staticSpan.end(); + staticSpan.cend(); + staticSpan.rbegin(); + staticSpan.crbegin(); + staticSpan.rend(); + staticSpan.crend(); + + staticSpan.front(); + staticSpan.back(); + staticSpan[0]; + staticSpan.data(); + + staticSpan.size(); + staticSpan.size_bytes(); + + staticSpan.empty(); + + staticSpan.first<2>(); + staticSpan.first(2); + /* staticSpan.first<6>(); */ + /* staticSpan.first(6); */ + staticSpan.last<2>(); + staticSpan.last(2); + /* staticSpan.last<6>(); */ + /* staticSpan.last(6); */ + staticSpan.subspan<1>(); + staticSpan.subspan<1, 2>(); + staticSpan.subspan(1); + staticSpan.subspan(1, 2); + /* staticSpan.subspan(2, 4); */ + + /* + * Compile-test construction and usage of spans with static + * extent. Commented-out tests are expected not to compile, or + * to generate undefined behaviour. + */ + + Span{}; + + Span{ &i[0], 4 }; + Span{ &i[0], &i[3] }; + + Span{ i }; + /* Span{ i }; */ + + Span{ a }; + Span{ a }; + /* Span{ a }; */ + + Span{ ca }; + /* Span{ca}; */ + /* Span{ca}; */ + + Span{ v }; + Span{ v }; + /* Span{ v }; */ + + Span{ v }; + /* Span{ v }; */ + /* Span{ v }; */ + + Span dynamicSpan{ i }; + Span{ dynamicSpan }; + Span{ dynamicSpan }; + + dynamicSpan = Span{ a }; + + dynamicSpan.begin(); + dynamicSpan.cbegin(); + dynamicSpan.end(); + dynamicSpan.cend(); + dynamicSpan.rbegin(); + dynamicSpan.crbegin(); + dynamicSpan.rend(); + dynamicSpan.crend(); + + dynamicSpan.front(); + dynamicSpan.back(); + dynamicSpan[0]; + dynamicSpan.data(); + + dynamicSpan.size(); + dynamicSpan.size_bytes(); + + dynamicSpan.empty(); + + dynamicSpan.first<2>(); + dynamicSpan.first(2); + /* dynamicSpan.first<6>(); */ + /* dynamicSpan.first(6); */ + dynamicSpan.last<2>(); + dynamicSpan.last(2); + /* dynamicSpan.last<6>(); */ + /* dynamicSpan.last(6); */ + dynamicSpan.subspan<1>(); + dynamicSpan.subspan<1, 2>(); + dynamicSpan.subspan(1); + dynamicSpan.subspan(1, 2); + /* dynamicSpan.subspan(2, 4); */ + + return TestPass; + } +}; + +TEST_REGISTER(SpanTest) From patchwork Fri Mar 6 15:59:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2975 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BB45F6285C for ; Fri, 6 Mar 2020 17:00:12 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1B444A48; Fri, 6 Mar 2020 17:00:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510412; bh=ZBHYvBkcVV4MISNlXC1xizfdw9CupPYqZuw++xBl9dM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=isz8UD2HI6vZocTmiOc59CpLKD14S3dOcLbNvNLgCdhusR4gpTpjaTc5SP/FqKv2j 2fkH10YrI1frTP5DNJ4Ld7Vq4q4bX8gahripqLCygnyi5JVTIfaS91kviSM4n037ZG 7G1XVAlCy9k5CpRnN15xDDZal4oTNG9sK788Vt8U= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:33 +0200 Message-Id: <20200306160002.30549-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 03/32] libcamera: gen-controls: Fix documentation issue with << 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: Fri, 06 Mar 2020 16:00:13 -0000 From: Jacopo Mondi Doxygen fails to parse entries with multiple << signs as, in example, \var extern const Control> Remove the type from the control documentation as unique control and property names should not need any additional information specified for Doxygen to correctly identify them. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Commit message updates --- src/libcamera/gen-controls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/gen-controls.py b/src/libcamera/gen-controls.py index 773e9b5d170c..6f020a327827 100755 --- a/src/libcamera/gen-controls.py +++ b/src/libcamera/gen-controls.py @@ -29,7 +29,7 @@ def generate_cpp(controls): enum_doc_value_template = string.Template(''' * \\var ${name}Values::${value} ${description}''') doc_template = string.Template('''/** - * \\var extern const Control<${type}> ${name} + * \\var ${name} ${description} */''') def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");') From patchwork Fri Mar 6 15:59:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2976 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AC366285C for ; Fri, 6 Mar 2020 17:00:13 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B43A61265; Fri, 6 Mar 2020 17:00:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510413; bh=OaP47GfKzwc/o9/d1YeQVQuGEMYh5zgzJkooIYzWXMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jCRxTqjBs60Wd03Pv0wJuy1+iCPBb8uLP/fPvBVdzPe2Zb4d/74S0pm/9el+kP5c6 YCJDURAnLQvbIgkuTQWKAVLEFfqL77rD7hPE1+k2JuNjdCtzloQXfJV1pRMt3AGO84 9T9hciDe4tHgjwJANhf1nLBcTp8/WHuysKIkwOAs= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:34 +0200 Message-Id: <20200306160002.30549-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 04/32] libcamera: ipa: Remove unused IPA control types 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: Fri, 06 Mar 2020 16:00:13 -0000 From: Jacopo Mondi The ipa_control_range_data structure is only used to document the IPA control serialization format, but isn't used in code at all as the ControlRange entries are directly serialized to a byte stream buffer. This applies to the ipa_control_value_data structure that is solely used by ipa_control_range_data. Expand the documentation of the IPA control serialization format to describe the layout of the control range data in words and diagrams instead of through a C structure. Remove the unused structures as a result. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/ipa/ipa_controls.h | 11 ---------- src/libcamera/ipa_controls.cpp | 38 ++++++++++++++-------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/include/ipa/ipa_controls.h b/include/ipa/ipa_controls.h index de3a017b0179..426d99689de2 100644 --- a/include/ipa/ipa_controls.h +++ b/include/ipa/ipa_controls.h @@ -36,17 +36,6 @@ struct ipa_control_range_entry { uint32_t padding[1]; }; -union ipa_control_value_data { - bool b; - int32_t i32; - int64_t i64; -}; - -struct ipa_control_range_data { - union ipa_control_value_data min; - union ipa_control_value_data max; -}; - #ifdef __cplusplus } #endif diff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp index ed12830c0d9e..6ea71bc6dc46 100644 --- a/src/libcamera/ipa_controls.cpp +++ b/src/libcamera/ipa_controls.cpp @@ -100,8 +100,22 @@ * * Entries are described by the ipa_control_range_entry structure. They contain * the numerical ID and type of the control. The control range data is stored - * in the data section as described by the ipa_control_range_data structure. - * The ipa_control_range_entry::offset field stores the offset from the + * in the data section as described by the following diagram. + * + * ~~~~ + * +-------------------------+ . + * / | ... | | entry[n].offset + * | +-------------------------+ <-----´ + * Data | | minimum value (#n) | \ + * section | +-------------------------+ | Entry #n + * | | maximum value (#n) | / + * | +-------------------------+ + * \ | ... | + * +-------------------------+ + * ~~~~ + * + * The minimum and maximum value are stored in the platform's native data + * format. The ipa_control_range_entry::offset field stores the offset from the * beginning of the data section to the range data. * * Range data in the data section shall be stored in the same order as the @@ -164,23 +178,3 @@ * \var ipa_control_range_entry::padding * Padding bytes (shall be set to 0) */ - -/** - * \union ipa_control_value_data - * \brief Serialized control value - * \var ipa_control_value_data::b - * Value for ControlTypeBool controls - * \var ipa_control_value_data::i32 - * Value for ControlTypeInteger32 controls - * \var ipa_control_value_data::i64 - * Value for ControlTypeInteger64 controls - */ - -/** - * \struct ipa_control_range_data - * \brief Serialized control range - * \var ipa_control_range_data::min - * The control minimum value - * \var ipa_control_range_data::max - * The control maximum value - */ From patchwork Fri Mar 6 15:59:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2977 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5763C6285C for ; Fri, 6 Mar 2020 17:00:14 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 795C324B for ; Fri, 6 Mar 2020 17:00:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510414; bh=cGJtiCPY/NxjiYSDGQN7Hj7nZeMJhi0ZJ8DWpEHJ7FQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fHjVJOzkGqvnkxkZ1yy2xX+LBTfCTF1EjjVDOtVwDoa1n+GjL8NFjQHlUuW5DMP65 9i7nSJlpVWkh0S8l9kPNoQxRkBsLwbeZuueJSO73pbduTs4jFXLWyS6HUv2l0OQpgu yvwYdlM7kWTHXGz/NFTy8ydbfjtxIIyi/SSGj+VY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:35 +0200 Message-Id: <20200306160002.30549-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 05/32] libcamera: ipa: Make self-contained 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: Fri, 06 Mar 2020 16:00:14 -0000 The header makes use of uint*_t types, but doesn't include stdint.h. Fix it, and include ipa_controls.h in ipa_controls.cpp to test compilation of the header on its own. While at it, fix the comment as the top of ipa_controls.cpp to refer to the correct file name. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/ipa/ipa_controls.h | 2 ++ src/libcamera/ipa_controls.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/ipa/ipa_controls.h b/include/ipa/ipa_controls.h index 426d99689de2..6371e34575f2 100644 --- a/include/ipa/ipa_controls.h +++ b/include/ipa/ipa_controls.h @@ -7,6 +7,8 @@ #ifndef __LIBCAMERA_IPA_CONTROLS_H__ #define __LIBCAMERA_IPA_CONTROLS_H__ +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp index 6ea71bc6dc46..dd3ff9a0d467 100644 --- a/src/libcamera/ipa_controls.cpp +++ b/src/libcamera/ipa_controls.cpp @@ -2,9 +2,11 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_controls.h - IPA control handling + * ipa_controls.cpp - IPA control handling */ +#include + /** * \file ipa_controls.h * \brief Type definitions for serialized controls From patchwork Fri Mar 6 15:59:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2978 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3DA80628A3 for ; Fri, 6 Mar 2020 17:00:15 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 69B0E24B for ; Fri, 6 Mar 2020 17:00:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510415; bh=6z9O1P228TqINXmjb5t/D9+EjZTQnJiyk7M5/TTfogk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZiQrlJomtDyAY2T5Jkgc/FoTVi3aPJxrrCCdvcy2b/3O1/Kh5cd+adZV1TINy+Ax4 hXQreUMlgvOdNoYDQcbShREoMhgrNYL6I9HtUdwaywxQCpfZezgbvx2Bkn0D9NzBEu kRm2Po4h22kuD5l4xW+YdTR4cOJb6/YWNCabP404= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:36 +0200 Message-Id: <20200306160002.30549-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 06/32] libcamera: ipa: Test control structure size with static_assert 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: Fri, 06 Mar 2020 16:00:16 -0000 The control-related structures ipa_controls_header, ipa_control_value_entry and ipa_control_range_entry define the IPA protocol and are thus part of the ABI. To avoid breaking it inadvertently, use static_assert() to check the size of the structures. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Improve wording of static_assert() message --- src/libcamera/ipa_controls.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp index dd3ff9a0d467..fc5ccd4210b2 100644 --- a/src/libcamera/ipa_controls.cpp +++ b/src/libcamera/ipa_controls.cpp @@ -153,6 +153,9 @@ * Reserved for future extensions */ +static_assert(sizeof(ipa_controls_header) == 32, + "Invalid ABI size change for struct ipa_control_header"); + /** * \struct ipa_control_value_entry * \brief Description of a serialized ControlValue entry @@ -167,6 +170,9 @@ * value data (shall be a multiple of 8 bytes). */ +static_assert(sizeof(ipa_control_value_entry) == 16, + "Invalid ABI size change for struct ipa_control_value_entry"); + /** * \struct ipa_control_range_entry * \brief Description of a serialized ControlRange entry @@ -180,3 +186,6 @@ * \var ipa_control_range_entry::padding * Padding bytes (shall be set to 0) */ + +static_assert(sizeof(ipa_control_range_entry) == 16, + "Invalid ABI size change for struct ipa_control_range_entry"); From patchwork Fri Mar 6 15:59:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2979 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 97F9E60424 for ; Fri, 6 Mar 2020 17:00:16 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7193224B; Fri, 6 Mar 2020 17:00:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510416; bh=iy4JGQCx0rlLCHuusEvC2m0rR877q4nzbFbBRZOjQJI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qhhYYSH3Z99G3qZM9ieo5en++v8d0RDp+6gfJmEGu86tL5Nb7/uDccciq6sT5zrB5 FgzmmEWZGcl4YsgxRN2KFRPxUwUG06TW3SW3Mc2i/os4DPQt5DWuN9clmlE/bhli7w huFeDHwpCiPJvMvgK7sZ6Zv5eeehtXY94EvX9NS4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:37 +0200 Message-Id: <20200306160002.30549-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 07/32] libcamera: controls: Reorder ControlValue methods 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: Fri, 06 Mar 2020 16:00:17 -0000 From: Jacopo Mondi Reorder functions in ControlValue class to group const methods together. Cosmetic change only. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 10 ++-- src/libcamera/controls.cpp | 94 ++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 458b84e8fa8c..9f8a9031bd74 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -33,11 +33,6 @@ public: ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } - template - const T &get() const; - template - void set(const T &value); - std::string toString() const; bool operator==(const ControlValue &other) const; @@ -46,6 +41,11 @@ public: return !(*this == other); } + template + const T &get() const; + template + void set(const T &value); + private: ControlType type_; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 0031cd064da9..613e6d768c0f 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -112,6 +112,53 @@ ControlValue::ControlValue(int64_t value) * \return True if the value type is ControlTypeNone, false otherwise */ +/** + * \brief Assemble and return a string describing the value + * \return A string describing the ControlValue + */ +std::string ControlValue::toString() const +{ + switch (type_) { + case ControlTypeNone: + return ""; + case ControlTypeBool: + return bool_ ? "True" : "False"; + case ControlTypeInteger32: + return std::to_string(integer32_); + case ControlTypeInteger64: + return std::to_string(integer64_); + } + + return ""; +} + +/** + * \brief Compare ControlValue instances for equality + * \return True if the values have identical types and values, false otherwise + */ +bool ControlValue::operator==(const ControlValue &other) const +{ + if (type_ != other.type_) + return false; + + switch (type_) { + case ControlTypeBool: + return bool_ == other.bool_; + case ControlTypeInteger32: + return integer32_ == other.integer32_; + case ControlTypeInteger64: + return integer64_ == other.integer64_; + default: + return false; + } +} + +/** + * \fn bool ControlValue::operator!=() + * \brief Compare ControlValue instances for non equality + * \return False if the values have identical types and values, true otherwise + */ + /** * \fn template const T &ControlValue::get() const * \brief Get the control value @@ -175,53 +222,6 @@ void ControlValue::set(const int64_t &value) } #endif /* __DOXYGEN__ */ -/** - * \brief Assemble and return a string describing the value - * \return A string describing the ControlValue - */ -std::string ControlValue::toString() const -{ - switch (type_) { - case ControlTypeNone: - return ""; - case ControlTypeBool: - return bool_ ? "True" : "False"; - case ControlTypeInteger32: - return std::to_string(integer32_); - case ControlTypeInteger64: - return std::to_string(integer64_); - } - - return ""; -} - -/** - * \brief Compare ControlValue instances for equality - * \return True if the values have identical types and values, false otherwise - */ -bool ControlValue::operator==(const ControlValue &other) const -{ - if (type_ != other.type_) - return false; - - switch (type_) { - case ControlTypeBool: - return bool_ == other.bool_; - case ControlTypeInteger32: - return integer32_ == other.integer32_; - case ControlTypeInteger64: - return integer64_ == other.integer64_; - default: - return false; - } -} - -/** - * \fn bool ControlValue::operator!=() - * \brief Compare ControlValue instances for non equality - * \return False if the values have identical types and values, true otherwise - */ - /** * \class ControlId * \brief Control static metadata From patchwork Fri Mar 6 15:59:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2980 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8564460424 for ; Fri, 6 Mar 2020 17:00:17 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A972D1265 for ; Fri, 6 Mar 2020 17:00:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510417; bh=pPpRtPzwTtWPqbAc8jW+/g6UiGXbaLBzXNluwdBV0KA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=n2QPOjJ/6XDaQT4dPXmgQEGP4Fvn6hf5S/gEkgMRkI/mvoRikuh7fH/S+7nHKfuqk z4t29aoPOnNHKVs3ASqFTswpxgvOjM1JSIDUR+HRrCV8NXM43vmPeHzI+LkjyciBBV MOXFA9mSOEn6GYrVfU82r5zylIdS99PPjElRIYaA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:38 +0200 Message-Id: <20200306160002.30549-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 08/32] libcamera: controls: Don't convert 32-bit and 64-bit implicitly 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: Fri, 06 Mar 2020 16:00:17 -0000 The ControlValue::get() method verifies that the T type corresponds to the ControlValue type. It however accepts int32_t as a return type for 64-bit integer controls, and int64_t as a return type for 32-bit integer controls. There's no reason to do so anymore, make the type check stricter. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/libcamera/controls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 613e6d768c0f..f632d60adc8b 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -187,7 +187,7 @@ const bool &ControlValue::get() const template<> const int32_t &ControlValue::get() const { - ASSERT(type_ == ControlTypeInteger32 || type_ == ControlTypeInteger64); + ASSERT(type_ == ControlTypeInteger32); return integer32_; } @@ -195,7 +195,7 @@ const int32_t &ControlValue::get() const template<> const int64_t &ControlValue::get() const { - ASSERT(type_ == ControlTypeInteger32 || type_ == ControlTypeInteger64); + ASSERT(type_ == ControlTypeInteger64); return integer64_; } From patchwork Fri Mar 6 15:59:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2981 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8F06C60424 for ; Fri, 6 Mar 2020 17:00:18 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AFB0624B for ; Fri, 6 Mar 2020 17:00:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510418; bh=FTYoyyw6XbuflBPuc7JX9YO3bSbZWDYwK1KMbQv0tCc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YAWw448UfU14MhttH6RyIe3YsPy5EjuU4hpc0FEl0i8nw3xRTo0Jueu7znNcH1k3r nhSkEMEJDk1XXER3GAq4fKC2a/AtjRWWn1edphKIoFnnzHfuapZeZNwNzsmIn5BDW8 57dWWqA876Okk0QOQQ0IK/Sg8lh3KGsQcGLWbaU4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:39 +0200 Message-Id: <20200306160002.30549-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 09/32] libcamera: controls: Decouple control and value type in ControlList::set() 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: Fri, 06 Mar 2020 16:00:18 -0000 The ControlList::set() method takes a reference to a Control, and requires the value to be a reference to T. This prevents the set() method from being used with value types that are convertible to T, and in particular with std::array or std::vector value types when the Control type is a Span<> to support array controls. Fix this by decoupling the control type and value type in the template parameters. The compiler will still catch invalid conversions, including cases where the constructor of type T from the value type is explicit. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 4 ++-- src/libcamera/controls.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 9f8a9031bd74..9d93064c11b2 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -223,8 +223,8 @@ public: return val->get(); } - template - void set(const Control &ctrl, const T &value) + template + void set(const Control &ctrl, const V &value) { ControlValue *val = find(ctrl.id()); if (!val) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index f632d60adc8b..a136ebd2653b 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -735,7 +735,7 @@ bool ControlList::contains(unsigned int id) const */ /** - * \fn template void ControlList::set(const Control &ctrl, const T &value) + * \fn template void ControlList::set(const Control &ctrl, const V &value) * \brief Set the control \a ctrl value to \a value * \param[in] ctrl The control * \param[in] value The control value From patchwork Fri Mar 6 15:59:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2982 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2C4E360424 for ; Fri, 6 Mar 2020 17:00:19 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B6CA01265 for ; Fri, 6 Mar 2020 17:00:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510418; bh=nEdJ49LSrpFJqAxFCHbW0A2W1vUawQAGfPF7GPyRiTw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=hPfxcm+xOo1zYT1bzdlilmF7oQFaSIeBB31tz3FCc+AnKWSTeuPIOJLGfBvBrSiEV HaB4D7Eulb/TuR7zhdx8nlApxbwFjyokIlaICRxgEAjPSzOlzE88n6WSIYS7KTb+mc dyZXtISP7mXZm5EX0roHLW+OMWNMm8nrO/mq4O2Q= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:40 +0200 Message-Id: <20200306160002.30549-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 10/32] libcamera: controls: Return control by 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: Fri, 06 Mar 2020 16:00:19 -0000 The ControlList::get() and ControlValue::get() methods return the control value by reference. This requires the ControlValue class to store the control value in the same form as the one returned by those functions. For the array controls that are soon to be added, the ControlValue class would need to store a span<> instance in addition to the control value itself, which would increase the required storage space. Prepare for support of array controls by returning from get() by value. As all control values are 8 bytes at most, this doesn't affect efficiency negatively. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 10 ++++------ src/libcamera/controls.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 9d93064c11b2..3b6b231c7c64 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -42,7 +42,7 @@ public: } template - const T &get() const; + T get() const; template void set(const T &value); @@ -212,13 +212,11 @@ public: bool contains(unsigned int id) const; template - const T &get(const Control &ctrl) const + T get(const Control &ctrl) const { const ControlValue *val = find(ctrl.id()); - if (!val) { - static T t(0); - return t; - } + if (!val) + return T{}; return val->get(); } diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index a136ebd2653b..6a0d66fbea8d 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -160,7 +160,7 @@ bool ControlValue::operator==(const ControlValue &other) const */ /** - * \fn template const T &ControlValue::get() const + * \fn template T ControlValue::get() const * \brief Get the control value * * The control value type shall match the type T, otherwise the behaviour is @@ -177,7 +177,7 @@ bool ControlValue::operator==(const ControlValue &other) const #ifndef __DOXYGEN__ template<> -const bool &ControlValue::get() const +bool ControlValue::get() const { ASSERT(type_ == ControlTypeBool); @@ -185,7 +185,7 @@ const bool &ControlValue::get() const } template<> -const int32_t &ControlValue::get() const +int32_t ControlValue::get() const { ASSERT(type_ == ControlTypeInteger32); @@ -193,7 +193,7 @@ const int32_t &ControlValue::get() const } template<> -const int64_t &ControlValue::get() const +int64_t ControlValue::get() const { ASSERT(type_ == ControlTypeInteger64); @@ -720,7 +720,7 @@ bool ControlList::contains(unsigned int id) const } /** - * \fn template const T &ControlList::get(const Control &ctrl) const + * \fn template T ControlList::get(const Control &ctrl) const * \brief Get the value of control \a ctrl * \param[in] ctrl The control * From patchwork Fri Mar 6 15:59:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2983 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7962660424 for ; Fri, 6 Mar 2020 17:00:19 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 14AA4312 for ; Fri, 6 Mar 2020 17:00:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510419; bh=FvMt2CDuxrLWByRMlcZXr0SNLQKHSQmpEe1tzjAjsGc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=acw2Iza1G5QhJ8Ddu0df89CRTxxJZC9+YtHyqg865WkumD7eEYVsQfyWvAIaI1iEn 1BJa/UxDBE91skSEBkk2fyeNDF6HRw2OTM74D+wQKXlNTuIDQG560XB2lC6lkf2ath k6RhJqT1dfbognXBlVnenB9eRfzd337/i5AHJCy8= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:41 +0200 Message-Id: <20200306160002.30549-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 11/32] libcamera: controls: Add templates to convert a type T to a ControlType 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: Fri, 06 Mar 2020 16:00:19 -0000 These will be used to implement ControlValue::get() and set() as template functions. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Documentation/Doxyfile.in | 2 +- include/libcamera/controls.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index d5ba5c4e3b80..3dffbf823398 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -881,7 +881,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \ libcamera::BoundMethodStatic \ libcamera::SignalBase \ libcamera::*::Private \ - libcamera::*::details::* \ + *::details::* \ std::* # The EXAMPLE_PATH tag can be used to specify one or more files or directories diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 3b6b231c7c64..429f01b0fd24 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -22,6 +22,34 @@ enum ControlType { ControlTypeInteger64, }; +namespace details { + +template +struct control_type { +}; + +template<> +struct control_type { + static constexpr ControlType value = ControlTypeNone; +}; + +template<> +struct control_type { + static constexpr ControlType value = ControlTypeBool; +}; + +template<> +struct control_type { + static constexpr ControlType value = ControlTypeInteger32; +}; + +template<> +struct control_type { + static constexpr ControlType value = ControlTypeInteger64; +}; + +} /* namespace details */ + class ControlValue { public: From patchwork Fri Mar 6 15:59:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2985 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 84302628D6 for ; Fri, 6 Mar 2020 17:00:20 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 68BEC24B for ; Fri, 6 Mar 2020 17:00:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510419; bh=kKXSORO7rK9owRXcTQZzLu5E7hy1IhLtxIObOgL0EBE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DSiwMBBbJ2r50X7XprlYYOGJGIZ1QKzhHRVdHrvUKfsfIZ7BfUMozqyTqTSd8ch71 Qf64CMVXI50GylAqbTZlSnSGkfH+LULdDGk1BwoQImV7vdD74qJxwA9HHbzHC9BIfN JFHuGv4H/7u23vOZwdt6nmCjjmFCEVLjv+Nf+QI4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:42 +0200 Message-Id: <20200306160002.30549-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 12/32] libcamera: controls: Move ControlValue get() and set() to 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: Fri, 06 Mar 2020 16:00:21 -0000 To avoid defining all specializations of ControlValue::get() and ControlValue::set() manually, move the definition of those functions to controls.h and turn them into single template functions. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 15 ++++++++++-- src/libcamera/controls.cpp | 47 ------------------------------------ 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 429f01b0fd24..39e240438861 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -8,6 +8,7 @@ #ifndef __LIBCAMERA_CONTROLS_H__ #define __LIBCAMERA_CONTROLS_H__ +#include #include #include @@ -70,9 +71,19 @@ public: } template - T get() const; + T get() const + { + assert(type_ == details::control_type>::value); + + return *reinterpret_cast(&bool_); + } + template - void set(const T &value); + void set(const T &value) + { + type_ = details::control_type>::value; + *reinterpret_cast(&bool_) = value; + } private: ControlType type_; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 6a0d66fbea8d..f3d79785e6a8 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -175,53 +175,6 @@ bool ControlValue::operator==(const ControlValue &other) const * \param[in] value The control value */ -#ifndef __DOXYGEN__ -template<> -bool ControlValue::get() const -{ - ASSERT(type_ == ControlTypeBool); - - return bool_; -} - -template<> -int32_t ControlValue::get() const -{ - ASSERT(type_ == ControlTypeInteger32); - - return integer32_; -} - -template<> -int64_t ControlValue::get() const -{ - ASSERT(type_ == ControlTypeInteger64); - - return integer64_; -} - -template<> -void ControlValue::set(const bool &value) -{ - type_ = ControlTypeBool; - bool_ = value; -} - -template<> -void ControlValue::set(const int32_t &value) -{ - type_ = ControlTypeInteger32; - integer32_ = value; -} - -template<> -void ControlValue::set(const int64_t &value) -{ - type_ = ControlTypeInteger64; - integer64_ = value; -} -#endif /* __DOXYGEN__ */ - /** * \class ControlId * \brief Control static metadata From patchwork Fri Mar 6 15:59:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2984 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DF146627C3 for ; Fri, 6 Mar 2020 17:00:20 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 77573312 for ; Fri, 6 Mar 2020 17:00:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510420; bh=DsTpPs4eXqU2lxxJeXEvAe1oDTBrGAdfoK9opzfPu6k=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tfrbjH3tOa07d19gfu+mTXesZ2DDw14MMNH5mqc3NwTSJLvmzcoJXj7raCD8RM9xa Dh0bqKQ6yHAQFbIE5i2s+6lADSxZvkrDszIK9AbyoAfnKwe4FqS5vZ4C/wzgXfyjwa 5ZX8UpWB0i1+8cXGa6jzjwUPIMKchVUQ7xSSGDaU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:43 +0200 Message-Id: <20200306160002.30549-14-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 13/32] libcamera: controls: Move ControlValue constructor to 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: Fri, 06 Mar 2020 16:00:21 -0000 To avoid defining all specializations of the ControlValue constructor manually, move the definition of those functions to controls.h and turn them into a single template function. The default constructor is still kept in controls.cpp. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 10 +++++++--- src/libcamera/controls.cpp | 27 +++------------------------ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 39e240438861..dfe69916cd64 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -55,9 +55,13 @@ class ControlValue { public: ControlValue(); - ControlValue(bool value); - ControlValue(int32_t value); - ControlValue(int64_t value); + + template + ControlValue(T value) + : type_(details::control_type>::value) + { + *reinterpret_cast(&bool_) = value; + } ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index f3d79785e6a8..5cc8ce2199d0 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -74,31 +74,10 @@ ControlValue::ControlValue() } /** - * \brief Construct a Boolean ControlValue - * \param[in] value Boolean value to store + * \fn template T ControlValue::ControlValue(T value) + * \brief Construct a ControlValue of type T + * \param[in] value Initial value */ -ControlValue::ControlValue(bool value) - : type_(ControlTypeBool), bool_(value) -{ -} - -/** - * \brief Construct an integer ControlValue - * \param[in] value Integer value to store - */ -ControlValue::ControlValue(int32_t value) - : type_(ControlTypeInteger32), integer32_(value) -{ -} - -/** - * \brief Construct a 64 bit integer ControlValue - * \param[in] value Integer value to store - */ -ControlValue::ControlValue(int64_t value) - : type_(ControlTypeInteger64), integer64_(value) -{ -} /** * \fn ControlValue::type() From patchwork Fri Mar 6 15:59:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2986 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53DC460424 for ; Fri, 6 Mar 2020 17:00:21 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E3A7E1265 for ; Fri, 6 Mar 2020 17:00:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510421; bh=ZlztJ5jHqC8Ob6WTYkXDBjBUwm3pr78ZBGAobchiMNs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dDXtDkxFVoox3rLyU6cwyjI3ptXtJw7Id0P/VhSVJgoKIV8BzwkzqQ0E3zI+2gxn1 fzsqfysv+F1cGMBHrVHUt9E1Mj/fZgzX7uXzc8ztSFA5XKN91F1qnE97YmHHeHrD5U goUIbG3+qioiDwvrvb7WYOX7ARoVQIRj85R0uPec= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:44 +0200 Message-Id: <20200306160002.30549-15-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 14/32] libcamera: controls: Move Control constructor to 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: Fri, 06 Mar 2020 16:00:21 -0000 To avoid defining all specializations of the Control constructor manually, move the definition of those functions to controls.h and turn them into a single template function. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 5 ++++- src/libcamera/controls.cpp | 26 -------------------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index dfe69916cd64..6f0ebf4f3ca5 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -146,7 +146,10 @@ class Control : public ControlId public: using type = T; - Control(unsigned int id, const char *name); + Control(unsigned int id, const char *name) + : ControlId(id, name, details::control_type>::value) + { + } private: Control(const Control &) = delete; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 5cc8ce2199d0..76230a052de1 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -249,32 +249,6 @@ bool ControlValue::operator==(const ControlValue &other) const * \brief The Control template type T */ -#ifndef __DOXYGEN__ -template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeNone) -{ -} - -template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeBool) -{ -} - -template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeInteger32) -{ -} - -template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeInteger64) -{ -} -#endif /* __DOXYGEN__ */ - /** * \class ControlRange * \brief Describe the limits of valid values for a Control From patchwork Fri Mar 6 15:59:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2987 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AFCC062895 for ; Fri, 6 Mar 2020 17:00:21 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4425124B for ; Fri, 6 Mar 2020 17:00:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510421; bh=xuFLzSoAs18VYq/y7PMVI17NmDrjR3rfdzUMuJ2YT1M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=vMWl2LoTnx/gEBj66K/z66jTy5mZ8Vr7aLPohvMGsYX4t0OXuFOzkKFPBVwGq+vXi XuKGFoDlt+OJikp7awh39IADuv5lcUbjmFa/G15TaKy+HxK8mq3scKC7cCIbscuhnb eiB+6A2TKZJ7py2g6LyKBtdnmL0duG/7FyejbyQQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:45 +0200 Message-Id: <20200306160002.30549-16-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 15/32] libcamera: controls: Expose raw data in ControlValue 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: Fri, 06 Mar 2020 16:00:22 -0000 Add a data() function to the ControlValue class to expose the raw data stored by the class as a Span. This will be useful to simplify the serialization of ControlValue instances. The size computation for the raw data is moved from the ControlSerializer, which is updated accordingly to use the data() function in order to access the size. Simplification of the ControlSerializer will happen in a subsequent change. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Fix documentation of the data() function --- include/libcamera/controls.h | 3 +++ src/libcamera/control_serializer.cpp | 13 +------------ src/libcamera/controls.cpp | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 6f0ebf4f3ca5..4538be06af93 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -12,6 +12,8 @@ #include #include +#include + namespace libcamera { class ControlValidator; @@ -65,6 +67,7 @@ public: ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } + Span data() const; std::string toString() const; diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 803ac16c2456..2b66ab978f81 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -27,17 +27,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(Serializer) -namespace { - -static constexpr size_t ControlValueSize[] = { - [ControlTypeNone] = 1, - [ControlTypeBool] = sizeof(bool), - [ControlTypeInteger32] = sizeof(int32_t), - [ControlTypeInteger64] = sizeof(int64_t), -}; - -} /* namespace */ - /** * \class ControlSerializer * \brief Serializer and deserializer for control-related classes @@ -106,7 +95,7 @@ void ControlSerializer::reset() size_t ControlSerializer::binarySize(const ControlValue &value) { - return ControlValueSize[value.type()]; + return value.data().size_bytes(); } size_t ControlSerializer::binarySize(const ControlRange &range) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 76230a052de1..e513188010e2 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -47,6 +47,17 @@ namespace libcamera { LOG_DEFINE_CATEGORY(Controls) +namespace { + +static constexpr size_t ControlValueSize[] = { + [ControlTypeNone] = 1, + [ControlTypeBool] = sizeof(bool), + [ControlTypeInteger32] = sizeof(int32_t), + [ControlTypeInteger64] = sizeof(int64_t), +}; + +} /* namespace */ + /** * \enum ControlType * \brief Define the data type of a Control @@ -91,6 +102,18 @@ ControlValue::ControlValue() * \return True if the value type is ControlTypeNone, false otherwise */ +/** + * \brief Retrieve the raw data of a control value + * \return The raw data of the control value as a span of uint8_t + */ +Span ControlValue::data() const +{ + return { + reinterpret_cast(&bool_), + ControlValueSize[type_] + }; +} + /** * \brief Assemble and return a string describing the value * \return A string describing the ControlValue From patchwork Fri Mar 6 15:59:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2988 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2277D628B9 for ; Fri, 6 Mar 2020 17:00:22 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 99863312; Fri, 6 Mar 2020 17:00:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510421; bh=pDY7DliOvE1W90V9SgaI1VTbzwETcaqJ6v5bMGeyKiE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WnucqWI/StNAo5AfCrx8eMNAAVHQ0AgHiMu1ia+JUGyM7+t0Sbmm3oGhYTnFvdhEn Z6dO4MMkLFny/8d8us3118W85r4e9PE+su/fbwyr4D/8jnVyCwrqQ1I04KiY751OE1 VZyLN7zo45/b96WjLv7coQdv3XIp94VBJ/fL4e2k= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:46 +0200 Message-Id: <20200306160002.30549-17-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 16/32] libcamera: controls: Support array controls in ControlValue 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: Fri, 06 Mar 2020 16:00:22 -0000 From: Jacopo Mondi Add array controls support to the ControlValue class. The polymorphic class can now store more than a single element and supports access and creation through the use of Span<>. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Use T::value_type instead of T::element_type to benefit from std::remove_cv - Fix ControlTypeNone test in ControlValue::toString() - Separate array elements with ", " in ControlValue::toString() - Use parentheses with sizeof operator - Drop unneeded documentation paragraph - Fix typos --- include/libcamera/controls.h | 81 +++++++++++++--- src/libcamera/controls.cpp | 181 +++++++++++++++++++++++++++++------ 2 files changed, 221 insertions(+), 41 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 4538be06af93..1e24ae30ab36 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -9,6 +9,7 @@ #define __LIBCAMERA_CONTROLS_H__ #include +#include #include #include @@ -51,6 +52,10 @@ struct control_type { static constexpr ControlType value = ControlTypeInteger64; }; +template +struct control_type> : public control_type> { +}; + } /* namespace details */ class ControlValue @@ -58,15 +63,35 @@ class ControlValue public: ControlValue(); +#ifndef __DOXYGEN__ + template::value, std::nullptr_t> = nullptr> + ControlValue(const T &value) + : type_(ControlTypeNone), numElements_(0) + { + set(details::control_type>::value, false, + &value, 1, sizeof(T)); + } + + template::value, std::nullptr_t> = nullptr> +#else template - ControlValue(T value) - : type_(details::control_type>::value) +#endif + ControlValue(const T &value) + : type_(ControlTypeNone), numElements_(0) { - *reinterpret_cast(&bool_) = value; + set(details::control_type>::value, true, + value.data(), value.size(), sizeof(typename T::value_type)); } + ~ControlValue(); + + ControlValue(const ControlValue &other); + ControlValue &operator=(const ControlValue &other); + ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } + bool isArray() const { return isArray_; } + std::size_t numElements() const { return numElements_; } Span data() const; std::string toString() const; @@ -77,31 +102,61 @@ public: return !(*this == other); } +#ifndef __DOXYGEN__ + template::value, std::nullptr_t> = nullptr> + T get() const + { + assert(type_ == details::control_type>::value); + assert(!isArray_); + + return *reinterpret_cast(data().data()); + } + + template::value, std::nullptr_t> = nullptr> +#else template +#endif T get() const { assert(type_ == details::control_type>::value); + assert(isArray_); + + using V = typename T::value_type; + const V *value = reinterpret_cast(data().data()); + return { value, numElements_ }; + } - return *reinterpret_cast(&bool_); +#ifndef __DOXYGEN__ + template::value, std::nullptr_t> = nullptr> + void set(const T &value) + { + set(details::control_type>::value, false, + reinterpret_cast(&value), 1, sizeof(T)); } + template::value, std::nullptr_t> = nullptr> +#else template +#endif void set(const T &value) { - type_ = details::control_type>::value; - *reinterpret_cast(&bool_) = value; + set(details::control_type>::value, true, + value.data(), value.size(), sizeof(typename T::value_type)); } private: - ControlType type_; - - union { - bool bool_; - int32_t integer32_; - int64_t integer64_; - }; + ControlType type_ : 8; + bool isArray_ : 1; + std::size_t numElements_ : 16; + uint64_t storage_; + + void release(); + void set(ControlType type, bool isArray, const void *data, + std::size_t numElements, std::size_t elementSize); }; +static_assert(sizeof(ControlValue) == 16, "Invalid size of ControlValue class"); + class ControlId { public: diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index e513188010e2..a1eca992884c 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "control_validator.h" #include "log.h" @@ -50,7 +51,7 @@ LOG_DEFINE_CATEGORY(Controls) namespace { static constexpr size_t ControlValueSize[] = { - [ControlTypeNone] = 1, + [ControlTypeNone] = 0, [ControlTypeBool] = sizeof(bool), [ControlTypeInteger32] = sizeof(int32_t), [ControlTypeInteger64] = sizeof(int64_t), @@ -80,15 +81,59 @@ static constexpr size_t ControlValueSize[] = { * \brief Construct an empty ControlValue. */ ControlValue::ControlValue() - : type_(ControlTypeNone) + : type_(ControlTypeNone), isArray_(false), numElements_(0) { } /** - * \fn template T ControlValue::ControlValue(T value) + * \fn template T ControlValue::ControlValue(const T &value) * \brief Construct a ControlValue of type T * \param[in] value Initial value + * + * This function constructs a new instance of ControlValue and stores the \a + * value inside it. If the type \a T is equivalent to Span, the instance + * stores an array of values of type \a R. Otherwise the instance stores a + * single value of type \a T. The numElements() and type() are updated to + * reflect the stored value. + */ + +void ControlValue::release() +{ + std::size_t size = numElements_ * ControlValueSize[type_]; + + if (size > sizeof(storage_)) { + delete[] *reinterpret_cast(&storage_); + storage_ = 0; + } +} + +ControlValue::~ControlValue() +{ + release(); +} + +/** + * \brief Construct a ControlValue with the content of \a other + * \param[in] other The ControlValue to copy content from */ +ControlValue::ControlValue(const ControlValue &other) + : type_(ControlTypeNone), numElements_(0) +{ + *this = other; +} + +/** + * \brief Replace the content of the ControlValue with a copy of the content + * of \a other + * \param[in] other The ControlValue to copy content from + * \return The ControlValue with its content replaced with the one of \a other + */ +ControlValue &ControlValue::operator=(const ControlValue &other) +{ + set(other.type_, other.isArray_, other.data().data(), + other.numElements_, ControlValueSize[other.type_]); + return *this; +} /** * \fn ControlValue::type() @@ -102,16 +147,33 @@ ControlValue::ControlValue() * \return True if the value type is ControlTypeNone, false otherwise */ +/** + * \fn ControlValue::isArray() + * \brief Determine if the value stores an array + * \return True if the value stores an array, false otherwise + */ + +/** + * \fn ControlValue::numElements() + * \brief Retrieve the number of elements stored in the ControlValue + * + * For instances storing an array, this function returns the number of elements + * in the array. Otherwise, it returns 1. + * + * \return The number of elements stored in the ControlValue + */ + /** * \brief Retrieve the raw data of a control value * \return The raw data of the control value as a span of uint8_t */ Span ControlValue::data() const { - return { - reinterpret_cast(&bool_), - ControlValueSize[type_] - }; + std::size_t size = numElements_ * ControlValueSize[type_]; + const uint8_t *data = size > sizeof(storage_) + ? *reinterpret_cast(&storage_) + : reinterpret_cast(&storage_); + return { data, size }; } /** @@ -120,18 +182,43 @@ Span ControlValue::data() const */ std::string ControlValue::toString() const { - switch (type_) { - case ControlTypeNone: - return ""; - case ControlTypeBool: - return bool_ ? "True" : "False"; - case ControlTypeInteger32: - return std::to_string(integer32_); - case ControlTypeInteger64: - return std::to_string(integer64_); + if (type_ == ControlTypeNone) + return ""; + + const uint8_t *data = ControlValue::data().data(); + std::string str(isArray_ ? "[ " : ""); + + for (unsigned int i = 0; i < numElements_; ++i) { + switch (type_) { + case ControlTypeBool: { + const bool *value = reinterpret_cast(data); + str += *value ? "True" : "False"; + break; + } + case ControlTypeInteger32: { + const int32_t *value = reinterpret_cast(data); + str += std::to_string(*value); + break; + } + case ControlTypeInteger64: { + const int64_t *value = reinterpret_cast(data); + str += std::to_string(*value); + break; + } + case ControlTypeNone: + break; + } + + if (i + 1 != numElements_) + str += ", "; + + data += ControlValueSize[type_]; } - return ""; + if (isArray_) + str += " ]"; + + return str; } /** @@ -143,16 +230,13 @@ bool ControlValue::operator==(const ControlValue &other) const if (type_ != other.type_) return false; - switch (type_) { - case ControlTypeBool: - return bool_ == other.bool_; - case ControlTypeInteger32: - return integer32_ == other.integer32_; - case ControlTypeInteger64: - return integer64_ == other.integer64_; - default: + if (numElements_ != other.numElements()) return false; - } + + if (isArray_ != other.isArray_) + return false; + + return memcmp(data().data(), other.data().data(), data().size()) == 0; } /** @@ -165,8 +249,16 @@ bool ControlValue::operator==(const ControlValue &other) const * \fn template T ControlValue::get() const * \brief Get the control value * - * The control value type shall match the type T, otherwise the behaviour is - * undefined. + * This function returns the contained value as an instance of \a T. If the + * ControlValue instance stores a single value, the type \a T shall match the + * stored value type(). If the instance stores an array of values, the type + * \a T should be equal to Span, and the type \a R shall match the + * stored value type(). The behaviour is undefined otherwise. + * + * Note that a ControlValue instance that stores a non-array value is not + * equivalent to an instance that stores an array value containing a single + * element. The latter shall be accessed through a Span type, while + * the former shall be accessed through a type \a T corresponding to type(). * * \return The control value */ @@ -175,8 +267,41 @@ bool ControlValue::operator==(const ControlValue &other) const * \fn template void ControlValue::set(const T &value) * \brief Set the control value to \a value * \param[in] value The control value + * + * This function stores the \a value in the instance. If the type \a T is + * equivalent to Span, the instance stores an array of values of type \a R. + * Otherwise the instance stores a single value of type \a T. The numElements() + * and type() are updated to reflect the stored value. + * + * The entire content of \a value is copied to the instance, no reference to \a + * value or to the data it references is retained. This may be an expensive + * operation for Span<> values that refer to large arrays. */ +void ControlValue::set(ControlType type, bool isArray, const void *data, + std::size_t numElements, std::size_t elementSize) +{ + ASSERT(elementSize == ControlValueSize[type]); + + release(); + + type_ = type; + numElements_ = numElements; + isArray_ = isArray; + + std::size_t size = elementSize * numElements; + void *storage; + + if (size > sizeof(storage_)) { + storage = reinterpret_cast(new char[size]); + *reinterpret_cast(&storage_) = storage; + } else { + storage = reinterpret_cast(&storage_); + } + + memcpy(storage, data, size); +} + /** * \class ControlId * \brief Control static metadata From patchwork Fri Mar 6 15:59:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2989 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 72362628B5 for ; Fri, 6 Mar 2020 17:00:22 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1A1C424B for ; Fri, 6 Mar 2020 17:00:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510422; bh=Y9NNa4ZR945n/emsic1UFPuZDNHwoiB30UwD/XOCVic=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZOgx8w2BdGCOnZRxwggoJrGg+D/vgks+/3b6E9HXriJICJbebN2/5BZVRBI3iJstA MxwNW52Y++mZeUpdLBThZrcPnC5N3H0XnVVMhZtIPBmF2w/q27C0QLkcCBlVi1ZDa3 xgwR9eUKRBB8YQnRbmKUaXgHvojR+lu+f+G3RC6o= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:47 +0200 Message-Id: <20200306160002.30549-18-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 17/32] libcamera: controls: Allow passing an std::initializer list to set() 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: Fri, 06 Mar 2020 16:00:22 -0000 For array controls, the ControlList::set() function takes a value as a type convertible to Span. This allows passing an std::array or an std::vector in addition to an explicit Span, but doesn't accept an std::initializer list as Span has no constructor that takes an initializer list. Callers are thus forced to create temporary objects explicitly, which isn't nice. Fix the issue by providing a ControlList::set() function that takes an std::initializer_list, and convert it to a Span internally. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 10 ++++++++++ src/libcamera/controls.cpp | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 1e24ae30ab36..2102d5711384 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -335,6 +335,16 @@ public: val->set(value); } + template + void set(const Control &ctrl, const std::initializer_list &value) + { + ControlValue *val = find(ctrl.id()); + if (!val) + return; + + val->set(Span>{ value.begin(), value.size() }); + } + const ControlValue &get(unsigned int id) const; void set(unsigned int id, const ControlValue &value); diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index a1eca992884c..3dd740e5f17e 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -802,6 +802,12 @@ bool ControlList::contains(unsigned int id) const * object that the list refers to. */ +/** + * \fn template \ + * void ControlList::set(const Control &ctrl, const std::initializer_list &value) + * \copydoc ControlList::set(const Control &ctrl, const V &value) + */ + /** * \brief Get the value of control \a id * \param[in] id The control numerical ID From patchwork Fri Mar 6 15:59:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2990 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DAB4F628D6 for ; Fri, 6 Mar 2020 17:00:22 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6AD1D312; Fri, 6 Mar 2020 17:00:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510422; bh=bmNaeovvXf+tItGMnvNYpiBOqQlzESZb62p5aC5BnVA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oDDW5jvo8VYYBOF3HaXraLfr3dQa8BU8WbD2yoSupBTGDNnE4r/OPhlzwlvZ5JqsL 3tFsRlzd2NZSm9RZ4KBI4hd3gMHFUfjdN4JUOdJVJ7U642DNGwvgQb4LZsIQqtO+ib Zgtct4GGUGgUTpY/tNPE7yPX+FtKYr4icWc45RjU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:48 +0200 Message-Id: <20200306160002.30549-19-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 18/32] libcamera: controls: Add a 'size' yaml property 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: Fri, 06 Mar 2020 16:00:24 -0000 From: Jacopo Mondi Add a 'size' property to the control yaml description, to convey the size constraints of array controls. The semantics of the property contents is currently unspecified, but its presence triggers the generation of an array control (Control>). Example: - BayerGains: type: float description: Gains to apply to the four Bayer colour components for white balance size: [4] Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/gen-controls.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libcamera/gen-controls.py b/src/libcamera/gen-controls.py index 6f020a327827..ff8bda6b16c1 100755 --- a/src/libcamera/gen-controls.py +++ b/src/libcamera/gen-controls.py @@ -42,9 +42,14 @@ ${description} name, ctrl = ctrl.popitem() id_name = snake_case(name).upper() + if ctrl.get('size'): + ctrl_type = 'Span' % ctrl['type'] + else: + ctrl_type = ctrl['type'] + info = { 'name': name, - 'type': ctrl['type'], + 'type': ctrl_type, 'description': format_description(ctrl['description']), 'id_name': id_name, } @@ -92,9 +97,14 @@ def generate_h(controls): ids.append('\t' + id_name + ' = ' + str(id_value) + ',') + if ctrl.get('size'): + ctrl_type = 'Span' % ctrl['type'] + else: + ctrl_type = ctrl['type'] + info = { 'name': name, - 'type': ctrl['type'], + 'type': ctrl_type, } enum = ctrl.get('enum') From patchwork Fri Mar 6 15:59:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2991 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4ABF0628DF for ; Fri, 6 Mar 2020 17:00:23 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C9E3924B; Fri, 6 Mar 2020 17:00:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510423; bh=JoPAu7quIBVbZUUCeWbJNQsxj2THxryMiJOlJLG4FH8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j0poidfuRq7/UxkZj+ZbqDpD2WQ1DRqKY2Zmac6AgjQNaG/dPZrcTtc3QT4T41cA9 B60adAA0769s8JRbSm+B02SfLg1CGh7Evl2TIfwlx2I2rer2JcFJKTOtrkJhMdcT3M w6kGvhK0qGcY+oM1PVhbfUc6x86+TWDbw1yBMMn4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:49 +0200 Message-Id: <20200306160002.30549-20-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 19/32] libcamera: controls: Add support for float 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-List-Received-Date: Fri, 06 Mar 2020 16:00:24 -0000 From: Jacopo Mondi Add support for float values in Control<> and ControlValue classes. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/libcamera/controls.h | 6 ++++++ src/libcamera/control_serializer.cpp | 12 ++++++++++++ src/libcamera/controls.cpp | 14 +++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 2102d5711384..0ad442b9e192 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -24,6 +24,7 @@ enum ControlType { ControlTypeBool, ControlTypeInteger32, ControlTypeInteger64, + ControlTypeFloat, }; namespace details { @@ -52,6 +53,11 @@ struct control_type { static constexpr ControlType value = ControlTypeInteger64; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypeFloat; +}; + template struct control_type> : public control_type> { }; diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 2b66ab978f81..5feaaa965cc5 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -165,6 +165,12 @@ void ControlSerializer::store(const ControlValue &value, break; } + case ControlTypeFloat: { + float data = value.get(); + buffer.write(&data); + break; + } + default: break; } @@ -337,6 +343,12 @@ ControlValue ControlSerializer::load(ControlType type, return ControlValue(value); } + case ControlTypeFloat: { + float value; + b.read(&value); + return ControlValue(value); + } + default: return ControlValue(); } diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 3dd740e5f17e..d095efd45b91 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -55,6 +55,7 @@ static constexpr size_t ControlValueSize[] = { [ControlTypeBool] = sizeof(bool), [ControlTypeInteger32] = sizeof(int32_t), [ControlTypeInteger64] = sizeof(int64_t), + [ControlTypeFloat] = sizeof(float), }; } /* namespace */ @@ -70,6 +71,8 @@ static constexpr size_t ControlValueSize[] = { * The control stores a 32-bit integer value * \var ControlTypeInteger64 * The control stores a 64-bit integer value + * \var ControlTypeFloat + * The control stores a 32-bit floating point value */ /** @@ -205,6 +208,11 @@ std::string ControlValue::toString() const str += std::to_string(*value); break; } + case ControlTypeFloat: { + const float *value = reinterpret_cast(data); + str += std::to_string(*value); + break; + } case ControlTypeNone: break; } @@ -374,9 +382,9 @@ void ControlValue::set(ControlType type, bool isArray, const void *data, * instead of Control. * * Controls of any type can be defined through template specialisation, but - * libcamera only supports the bool, int32_t and int64_t types natively (this - * includes types that are equivalent to the supported types, such as int and - * long int). + * libcamera only supports the bool, int32_t, int64_t and float types natively + * (this includes types that are equivalent to the supported types, such as int + * and long int). * * Controls IDs shall be unique. While nothing prevents multiple instances of * the Control class to be created with the same ID for the same object, doing From patchwork Fri Mar 6 15:59:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2992 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C7C4628EB for ; Fri, 6 Mar 2020 17:00:23 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 36EFA312; Fri, 6 Mar 2020 17:00:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510423; bh=3Qe0zeavKfJ3kqqGx0bBLZZl6OnW0KiJm9k1mN6Gd3Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BL3chhN+4z18osz2qR1ZWNk7f8DyaPqWwjny+UGJwnj/l0wGD4zjb5nWXmaiNtp+Z lHl3T1vI9osS/waMRn29YWm7xq0sxk/NaQFXFx6CTL2yuHzPcp4Av96VZHBS8hkaRB J9+a9bwLYPePxq4z5ljBPRBnRa9KLCuv9j0Tzi5U= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:50 +0200 Message-Id: <20200306160002.30549-21-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 20/32] libcamera: controls: Add support for byte 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-List-Received-Date: Fri, 06 Mar 2020 16:00:24 -0000 From: Jacopo Mondi Add support for byte values to the control framework and to the control serializer. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Renamed Integer8 to Byte - Turned the underlying type to uint8_t --- include/libcamera/controls.h | 6 ++++++ src/libcamera/control_serializer.cpp | 12 ++++++++++++ src/libcamera/controls.cpp | 14 +++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 0ad442b9e192..4767e2d3fc8c 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -22,6 +22,7 @@ class ControlValidator; enum ControlType { ControlTypeNone, ControlTypeBool, + ControlTypeByte, ControlTypeInteger32, ControlTypeInteger64, ControlTypeFloat, @@ -43,6 +44,11 @@ struct control_type { static constexpr ControlType value = ControlTypeBool; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypeByte; +}; + template<> struct control_type { static constexpr ControlType value = ControlTypeInteger32; diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 5feaaa965cc5..6c676811ebf3 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -153,6 +153,12 @@ void ControlSerializer::store(const ControlValue &value, break; } + case ControlTypeByte: { + uint8_t data = value.get(); + buffer.write(&data); + break; + } + case ControlTypeInteger32: { int32_t data = value.get(); buffer.write(&data); @@ -331,6 +337,12 @@ ControlValue ControlSerializer::load(ControlType type, return ControlValue(value); } + case ControlTypeByte: { + uint8_t value; + b.read(&value); + return ControlValue(value); + } + case ControlTypeInteger32: { int32_t value; b.read(&value); diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index d095efd45b91..0663a2201609 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -53,6 +53,7 @@ namespace { static constexpr size_t ControlValueSize[] = { [ControlTypeNone] = 0, [ControlTypeBool] = sizeof(bool), + [ControlTypeByte] = sizeof(uint8_t), [ControlTypeInteger32] = sizeof(int32_t), [ControlTypeInteger64] = sizeof(int64_t), [ControlTypeFloat] = sizeof(float), @@ -67,6 +68,8 @@ static constexpr size_t ControlValueSize[] = { * Invalid type, for empty values * \var ControlTypeBool * The control stores a boolean value + * \var ControlTypeByte + * The control stores a byte value as an unsigned 8-bit integer * \var ControlTypeInteger32 * The control stores a 32-bit integer value * \var ControlTypeInteger64 @@ -198,6 +201,11 @@ std::string ControlValue::toString() const str += *value ? "True" : "False"; break; } + case ControlTypeByte: { + const uint8_t *value = reinterpret_cast(data); + str += std::to_string(*value); + break; + } case ControlTypeInteger32: { const int32_t *value = reinterpret_cast(data); str += std::to_string(*value); @@ -382,9 +390,9 @@ void ControlValue::set(ControlType type, bool isArray, const void *data, * instead of Control. * * Controls of any type can be defined through template specialisation, but - * libcamera only supports the bool, int32_t, int64_t and float types natively - * (this includes types that are equivalent to the supported types, such as int - * and long int). + * libcamera only supports the bool, uint8_t, int32_t, int64_t and float types + * natively (this includes types that are equivalent to the supported types, + * such as int and long int). * * Controls IDs shall be unique. While nothing prevents multiple instances of * the Control class to be created with the same ID for the same object, doing From patchwork Fri Mar 6 15:59:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2993 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0066F628A3 for ; Fri, 6 Mar 2020 17:00:24 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 93A3F24B for ; Fri, 6 Mar 2020 17:00:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510423; bh=RkzQicivtlWkMIm0eHjiuGRnhvtl/p1tEGUu+UUN38A=; h=From:To:Subject:Date:In-Reply-To:References:From; b=V8ORNGZxTHdU7FA/iFKo0fh3pR0Y+jsXVEwhmB2hjC8d/bh8El1uBywgfxTJkfb1L xutqJm8Kg5F+zmhxhF77fQN4eQfQUeODYZTsubZ/CoKiry34BUwbtmYDzUTfH2u88e PelWJ0mCVAMA9UdI1X7TWi7/FECpqXk29vEpWWcM= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:51 +0200 Message-Id: <20200306160002.30549-22-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 21/32] libcamera: controls: Convert bool ControlValue to lowercase strings 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: Fri, 06 Mar 2020 16:00:24 -0000 The C++ boolean types are lower case, and std::ostream::operator<<(bool) produces a lowercase string (when std::boolalpha is in effect, otherwise it produces 0 or 1). Switch ControlValue::toString() to produce lowercase "true" and "false" strings too for consistency. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/controls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 0663a2201609..94bdbdd9c388 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -198,7 +198,7 @@ std::string ControlValue::toString() const switch (type_) { case ControlTypeBool: { const bool *value = reinterpret_cast(data); - str += *value ? "True" : "False"; + str += *value ? "true" : "false"; break; } case ControlTypeByte: { From patchwork Fri Mar 6 15:59:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2994 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 56EA562895 for ; Fri, 6 Mar 2020 17:00:24 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E54DAA48 for ; Fri, 6 Mar 2020 17:00:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510424; bh=/UMbelP5S1DFbAsOKVftaI9xKR3VpHsTizm9OsiyD8s=; h=From:To:Subject:Date:In-Reply-To:References:From; b=anvAbvOPBSwaTTIeA4v99Vatu39UYiAGZ8hcGXHCiRSm4LoyZzOVAD4DvYpdAXinp 47vDJGC9BUNFu+gs9xUvsUf9NAnFZ8gZW3Gn470n8HCbJio/cWfwkm7HIFbQZw9G62 QH061beIGzxgrdC0k9B7E3reW5edcvcSF63NXU4M= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:52 +0200 Message-Id: <20200306160002.30549-23-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 22/32] libcamera: ipa: Support array controls in ipa_control_value_entry 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: Fri, 06 Mar 2020 16:00:25 -0000 Report in a new field of the ipa_control_value_entry structure if the value contains an array. Reorganize the other fields of the structure to avoid increasing its size. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- include/ipa/ipa_controls.h | 6 ++++-- src/libcamera/ipa_controls.cpp | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/ipa/ipa_controls.h b/include/ipa/ipa_controls.h index 6371e34575f2..37f97d6ad2a4 100644 --- a/include/ipa/ipa_controls.h +++ b/include/ipa/ipa_controls.h @@ -26,9 +26,11 @@ struct ipa_controls_header { struct ipa_control_value_entry { uint32_t id; - uint32_t type; - uint32_t count; + uint8_t type; + uint8_t is_array; + uint16_t count; uint32_t offset; + uint32_t padding[1]; }; struct ipa_control_range_entry { diff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp index fc5ccd4210b2..da4724b178e2 100644 --- a/src/libcamera/ipa_controls.cpp +++ b/src/libcamera/ipa_controls.cpp @@ -163,11 +163,15 @@ static_assert(sizeof(ipa_controls_header) == 32, * The numerical ID of the control * \var ipa_control_value_entry::type * The type of the control (defined by enum ControlType) + * \var ipa_control_value_entry::is_array + * True if the control value stores an array, false otherwise * \var ipa_control_value_entry::count * The number of control array entries for array controls (1 otherwise) * \var ipa_control_value_entry::offset * The offset in bytes from the beginning of the data section to the control * value data (shall be a multiple of 8 bytes). + * \var ipa_control_value_entry::padding + * Padding bytes (shall be set to 0) */ static_assert(sizeof(ipa_control_value_entry) == 16, From patchwork Fri Mar 6 15:59:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2995 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B520E628B7 for ; Fri, 6 Mar 2020 17:00:24 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 449CE24B; Fri, 6 Mar 2020 17:00:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510424; bh=ZTP+9rVrH5qUMHcVTdc9d7h/GTi8MPowVEmbja9/4vI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u7KWdTijXIMY0t8XHiHjNSj7j69MQqOJhxeoo2HCqfma4Ru5q2bKpY8ZbIDCf7N9q qNgbqx+79BQyRDc4matxj8Jxy4sRVapndJyBDPOkY0291/o0y0eRIARNsIpB9i0qA0 vA4NzfNRHXRo/M3jiTq1C1+FMrwJldgEiBY2J19I= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:53 +0200 Message-Id: <20200306160002.30549-24-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 23/32] libcamera: byte_stream_buffer: Fix documentation of read() and write() 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: Fri, 06 Mar 2020 16:00:25 -0000 From: Jacopo Mondi The documentation of the read() and write() functions refer to non existent 'size' and 'data' parameters in their brief. Fix them. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/byte_stream_buffer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcamera/byte_stream_buffer.cpp b/src/libcamera/byte_stream_buffer.cpp index 23d624dd0a06..cd1d8a36d464 100644 --- a/src/libcamera/byte_stream_buffer.cpp +++ b/src/libcamera/byte_stream_buffer.cpp @@ -225,7 +225,7 @@ int ByteStreamBuffer::skip(size_t size) /** * \fn template int ByteStreamBuffer::read(T *t) - * \brief Read \a size \a data from the managed memory buffer + * \brief Read data from the managed memory buffer into \a t * \param[out] t Pointer to the memory containing the read data * \return 0 on success, a negative error code otherwise * \retval -EACCES attempting to read from a write buffer @@ -234,7 +234,7 @@ int ByteStreamBuffer::skip(size_t size) /** * \fn template int ByteStreamBuffer::write(const T *t) - * \brief Write \a data of \a size to the managed memory buffer + * \brief Write \a t to the managed memory buffer * \param[in] t The data to write to memory * \return 0 on success, a negative error code otherwise * \retval -EACCES attempting to write to a read buffer From patchwork Fri Mar 6 15:59:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2996 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BAE0E62895 for ; Fri, 6 Mar 2020 17:00:25 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A4552A48; Fri, 6 Mar 2020 17:00:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510424; bh=1/2Wqqln0poX9Rz1quWVVe9nTWwmDhh7XhouunM5ZpY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YktRlJFPm0EJz0uVAbSGshESfdnM7Ue3oWP8fxnxmLtXkDcQx7QwpoSsNKNZAPWpc faGFhXI8K5fUTL+LZHlmWItuyrcGCHe57DbZjK2R3C3Nv1qyWfA3sBJP88B7WDWNtd c+co21dsNasahVUVf4LxjM8QiT8+wtwwOZ4C8QGw= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:54 +0200 Message-Id: <20200306160002.30549-25-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 24/32] libcamera: byte_stream_buffer: Add Span<> support 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: Fri, 06 Mar 2020 16:00:27 -0000 From: Jacopo Mondi Add support to write and read a Span<> to and from the ByteStreamBuffer class. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/byte_stream_buffer.cpp | 18 ++++++++++++++++++ src/libcamera/include/byte_stream_buffer.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/libcamera/byte_stream_buffer.cpp b/src/libcamera/byte_stream_buffer.cpp index cd1d8a36d464..17e710c4887e 100644 --- a/src/libcamera/byte_stream_buffer.cpp +++ b/src/libcamera/byte_stream_buffer.cpp @@ -232,6 +232,15 @@ int ByteStreamBuffer::skip(size_t size) * \retval -ENOSPC no more space is available in the managed memory buffer */ +/** + * \fn template int ByteStreamBuffer::read(const Span &data) + * \brief Read data from the managed memory buffer into Span \a data + * \param[out] data Span representing the destination memory + * \return 0 on success, a negative error code otherwise + * \retval -EACCES attempting to read from a write buffer + * \retval -ENOSPC no more space is available in the managed memory buffer + */ + /** * \fn template int ByteStreamBuffer::write(const T *t) * \brief Write \a t to the managed memory buffer @@ -241,6 +250,15 @@ int ByteStreamBuffer::skip(size_t size) * \retval -ENOSPC no more space is available in the managed memory buffer */ +/** + * \fn template int ByteStreamBuffer::write(const Span &data) + * \brief Write \a data to the managed memory buffer + * \param[in] data The data to write to memory + * \return 0 on success, a negative error code otherwise + * \retval -EACCES attempting to write to a read buffer + * \retval -ENOSPC no more space is available in the managed memory buffer + */ + int ByteStreamBuffer::read(uint8_t *data, size_t size) { if (!read_) diff --git a/src/libcamera/include/byte_stream_buffer.h b/src/libcamera/include/byte_stream_buffer.h index b5274c62b85e..17cb0146061e 100644 --- a/src/libcamera/include/byte_stream_buffer.h +++ b/src/libcamera/include/byte_stream_buffer.h @@ -10,6 +10,8 @@ #include #include +#include + namespace libcamera { class ByteStreamBuffer @@ -33,12 +35,27 @@ public: { return read(reinterpret_cast(t), sizeof(*t)); } + + template + int read(const Span &data) + { + return read(reinterpret_cast(data.data()), + data.size_bytes()); + } + template int write(const T *t) { return write(reinterpret_cast(t), sizeof(*t)); } + template + int write(const Span &data) + { + return write(reinterpret_cast(data.data()), + data.size_bytes()); + } + private: ByteStreamBuffer(const ByteStreamBuffer &other) = delete; ByteStreamBuffer &operator=(const ByteStreamBuffer &other) = delete; From patchwork Fri Mar 6 15:59:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2997 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1F9CF628B7 for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B08A824B for ; Fri, 6 Mar 2020 17:00:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510425; bh=IB2SdpK9t3+O0qL+nuKVMs4Yb2mP1wIBYwMpFTN+us8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YEbbRE5aG1gkR9YKCgGp2Xspz1rCcktGU2WcsTv6UTifs+q9ItauegMR+SOmKXRRk zvExdlaiQ0BDWCutQ94xMa+NQhcyh3F9IdoD7e5Ejedl/VtLC7n2kMpGv+EmFD2bPQ x/eokJv8XRDVsKvMUVKPs+7LzVjScJ764l3HgkBQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:55 +0200 Message-Id: <20200306160002.30549-26-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 25/32] libcamera: byte_stream_buffer: Add zero-copy read() variant 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: Fri, 06 Mar 2020 16:00:27 -0000 Add a read() function to ByteStreamBuffer that returns a pointer to the data instead of copying it. Overflow check is still handled by the class, but the caller must check the returned pointer explicitly. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/byte_stream_buffer.cpp | 39 ++++++++++++++++++++++ src/libcamera/include/byte_stream_buffer.h | 9 +++++ 2 files changed, 48 insertions(+) diff --git a/src/libcamera/byte_stream_buffer.cpp b/src/libcamera/byte_stream_buffer.cpp index 17e710c4887e..20d6a6552c5f 100644 --- a/src/libcamera/byte_stream_buffer.cpp +++ b/src/libcamera/byte_stream_buffer.cpp @@ -241,6 +241,19 @@ int ByteStreamBuffer::skip(size_t size) * \retval -ENOSPC no more space is available in the managed memory buffer */ +/** + * \fn template const T *ByteStreamBuffer::read(size_t count) + * \brief Read data from the managed memory buffer without performing a copy + * \param[in] count Number of data items to read + * + * This function reads \a count elements of type \a T from the buffer. Unlike + * the other read variants, it doesn't copy the data but returns a pointer to + * the first element. If data can't be read for any reason (usually due to + * reading more data than available), the function returns nullptr. + * + * \return A pointer to the data on success, or nullptr otherwise + */ + /** * \fn template int ByteStreamBuffer::write(const T *t) * \brief Write \a t to the managed memory buffer @@ -259,6 +272,32 @@ int ByteStreamBuffer::skip(size_t size) * \retval -ENOSPC no more space is available in the managed memory buffer */ +const uint8_t *ByteStreamBuffer::read(size_t size, size_t count) +{ + if (!read_) + return nullptr; + + if (overflow_) + return nullptr; + + size_t bytes; + if (__builtin_mul_overflow(size, count, &bytes)) { + setOverflow(); + return nullptr; + } + + if (read_ + bytes > base_ + size_) { + LOG(Serialization, Error) + << "Unable to read " << bytes << " bytes: out of bounds"; + setOverflow(); + return nullptr; + } + + const uint8_t *data = read_; + read_ += bytes; + return data; +} + int ByteStreamBuffer::read(uint8_t *data, size_t size) { if (!read_) diff --git a/src/libcamera/include/byte_stream_buffer.h b/src/libcamera/include/byte_stream_buffer.h index 17cb0146061e..b3aaa8b9fb28 100644 --- a/src/libcamera/include/byte_stream_buffer.h +++ b/src/libcamera/include/byte_stream_buffer.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -43,6 +44,13 @@ public: data.size_bytes()); } + template + const std::remove_reference_t *read(size_t count = 1) + { + using return_type = const std::remove_reference_t *; + return reinterpret_cast(read(sizeof(T), count)); + } + template int write(const T *t) { @@ -63,6 +71,7 @@ private: void setOverflow(); int read(uint8_t *data, size_t size); + const uint8_t *read(size_t size, size_t count); int write(const uint8_t *data, size_t size); ByteStreamBuffer *parent_; From patchwork Fri Mar 6 15:59:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2998 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 71745628C8 for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0E083312 for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510426; bh=7PF0FfPppnfJyEzZJKQHWs0q6qi4YRMie18Dc/wYhjk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dyAjYxHbFqjPnFHkHzktaR4LIA7tTy8UICJ0xyHvWykbiQudGThQa9dQMQqAZYGgT RH3Xos9H0u6cX7EFf1VNAu/piacBzdaxM6fCACuqXuieNq3E6qY6A3N92i2zUfXKZt SoQ7v5M6fBWpUXrxCF5sC8NlbudSA2U/7DDT+OYo= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:56 +0200 Message-Id: <20200306160002.30549-27-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 26/32] libcamera: control_serializer: Use explicit ControlTypeNone case 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: Fri, 06 Mar 2020 16:00:28 -0000 Replace the default case with an explicit ControlTypeNone case in ControlSerializer::load() to catch omissions when adding new control types. A return statement needs to be added to the end of the function to avoid gcc incorrectly reporting that some exit paths don't contain a return statement. The compiler will still warn that not all cases are handled when adding a new control type. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- - Add a return statement at the end of the function --- src/libcamera/control_serializer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 6c676811ebf3..edf3e5cab09f 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -361,9 +361,11 @@ ControlValue ControlSerializer::load(ControlType type, return ControlValue(value); } - default: + case ControlTypeNone: return ControlValue(); } + + return ControlValue(); } template<> From patchwork Fri Mar 6 15:59:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2999 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C71D0628B1 for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5E1F71265 for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510426; bh=oFiLAcNlTeOM8OlPjueQgF0oovjVB0y8QA5hKJv6BSA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=aiFPG34V04MgtezYw5+T3iBNa2bE32p8P2EsGIZhtyRx2+I5OiFG9Y0zGxsuoB07c 9i8R38Emu99wBwDC7Ix1ho8uqt5XsI/80weiXh2YPYjj39aUY+lAVE8ZUrEb3a5ear rSWI+9jIareN/e+lZSpshk+b9isAQ0nQrubH4I+I= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:57 +0200 Message-Id: <20200306160002.30549-28-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 27/32] libcamera: control_serializer: Simplify serialization of ControlValue 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: Fri, 06 Mar 2020 16:00:28 -0000 Use the ControlValue::data() function to access raw data stored in the control value and simplify serialization. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/control_serializer.cpp | 35 +--------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index edf3e5cab09f..997e87bec817 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -146,40 +146,7 @@ size_t ControlSerializer::binarySize(const ControlList &list) void ControlSerializer::store(const ControlValue &value, ByteStreamBuffer &buffer) { - switch (value.type()) { - case ControlTypeBool: { - bool data = value.get(); - buffer.write(&data); - break; - } - - case ControlTypeByte: { - uint8_t data = value.get(); - buffer.write(&data); - break; - } - - case ControlTypeInteger32: { - int32_t data = value.get(); - buffer.write(&data); - break; - } - - case ControlTypeInteger64: { - uint64_t data = value.get(); - buffer.write(&data); - break; - } - - case ControlTypeFloat: { - float data = value.get(); - buffer.write(&data); - break; - } - - default: - break; - } + buffer.write(value.data()); } void ControlSerializer::store(const ControlRange &range, From patchwork Fri Mar 6 15:59:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3000 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 20C6C628DF for ; Fri, 6 Mar 2020 17:00:27 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B084024B for ; Fri, 6 Mar 2020 17:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510426; bh=L3GkoxDy2u5cprwdKxL8JS9B3xvdJtsEZwIpKK1Jeqg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TByOm/HRlkoLU/FEmMzplIORcpZLV9wn3TO+yHTRmRq7Fa2kzWae27UHMd72CHFSP SDvWTa2CuVdZqplS8+KR6VcEimZGJZeHgFllHYHpUw/isjg4F1V5t5OgUSsMYuzs7f QlJ8MI9yquEZE5ul+wbZAMgNjdZM+ShPSpUdp5aQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:58 +0200 Message-Id: <20200306160002.30549-29-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 28/32] libcamera: control_serializer: Use zero-copy ByteStreamBuffer::read() 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: Fri, 06 Mar 2020 16:00:28 -0000 Use the zero-copy variant of ByteStreamBuffer::read() to read packet headers and control entries. This enhances the performance of ControlList and ControlInfoMap deserialization. Deserialization of the actual ControlValue is untouched for now and will be optimized later. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/control_serializer.cpp | 74 +++++++++++++++++----------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 997e87bec817..b4c1ed410b92 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -366,39 +366,46 @@ ControlRange ControlSerializer::load(ControlType type, template<> ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer &buffer) { - struct ipa_controls_header hdr; - buffer.read(&hdr); + const struct ipa_controls_header *hdr = buffer.read(); + if (!hdr) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (hdr.version != IPA_CONTROLS_FORMAT_VERSION) { + if (hdr->version != IPA_CONTROLS_FORMAT_VERSION) { LOG(Serializer, Error) << "Unsupported controls format version " - << hdr.version; + << hdr->version; return {}; } - ByteStreamBuffer entries = buffer.carveOut(hdr.data_offset - sizeof(hdr)); - ByteStreamBuffer values = buffer.carveOut(hdr.size - hdr.data_offset); + ByteStreamBuffer entries = buffer.carveOut(hdr->data_offset - sizeof(*hdr)); + ByteStreamBuffer values = buffer.carveOut(hdr->size - hdr->data_offset); if (buffer.overflow()) { - LOG(Serializer, Error) << "Serialized packet too small"; + LOG(Serializer, Error) << "Out of data"; return {}; } ControlInfoMap::Map ctrls; - for (unsigned int i = 0; i < hdr.entries; ++i) { - struct ipa_control_range_entry entry; - entries.read(&entry); + for (unsigned int i = 0; i < hdr->entries; ++i) { + const struct ipa_control_range_entry *entry = + entries.read(); + if (!entry) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } /* Create and cache the individual ControlId. */ - ControlType type = static_cast(entry.type); + ControlType type = static_cast(entry->type); /** * \todo Find a way to preserve the control name for debugging * purpose. */ - controlIds_.emplace_back(std::make_unique(entry.id, "", type)); + controlIds_.emplace_back(std::make_unique(entry->id, "", type)); - if (entry.offset != values.offset()) { + if (entry->offset != values.offset()) { LOG(Serializer, Error) << "Bad data, entry offset mismatch (entry " << i << ")"; @@ -414,8 +421,8 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & * Create the ControlInfoMap in the cache, and store the map to handle * association. */ - ControlInfoMap &map = infoMaps_[hdr.handle] = std::move(ctrls); - infoMapHandles_[&map] = hdr.handle; + ControlInfoMap &map = infoMaps_[hdr->handle] = std::move(ctrls); + infoMapHandles_[&map] = hdr->handle; return map; } @@ -432,21 +439,24 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & template<> ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer) { - struct ipa_controls_header hdr; - buffer.read(&hdr); + const struct ipa_controls_header *hdr = buffer.read(); + if (!hdr) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (hdr.version != IPA_CONTROLS_FORMAT_VERSION) { + if (hdr->version != IPA_CONTROLS_FORMAT_VERSION) { LOG(Serializer, Error) << "Unsupported controls format version " - << hdr.version; + << hdr->version; return {}; } - ByteStreamBuffer entries = buffer.carveOut(hdr.data_offset - sizeof(hdr)); - ByteStreamBuffer values = buffer.carveOut(hdr.size - hdr.data_offset); + ByteStreamBuffer entries = buffer.carveOut(hdr->data_offset - sizeof(*hdr)); + ByteStreamBuffer values = buffer.carveOut(hdr->size - hdr->data_offset); if (buffer.overflow()) { - LOG(Serializer, Error) << "Serialized packet too small"; + LOG(Serializer, Error) << "Out of data"; return {}; } @@ -458,10 +468,10 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer * use the global control::control idmap. */ const ControlInfoMap *infoMap; - if (hdr.handle) { + if (hdr->handle) { auto iter = std::find_if(infoMapHandles_.begin(), infoMapHandles_.end(), [&](decltype(infoMapHandles_)::value_type &entry) { - return entry.second == hdr.handle; + return entry.second == hdr->handle; }); if (iter == infoMapHandles_.end()) { LOG(Serializer, Error) @@ -476,19 +486,23 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer ControlList ctrls(infoMap ? infoMap->idmap() : controls::controls); - for (unsigned int i = 0; i < hdr.entries; ++i) { - struct ipa_control_value_entry entry; - entries.read(&entry); + for (unsigned int i = 0; i < hdr->entries; ++i) { + const struct ipa_control_value_entry *entry = + entries.read(); + if (!entry) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (entry.offset != values.offset()) { + if (entry->offset != values.offset()) { LOG(Serializer, Error) << "Bad data, entry offset mismatch (entry " << i << ")"; return {}; } - ControlType type = static_cast(entry.type); - ctrls.set(entry.id, load(type, values)); + ControlType type = static_cast(entry->type); + ctrls.set(entry->id, load(type, values)); } return ctrls; From patchwork Fri Mar 6 15:59:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3001 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 76179628A1 for ; Fri, 6 Mar 2020 17:00:27 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0EB3FA48; Fri, 6 Mar 2020 17:00:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510427; bh=6koFU6JlzRHu8uQAgNwR89vLNf0jsUTxuw+NVjBWtXA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M1VuD4cPRpt8shYnySnYNasZEW7/ugKkjkBVsFtybNtD19y+gyxiUwaOipsJefCvl IZbe3aH+QCuwoW+VXXUHHGFhR+DgIK9yFijGlQBRDFRpjW1VbYGOwQbdBZXiwOp1K1 +JWUw6X8IrR+5v1Ypeg4uZetdushnJaBeZEB8UM4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 17:59:59 +0200 Message-Id: <20200306160002.30549-30-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 29/32] libcamera: control_serializer: Add support for array 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-List-Received-Date: Fri, 06 Mar 2020 16:00:28 -0000 From: Jacopo Mondi Add support for serializing and deserializing control values that store arrays of values. The serialized format is extended to explicitly handle arrays. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/control_serializer.cpp | 80 ++++++++++++---------- src/libcamera/include/control_serializer.h | 6 +- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index b4c1ed410b92..004735fb2aa0 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "byte_stream_buffer.h" #include "log.h" @@ -279,8 +280,9 @@ int ControlSerializer::serialize(const ControlList &list, struct ipa_control_value_entry entry; entry.id = id; - entry.count = 1; entry.type = value.type(); + entry.is_array = value.isArray(); + entry.count = value.numElements(); entry.offset = values.offset(); entries.write(&entry); @@ -293,40 +295,45 @@ int ControlSerializer::serialize(const ControlList &list, return 0; } -template<> -ControlValue ControlSerializer::load(ControlType type, - ByteStreamBuffer &b) +template +ControlValue ControlSerializer::loadControlValue(ByteStreamBuffer &buffer, + bool isArray, + unsigned int count) +{ + ControlValue value; + + const T *data = buffer.read(count); + if (!data) + return value; + + if (isArray) + value.set(Span{ data, count }); + else + value.set(*data); + + return value; +} + +ControlValue ControlSerializer::loadControlValue(ControlType type, + ByteStreamBuffer &buffer, + bool isArray, + unsigned int count) { switch (type) { - case ControlTypeBool: { - bool value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeBool: + return loadControlValue(buffer, isArray, count); - case ControlTypeByte: { - uint8_t value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeByte: + return loadControlValue(buffer, isArray, count); - case ControlTypeInteger32: { - int32_t value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeInteger32: + return loadControlValue(buffer, isArray, count); - case ControlTypeInteger64: { - int64_t value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeInteger64: + return loadControlValue(buffer, isArray, count); - case ControlTypeFloat: { - float value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeFloat: + return loadControlValue(buffer, isArray, count); case ControlTypeNone: return ControlValue(); @@ -335,12 +342,11 @@ ControlValue ControlSerializer::load(ControlType type, return ControlValue(); } -template<> -ControlRange ControlSerializer::load(ControlType type, - ByteStreamBuffer &b) +ControlRange ControlSerializer::loadControlRange(ControlType type, + ByteStreamBuffer &b) { - ControlValue min = load(type, b); - ControlValue max = load(type, b); + ControlValue min = loadControlValue(type, b); + ControlValue max = loadControlValue(type, b); return ControlRange(min, max); } @@ -414,7 +420,7 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & /* Create and store the ControlRange. */ ctrls.emplace(controlIds_.back().get(), - load(type, values)); + loadControlRange(type, values)); } /* @@ -502,7 +508,9 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer } ControlType type = static_cast(entry->type); - ctrls.set(entry->id, load(type, values)); + ctrls.set(entry->id, + loadControlValue(type, values, entry->is_array, + entry->count)); } return ctrls; diff --git a/src/libcamera/include/control_serializer.h b/src/libcamera/include/control_serializer.h index 55259913a2ca..b91d13155f5e 100644 --- a/src/libcamera/include/control_serializer.h +++ b/src/libcamera/include/control_serializer.h @@ -41,7 +41,11 @@ private: static void store(const ControlRange &range, ByteStreamBuffer &buffer); template - T load(ControlType type, ByteStreamBuffer &b); + ControlValue loadControlValue(ByteStreamBuffer &buffer, bool isArray, + unsigned int count); + ControlValue loadControlValue(ControlType type, ByteStreamBuffer &buffer, + bool isArray = false, unsigned int count = 1); + ControlRange loadControlRange(ControlType type, ByteStreamBuffer &buffer); unsigned int serial_; std::vector> controlIds_; From patchwork Fri Mar 6 16:00:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3002 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C729A628DC for ; Fri, 6 Mar 2020 17:00:27 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6EEB613C2 for ; Fri, 6 Mar 2020 17:00:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510427; bh=SpuC2fqlNBdLpoKFLny8epULykqnOwoyDMWKj17ltOE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=s4i6qADI3TOyZ3kYRWbfvMj5UE6LWx+E0/EEgl8RQz0XtAwO4tQIgWaFyN2jfTrFX ry09KgOkHBb+XofuQzmHEiFMGWGFWhVHozEZOR0tqEieWOr+l2nnTVR4Sx3153FaGM f5XeIh4t9XtUbBX6AunPYN6KYC+ScZmk3PNUr/50= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 18:00:00 +0200 Message-Id: <20200306160002.30549-31-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 30/32] test: controls: control_value: Expand test to cover all control types 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: Fri, 06 Mar 2020 16:00:28 -0000 The ControlValueTest hasn't been updated for a long time and is outdated. Improve it to support all control types, and test the type(), isArray() and toString() methods. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v1: - Move change to ControlValue::toString() to a separate patch --- test/controls/control_value.cpp | 110 +++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp index a1ffa842f29e..37f415302ff6 100644 --- a/test/controls/control_value.cpp +++ b/test/controls/control_value.cpp @@ -19,46 +19,112 @@ class ControlValueTest : public Test protected: int run() { - ControlValue integer(1234); - ControlValue boolean(true); + /* + * None type. + */ + ControlValue value; + if (!value.isNone() || value.isArray()) { + cerr << "Empty value is non-null" << endl; + return TestFail; + } - /* Just a string conversion output test... no validation */ - cout << "Int: " << integer.toString() - << " Bool: " << boolean.toString() - << endl; + /* + * Bool type. + */ + value.set(true); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeBool) { + cerr << "Control type mismatch after setting to bool" << endl; + return TestFail; + } - if (integer.get() != 1234) { - cerr << "Failed to get Integer" << endl; + if (value.get() != true) { + cerr << "Control value mismatch after setting to bool" << endl; return TestFail; } - if (boolean.get() != true) { - cerr << "Failed to get Boolean" << endl; + if (value.toString() != "true") { + cerr << "Control string mismatch after setting to bool" << endl; return TestFail; } - /* Test an uninitialised value, and updating it. */ + /* + * Integer8 type. + */ + value.set(static_cast(42)); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeByte) { + cerr << "Control type mismatch after setting to uint8_t" << endl; + return TestFail; + } - ControlValue value; - if (!value.isNone()) { - cerr << "Empty value is non-null" << endl; + if (value.get() != 42) { + cerr << "Control value mismatch after setting to uint8_t" << endl; return TestFail; } - value.set(true); - if (value.isNone()) { - cerr << "Failed to set an empty object" << endl; + if (value.toString() != "42") { + cerr << "Control string mismatch after setting to uint8_t" << endl; return TestFail; } - if (value.get() != true) { - cerr << "Failed to get Booleans" << endl; + /* + * Integer32 type. + */ + value.set(0x42000000); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeInteger32) { + cerr << "Control type mismatch after setting to int32_t" << endl; + return TestFail; + } + + if (value.get() != 0x42000000) { + cerr << "Control value mismatch after setting to int32_t" << endl; + return TestFail; + } + + if (value.toString() != "1107296256") { + cerr << "Control string mismatch after setting to int32_t" << endl; + return TestFail; + } + + /* + * Integer64 type. + */ + value.set(static_cast(-42)); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeInteger64) { + cerr << "Control type mismatch after setting to int64_t" << endl; + return TestFail; + } + + if (value.get() != -42) { + cerr << "Control value mismatch after setting to int64_t" << endl; + return TestFail; + } + + if (value.toString() != "-42") { + cerr << "Control string mismatch after setting to int64_t" << endl; + return TestFail; + } + + /* + * Float type. + */ + value.set(-0.42f); + if (value.isNone() || value.isArray() || + value.type() != ControlTypeFloat) { + cerr << "Control type mismatch after setting to float" << endl; + return TestFail; + } + + if (value.get() != -0.42f) { + cerr << "Control value mismatch after setting to float" << endl; return TestFail; } - value.set(10); - if (value.get() != 10) { - cerr << "Failed to get Integer" << endl; + if (value.toString() != "-0.420000") { + cerr << "Control string mismatch after setting to float" << endl; return TestFail; } From patchwork Fri Mar 6 16:00:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3003 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 311F9628E0 for ; Fri, 6 Mar 2020 17:00:28 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C10A824B for ; Fri, 6 Mar 2020 17:00:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510427; bh=n8DnTCdboN0zG0KmvXupotD2rPXq5x5/jyNh0KMTpwQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=t+/crHY3gEbhNWfx5SJU0mKyvlD7QvgoXL2AQJDXSdsOH/ROzZ0up+wvp7DvFqao8 4wSn1+E+7wLGp52/Q/LxVs6Aw2iFQQqDuTLc/g5IzGJ31LQz6KC6wOMvsn0MHtQRA1 cd4s39hZkp5rUqqbWMC4KFgGvcGJOqjht5XQ8JAg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 18:00:01 +0200 Message-Id: <20200306160002.30549-32-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 31/32] test: controls: control_value: Expand test to cover array 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-List-Received-Date: Fri, 06 Mar 2020 16:00:28 -0000 Add tests to ControlValueTest to cover array controls of all supported types. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Kieran Bingham --- Changes since v1: - Renamed int8s to bytes --- test/controls/control_value.cpp | 101 ++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp index 37f415302ff6..fd28bfe4604a 100644 --- a/test/controls/control_value.cpp +++ b/test/controls/control_value.cpp @@ -5,6 +5,7 @@ * control_value.cpp - ControlValue tests */ +#include #include #include @@ -48,6 +49,26 @@ protected: return TestFail; } + std::array bools{ true, false }; + value.set(Span(bools)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeBool) { + cerr << "Control type mismatch after setting to bool array" << endl; + return TestFail; + } + + Span boolsResult = value.get>(); + if (bools.size() != boolsResult.size() || + !std::equal(bools.begin(), bools.end(), boolsResult.begin())) { + cerr << "Control value mismatch after setting to bool" << endl; + return TestFail; + } + + if (value.toString() != "[ true, false ]") { + cerr << "Control string mismatch after setting to bool array" << endl; + return TestFail; + } + /* * Integer8 type. */ @@ -68,6 +89,26 @@ protected: return TestFail; } + std::array bytes{ 3, 14, 15, 9 }; + value.set(Span(bytes)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeByte) { + cerr << "Control type mismatch after setting to uint8_t array" << endl; + return TestFail; + } + + Span int8sResult = value.get>(); + if (bytes.size() != int8sResult.size() || + !std::equal(bytes.begin(), bytes.end(), int8sResult.begin())) { + cerr << "Control value mismatch after setting to uint8_t array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3, 14, 15, 9 ]") { + cerr << "Control string mismatch after setting to uint8_t array" << endl; + return TestFail; + } + /* * Integer32 type. */ @@ -88,6 +129,26 @@ protected: return TestFail; } + std::array int32s{ 3, 14, 15, 9 }; + value.set(Span(int32s)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeInteger32) { + cerr << "Control type mismatch after setting to int32_t array" << endl; + return TestFail; + } + + Span int32sResult = value.get>(); + if (int32s.size() != int32sResult.size() || + !std::equal(int32s.begin(), int32s.end(), int32sResult.begin())) { + cerr << "Control value mismatch after setting to int32_t array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3, 14, 15, 9 ]") { + cerr << "Control string mismatch after setting to int32_t array" << endl; + return TestFail; + } + /* * Integer64 type. */ @@ -108,6 +169,26 @@ protected: return TestFail; } + std::array int64s{ 3, 14, 15, 9 }; + value.set(Span(int64s)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeInteger64) { + cerr << "Control type mismatch after setting to int64_t array" << endl; + return TestFail; + } + + Span int64sResult = value.get>(); + if (int64s.size() != int64sResult.size() || + !std::equal(int64s.begin(), int64s.end(), int64sResult.begin())) { + cerr << "Control value mismatch after setting to int64_t array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3, 14, 15, 9 ]") { + cerr << "Control string mismatch after setting to int64_t array" << endl; + return TestFail; + } + /* * Float type. */ @@ -128,6 +209,26 @@ protected: return TestFail; } + std::array floats{ 3.141593, 2.718282, 299792458.0 }; + value.set(Span(floats)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeFloat) { + cerr << "Control type mismatch after setting to float array" << endl; + return TestFail; + } + + Span floatsResult = value.get>(); + if (floats.size() != floatsResult.size() || + !std::equal(floats.begin(), floats.end(), floatsResult.begin())) { + cerr << "Control value mismatch after setting to float array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3.141593, 2.718282, 299792448.000000 ]") { + cerr << "Control string mismatch after setting to float array" << endl; + return TestFail; + } + return TestPass; } }; From patchwork Fri Mar 6 16:00:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3004 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D671628F6 for ; Fri, 6 Mar 2020 17:00:28 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1F8E1312; Fri, 6 Mar 2020 17:00:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583510428; bh=OjAhBx/e7LOXNzLPldOlU4fjLMb8ZaO1XbSkeO9tjUM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QI0YFBpOnERaQwP6w76bevOc9FgrmoecGluhAI3YoL1TR/uWTvCvl8LBrXF28MHVk ElQArV9bVM2zbFTvr9MiCKKugrVETbc03x6JIelwqnNKhVXRS8I24LMRmW80/fQ6dF r9TUSW3yBaapRU2Gz/JLCNTVLd2ffQQaJ/SD0+nA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Mar 2020 18:00:02 +0200 Message-Id: <20200306160002.30549-33-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> References: <20200306160002.30549-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 32/32] 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: Fri, 06 Mar 2020 16:00:28 -0000 From: Jacopo Mondi Add the '-p'|'--list-properties' option to the cam application to list the properties of a camera. Signed-off-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/cam/main.cpp | 28 ++++++++++++++++++++++++++++ src/cam/main.h | 1 + 2 files changed, 29 insertions(+) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index a38cca959aca..ea6f7914839c 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,8 @@ 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 +272,24 @@ int CamApp::prepareConfig() return 0; } +int CamApp::listProperties() +{ + if (!camera_) { + std::cout << "Cannot list properties without a camera" + << std::endl; + return -EINVAL; + } + + for (const auto &prop : camera_->properties()) { + const ControlId *id = properties::properties.at(prop.first); + const ControlValue &value = prop.second; + + std::cout << "Property: " << id->name() << " = " << value.toString(); + } + + return 0; +} + int CamApp::infoConfiguration() { if (!config_) { @@ -312,6 +334,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', };