mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 23:39:44 +03:00
libcamera: software_isp: Make stats frame and buffer aware
This patch adds frame and bufferId arguments to stats related calls. Although the parameters are currently unused, because frame ids are not tracked and used and the stats buffer is passed around directly rather than being referred by its id, they bring the internal APIs closer to their counterparts in hardware pipelines. It serves as a preparation for followup patches that will introduce: - Frame number tracking in order to switch to DelayedControls (software ISP TODO #11 + #12). - A ring buffer for stats in order to improve passing the stats (software ISP TODO #2). Frame and buffer ids are unrelated for the given purposes but since they are passed together at the same places, the change is implemented as a single patch rather than two, basically the same, patches. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
0cc74c492a
commit
c64f2f197a
8 changed files with 38 additions and 18 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -66,7 +67,8 @@ public:
|
||||||
int exportBuffers(const Stream *stream, unsigned int count,
|
int exportBuffers(const Stream *stream, unsigned int count,
|
||||||
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
|
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
|
||||||
|
|
||||||
void processStats(const ControlList &sensorControls);
|
void processStats(const uint32_t frame, const uint32_t bufferId,
|
||||||
|
const ControlList &sensorControls);
|
||||||
|
|
||||||
int start();
|
int start();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -78,13 +80,13 @@ public:
|
||||||
|
|
||||||
Signal<FrameBuffer *> inputBufferReady;
|
Signal<FrameBuffer *> inputBufferReady;
|
||||||
Signal<FrameBuffer *> outputBufferReady;
|
Signal<FrameBuffer *> outputBufferReady;
|
||||||
Signal<> ispStatsReady;
|
Signal<uint32_t, uint32_t> ispStatsReady;
|
||||||
Signal<const ControlList &> setSensorControls;
|
Signal<const ControlList &> setSensorControls;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveIspParams();
|
void saveIspParams();
|
||||||
void setSensorCtrls(const ControlList &sensorControls);
|
void setSensorCtrls(const ControlList &sensorControls);
|
||||||
void statsReady();
|
void statsReady(uint32_t frame, uint32_t bufferId);
|
||||||
void inputReady(FrameBuffer *input);
|
void inputReady(FrameBuffer *input);
|
||||||
void outputReady(FrameBuffer *output);
|
void outputReady(FrameBuffer *output);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ interface IPASoftInterface {
|
||||||
configure(libcamera.ControlInfoMap sensorCtrlInfoMap)
|
configure(libcamera.ControlInfoMap sensorCtrlInfoMap)
|
||||||
=> (int32 ret);
|
=> (int32 ret);
|
||||||
|
|
||||||
[async] processStats(libcamera.ControlList sensorControls);
|
[async] processStats(uint32 frame,
|
||||||
|
uint32 bufferId,
|
||||||
|
libcamera.ControlList sensorControls);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IPASoftEventInterface {
|
interface IPASoftEventInterface {
|
||||||
|
|
|
@ -75,7 +75,8 @@ public:
|
||||||
int start() override;
|
int start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
void processStats(const ControlList &sensorControls) override;
|
void processStats(const uint32_t frame, const uint32_t bufferId,
|
||||||
|
const ControlList &sensorControls) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string logPrefix() const override;
|
std::string logPrefix() const override;
|
||||||
|
@ -249,7 +250,9 @@ void IPASoftSimple::stop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPASoftSimple::processStats(const ControlList &sensorControls)
|
void IPASoftSimple::processStats([[maybe_unused]] const uint32_t frame,
|
||||||
|
[[maybe_unused]] const uint32_t bufferId,
|
||||||
|
const ControlList &sensorControls)
|
||||||
{
|
{
|
||||||
SwIspStats::Histogram histogram = stats_->yHistogram;
|
SwIspStats::Histogram histogram = stats_->yHistogram;
|
||||||
if (ignoreUpdates_ > 0)
|
if (ignoreUpdates_ > 0)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -291,7 +292,7 @@ private:
|
||||||
void conversionInputDone(FrameBuffer *buffer);
|
void conversionInputDone(FrameBuffer *buffer);
|
||||||
void conversionOutputDone(FrameBuffer *buffer);
|
void conversionOutputDone(FrameBuffer *buffer);
|
||||||
|
|
||||||
void ispStatsReady();
|
void ispStatsReady(uint32_t frame, uint32_t bufferId);
|
||||||
void setSensorControls(const ControlList &sensorControls);
|
void setSensorControls(const ControlList &sensorControls);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -887,10 +888,11 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
|
||||||
pipe->completeRequest(request);
|
pipe->completeRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleCameraData::ispStatsReady()
|
void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)
|
||||||
{
|
{
|
||||||
/* \todo Use the DelayedControls class */
|
/* \todo Use the DelayedControls class */
|
||||||
swIsp_->processStats(sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,
|
swIsp_->processStats(frame, bufferId,
|
||||||
|
sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,
|
||||||
V4L2_CID_EXPOSURE }));
|
V4L2_CID_EXPOSURE }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -807,7 +807,13 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stats_->finishFrame();
|
/*
|
||||||
|
* Frame and buffer ids are currently not used, so pass zeros as parameters.
|
||||||
|
*
|
||||||
|
* \todo Pass real values once frame is passed here and stats buffer passing
|
||||||
|
* is changed.
|
||||||
|
*/
|
||||||
|
stats_->finishFrame(0, 0);
|
||||||
outputBufferReady.emit(output);
|
outputBufferReady.emit(output);
|
||||||
inputBufferReady.emit(input);
|
inputBufferReady.emit(input);
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,15 +155,18 @@ SoftwareIsp::~SoftwareIsp()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Process the statistics gathered
|
* \brief Process the statistics gathered
|
||||||
|
* \param[in] frame The frame number
|
||||||
|
* \param[in] bufferId ID of the statistics buffer
|
||||||
* \param[in] sensorControls The sensor controls
|
* \param[in] sensorControls The sensor controls
|
||||||
*
|
*
|
||||||
* Requests the IPA to calculate new parameters for ISP and new control
|
* Requests the IPA to calculate new parameters for ISP and new control
|
||||||
* values for the sensor.
|
* values for the sensor.
|
||||||
*/
|
*/
|
||||||
void SoftwareIsp::processStats(const ControlList &sensorControls)
|
void SoftwareIsp::processStats(const uint32_t frame, const uint32_t bufferId,
|
||||||
|
const ControlList &sensorControls)
|
||||||
{
|
{
|
||||||
ASSERT(ipa_);
|
ASSERT(ipa_);
|
||||||
ipa_->processStats(sensorControls);
|
ipa_->processStats(frame, bufferId, sensorControls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -349,9 +352,9 @@ void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)
|
||||||
setSensorControls.emit(sensorControls);
|
setSensorControls.emit(sensorControls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareIsp::statsReady()
|
void SoftwareIsp::statsReady(uint32_t frame, uint32_t bufferId)
|
||||||
{
|
{
|
||||||
ispStatsReady.emit();
|
ispStatsReady.emit(frame, bufferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareIsp::inputReady(FrameBuffer *input)
|
void SoftwareIsp::inputReady(FrameBuffer *input)
|
||||||
|
|
|
@ -311,13 +311,15 @@ void SwStatsCpu::startFrame(void)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Finish statistics calculation for the current frame
|
* \brief Finish statistics calculation for the current frame
|
||||||
|
* \param[in] frame The frame number
|
||||||
|
* \param[in] bufferId ID of the statistics buffer
|
||||||
*
|
*
|
||||||
* This may only be called after a successful setWindow() call.
|
* This may only be called after a successful setWindow() call.
|
||||||
*/
|
*/
|
||||||
void SwStatsCpu::finishFrame(void)
|
void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId)
|
||||||
{
|
{
|
||||||
*sharedStats_ = stats_;
|
*sharedStats_ = stats_;
|
||||||
statsReady.emit();
|
statsReady.emit(frame, bufferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
int configure(const StreamConfiguration &inputCfg);
|
int configure(const StreamConfiguration &inputCfg);
|
||||||
void setWindow(const Rectangle &window);
|
void setWindow(const Rectangle &window);
|
||||||
void startFrame();
|
void startFrame();
|
||||||
void finishFrame();
|
void finishFrame(uint32_t frame, uint32_t bufferId);
|
||||||
|
|
||||||
void processLine0(unsigned int y, const uint8_t *src[])
|
void processLine0(unsigned int y, const uint8_t *src[])
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
(this->*stats2_)(src);
|
(this->*stats2_)(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal<> statsReady;
|
Signal<uint32_t, uint32_t> statsReady;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]);
|
using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue