libcamera: swstats_cpu: Add processFrame() method
Add a method to the SwstatsCpu class to process a whole Framebuffer in one go, rather then line by line. This is useful for gathering stats when debayering is not necessary or is not done on the CPU. Reviewed-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
This commit is contained in:
parent
ba4218669b
commit
d4bc61f716
2 changed files with 63 additions and 0 deletions
|
@ -18,12 +18,16 @@
|
||||||
#include <libcamera/geometry.h>
|
#include <libcamera/geometry.h>
|
||||||
|
|
||||||
#include "libcamera/internal/bayer_format.h"
|
#include "libcamera/internal/bayer_format.h"
|
||||||
|
#include "libcamera/internal/framebuffer.h"
|
||||||
#include "libcamera/internal/shared_mem_object.h"
|
#include "libcamera/internal/shared_mem_object.h"
|
||||||
#include "libcamera/internal/software_isp/swisp_stats.h"
|
#include "libcamera/internal/software_isp/swisp_stats.h"
|
||||||
|
|
||||||
|
#include "benchmark.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
class PixelFormat;
|
class PixelFormat;
|
||||||
|
class MappedFrameBuffer;
|
||||||
struct StreamConfiguration;
|
struct StreamConfiguration;
|
||||||
|
|
||||||
class SwStatsCpu
|
class SwStatsCpu
|
||||||
|
@ -42,6 +46,7 @@ public:
|
||||||
void setWindow(const Rectangle &window);
|
void setWindow(const Rectangle &window);
|
||||||
void startFrame();
|
void startFrame();
|
||||||
void finishFrame(uint32_t frame, uint32_t bufferId);
|
void finishFrame(uint32_t frame, uint32_t bufferId);
|
||||||
|
void processFrame(uint32_t frame, uint32_t bufferId, FrameBuffer *input);
|
||||||
|
|
||||||
void processLine0(unsigned int y, const uint8_t *src[])
|
void processLine0(unsigned int y, const uint8_t *src[])
|
||||||
{
|
{
|
||||||
|
@ -65,6 +70,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]);
|
using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]);
|
||||||
|
using processFrameFn = void (SwStatsCpu::*)(MappedFrameBuffer &in);
|
||||||
|
|
||||||
int setupStandardBayerOrder(BayerFormat::Order order);
|
int setupStandardBayerOrder(BayerFormat::Order order);
|
||||||
/* Bayer 8 bpp unpacked */
|
/* Bayer 8 bpp unpacked */
|
||||||
|
@ -77,6 +83,10 @@ private:
|
||||||
void statsBGGR10PLine0(const uint8_t *src[]);
|
void statsBGGR10PLine0(const uint8_t *src[]);
|
||||||
void statsGBRG10PLine0(const uint8_t *src[]);
|
void statsGBRG10PLine0(const uint8_t *src[]);
|
||||||
|
|
||||||
|
void processBayerFrame2(MappedFrameBuffer &in);
|
||||||
|
|
||||||
|
processFrameFn processFrame_;
|
||||||
|
|
||||||
/* Variables set by configure(), used every line */
|
/* Variables set by configure(), used every line */
|
||||||
statsProcessFn stats0_;
|
statsProcessFn stats0_;
|
||||||
statsProcessFn stats2_;
|
statsProcessFn stats2_;
|
||||||
|
@ -89,9 +99,11 @@ private:
|
||||||
Size patternSize_;
|
Size patternSize_;
|
||||||
|
|
||||||
unsigned int xShift_;
|
unsigned int xShift_;
|
||||||
|
unsigned int stride_;
|
||||||
|
|
||||||
SharedMemObject<SwIspStats> sharedStats_;
|
SharedMemObject<SwIspStats> sharedStats_;
|
||||||
SwIspStats stats_;
|
SwIspStats stats_;
|
||||||
|
Benchmark bench_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <libcamera/stream.h>
|
#include <libcamera/stream.h>
|
||||||
|
|
||||||
#include "libcamera/internal/bayer_format.h"
|
#include "libcamera/internal/bayer_format.h"
|
||||||
|
#include "libcamera/internal/mapped_framebuffer.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
|
@ -360,11 +361,14 @@ int SwStatsCpu::setupStandardBayerOrder(BayerFormat::Order order)
|
||||||
*/
|
*/
|
||||||
int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
|
int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
|
||||||
{
|
{
|
||||||
|
stride_ = inputCfg.stride;
|
||||||
|
|
||||||
BayerFormat bayerFormat =
|
BayerFormat bayerFormat =
|
||||||
BayerFormat::fromPixelFormat(inputCfg.pixelFormat);
|
BayerFormat::fromPixelFormat(inputCfg.pixelFormat);
|
||||||
|
|
||||||
if (bayerFormat.packing == BayerFormat::Packing::None &&
|
if (bayerFormat.packing == BayerFormat::Packing::None &&
|
||||||
setupStandardBayerOrder(bayerFormat.order) == 0) {
|
setupStandardBayerOrder(bayerFormat.order) == 0) {
|
||||||
|
processFrame_ = &SwStatsCpu::processBayerFrame2;
|
||||||
switch (bayerFormat.bitDepth) {
|
switch (bayerFormat.bitDepth) {
|
||||||
case 8:
|
case 8:
|
||||||
stats0_ = &SwStatsCpu::statsBGGR8Line0;
|
stats0_ = &SwStatsCpu::statsBGGR8Line0;
|
||||||
|
@ -385,6 +389,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
|
||||||
/* Skip every 3th and 4th line, sample every other 2x2 block */
|
/* Skip every 3th and 4th line, sample every other 2x2 block */
|
||||||
ySkipMask_ = 0x02;
|
ySkipMask_ = 0x02;
|
||||||
xShift_ = 0;
|
xShift_ = 0;
|
||||||
|
processFrame_ = &SwStatsCpu::processBayerFrame2;
|
||||||
|
|
||||||
switch (bayerFormat.order) {
|
switch (bayerFormat.order) {
|
||||||
case BayerFormat::BGGR:
|
case BayerFormat::BGGR:
|
||||||
|
@ -425,4 +430,50 @@ void SwStatsCpu::setWindow(const Rectangle &window)
|
||||||
window_.height &= ~(patternSize_.height - 1);
|
window_.height &= ~(patternSize_.height - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwStatsCpu::processBayerFrame2(MappedFrameBuffer &in)
|
||||||
|
{
|
||||||
|
const uint8_t *src = in.planes()[0].data();
|
||||||
|
const uint8_t *linePointers[3];
|
||||||
|
|
||||||
|
/* Adjust src for starting at window_.y */
|
||||||
|
src += window_.y * stride_;
|
||||||
|
|
||||||
|
for (unsigned int y = 0; y < window_.height; y += 2) {
|
||||||
|
if (y & ySkipMask_) {
|
||||||
|
src += stride_ * 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* linePointers[0] is not used by any stats0_ functions */
|
||||||
|
linePointers[1] = src;
|
||||||
|
linePointers[2] = src + stride_;
|
||||||
|
(this->*stats0_)(linePointers);
|
||||||
|
src += stride_ * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Calculate statistics for a frame in one go
|
||||||
|
* \param[in] frame The frame number
|
||||||
|
* \param[in] bufferId ID of the statistics buffer
|
||||||
|
* \param[in] input The frame to process
|
||||||
|
*
|
||||||
|
* This may only be called after a successful setWindow() call.
|
||||||
|
*/
|
||||||
|
void SwStatsCpu::processFrame(uint32_t frame, uint32_t bufferId, FrameBuffer *input)
|
||||||
|
{
|
||||||
|
bench_.startFrame();
|
||||||
|
startFrame();
|
||||||
|
|
||||||
|
MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);
|
||||||
|
if (!in.isValid()) {
|
||||||
|
LOG(SwStatsCpu, Error) << "mmap-ing buffer(s) failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(this->*processFrame_)(in);
|
||||||
|
finishFrame(frame, bufferId);
|
||||||
|
bench_.finishFrame();
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue