libcamera: pipeline: raspberrypi: Don't inline all of StaggeredCtrl
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@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
libcamera_sources += files([
|
||||
'raspberrypi.cpp'
|
||||
'raspberrypi.cpp',
|
||||
'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 */
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user