summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ipa/ipa_interface.h2
-rw-r--r--include/libcamera/controls.h45
-rw-r--r--src/ipa/ipa_vimc.cpp2
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp6
-rw-r--r--src/libcamera/camera_sensor.cpp2
-rw-r--r--src/libcamera/controls.cpp139
-rw-r--r--src/libcamera/include/camera_sensor.h4
-rw-r--r--src/libcamera/include/v4l2_controls.h36
-rw-r--r--src/libcamera/include/v4l2_device.h4
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp11
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp12
-rw-r--r--src/libcamera/pipeline/vimc.cpp11
-rw-r--r--src/libcamera/proxy/ipa_proxy_linux.cpp2
-rw-r--r--src/libcamera/v4l2_controls.cpp94
-rw-r--r--src/libcamera/v4l2_device.cpp2
-rw-r--r--test/v4l2_videodevice/controls.cpp2
16 files changed, 220 insertions, 154 deletions
diff --git a/include/ipa/ipa_interface.h b/include/ipa/ipa_interface.h
index dfb1bcbe..8fd658af 100644
--- a/include/ipa/ipa_interface.h
+++ b/include/ipa/ipa_interface.h
@@ -43,7 +43,7 @@ public:
virtual int init() = 0;
virtual void configure(const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, V4L2ControlInfoMap> &entityControls) = 0;
+ const std::map<unsigned int, ControlInfoMap> &entityControls) = 0;
virtual void mapBuffers(const std::vector<IPABuffer> &buffers) = 0;
virtual void unmapBuffers(const std::vector<unsigned int> &ids) = 0;
diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index 5534a2ed..80414c6f 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -118,7 +118,50 @@ private:
};
using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;
-using ControlInfoMap = std::unordered_map<const ControlId *, ControlRange>;
+
+class ControlInfoMap : private std::unordered_map<const ControlId *, ControlRange>
+{
+public:
+ using Map = std::unordered_map<const ControlId *, ControlRange>;
+
+ ControlInfoMap() = default;
+ ControlInfoMap(const ControlInfoMap &other) = default;
+ ControlInfoMap(std::initializer_list<Map::value_type> init);
+
+ ControlInfoMap &operator=(const ControlInfoMap &other) = default;
+ ControlInfoMap &operator=(std::initializer_list<Map::value_type> init);
+ ControlInfoMap &operator=(Map &&info);
+
+ using Map::key_type;
+ using Map::mapped_type;
+ using Map::value_type;
+ using Map::size_type;
+ using Map::iterator;
+ using Map::const_iterator;
+
+ using Map::begin;
+ using Map::cbegin;
+ using Map::end;
+ using Map::cend;
+ using Map::at;
+ using Map::empty;
+ using Map::size;
+ using Map::count;
+ using Map::find;
+
+ mapped_type &at(unsigned int key);
+ const mapped_type &at(unsigned int key) const;
+ size_type count(unsigned int key) const;
+ iterator find(unsigned int key);
+ const_iterator find(unsigned int key) const;
+
+ const ControlIdMap &idmap() const { return idmap_; }
+
+private:
+ void generateIdmap();
+
+ ControlIdMap idmap_;
+};
class ControlList
{
diff --git a/src/ipa/ipa_vimc.cpp b/src/ipa/ipa_vimc.cpp
index 620dc25f..63d578b4 100644
--- a/src/ipa/ipa_vimc.cpp
+++ b/src/ipa/ipa_vimc.cpp
@@ -31,7 +31,7 @@ public:
int init() override;
void configure(const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, V4L2ControlInfoMap> &entityControls) override {}
+ const std::map<unsigned int, ControlInfoMap> &entityControls) override {}
void mapBuffers(const std::vector<IPABuffer> &buffers) override {}
void unmapBuffers(const std::vector<unsigned int> &ids) override {}
void processEvent(const IPAOperationData &event) override {}
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index d64c334c..bd703898 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -33,7 +33,7 @@ public:
int init() override { return 0; }
void configure(const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, V4L2ControlInfoMap> &entityControls) override;
+ const std::map<unsigned int, ControlInfoMap> &entityControls) override;
void mapBuffers(const std::vector<IPABuffer> &buffers) override;
void unmapBuffers(const std::vector<unsigned int> &ids) override;
void processEvent(const IPAOperationData &event) override;
@@ -49,7 +49,7 @@ private:
std::map<unsigned int, BufferMemory> bufferInfo_;
- V4L2ControlInfoMap ctrls_;
+ ControlInfoMap ctrls_;
/* Camera sensor controls. */
bool autoExposure_;
@@ -62,7 +62,7 @@ private:
};
void IPARkISP1::configure(const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, V4L2ControlInfoMap> &entityControls)
+ const std::map<unsigned int, ControlInfoMap> &entityControls)
{
if (entityControls.empty())
return;
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 1b8e8c0e..86f0c772 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -251,7 +251,7 @@ int CameraSensor::setFormat(V4L2SubdeviceFormat *format)
* \brief Retrieve the supported V4L2 controls and their information
* \return A map of the V4L2 controls supported by the sensor
*/
-const V4L2ControlInfoMap &CameraSensor::controls() const
+const ControlInfoMap &CameraSensor::controls() const
{
return subdev_->controls();
}
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 6a0301f3..bf7634aa 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -393,9 +393,146 @@ std::string ControlRange::toString() const
*/
/**
- * \typedef ControlInfoMap
+ * \class ControlInfoMap
* \brief A map of ControlId to ControlRange
+ *
+ * The ControlInfoMap class describes controls supported by an object as an
+ * unsorted map of ControlId pointers to ControlRange instances. Unlike the
+ * standard std::unsorted_map<> class, it is designed the be immutable once
+ * constructed, and thus only exposes the read accessors of the
+ * std::unsorted_map<> base class.
+ *
+ * In addition to the features of the standard unsorted map, this class also
+ * provides access to the mapped elements using numerical ID keys. It maintains
+ * an internal map of numerical ID to ControlId for this purpose, and exposes it
+ * through the idmap() method to help construction of ControlList instances.
+ */
+
+/**
+ * \typedef ControlInfoMap::Map
+ * \brief The base std::unsorted_map<> container
+ */
+
+/**
+ * \fn ControlInfoMap::ControlInfoMap(const ControlInfoMap &other)
+ * \brief Copy constructor, construct a ControlInfoMap from a copy of \a other
+ * \param[in] other The other ControlInfoMap
+ */
+
+/**
+ * \brief Construct a ControlInfoMap from an initializer list
+ * \param[in] init The initializer list
+ */
+ControlInfoMap::ControlInfoMap(std::initializer_list<Map::value_type> init)
+ : Map(init)
+{
+ generateIdmap();
+}
+
+/**
+ * \fn ControlInfoMap &ControlInfoMap::operator=(const ControlInfoMap &other)
+ * \brief Copy assignment operator, replace the contents with a copy of \a other
+ * \param[in] other The other ControlInfoMap
+ * \return A reference to the ControlInfoMap
+ */
+
+/**
+ * \brief Replace the contents with those from the initializer list
+ * \param[in] init The initializer list
+ * \return A reference to the ControlInfoMap
+ */
+ControlInfoMap &ControlInfoMap::operator=(std::initializer_list<Map::value_type> init)
+{
+ Map::operator=(init);
+ generateIdmap();
+ return *this;
+}
+
+/**
+ * \brief Move assignment operator from a plain map
+ * \param[in] info The control info plain map
+ *
+ * Populate the map by replacing its contents with those of \a info using move
+ * semantics. Upon return the \a info map will be empty.
+ *
+ * \return A reference to the populated ControlInfoMap
+ */
+ControlInfoMap &ControlInfoMap::operator=(Map &&info)
+{
+ Map::operator=(std::move(info));
+ generateIdmap();
+ return *this;
+}
+
+/**
+ * \brief Access specified element by numerical ID
+ * \param[in] id The numerical ID
+ * \return A reference to the element whose ID is equal to \a id
*/
+ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id)
+{
+ return at(idmap_.at(id));
+}
+
+/**
+ * \brief Access specified element by numerical ID
+ * \param[in] id The numerical ID
+ * \return A const reference to the element whose ID is equal to \a id
+ */
+const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const
+{
+ return at(idmap_.at(id));
+}
+
+/**
+ * \brief Count the number of elements matching a numerical ID
+ * \param[in] id The numerical ID
+ * \return The number of elements matching the numerical \a id
+ */
+ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
+{
+ return count(idmap_.at(id));
+}
+
+/**
+ * \brief Find the element matching a numerical ID
+ * \param[in] id The numerical ID
+ * \return An iterator pointing to the element matching the numerical \a id, or
+ * end() if no such element exists
+ */
+ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
+{
+ return find(idmap_.at(id));
+}
+
+/**
+ * \brief Find the element matching a numerical ID
+ * \param[in] id The numerical ID
+ * \return A const iterator pointing to the element matching the numerical
+ * \a id, or end() if no such element exists
+ */
+ControlInfoMap::const_iterator ControlInfoMap::find(unsigned int id) const
+{
+ return find(idmap_.at(id));
+}
+
+/**
+ * \fn const ControlIdMap &ControlInfoMap::idmap() const
+ * \brief Retrieve the ControlId map
+ *
+ * Constructing ControlList instances for V4L2 controls requires a ControlIdMap
+ * for the V4L2 device that the control list targets. This helper method
+ * returns a suitable idmap for that purpose.
+ *
+ * \return The ControlId map
+ */
+
+void ControlInfoMap::generateIdmap()
+{
+ idmap_.clear();
+ for (const auto &ctrl : *this)
+ idmap_[ctrl.first->id()] = ctrl.first;
+}
/**
* \class ControlList
diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h
index f426e29b..1fb36a4f 100644
--- a/src/libcamera/include/camera_sensor.h
+++ b/src/libcamera/include/camera_sensor.h
@@ -16,9 +16,9 @@
namespace libcamera {
+class ControlInfoMap;
class ControlList;
class MediaEntity;
-class V4L2ControlInfoMap;
class V4L2Subdevice;
struct V4L2SubdeviceFormat;
@@ -43,7 +43,7 @@ public:
const Size &size) const;
int setFormat(V4L2SubdeviceFormat *format);
- const V4L2ControlInfoMap &controls() const;
+ const ControlInfoMap &controls() const;
int getControls(ControlList *ctrls);
int setControls(ControlList *ctrls);
diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h
index c427b845..e16c4957 100644
--- a/src/libcamera/include/v4l2_controls.h
+++ b/src/libcamera/include/v4l2_controls.h
@@ -31,44 +31,10 @@ public:
V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl);
};
-class V4L2ControlInfoMap : private ControlInfoMap
-{
-public:
- V4L2ControlInfoMap &operator=(ControlInfoMap &&info);
-
- using ControlInfoMap::key_type;
- using ControlInfoMap::mapped_type;
- using ControlInfoMap::value_type;
- using ControlInfoMap::size_type;
- using ControlInfoMap::iterator;
- using ControlInfoMap::const_iterator;
-
- using ControlInfoMap::begin;
- using ControlInfoMap::cbegin;
- using ControlInfoMap::end;
- using ControlInfoMap::cend;
- using ControlInfoMap::at;
- using ControlInfoMap::empty;
- using ControlInfoMap::size;
- using ControlInfoMap::count;
- using ControlInfoMap::find;
-
- mapped_type &at(unsigned int key);
- const mapped_type &at(unsigned int key) const;
- size_type count(unsigned int key) const;
- iterator find(unsigned int key);
- const_iterator find(unsigned int key) const;
-
- const ControlIdMap &idmap() const { return idmap_; }
-
-private:
- ControlIdMap idmap_;
-};
-
class V4L2ControlList : public ControlList
{
public:
- V4L2ControlList(const V4L2ControlInfoMap &info)
+ V4L2ControlList(const ControlInfoMap &info)
: ControlList(info.idmap())
{
}
diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h
index f30b1c2c..6bfddefe 100644
--- a/src/libcamera/include/v4l2_device.h
+++ b/src/libcamera/include/v4l2_device.h
@@ -24,7 +24,7 @@ public:
void close();
bool isOpen() const { return fd_ != -1; }
- const V4L2ControlInfoMap &controls() const { return controls_; }
+ const ControlInfoMap &controls() const { return controls_; }
int getControls(ControlList *ctrls);
int setControls(ControlList *ctrls);
@@ -49,7 +49,7 @@ private:
unsigned int count);
std::vector<std::unique_ptr<V4L2ControlId>> controlIds_;
- V4L2ControlInfoMap controls_;
+ ControlInfoMap controls_;
std::string deviceNode_;
int fd_;
};
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 9b19bde8..7a28b03b 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -776,7 +776,7 @@ int PipelineHandlerRkISP1::start(Camera *camera)
.size = data->stream_.configuration().size,
};
- std::map<unsigned int, V4L2ControlInfoMap> entityControls;
+ std::map<unsigned int, ControlInfoMap> entityControls;
entityControls.emplace(0, data->sensor_->controls());
data->ipa_->configure(streamConfig, entityControls);
@@ -875,9 +875,12 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
std::unique_ptr<RkISP1CameraData> data =
utils::make_unique<RkISP1CameraData>(this);
- data->controlInfo_.emplace(std::piecewise_construct,
- std::forward_as_tuple(&controls::AeEnable),
- std::forward_as_tuple(false, true));
+ ControlInfoMap::Map ctrls;
+ ctrls.emplace(std::piecewise_construct,
+ std::forward_as_tuple(&controls::AeEnable),
+ std::forward_as_tuple(false, true));
+
+ data->controlInfo_ = std::move(ctrls);
data->sensor_ = new CameraSensor(sensor);
ret = data->sensor_->init();
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 018c7691..a64e1af4 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -335,7 +335,9 @@ int UVCCameraData::init(MediaEntity *entity)
video_->bufferReady.connect(this, &UVCCameraData::bufferReady);
/* Initialise the supported controls. */
- const V4L2ControlInfoMap &controls = video_->controls();
+ const ControlInfoMap &controls = video_->controls();
+ ControlInfoMap::Map ctrls;
+
for (const auto &ctrl : controls) {
const ControlRange &range = ctrl.second;
const ControlId *id;
@@ -360,11 +362,13 @@ int UVCCameraData::init(MediaEntity *entity)
continue;
}
- controlInfo_.emplace(std::piecewise_construct,
- std::forward_as_tuple(id),
- std::forward_as_tuple(range));
+ ctrls.emplace(std::piecewise_construct,
+ std::forward_as_tuple(id),
+ std::forward_as_tuple(range));
}
+ controlInfo_ = std::move(ctrls);
+
return 0;
}
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index f7f82edc..6a424411 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -411,7 +411,9 @@ int VimcCameraData::init(MediaDevice *media)
return -ENODEV;
/* Initialise the supported controls. */
- const V4L2ControlInfoMap &controls = sensor_->controls();
+ const ControlInfoMap &controls = sensor_->controls();
+ ControlInfoMap::Map ctrls;
+
for (const auto &ctrl : controls) {
const ControlRange &range = ctrl.second;
const ControlId *id;
@@ -430,11 +432,12 @@ int VimcCameraData::init(MediaDevice *media)
continue;
}
- controlInfo_.emplace(std::piecewise_construct,
- std::forward_as_tuple(id),
- std::forward_as_tuple(range));
+ ctrls.emplace(std::piecewise_construct,
+ std::forward_as_tuple(id),
+ std::forward_as_tuple(range));
}
+ controlInfo_ = std::move(ctrls);
return 0;
}
diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp
index 41bd965f..4e6fa689 100644
--- a/src/libcamera/proxy/ipa_proxy_linux.cpp
+++ b/src/libcamera/proxy/ipa_proxy_linux.cpp
@@ -28,7 +28,7 @@ public:
int init() override { return 0; }
void configure(const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, V4L2ControlInfoMap> &entityControls) override {}
+ const std::map<unsigned int, ControlInfoMap> &entityControls) override {}
void mapBuffers(const std::vector<IPABuffer> &buffers) override {}
void unmapBuffers(const std::vector<unsigned int> &ids) override {}
void processEvent(const IPAOperationData &event) override {}
diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp
index 33816571..37ff034e 100644
--- a/src/libcamera/v4l2_controls.cpp
+++ b/src/libcamera/v4l2_controls.cpp
@@ -127,101 +127,11 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl)
}
/**
- * \class V4L2ControlInfoMap
- * \brief A map of controlID to ControlRange for V4L2 controls
- */
-
-/**
- * \brief Move assignment operator from a ControlInfoMap
- * \param[in] info The control info map
- *
- * Populate the map by replacing its contents with those of \a info using move
- * semantics. Upon return the \a info map will be empty.
- *
- * This is the only supported way to populate a V4L2ControlInfoMap.
- *
- * \return The populated V4L2ControlInfoMap
- */
-V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(ControlInfoMap &&info)
-{
- ControlInfoMap::operator=(std::move(info));
-
- idmap_.clear();
- for (const auto &ctrl : *this)
- idmap_[ctrl.first->id()] = ctrl.first;
-
- return *this;
-}
-
-/**
- * \brief Access specified element by numerical ID
- * \param[in] id The numerical ID
- * \return A reference to the element whose ID is equal to \a id
- */
-V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id)
-{
- return at(idmap_.at(id));
-}
-
-/**
- * \brief Access specified element by numerical ID
- * \param[in] id The numerical ID
- * \return A const reference to the element whose ID is equal to \a id
- */
-const V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) const
-{
- return at(idmap_.at(id));
-}
-
-/**
- * \brief Count the number of elements matching a numerical ID
- * \param[in] id The numerical ID
- * \return The number of elements matching the numerical \a id
- */
-V4L2ControlInfoMap::size_type V4L2ControlInfoMap::count(unsigned int id) const
-{
- return count(idmap_.at(id));
-}
-
-/**
- * \brief Find the element matching a numerical ID
- * \param[in] id The numerical ID
- * \return An iterator pointing to the element matching the numerical \a id, or
- * end() if no such element exists
- */
-V4L2ControlInfoMap::iterator V4L2ControlInfoMap::find(unsigned int id)
-{
- return find(idmap_.at(id));
-}
-
-/**
- * \brief Find the element matching a numerical ID
- * \param[in] id The numerical ID
- * \return A const iterator pointing to the element matching the numerical
- * \a id, or end() if no such element exists
- */
-V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) const
-{
- return find(idmap_.at(id));
-}
-
-/**
- * \fn const ControlIdMap &V4L2ControlInfoMap::idmap() const
- * \brief Retrieve the ControlId map
- *
- * Constructing ControlList instances for V4L2 controls requires a ControlIdMap
- * for the V4L2 device that the control list targets. This helper method
- * returns a suitable idmap for that purpose.
- *
- * \return The ControlId map
- */
-
-/**
* \class V4L2ControlList
* \brief A list of controls for a V4L2 device
*
* This class specialises the ControList class for use with V4L2 devices. It
- * offers a convenience API to create a ControlList from a V4L2ControlInfoMap.
+ * offers a convenience API to create a ControlList from a ControlInfoMap.
*
* V4L2ControlList allows easy construction of a ControlList containing V4L2
* controls for a device. It can be used to construct the list of controls
@@ -231,7 +141,7 @@ V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) con
*/
/**
- * \fn V4L2ControlList::V4L2ControlList(const V4L2ControlInfoMap &info)
+ * \fn V4L2ControlList::V4L2ControlList(const ControlInfoMap &info)
* \brief Construct a V4L2ControlList associated with a V4L2 device
* \param[in] info The V4L2 device control info map
*/
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 06155eb5..a2b0d891 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -342,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp)
*/
void V4L2Device::listControls()
{
- ControlInfoMap ctrls;
+ ControlInfoMap::Map ctrls;
struct v4l2_query_ext_ctrl ctrl = {};
/* \todo Add support for menu and compound controls. */
diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp
index 182228f3..31879b79 100644
--- a/test/v4l2_videodevice/controls.cpp
+++ b/test/v4l2_videodevice/controls.cpp
@@ -26,7 +26,7 @@ public:
protected:
int run()
{
- const V4L2ControlInfoMap &info = capture_->controls();
+ const ControlInfoMap &info = capture_->controls();
/* Test control enumeration. */
if (info.empty()) {