[libcamera-devel] [PATCH 1/2] libcamera: pipeline: raspberrypi: Don't inline all of StaggeredCtrl
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Thu May 14 16:39:57 CEST 2020
Hi Naush,
I wonder if I forgot to CC you on this.
On Tue, May 12, 2020 at 03:39:02AM +0300, Laurent Pinchart wrote:
> The StaggeredCtrl class has large functions, move them to a .cpp file
> instead of inlining them all to reduce the binary size.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> .../pipeline/raspberrypi/meson.build | 3 +-
> .../pipeline/raspberrypi/staggered_ctrl.cpp | 173 ++++++++++++++++++
> .../pipeline/raspberrypi/staggered_ctrl.h | 168 ++---------------
> 3 files changed, 186 insertions(+), 158 deletions(-)
> create mode 100644 src/libcamera/pipeline/raspberrypi/staggered_ctrl.cpp
>
> diff --git a/src/libcamera/pipeline/raspberrypi/meson.build b/src/libcamera/pipeline/raspberrypi/meson.build
> index 737857977831..565a8902f1f4 100644
> --- a/src/libcamera/pipeline/raspberrypi/meson.build
> +++ b/src/libcamera/pipeline/raspberrypi/meson.build
> @@ -1,3 +1,4 @@
> libcamera_sources += files([
> - 'raspberrypi.cpp'
> + 'raspberrypi.cpp',
> + 'staggered_ctrl.cpp',
> ])
> diff --git a/src/libcamera/pipeline/raspberrypi/staggered_ctrl.cpp b/src/libcamera/pipeline/raspberrypi/staggered_ctrl.cpp
> new file mode 100644
> index 000000000000..fbd87d3e791e
> --- /dev/null
> +++ b/src/libcamera/pipeline/raspberrypi/staggered_ctrl.cpp
> @@ -0,0 +1,173 @@
> +/* SPDX-License-Identifier: BSD-2-Clause */
> +/*
> + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd.
> + *
> + * staggered_ctrl.cpp - Helper for writing staggered ctrls to a V4L2 device.
> + */
> +
> +#include "staggered_ctrl.h"
> +
> +#include <algorithm>
> +
> +#include "log.h"
> +#include "utils.h"
> +
> +/* For logging... */
> +using libcamera::LogCategory;
> +using libcamera::LogDebug;
> +using libcamera::LogInfo;
> +using libcamera::utils::hex;
> +
> +LOG_DEFINE_CATEGORY(RPI_S_W);
> +
> +namespace RPi {
> +
> +void StaggeredCtrl::init(libcamera::V4L2VideoDevice *dev,
> + std::initializer_list<std::pair<const uint32_t, uint8_t>> delayList)
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + dev_ = dev;
> + delay_ = delayList;
> + ctrl_.clear();
> +
> + /* Find the largest delay across all controls. */
> + maxDelay_ = 0;
> + for (auto const &p : delay_) {
> + LOG(RPI_S_W, Info) << "Init ctrl "
> + << hex(p.first) << " with delay "
> + << static_cast<int>(p.second);
> + maxDelay_ = std::max(maxDelay_, p.second);
> + }
> +
> + init_ = true;
> +}
> +
> +void StaggeredCtrl::reset()
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + int lastSetCount = std::max<int>(0, setCount_ - 1);
> + std::unordered_map<uint32_t, int32_t> lastVal;
> +
> + /* Reset the counters. */
> + setCount_ = getCount_ = 0;
> +
> + /* Look for the last set values. */
> + for (auto const &c : ctrl_)
> + lastVal[c.first] = c.second[lastSetCount].value;
> +
> + /* Apply the last set values as the next to be applied. */
> + ctrl_.clear();
> + for (auto &c : lastVal)
> + ctrl_[c.first][setCount_] = CtrlInfo(c.second);
> +}
> +
> +bool StaggeredCtrl::set(uint32_t ctrl, int32_t value)
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + /* Can we find this ctrl as one that is registered? */
> + if (delay_.find(ctrl) == delay_.end())
> + return false;
> +
> + ctrl_[ctrl][setCount_].value = value;
> + ctrl_[ctrl][setCount_].updated = true;
> +
> + return true;
> +}
> +
> +bool StaggeredCtrl::set(std::initializer_list<std::pair<const uint32_t, int32_t>> ctrlList)
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + for (auto const &p : ctrlList) {
> + /* Can we find this ctrl? */
> + if (delay_.find(p.first) == delay_.end())
> + return false;
> +
> + ctrl_[p.first][setCount_] = CtrlInfo(p.second);
> + }
> +
> + return true;
> +}
> +
> +bool StaggeredCtrl::set(libcamera::ControlList &controls)
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + for (auto const &p : controls) {
> + /* Can we find this ctrl? */
> + if (delay_.find(p.first) == delay_.end())
> + return false;
> +
> + ctrl_[p.first][setCount_] = CtrlInfo(p.second.get<int32_t>());
> + LOG(RPI_S_W, Debug) << "Setting ctrl "
> + << hex(p.first) << " to "
> + << ctrl_[p.first][setCount_].value
> + << " at index "
> + << setCount_;
> + }
> +
> + return true;
> +}
> +
> +int StaggeredCtrl::write()
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> + libcamera::ControlList controls(dev_->controls());
> +
> + for (auto &p : ctrl_) {
> + int delayDiff = maxDelay_ - delay_[p.first];
> + int index = std::max<int>(0, setCount_ - delayDiff);
> +
> + if (p.second[index].updated) {
> + /* We need to write this value out. */
> + controls.set(p.first, p.second[index].value);
> + p.second[index].updated = false;
> + LOG(RPI_S_W, Debug) << "Writing ctrl "
> + << hex(p.first) << " to "
> + << p.second[index].value
> + << " at index "
> + << index;
> + }
> + }
> +
> + nextFrame();
> + return dev_->setControls(&controls);
> +}
> +
> +void StaggeredCtrl::get(std::unordered_map<uint32_t, int32_t> &ctrl, uint8_t offset)
> +{
> + std::lock_guard<std::mutex> lock(lock_);
> +
> + /* Account for the offset to reset the getCounter. */
> + getCount_ += offset + 1;
> +
> + ctrl.clear();
> + for (auto &p : ctrl_) {
> + int index = std::max<int>(0, getCount_ - maxDelay_);
> + ctrl[p.first] = p.second[index].value;
> + LOG(RPI_S_W, Debug) << "Getting ctrl "
> + << hex(p.first) << " to "
> + << p.second[index].value
> + << " at index "
> + << index;
> + }
> +}
> +
> +void StaggeredCtrl::nextFrame()
> +{
> + /* Advance the control history to the next frame */
> + int prevCount = setCount_;
> + setCount_++;
> +
> + LOG(RPI_S_W, Debug) << "Next frame, set index is " << setCount_;
> +
> + for (auto &p : ctrl_) {
> + p.second[setCount_].value = p.second[prevCount].value;
> + p.second[setCount_].updated = false;
> + }
> +}
> +
> +} /* namespace RPi */
> diff --git a/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h b/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h
> index 0403c087c686..c8f000a0b43c 100644
> --- a/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h
> +++ b/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h
> @@ -6,24 +6,16 @@
> */
> #pragma once
>
> -#include <algorithm>
> +#include <array>
> #include <initializer_list>
> #include <mutex>
> #include <unordered_map>
> +#include <utility>
>
> #include <libcamera/controls.h>
> -#include "log.h"
> -#include "utils.h"
> +
> #include "v4l2_videodevice.h"
>
> -/* For logging... */
> -using libcamera::LogCategory;
> -using libcamera::LogDebug;
> -using libcamera::LogInfo;
> -using libcamera::utils::hex;
> -
> -LOG_DEFINE_CATEGORY(RPI_S_W);
> -
> namespace RPi {
>
> class StaggeredCtrl
> @@ -34,163 +26,25 @@ public:
> {
> }
>
> - ~StaggeredCtrl()
> - {
> - }
> -
> operator bool() const
> {
> return init_;
> }
>
> void init(libcamera::V4L2VideoDevice *dev,
> - std::initializer_list<std::pair<const uint32_t, uint8_t>> delayList)
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> + std::initializer_list<std::pair<const uint32_t, uint8_t>> delayList);
> + void reset();
>
> - dev_ = dev;
> - delay_ = delayList;
> - ctrl_.clear();
> + void get(std::unordered_map<uint32_t, int32_t> &ctrl, uint8_t offset = 0);
>
> - /* Find the largest delay across all controls. */
> - maxDelay_ = 0;
> - for (auto const &p : delay_) {
> - LOG(RPI_S_W, Info) << "Init ctrl "
> - << hex(p.first) << " with delay "
> - << static_cast<int>(p.second);
> - maxDelay_ = std::max(maxDelay_, p.second);
> - }
> + bool set(uint32_t ctrl, int32_t value);
> + bool set(std::initializer_list<std::pair<const uint32_t, int32_t>> ctrlList);
> + bool set(libcamera::ControlList &controls);
>
> - init_ = true;
> - }
> -
> - void reset()
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> -
> - int lastSetCount = std::max<int>(0, setCount_ - 1);
> - std::unordered_map<uint32_t, int32_t> lastVal;
> -
> - /* Reset the counters. */
> - setCount_ = getCount_ = 0;
> -
> - /* Look for the last set values. */
> - for (auto const &c : ctrl_)
> - lastVal[c.first] = c.second[lastSetCount].value;
> -
> - /* Apply the last set values as the next to be applied. */
> - ctrl_.clear();
> - for (auto &c : lastVal)
> - ctrl_[c.first][setCount_] = CtrlInfo(c.second);
> - }
> -
> - bool set(uint32_t ctrl, int32_t value)
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> -
> - /* Can we find this ctrl as one that is registered? */
> - if (delay_.find(ctrl) == delay_.end())
> - return false;
> -
> - ctrl_[ctrl][setCount_].value = value;
> - ctrl_[ctrl][setCount_].updated = true;
> -
> - return true;
> - }
> -
> - bool set(std::initializer_list<std::pair<const uint32_t, int32_t>> ctrlList)
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> -
> - for (auto const &p : ctrlList) {
> - /* Can we find this ctrl? */
> - if (delay_.find(p.first) == delay_.end())
> - return false;
> -
> - ctrl_[p.first][setCount_] = CtrlInfo(p.second);
> - }
> -
> - return true;
> - }
> -
> - bool set(libcamera::ControlList &controls)
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> -
> - for (auto const &p : controls) {
> - /* Can we find this ctrl? */
> - if (delay_.find(p.first) == delay_.end())
> - return false;
> -
> - ctrl_[p.first][setCount_] = CtrlInfo(p.second.get<int32_t>());
> - LOG(RPI_S_W, Debug) << "Setting ctrl "
> - << hex(p.first) << " to "
> - << ctrl_[p.first][setCount_].value
> - << " at index "
> - << setCount_;
> - }
> -
> - return true;
> - }
> -
> - int write()
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> - libcamera::ControlList controls(dev_->controls());
> -
> - for (auto &p : ctrl_) {
> - int delayDiff = maxDelay_ - delay_[p.first];
> - int index = std::max<int>(0, setCount_ - delayDiff);
> -
> - if (p.second[index].updated) {
> - /* We need to write this value out. */
> - controls.set(p.first, p.second[index].value);
> - p.second[index].updated = false;
> - LOG(RPI_S_W, Debug) << "Writing ctrl "
> - << hex(p.first) << " to "
> - << p.second[index].value
> - << " at index "
> - << index;
> - }
> - }
> -
> - nextFrame();
> - return dev_->setControls(&controls);
> - }
> -
> - void get(std::unordered_map<uint32_t, int32_t> &ctrl, uint8_t offset = 0)
> - {
> - std::lock_guard<std::mutex> lock(lock_);
> -
> - /* Account for the offset to reset the getCounter. */
> - getCount_ += offset + 1;
> -
> - ctrl.clear();
> - for (auto &p : ctrl_) {
> - int index = std::max<int>(0, getCount_ - maxDelay_);
> - ctrl[p.first] = p.second[index].value;
> - LOG(RPI_S_W, Debug) << "Getting ctrl "
> - << hex(p.first) << " to "
> - << p.second[index].value
> - << " at index "
> - << index;
> - }
> - }
> + int write();
>
> private:
> - void nextFrame()
> - {
> - /* Advance the control history to the next frame */
> - int prevCount = setCount_;
> - setCount_++;
> -
> - LOG(RPI_S_W, Debug) << "Next frame, set index is " << setCount_;
> -
> - for (auto &p : ctrl_) {
> - p.second[setCount_].value = p.second[prevCount].value;
> - p.second[setCount_].updated = false;
> - }
> - }
> + void nextFrame();
>
> /* listSize must be a power of 2. */
> static constexpr int listSize = (1 << 4);
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list