From patchwork Sat Feb 29 16:42:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2919 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D14A62689 for ; Sat, 29 Feb 2020 17:43: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 1216DA28; Sat, 29 Feb 2020 17:43:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994602; bh=ptdAb66FWFDwGE6nwbpVByCYnUyXRaVwFUb9/1L+ctM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eeHqfBeA/vBGdD4Ile8vrAleDRfbqKya/yK4Nr3fKJpWX9Z13XuUaZH634tM/yGRy QwhnYU3i9jXEcna973HwJTK10kfchUOGqw/qfw8slM1/Tah2dZjmAYU16ZubB02IYr rhiP6n85sJYewWrLGv3h0nSC5CgpxzSc0Ov7N5Cc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:24 +0200 Message-Id: <20200229164254.23604-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/31] 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: Sat, 29 Feb 2020 16:43:22 -0000 From: Jacopo Mondi C++20 will contain a std::span<> class that represents a contiguous sequence of objects. Its main purpose is to group array pointers and size together in APIs. 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 --- Documentation/Doxyfile.in | 4 +- include/libcamera/meson.build | 1 + include/libcamera/span.h | 417 ++++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + src/libcamera/span.cpp | 12 + 5 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 include/libcamera/span.h create mode 100644 src/libcamera/span.cpp diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index beeaf6d3cf48..457e23a086a2 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -840,8 +840,10 @@ 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/span.cpp \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_sysfs.h \ @TOP_SRCDIR@/src/libcamera/include/device_enumerator_udev.h \ @TOP_SRCDIR@/src/libcamera/pipeline/ \ 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__ */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 88658ac563f7..2448f0e96468 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -36,6 +36,7 @@ libcamera_sources = files([ 'request.cpp', 'semaphore.cpp', 'signal.cpp', + 'span.cpp', 'stream.cpp', 'thread.cpp', 'timer.cpp', diff --git a/src/libcamera/span.cpp b/src/libcamera/span.cpp new file mode 100644 index 000000000000..753104765cea --- /dev/null +++ b/src/libcamera/span.cpp @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * span.h - C++20 std::span<> implementation for C++11 + */ + +#include + +namespace libcamera { + +} /* namespace libcamera */ From patchwork Sat Feb 29 16:42:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2920 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D06BE62689 for ; Sat, 29 Feb 2020 17:43: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 7652933E for ; Sat, 29 Feb 2020 17:43:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994602; bh=rTG5uiSgCf8ZncXT5gLvo4lI/pqVJpXttlHniz78ehs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=eSvLIPQzpuC9M6S6uSDoXhnoBIJZYq4GTNZs0XELKRloZLx2l7L10MILEIwH7WuY0 Wk/kZDYfidDNd/oTEUwm47xqou/lCDKwBoWXV2GV9ZnHVao7pRbhtdPLPLowiRg5iG e1GsAcqHaZmdouD2Nezm/MmnDMGiK9MV/GAX8394= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:25 +0200 Message-Id: <20200229164254.23604-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/31] 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: Sat, 29 Feb 2020 16:43:23 -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 --- test/meson.build | 1 + test/span.cpp | 177 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 test/span.cpp diff --git a/test/meson.build b/test/meson.build index daaa1aac926d..92be382bfe41 100644 --- a/test/meson.build +++ b/test/meson.build @@ -30,6 +30,7 @@ internal_tests = [ ['object', 'object.cpp'], ['object-invoke', 'object-invoke.cpp'], ['signal-threads', 'signal-threads.cpp'], + ['span', 'span.cpp'], ['threads', 'threads.cpp'], ['timer', 'timer.cpp'], ['timer-thread', 'timer-thread.cpp'], diff --git a/test/span.cpp b/test/span.cpp new file mode 100644 index 000000000000..609749f51b86 --- /dev/null +++ b/test/span.cpp @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * span.cpp - Span tests + */ + +#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 Sat Feb 29 16:42:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2921 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 44FE462789 for ; Sat, 29 Feb 2020 17:43: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 C91EAA28; Sat, 29 Feb 2020 17:43:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994603; bh=25QrjndSjN/tGA2KGr+Azbv20+Akchee2Dn86gYqtnw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o1VGzC2lN/v7t4f3yNoOZlA9XNvPAaMEamHJYPYQAuX+YMboSCHcGTq8KD2iMyN9A CO+F29Orl3CfVvmY+ERJcHZrlOl6raXTW4UNJRY8G2XaGSUqjXmh5VBr2wECvPFvKY eFFFMdCRWoHUKJTxP/KDXASun56CuQjKhLwL4Fkg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:26 +0200 Message-Id: <20200229164254.23604-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/31] 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: Sat, 29 Feb 2020 16:43:24 -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 properties name should not need any additional information specified for Doxygen to correctly identify them. Not sure this patch is the right way to fix this, but it's mostly here to highlight an issue. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- 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 Sat Feb 29 16:42:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2922 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A3A0862787 for ; Sat, 29 Feb 2020 17:43: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 336B733E; Sat, 29 Feb 2020 17:43:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994603; bh=+wWhkoEz+xi/4MsIb+QgRnlaZWkFWTBMfQGULBbuYac=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XXUfPJs+i9xk4N2QPR+tKjPKVRhrUXAc3u9jS4K2DpxzcWhOcdak06tqe51MTBM4+ nvk65d7cObpJqC3xVbBICRgnfhqmctCFx9GN0KoMGx0VTvdm+g9wx2m7uegx1UiVc4 0xkbCo2ymVN87jSt8akNoI6HXzNlhHEdnuGEoqCc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:27 +0200 Message-Id: <20200229164254.23604-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/31] 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: Sat, 29 Feb 2020 16:43:25 -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 IPA control serialization format documentation to describe the layout of 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 Sat Feb 29 16:42:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2923 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 ED36662790 for ; Sat, 29 Feb 2020 17:43: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 948C9A28 for ; Sat, 29 Feb 2020 17:43:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994603; bh=dt9Tvp/GrixvCHBEY+meD+WPLarBtdXAxb3wj8awSl4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=kqYTWknPpS1vnJ7SMOV3kD+oVnT9bhKfdrWSUw6T04kHdkRqV/wvgrk7+1tGa6huj 5zqQxuz1bf7Hh8qFpO0oWo3M6krHeQJKqXJn+EU1c20H+otF5Dq+a3R57eEjM56cob MpxpR/C8Wy1n4v0JlyIqrD94dyeoYywX+vvh+TkE= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:28 +0200 Message-Id: <20200229164254.23604-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/31] 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: Sat, 29 Feb 2020 16:43:25 -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 Sat Feb 29 16:42:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2924 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 50DA262689 for ; Sat, 29 Feb 2020 17:43: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 E479233E for ; Sat, 29 Feb 2020 17:43:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994604; bh=2Rz6XO1bXJrYs0sXHFeMDi56iMZxCJgRhR1LvT0iyxg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=qLgNf3dOF6Rx5/6K4a/QPY9T+Y8VZcZCezSehwoIOhr+Uw2UMHRr/8Ku6r2PNTbsC YW84bLIOxyxRiWUcWSdA/1tnrUJEgHNxfYxAtoQXHUKgg3CAUjHnqaY2OQPfz9OtYr PELRCYl0Ajdpa5eVQ8vWSVpQD0VKSxLbPOX4qvyA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:29 +0200 Message-Id: <20200229164254.23604-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/31] 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: Sat, 29 Feb 2020 16:43:25 -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 --- 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..25f38bab3dd9 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 size 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 size 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 size for struct ipa_control_range_entry"); From patchwork Sat Feb 29 16:42:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2925 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F291962783 for ; Sat, 29 Feb 2020 17:43: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 41197A28; Sat, 29 Feb 2020 17:43:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994604; bh=weNm1FRPnhjQp5i7ZXRbAD1CWUXO3yjGiVw8iyxqydY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BqVHm27U+jVdmqL2gUMpiQaUKjkQcJKZuVLoV1qpzvSQMQu3c0LJ8eGSa0/mtQ9rS PAlAK2K33qcX6hP0F7xp68MwuK6rO+0efWd0Yrt7b3QasZ8kcq/r1yFdStk3Owdgbw 8CnnN/s++7JDEsThO+ulyIqLkFQfL780iYNZyWNA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:30 +0200 Message-Id: <20200229164254.23604-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/31] 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: Sat, 29 Feb 2020 16:43:25 -0000 From: Jacopo Mondi Reorder functions in ControlValue class to group const methods together. Cosmetic change only. Signed-off-by: Jacopo Mondi 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 Sat Feb 29 16:42: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: 2926 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B37062789 for ; Sat, 29 Feb 2020 17:43: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 A48E4ABC for ; Sat, 29 Feb 2020 17:43:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994604; bh=K//ya32xbstbTy7UFqCFllLBS+9oWm1kZHrC0wMqcNM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=GJxpyHL9Qvx+SaGbrTmJmkZdleQVenVZqP/PSNPDPSMkQJJLyO70CKYwriQsBFJgJ lbUxbdar6kBdM2Ztst+EgAMKwJLBKIh2bPOXkpW5lzPyhqs7s1RAwFIuFHLtxbWKSX NA3l0lXxEYu/i6PMZfdDt6jFCElqY29rpxxg+lOE= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:31 +0200 Message-Id: <20200229164254.23604-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/31] 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: Sat, 29 Feb 2020 16:43:25 -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 Sat Feb 29 16:42: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: 2927 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 62BBA62787 for ; Sat, 29 Feb 2020 17:43: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 0217F33E for ; Sat, 29 Feb 2020 17:43:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994605; bh=yILmkhNrTwHmEcsjNAazHHfb3IUGlKb786I96spDtdI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DKjyIwRfOwo7dCn8k0hyPD63igLed/MFwCijiGE0VJX+Rrd9rsQd6UuAapm/7m5iB QNcWW+7B/aN3ENA3fkaoGnK60iIFaTsAJJHsKb4t57yh/fkoDQUiRkzIMwWzenGfCB JBRVFkHMTvCfmw9fiZRqDv84eLiyoD/VSmSLqD4E= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:32 +0200 Message-Id: <20200229164254.23604-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/31] 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: Sat, 29 Feb 2020 16:43:25 -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 to be used with value types that are convertible to T, and in particular with std::array or std::vector values types when the Control type will be a Span<> to support compound 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 constructor a 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 Sat Feb 29 16:42: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: 2928 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AAE8462689 for ; Sat, 29 Feb 2020 17:43: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 53144A28 for ; Sat, 29 Feb 2020 17:43:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994605; bh=LvRydhLlauP2ZTU/9LX68g/D+FF/gykag+1WHclmQMs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dv3OlJ9zncULWpuNesasfAsQtmoTzWU3UUmIaCuLwQQBJ6i1GH6qFeR2IiUTWDyuY cM+7r7H6VVXbgIeVidzRwz6ztYCwJ9wzUEpyeOojYoSLAlUlw0us12MmpRrSDo9YRa 0Kt+PFNkhinf7a81QkLoHGDB4/SNxlV4gYCuOiXI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:33 +0200 Message-Id: <20200229164254.23604-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/31] libcamera: controls: Return control by value in ControlList::get() 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: Sat, 29 Feb 2020 16:43:26 -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 compound 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 compound 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 Sat Feb 29 16:42:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2929 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 07E1262789 for ; Sat, 29 Feb 2020 17:43: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 A507033E for ; Sat, 29 Feb 2020 17:43:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994605; bh=9jDC8xaUozZIOtVPQBHRJ+FMhjCUXQ/Or5ur1AT8m00=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rj1pLBXGfSwrVHuwPPORyHNJkvsw/zmC0emi0xQ5HAUEefdAPcPbBjSIHKhggSRdL Ho/qt8EWvZ+SSB+pI17srV0QsnsZb1zBe6rifhFBHL3dp54f5Yi/3wROIY0AT0yV1r 8QYzl3jlw6bAkW+15Lz/PFdY2VYPURRMvBLc+ay4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:34 +0200 Message-Id: <20200229164254.23604-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/31] 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: Sat, 29 Feb 2020 16:43:26 -0000 This 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 457e23a086a2..430d80d5f21b 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -882,7 +882,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 Sat Feb 29 16:42: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: 2930 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 61F4F62789 for ; Sat, 29 Feb 2020 17:43: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 01664A28 for ; Sat, 29 Feb 2020 17:43:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994606; bh=kjlGLweGKYC3rHM+BnPYckKBUCNnYZR4sEgFzQal6QM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=LH1kwMxqJ+C1Gxf5uoG8ZpUyooAH6c5DO+X6Q3gTbOfNziRJvdkDm+XZxGmjGrUUu RDAJKbiz6Xi7EGT43mQKztGl4A7PZwbx8H545zdWtdEAmoVk7pP2MQsVeAgkMhwWwB vUKA6DFLZKcjaGug/B6LAa2zcVLW+A2Eice9OrSs= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:35 +0200 Message-Id: <20200229164254.23604-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/31] 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: Sat, 29 Feb 2020 16:43:26 -0000 To avoid defining all specializations of ControlValue::get() and ControlValue::set() manually, move the definition of those functions to controls.h. 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 Sat Feb 29 16:42: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: 2931 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B7A4A62796 for ; Sat, 29 Feb 2020 17:43: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 5289C33E for ; Sat, 29 Feb 2020 17:43:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994606; bh=Ju4ChpgLD5KCr++ioggZpJWGE95fy+RCeo4LCssiYbY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=U0J6T09iDx+JZihNPoDWE877XtnjrO1egnRSr94O+WWEbPbKtF+/g/VJG1ZX5RClX wTu4rSIUxb1w+7ybvbU8M2pgZcVtw/lBkBM0OMf6Wy56qV/DzEehVnucmpbEl6ebp8 A4s+2NpoC8d68p0KFft1SnjNGWxQAyrhIzQe2yeI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:36 +0200 Message-Id: <20200229164254.23604-14-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/31] 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: Sat, 29 Feb 2020 16:43:31 -0000 To avoid defining all specializations of the ControlValue constructor manually, move the definition of those functions to controls.h. 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 Sat Feb 29 16:42: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: 2932 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 18BFD627AA for ; Sat, 29 Feb 2020 17:43: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 A68A7A28 for ; Sat, 29 Feb 2020 17:43:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994606; bh=kcM3gADstjTOGmi790G+bL0EPl9Pw37NnY1W7LB3//Y=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WgDiDtP/Xco5ikT/+mOsFLZyWo9JhC7Se++tWdBqGooMD7GVhF/8rtNhAS9Zlealk /JqR/lCGlfQ9vfMt0R/s47HNG9ueB8Cg1DCnD/161IR9oxRz3JuwW2H1Z3QEBOTIAn jZfxrfRBVcOe0qZXTqOhgtos1n4EXMqnVgDMRMvg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:37 +0200 Message-Id: <20200229164254.23604-15-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 14/31] 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: Sat, 29 Feb 2020 16:43:31 -0000 To avoid defining all specializations of the Control constructor manually, move the definition of those functions to controls.h. 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 Sat Feb 29 16:42: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: 2933 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 8D987627AB for ; Sat, 29 Feb 2020 17:43: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 0672FA49 for ; Sat, 29 Feb 2020 17:43:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994607; bh=Jr+UsjTu+IpR948LvDC61E8yrlBuGmxw5fm5LwXPVT4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=BPhPuXgoKDXIBPRlADGlaJKCDrNiZyypkK4UCkNLhAcn40AeZ2o4Kd7HdxhR5PFXi +xH5+ablleNHy1m66XXawEJAyoVLvOpCEtIgQIFM91DfJvvjFQUbgbOe8toQSgYEmh Bc/I7wB00UhIpa4vt2btBLKudXOtoGvw2nzPQBzQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:38 +0200 Message-Id: <20200229164254.23604-16-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 15/31] 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: Sat, 29 Feb 2020 16:43:31 -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 --- 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..b2331ab7540d 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 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 Sat Feb 29 16:42: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: 2936 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 C24A2627AE for ; Sat, 29 Feb 2020 17:43: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 5B528ABC; Sat, 29 Feb 2020 17:43:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994607; bh=vDSloscGYkyDTrD+Zu1YarDBVO/L4qE1VErLHPDEkd8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nFw+ULu9Rt4DpVY3jqQPLVdOxgsN+0rWG2SGFfNZf9wXXVhZJyyKy8P6o4uMsG9qB 71CjltjMBHg5iPzX6yAFApGr/EUcEZlvT2Y3r2umViSaq3Qothgi6tw8Ozdvep7nBM ozuB33gjDZaOtELjbjhnu2wrIpPT7cqD/+C4QMmc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:39 +0200 Message-Id: <20200229164254.23604-17-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 16/31] 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: Sat, 29 Feb 2020 16:43:33 -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 --- include/libcamera/controls.h | 81 ++++++++++++--- src/libcamera/controls.cpp | 185 +++++++++++++++++++++++++++++------ 2 files changed, 225 insertions(+), 41 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 4538be06af93..d70a6bc4b83a 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::element_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::element_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::element_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 b2331ab7540d..f4089c8ffb4e 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,63 @@ 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 Contruct 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 the one of \a other + * \param[in] other The ControlValue to copy content from + * + * Deep-copy the content of \a other into the ControlValue by reserving memory + * and copy data there in case \a other transports arrays of values in one of + * its pointer data members. + * + * \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 +151,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 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 +186,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 (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 +234,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 +253,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 +271,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 Sat Feb 29 16:42: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: 2934 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 27341627B1 for ; Sat, 29 Feb 2020 17:43: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 BA1A4A28 for ; Sat, 29 Feb 2020 17:43:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994607; bh=C+HNPoqHGm77ozAdT3bjmZwyOkAxGPmKZhu1ad5gpm8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=IfCOe6DHQxnxG9JX8puYICDbm3AlZi/d+Q4rZJOoPcWFsZzno+6rmWiOTt1If4uVy SoGiTt5xfMVuZURkeMvdQMkZkJQbLQOmOm7Qf4vZ1bmPOy3Zw3YTXItZN4BO/0MxyL rIXzc0Hu6mg3xm6ugjV9RvfxafjqSBQAnXXUQMYI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:40 +0200 Message-Id: <20200229164254.23604-18-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 17/31] 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: Sat, 29 Feb 2020 16:43:31 -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 d70a6bc4b83a..f99c90e934c1 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 f4089c8ffb4e..829eea6f4240 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -806,6 +806,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 Sat Feb 29 16:42: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: 2935 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C29662797 for ; Sat, 29 Feb 2020 17:43: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 14ECDA49; Sat, 29 Feb 2020 17:43:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994608; bh=XgajUA+wYxeI21vUsHJ3ZrF9vgZdcdN5FsRt9F13gX4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ekJ7h9shr0HXzSbWCxVimDrK87gD8woeXtZhc/fcNs8ORN/43GmxQKzCf+egTtlo7 x/p/TK+Ivg1GgguYmcXZ+JfGfqivmY41zZbaFPFasvBNZ1jh5UwP3CouwIXmyNuPr2 78wXtow0QS7GAEmrsaRNg+mDvDLqYTuqxZpZmMx4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:41 +0200 Message-Id: <20200229164254.23604-19-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 18/31] 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: Sat, 29 Feb 2020 16:43:31 -0000 From: Jacopo Mondi Add a 'size' property to the control yaml description, to convey the size constraints of array constrols. 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 Sat Feb 29 16:42: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: 2938 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 DEACF6278B for ; Sat, 29 Feb 2020 17:43: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 755BAA28; Sat, 29 Feb 2020 17:43:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994608; bh=2T97E/upi6cYLoYbYWlfeMfQCGIfeR85Ph86ju/H8bw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N69glqaxREmsNH/jbSpy6uvgyYT9OJ6Xqm7FzgfVArFC5MFgLCn/gTYybHsM6Tda1 FMWRZaRgCJEsdKFSDnvkoJY/V8Lo0ysqI+abTYkiymLziuxb3F5qa4icafvnP0VXcf pvwhpxIEgIaQ3M+Ajq4gjMF3m3QZ+69o/Ao5EdnA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:42 +0200 Message-Id: <20200229164254.23604-20-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 19/31] 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: Sat, 29 Feb 2020 16:43:35 -0000 From: Jacopo Mondi Add support for float values in Control<> and ControlValue classes. Signed-off-by: Jacopo Mondi 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 f99c90e934c1..97a662e3f4a6 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 829eea6f4240..46469dd8b98b 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 */ /** @@ -209,6 +212,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; } @@ -378,9 +386,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 Sat Feb 29 16:42: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: 2937 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4F79A6277E for ; Sat, 29 Feb 2020 17:43:29 +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 D2C1433E; Sat, 29 Feb 2020 17:43:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994609; bh=/Jg+xdEQxOoTTB/rjIlYQHdW2FhGyFXTnbbRLgKG8RY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ICdFKCFfq2p6dith20r9WEmljfFn0AYboI1YIbXtlDl92zESlHlHyIVSeg9c6jVTx EgVBxdcEJFzBO+KknJJqFTX+LT6pell1F9LcC+E/t1vXIOeTXxrqV5L+Ip7Gi2zGf+ Ds3B1Rw+L6Mt+bqEmOi4yfxGOBQq/Q+nN0m+6t44= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:43 +0200 Message-Id: <20200229164254.23604-21-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 20/31] libcamera: controls: Add support for int8_t 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: Sat, 29 Feb 2020 16:43:35 -0000 From: Jacopo Mondi Add support for 8 bit integers to the control framework and to the control serializer. Signed-off-by: Jacopo Mondi 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 97a662e3f4a6..9b3aaae55c78 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -22,6 +22,7 @@ class ControlValidator; enum ControlType { ControlTypeNone, ControlTypeBool, + ControlTypeInteger8, ControlTypeInteger32, ControlTypeInteger64, ControlTypeFloat, @@ -43,6 +44,11 @@ struct control_type { static constexpr ControlType value = ControlTypeBool; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypeInteger8; +}; + 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..5537c5466025 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 ControlTypeInteger8: { + int8_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 ControlTypeInteger8: { + int8_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 46469dd8b98b..9970d75ea684 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), + [ControlTypeInteger8] = sizeof(int8_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 ControlTypeInteger8 + * The control stores an 8-bit integer value * \var ControlTypeInteger32 * The control stores a 32-bit integer value * \var ControlTypeInteger64 @@ -202,6 +205,11 @@ std::string ControlValue::toString() const str += *value ? "True" : "False"; break; } + case ControlTypeInteger8: { + const int8_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); @@ -386,9 +394,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, int8_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 Sat Feb 29 16:42: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: 2939 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A7C7C6279B for ; Sat, 29 Feb 2020 17:43:29 +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 3DC13A28 for ; Sat, 29 Feb 2020 17:43:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994609; bh=L0RUa2Fo8cBkPo9NUVkJbcQriLqiHOtWv0uA+4JKRFs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=D08DItmlSvBhDkW0bEfJ2gqfuGRAlmwnc7uG0uhtFpEe1faHpYONl2K9Wv+0tAD9p mR3DJKUZFwTGSkLhqSNEOGUQugtpAzs/bkn9Jc7DiOSkMVkwcV96col//JtyQWjrVD L8J5+2WmVxOqsl1ZiUMCFihwCJ6EPLGx1MCLHbW4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:44 +0200 Message-Id: <20200229164254.23604-22-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 21/31] 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: Sat, 29 Feb 2020 16:43:35 -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 25f38bab3dd9..cfb5c59dd028 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 Sat Feb 29 16:42: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: 2946 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 110636279A for ; Sat, 29 Feb 2020 17:43:30 +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 9510E33E; Sat, 29 Feb 2020 17:43:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994609; bh=GNVlyIH05vqc1DFwT9iV1N/4mJpUnELHv9994EracBs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tu9O6CuNsg8KqkisRmWI6vx5ISXWWll2ZsWvLRbZmx0bEYOV2UuerkieOWd1MqxT5 61USiJ+4GXrhXVZna+azg+0ozu1hEWWO0+zCEm+MyGTAs+7YjAaeS+LI33TD3yRYmR YxqfGnuKMBfwris0bIdDH8OmhxJP5pvKKf+9G3uw= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:45 +0200 Message-Id: <20200229164254.23604-23-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 22/31] 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: Sat, 29 Feb 2020 16:43:36 -0000 From: Jacopo Mondi The documentation of the read() and write() functions refer to inexistent '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 Sat Feb 29 16:42: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: 2940 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 6B2F86279C for ; Sat, 29 Feb 2020 17:43:30 +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 0100EA28; Sat, 29 Feb 2020 17:43:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994610; bh=zSHTjgu+vDt7JU2m5H9mOXFBD8jOA4e7olWkvvLRQQs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PrKDDiOr86GLcgnjl+PD+cSwauwMG0nVNlpkH/UpKeXv1Y6DY4TtO08wCGrGV5knw WWyuTraDOMZhLr5mI2S4jMmh+gz2Uhcz3UEkzqbt9TDDRGFXZS0h3+31zN6/B7qWny jLWpPfXPcqXzYgaKxTAmI8bq86H5EYZjp7lEtc1M= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:46 +0200 Message-Id: <20200229164254.23604-24-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 23/31] 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: Sat, 29 Feb 2020 16:43:36 -0000 From: Jacopo Mondi Add support to read and write a Span<> from and to 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..40380bf0434a 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 Sat Feb 29 16:42: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: 2941 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C482F6279D for ; Sat, 29 Feb 2020 17:43:30 +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 61BFB33E for ; Sat, 29 Feb 2020 17:43:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994610; bh=zhDNblkfSQLU1G/Vc9G29AQadAk7T5KBXLiuFTv8eOw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ArfzMrLUNbjW3j7LSunCEANX03X+MimCcLAPJ/Al3+ix/NXVgjdWpdfYED6fJMqAu i4yt/Jcd1j1gmMDdEucIaO3RAF4iMg7fknxUFeI5C0T+vPk8Z7641L5BZ89865HN4d JkNc5jLU9nXDlABTCS1ewGuEc+6nq/h7a2u53Qes= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:47 +0200 Message-Id: <20200229164254.23604-25-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 24/31] 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: Sat, 29 Feb 2020 16:43:36 -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 40380bf0434a..576f556f54a7 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 copy + * \param[in] count Number of data items to read + * + * This function read \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 Sat Feb 29 16:42: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: 2942 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 2412E6279E for ; Sat, 29 Feb 2020 17:43:31 +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 B4F1DA28 for ; Sat, 29 Feb 2020 17:43:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994610; bh=GN++EwtLbNzNVWBcuyBmbQ/OJB1OHW3zU6QAvEQhw0U=; h=From:To:Subject:Date:In-Reply-To:References:From; b=eFJ875+dMRTwa4KRMDVv7XOHzHtt9lFyZLoOpYfiDXS18sw6Q+L7Q3/DU7L9jNfYZ 50wGHNJ3YMrVnACGZjtqVp2fodwcrXWFEIju9AvG2ZeSdiz1SrgzCwJsJYLLckEf7x 6JGg7rX6u1HHcXpuBKbZralaTlPEhUs4o1/7+eSg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:48 +0200 Message-Id: <20200229164254.23604-26-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 25/31] 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: Sat, 29 Feb 2020 16:43:36 -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 5537c5466025..dc87b96f384b 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 ControlTypeInteger8: { - int8_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 Sat Feb 29 16:42: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: 2943 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 6E4376278C for ; Sat, 29 Feb 2020 17:43:31 +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 1205D33E for ; Sat, 29 Feb 2020 17:43:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994611; bh=FbhM2pKsf9zAPJD/WdkQfCaXmIBrLIK1B+8/o/+OiWo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DWHl/Y+AyZWzwQULaMbSlIwXkoCVEhrgRRebolpCDKWsD9SG9JDhidxV6wNaUEWX8 pvkvohK+jMElq0mWymyfKfmAAI9TMpNfGYnO4uSEdr3j1zeP6+4jOK/nqJi/4EfwD1 bupk/qBKA5gMoQpDHpe+Waw8BwZZyPpq5q6F0wPU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:49 +0200 Message-Id: <20200229164254.23604-27-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 26/31] 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: Sat, 29 Feb 2020 16:43:36 -0000 Use the zero-copy variant of ByteStreamBuffer::read() to read packet haders and control entries. This enhance 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 dc87b96f384b..6cac70739468 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -364,39 +364,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 << ")"; @@ -412,8 +419,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; } @@ -430,21 +437,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 {}; } @@ -456,10 +466,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) @@ -474,19 +484,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 Sat Feb 29 16:42: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: 2944 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 D8634627B1 for ; Sat, 29 Feb 2020 17:43:31 +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 650C8A28; Sat, 29 Feb 2020 17:43:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994611; bh=5WMaq6ShjVpoElkukTSQMf+J1iplhPR/Tv+cYIKDfbQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n/dNHW3RDrjPUXUTLVRjFd/6hPI7DIUQF4B3f2CU/j8QvwVxNagdyPFArKhBwWkbI uobE6iQ+eS5kSH3vzSdUZUqQ8qNX1d8q17N3ese/tTsGbZO8DWp0deVlf1HTbJVTzN e2hg8bDLClMatSu7/WkxJmgw9xx/G1kR8OztGToc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:50 +0200 Message-Id: <20200229164254.23604-28-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 27/31] 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: Sat, 29 Feb 2020 16:43:36 -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 6cac70739468..31b03e6e6d7c 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,52 +295,56 @@ 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 ControlTypeInteger8: { - int8_t value; - b.read(&value); - return ControlValue(value); - } + case ControlTypeInteger8: + 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); default: 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); } @@ -412,7 +418,7 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & /* Create and store the ControlRange. */ ctrls.emplace(controlIds_.back().get(), - load(type, values)); + loadControlRange(type, values)); } /* @@ -500,7 +506,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 Sat Feb 29 16:42:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2945 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3D75262797 for ; Sat, 29 Feb 2020 17:43:32 +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 CA47833E; Sat, 29 Feb 2020 17:43:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994612; bh=H8lEPXXZYPJsDflwWU/6s11F3CBs2bhReoeVcz6rVEg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hBUAgZgcHqH7W9+vF8fesHjodCP4QkRizXy0EeF0EJsZXal8sEkF4bDeiJEAoJWWN MgHXT/9PxHaAcBAIcU7KbbDIH964G6mk4B5lTktsSCVbiKEaD6UBdqEGl0gURFH8gZ dvTsoFENwE6l4z1XTQZFLANaOdCLh7WHIP1unAD0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:51 +0200 Message-Id: <20200229164254.23604-29-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 28/31] 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: Sat, 29 Feb 2020 16:43:36 -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', }; From patchwork Sat Feb 29 16:42: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: 2947 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A73DD627AB for ; Sat, 29 Feb 2020 17:43:32 +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 38742A28; Sat, 29 Feb 2020 17:43:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994612; bh=0dCmsokvOcYVUCdhUmP3Cy39eRfW/7lNRK5xMNbW5WI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bufR7iu9YzbfkIPUlFim0BBc+VIdptVZ9o0guabSFkzrIaxfCuPOrBMQVzyIoAe3z 27UxqzZUXaRDNsfaLfT2/rBD3KrmXRCoIAkHKQdVXhlcvvJmbnVc7gTXcLCAo9gBqB u1YqMsDx15C2Z4GzWdC9xm+7VKZBhGhU39UM/N00= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:52 +0200 Message-Id: <20200229164254.23604-30-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 29/31] DNI: test 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: Sat, 29 Feb 2020 16:43:36 -0000 From: Jacopo Mondi Define a fictional array control and register it in the VIMC pipeline handler. Add a test to exercise it. Do not include, just a proof of concept. The test could be included once we'll have real array controls defined. Signed-off-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/libcamera/control_ids.yaml | 5 ++ src/libcamera/pipeline/vimc.cpp | 5 ++ test/controls/array_controls.cpp | 107 +++++++++++++++++++++++++++++++ test/controls/meson.build | 1 + 4 files changed, 118 insertions(+) create mode 100644 test/controls/array_controls.cpp diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml index 4befec746a59..14adb0dc78e8 100644 --- a/src/libcamera/control_ids.yaml +++ b/src/libcamera/control_ids.yaml @@ -50,4 +50,9 @@ controls: type: int32_t description: Specify a fixed gain parameter + - BayerGains: + type: float + description: Gains to apply to the four Bayer colour components for white balance + size: [4] + ... diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 5d3d12fef30b..3fa4d222e06e 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -451,6 +451,11 @@ int VimcCameraData::init(MediaDevice *media) ctrls.emplace(id, range); } + /* Register a compound control. */ + ctrls.emplace(std::piecewise_construct, + std::forward_as_tuple(&controls::BayerGains), + std::forward_as_tuple(0.5f, 4.0f)); + controlInfo_ = std::move(ctrls); /* Initialize the camera properties. */ diff --git a/test/controls/array_controls.cpp b/test/controls/array_controls.cpp new file mode 100644 index 000000000000..b75219d82c37 --- /dev/null +++ b/test/controls/array_controls.cpp @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * array_controls.cpp - Array controls test + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "camera_controls.h" + +#include "camera_test.h" +#include "test.h" + +using namespace std; +using namespace libcamera; + +class ArrayControlsTest : public CameraTest, public Test +{ +public: + ArrayControlsTest() + : CameraTest("VIMC Sensor B") + { + } + +protected: + int init() override + { + return status_; + } + + template + int compareValues(const Span &span, const R &value) + { + if (value.size() != span.size()) { + cerr << "set(" << typeid(T).name() << ") and get() dimension mismatch" << endl; + return TestFail; + } + + for (unsigned int i = 0; i < value.size(); ++i) { + if (value[i] != span[i]) { + cerr << "set(" << typeid(T).name() << ") and get() value mismatch" << endl; + return TestFail; + } + } + + return TestPass; + } + + int run() override + { + CameraControlValidator validator(camera_.get()); + ControlList list(controls::controls, &validator); + + /* + * Test array control get and set. set() is tested using + * std::initializer_list, std::array, std::vector, and Span() + * constructed from both an array and a vector as from a plain + * C array. Const and non-const versions are compile-tested. + */ + constexpr float const_array[4] = { 1.1, 1.0, 1.2, 0.9 }; + float array[4] = { 1.1, 1.0, 1.2, 0.9 }; + + list.set(controls::BayerGains, { 1.1f, 1.0f, 1.2f, 0.9f }); + list.set(controls::BayerGains, Span(const_array)); + list.set(controls::BayerGains, Span(array)); + list.set(controls::BayerGains, const_array); + list.set(controls::BayerGains, array); + + if (compareValues(list.get(controls::BayerGains), Span(array)) == TestFail) + return TestFail; + + constexpr std::array const_std_array{ 1.3, 0.9, 1.5, 0.8 }; + std::array std_array{ 1.3, 0.9, 1.5, 0.8 }; + + list.set(controls::BayerGains, Span(const_std_array)); + list.set(controls::BayerGains, Span(std_array)); + list.set(controls::BayerGains, const_std_array); + list.set(controls::BayerGains, std_array); + + if (compareValues(list.get(controls::BayerGains), std_array) == TestFail) + return TestFail; + + const std::vector const_vector{ 1.0, 1.0, 1.0, 1.0 }; + std::vector vector{ 1.0, 1.0, 1.0, 1.0 }; + + list.set(controls::BayerGains, Span(const_vector)); + list.set(controls::BayerGains, Span(vector)); + list.set(controls::BayerGains, const_vector); + list.set(controls::BayerGains, vector); + + if (compareValues(list.get(controls::BayerGains), const_vector) == TestFail) + return TestFail; + + return TestPass; + } +}; + +TEST_REGISTER(ArrayControlsTest) diff --git a/test/controls/meson.build b/test/controls/meson.build index f0850df28c8a..9d9b6ed1d666 100644 --- a/test/controls/meson.build +++ b/test/controls/meson.build @@ -1,4 +1,5 @@ control_tests = [ + [ 'array_controls', 'array_controls.cpp'], [ 'control_info', 'control_info.cpp' ], [ 'control_list', 'control_list.cpp' ], [ 'control_range', 'control_range.cpp' ], From patchwork Sat Feb 29 16:42: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: 2948 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 0B6A9627AD for ; Sat, 29 Feb 2020 17:43:33 +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 9758EA49; Sat, 29 Feb 2020 17:43:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994612; bh=8UKmWivj2LLmPXl2xn/4GadqVCsArv+M6txJNT5cBJw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PEtrAGi4yhjHgCoEqi9QLPNMGo3OLxi0inmxHhPrqiaz/UEuklts4eEvnxj73Yzb5 OedN3kK5jceBbzDyOy5BVYTO5LIkNYGrTAL6O9yKDOZaKtQ6p3QSkrrbIzLvwbxo5w 2eDvxqIxcrUPYOE0dDtwWW3lOm9uexMDC/JgC8rQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:53 +0200 Message-Id: <20200229164254.23604-31-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 30/31] DNI: test: serialization: Serialize 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: Sat, 29 Feb 2020 16:43:36 -0000 From: Jacopo Mondi Depends on the fictional array control definition. Not for inclusion. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart --- test/serialization/control_serialization.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/serialization/control_serialization.cpp b/test/serialization/control_serialization.cpp index 2989b52774fb..1de54a02c443 100644 --- a/test/serialization/control_serialization.cpp +++ b/test/serialization/control_serialization.cpp @@ -38,13 +38,14 @@ protected: size_t size; int ret; - /* Create a control list with three controls. */ + /* Create a control list with several controls. */ const ControlInfoMap &infoMap = camera_->controls(); ControlList list(infoMap); list.set(controls::Brightness, 255); list.set(controls::Contrast, 128); list.set(controls::Saturation, 50); + list.set(controls::BayerGains, { 1.0f, 1.1f, 0.9f, 1.0f }); /* * Serialize the control list, this should fail as the control From patchwork Sat Feb 29 16:42: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: 2949 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 71A9A627BB for ; Sat, 29 Feb 2020 17:43:33 +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 F3C3D33E for ; Sat, 29 Feb 2020 17:43:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994613; bh=nlE3y3JJyqKIf4WHT9r9zQrrKR/kKIaHUi0LiVR3nks=; h=From:To:Subject:Date:In-Reply-To:References:From; b=E0sN83JqJyBLfNZhlqOQXuyWKsZ62EVZ9kOTvtBXjrjscFMB56iI+M2Pw2W9w0rfw FQ434EvvJ1QkGshcgNL7sVWJIsjA6bXXc9DH1YeeWbkKZtihjN4MgyaoonT7oyfxmf gBMk3zWrddMbvRGvHeiLoDEjdKuV2CeVTyWggwu0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:54 +0200 Message-Id: <20200229164254.23604-32-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 31/31] DNI: test: serialization: Serialize array control with a single element 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: Sat, 29 Feb 2020 16:43:37 -0000 Serializing an array control with a single element tests the difference between single-element arrays and non-array controls. Signed-off-by: Laurent Pinchart --- test/serialization/control_serialization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/serialization/control_serialization.cpp b/test/serialization/control_serialization.cpp index 1de54a02c443..f62efe934555 100644 --- a/test/serialization/control_serialization.cpp +++ b/test/serialization/control_serialization.cpp @@ -45,7 +45,7 @@ protected: list.set(controls::Brightness, 255); list.set(controls::Contrast, 128); list.set(controls::Saturation, 50); - list.set(controls::BayerGains, { 1.0f, 1.1f, 0.9f, 1.0f }); + list.set(controls::BayerGains, { 1.0f }); /* * Serialize the control list, this should fail as the control From patchwork Sun Mar 1 19:26:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2953 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 E285960429 for ; Sun, 1 Mar 2020 20:26:47 +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 6104B54A for ; Sun, 1 Mar 2020 20:26:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583090807; bh=ZZ3uVv5o9JYeqnSycgzk6Xtwj05iu9U3XqBjFgoMS/M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=EnnVQEdyo0u2o4PPLyyRNtbu4QYngK8jZiJtAg6Hz/ZjsB5eYpyl04cQpRcbedipt 0yQ/ngwaHAnjQc6+lCCIu6A4Oz+FRjx7VB+x+7lAzxQnSnDDhj/+qK2EgPEdlhKff7 yFp3eptZVEMHXS+B6yzwaDJ/8nTy9qw+UputbIUc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sun, 1 Mar 2020 21:26:18 +0200 Message-Id: <20200301192619.15644-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 32/31] 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: Sun, 01 Mar 2020 19:26:48 -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 --- src/libcamera/controls.cpp | 2 +- test/controls/control_value.cpp | 110 +++++++++++++++++++++++++------- 2 files changed, 89 insertions(+), 23 deletions(-) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index a9dfc53e8565..aa3e7a267303 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -202,7 +202,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 ControlTypeInteger8: { diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp index a1ffa842f29e..111b4c5d1a08 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() != ControlTypeInteger8) { + cerr << "Control type mismatch after setting to int8_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 int8_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 int8_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 Sun Mar 1 19:26:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2954 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2FB3F60429 for ; Sun, 1 Mar 2020 20:26:48 +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 B6FDC555 for ; Sun, 1 Mar 2020 20:26:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1583090807; bh=TWjmRddmPHzB77pj03mttptvjutG79f06p466PSWFTU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YfwUaek/wnO0ahlIH8h2qG+Kccv4MmZuPqXjBk7xAWxzkr8IQdR8PoK7jqeYrCQxb OCMh0MJpL54dh+1fTW/RztCuT6U5X1WHA6ZTdUMg/CCmf+KPQTqYn70NC5rMIxFW7x WQIzoqyhL70wQ/e9R2rKvtbmsmlSdrfqvfJrj+tY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sun, 1 Mar 2020 21:26:19 +0200 Message-Id: <20200301192619.15644-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200301192619.15644-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> <20200301192619.15644-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 33/31] 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: Sun, 01 Mar 2020 19:26:48 -0000 Add tests to ControlValueTest to cover array controls of all supported types. Signed-off-by: Laurent Pinchart --- 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 111b4c5d1a08..f30bff4acc68 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 int8s{ 3, 14, 15, 9 }; + value.set(Span(int8s)); + if (value.isNone() || !value.isArray() || + value.type() != ControlTypeInteger8) { + cerr << "Control type mismatch after setting to int8_t array" << endl; + return TestFail; + } + + Span int8sResult = value.get>(); + if (int8s.size() != int8sResult.size() || + !std::equal(int8s.begin(), int8s.end(), int8sResult.begin())) { + cerr << "Control value mismatch after setting to int8_t array" << endl; + return TestFail; + } + + if (value.toString() != "[ 3, 14, 15, 9 ]") { + cerr << "Control string mismatch after setting to int8_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; } };