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:
Laurent Pinchart
2020-05-12 03:18:02 +03:00
parent 924778eb07
commit 4d536996c7
3 changed files with 186 additions and 158 deletions
@@ -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);