diff options
-rw-r--r-- | include/ipa/ipa_interface.h | 2 | ||||
-rw-r--r-- | include/libcamera/controls.h | 45 | ||||
-rw-r--r-- | src/ipa/ipa_vimc.cpp | 2 | ||||
-rw-r--r-- | src/ipa/rkisp1/rkisp1.cpp | 6 | ||||
-rw-r--r-- | src/libcamera/camera_sensor.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/controls.cpp | 139 | ||||
-rw-r--r-- | src/libcamera/include/camera_sensor.h | 4 | ||||
-rw-r--r-- | src/libcamera/include/v4l2_controls.h | 36 | ||||
-rw-r--r-- | src/libcamera/include/v4l2_device.h | 4 | ||||
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1.cpp | 11 | ||||
-rw-r--r-- | src/libcamera/pipeline/uvcvideo.cpp | 12 | ||||
-rw-r--r-- | src/libcamera/pipeline/vimc.cpp | 11 | ||||
-rw-r--r-- | src/libcamera/proxy/ipa_proxy_linux.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/v4l2_controls.cpp | 94 | ||||
-rw-r--r-- | src/libcamera/v4l2_device.cpp | 2 | ||||
-rw-r--r-- | test/v4l2_videodevice/controls.cpp | 2 |
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()) { |