summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/controls.h2
-rw-r--r--src/libcamera/controls.cpp30
2 files changed, 32 insertions, 0 deletions
diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index 1a5690a5..1c9b37e6 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -363,7 +363,9 @@ public:
bool empty() const { return controls_.empty(); }
std::size_t size() const { return controls_.size(); }
+
void clear() { controls_.clear(); }
+ void merge(const ControlList &source);
bool contains(const ControlId &id) const;
bool contains(unsigned int id) const;
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index c58ed394..b763148d 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -875,6 +875,36 @@ ControlList::ControlList(const ControlInfoMap &infoMap, ControlValidator *valida
*/
/**
+ * \brief Merge the \a source into the ControlList
+ * \param[in] source The ControlList to merge into this object
+ *
+ * Merging two control lists copies elements from the \a source and inserts
+ * them in *this. If the \a source contains elements whose key is already
+ * present in *this, then those elements are not overwritten.
+ *
+ * Only control lists created from the same ControlIdMap or ControlInfoMap may
+ * be merged. Attempting to do otherwise results in undefined behaviour.
+ *
+ * \todo Reimplement or implement an overloaded version which internally uses
+ * std::unordered_map::merge() and accepts a non-const argument.
+ */
+void ControlList::merge(const ControlList &source)
+{
+ ASSERT(idmap_ == source.idmap_);
+
+ for (const auto &ctrl : source) {
+ if (contains(ctrl.first)) {
+ const ControlId *id = idmap_->at(ctrl.first);
+ LOG(Controls, Warning)
+ << "Control " << id->name() << " not overwritten";
+ continue;
+ }
+
+ set(ctrl.first, ctrl.second);
+ }
+}
+
+/**
* \brief Check if the list contains a control with the specified \a id
* \param[in] id The control ID
*
id='n173' href='#n173'>173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * ipa_controls.cpp - IPA control handling
 */

#include <libcamera/ipa/ipa_controls.h>

/**
 * \file ipa_controls.h
 * \brief Type definitions for serialized controls
 *
 * This file defines binary formats to store ControlList and ControlInfoMap
 * instances in contiguous, self-contained memory areas called control packets.
 * It describes the layout of the packets through a set of C structures. These
 * formats shall be used when serializing ControlList and ControlInfoMap to
 * transfer them through the IPA C interface and IPA IPC transports.
 *
 * A control packet contains a list of entries, each of them describing a single
 * control info or control value. The packet starts with a fixed-size header
 * described by the ipa_controls_header structure, followed by an array of
 * fixed-size entries. Each entry is associated with data, stored either
 * directly in the entry, or in a data section after the entries array.
 *
 * The following diagram describes the layout of the ControlList packet.
 *
 * ~~~~
 *           +-------------------------+    .                      .
 *  Header / | ipa_controls_header     |    |                      |
 *         | |                         |    |                      |
 *         \ |                         |    |                      |
 *           +-------------------------+    |                      |
 *         / | ipa_control_value_entry |    | hdr.data_offset      |
 *         | | #0                      |    |                      |
 * Control | +-------------------------+    |                      |
 *   value | | ...                     |    |                      |
 * entries | +-------------------------+    |                      |
 *         | | ipa_control_value_entry |    |             hdr.size |
 *         \ | #hdr.entries - 1        |    |                      |
 *           +-------------------------+    |                      |
 *           | empty space (optional)  |    |                      |
 *           +-------------------------+ <--´  .                   |
 *         / | ...                     |       | entry[n].offset   |
 *    Data | | ...                     |       |                   |
 * section | | value data for entry #n | <-----´                   |
 *         \ | ...                     |                           |
 *           +-------------------------+                           |
 *           | empty space (optional)  |                           |
 *           +-------------------------+ <-------------------------´
 * ~~~~
 *
 * The packet header contains the size of the packet, the number of entries, and
 * the offset from the beginning of the packet to the data section. The packet
 * entries array immediately follows the header. The data section starts at the
 * offset ipa_controls_header::data_offset from the beginning of the packet, and
 * shall be aligned to a multiple of 8 bytes.
 *
 * Entries are described by the ipa_control_value_entry structure. They contain
 * the numerical ID of the control, its type, and the number of control values.
 *
 * The control values are stored in the data section in the platform's native
 * format. The ipa_control_value_entry::offset field stores the offset from the
 * beginning of the data section to the values.
 *
 * All control values in the data section shall be stored in the same order as
 * the respective control entries, shall be aligned to a multiple of 8 bytes,
 * and shall be contiguous in memory.
 *
 * Empty spaces may be present between the end of the entries array and the
 * data section, and after the data section. They shall be ignored when parsing
 * the packet.
 *
 * The following diagram describes the layout of the ControlInfoMap packet.
 *
 * ~~~~
 *           +-------------------------+    .                      .
 *  Header / | ipa_controls_header     |    |                      |
 *         | |                         |    |                      |
 *         \ |                         |    |                      |
 *           +-------------------------+    |                      |
 *         / | ipa_control_info_entry  |    | hdr.data_offset      |
 *         | | #0                      |    |                      |
 * Control | +-------------------------+    |                      |
 *    info | | ...                     |    |                      |
 * entries | +-------------------------+    |                      |
 *         | | ipa_control_info_entry  |    |             hdr.size |
 *         \ | #hdr.entries - 1        |    |                      |
 *           +-------------------------+    |                      |
 *           | empty space (optional)  |    |                      |
 *           +-------------------------+ <--´  .                   |
 *         / | ...                     |       | entry[n].offset   |
 *    Data | | ...                     |       |                   |
 * section | | info data for entry #n  | <-----´                   |
 *         \ | ...                     |                           |
 *           +-------------------------+                           |
 *           | empty space (optional)  |                           |
 *           +-------------------------+ <-------------------------´
 * ~~~~
 *
 * The packet header is identical to the ControlList packet header.
 *
 * Entries are described by the ipa_control_info_entry structure. They contain
 * the numerical ID and type of the control. The control info data is stored
 * in the data section as described by the following diagram.
 *
 * ~~~~
 *           +-------------------------+       .
 *         / | ...                     |       | entry[n].offset
 *         | +-------------------------+ <-----´
 *    Data | | minimum value (#n)      | \
 * section | +-------------------------+ | Entry #n
 *         | | maximum value (#n)      | /
 *         | +-------------------------+
 *         \ | ...                     |