summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/pipeline/raspberrypi/meson.build3
-rw-r--r--src/libcamera/pipeline/raspberrypi/staggered_ctrl.cpp173
-rw-r--r--src/libcamera/pipeline/raspberrypi/staggered_ctrl.h168
3 files changed, 186 insertions, 158 deletions
diff --git a/src/libcamera/pipeline/raspberrypi/meson.build b/src/libcamera/pipeline/raspberrypi/meson.build
index fc117b77..dcfe07c5 100644
--- a/src/libcamera/pipeline/raspberrypi/meson.build
+++ b/src/libcamera/pipeline/raspberrypi/meson.build
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: CC0-1.0
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 00000000..fbd87d3e
--- /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 0403c087..c8f000a0 100644
--- a/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h
+++ b/src/libcamera/pipeline/raspberrypi/staggered_ctrl.h
@@ -6,23 +6,15 @@
*/
#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);
+#include "v4l2_videodevice.h"
namespace RPi {
@@ -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_);
-
- 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 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;
- }
+ std::initializer_list<std::pair<const uint32_t, uint8_t>> delayList);
+ void reset();
- 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;
- }
+ void get(std::unordered_map<uint32_t, int32_t> &ctrl, uint8_t offset = 0);
- 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;
- }
+ 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);
- 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);