libcamera: software_isp: Move benchmark code to its own class
Move the code for the builtin benchmark to its own small Benchmark class. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> 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
d9ffeb0bf1
commit
ba4218669b
6 changed files with 135 additions and 39 deletions
36
include/libcamera/internal/software_isp/benchmark.h
Normal file
36
include/libcamera/internal/software_isp/benchmark.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024, Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hans de Goede <hdegoede@redhat.com>
|
||||||
|
*
|
||||||
|
* Simple builtin benchmark to measure software ISP processing times
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
class Benchmark
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Benchmark();
|
||||||
|
~Benchmark();
|
||||||
|
|
||||||
|
void startFrame(void);
|
||||||
|
void finishFrame(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int measuredFrames_;
|
||||||
|
int64_t frameProcessTime_;
|
||||||
|
timespec frameStartTime_;
|
||||||
|
/* Skip 30 frames for things to stabilize then measure 30 frames */
|
||||||
|
static constexpr unsigned int kFramesToSkip = 30;
|
||||||
|
static constexpr unsigned int kLastFrameToMeasure = 60;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
|
@ -1,6 +1,7 @@
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
libcamera_internal_headers += files([
|
libcamera_internal_headers += files([
|
||||||
|
'benchmark.h',
|
||||||
'debayer_params.h',
|
'debayer_params.h',
|
||||||
'software_isp.h',
|
'software_isp.h',
|
||||||
'swisp_stats.h',
|
'swisp_stats.h',
|
||||||
|
|
93
src/libcamera/software_isp/benchmark.cpp
Normal file
93
src/libcamera/software_isp/benchmark.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024, Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hans de Goede <hdegoede@redhat.com>
|
||||||
|
*
|
||||||
|
* Simple builtin benchmark to measure software ISP processing times
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libcamera/internal/software_isp/benchmark.h"
|
||||||
|
|
||||||
|
#include <libcamera/base/log.h>
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
LOG_DEFINE_CATEGORY(Benchmark)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class Benchmark
|
||||||
|
* \brief Simple builtin benchmark
|
||||||
|
*
|
||||||
|
* Simple builtin benchmark to measure software ISP processing times.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructs a Benchmark object
|
||||||
|
*/
|
||||||
|
Benchmark::Benchmark()
|
||||||
|
: measuredFrames_(0), frameProcessTime_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Benchmark::~Benchmark()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64_t timeDiff(timespec &after, timespec &before)
|
||||||
|
{
|
||||||
|
return (after.tv_sec - before.tv_sec) * 1000000000LL +
|
||||||
|
(int64_t)after.tv_nsec - (int64_t)before.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Start measuring process time for a single frame
|
||||||
|
*
|
||||||
|
* Call this function before processing frame data to start measuring
|
||||||
|
* the process time for a frame.
|
||||||
|
*/
|
||||||
|
void Benchmark::startFrame(void)
|
||||||
|
{
|
||||||
|
if (measuredFrames_ >= Benchmark::kLastFrameToMeasure)
|
||||||
|
return;
|
||||||
|
|
||||||
|
frameStartTime_ = {};
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Finish measuring process time for a single frame
|
||||||
|
*
|
||||||
|
* Call this function after processing frame data to finish measuring
|
||||||
|
* the process time for a frame.
|
||||||
|
*
|
||||||
|
* This function will log frame processing time information after
|
||||||
|
* Benchmark::kLastFrameToMeasure frames have been processed.
|
||||||
|
*/
|
||||||
|
void Benchmark::finishFrame(void)
|
||||||
|
{
|
||||||
|
if (measuredFrames_ >= Benchmark::kLastFrameToMeasure)
|
||||||
|
return;
|
||||||
|
|
||||||
|
measuredFrames_++;
|
||||||
|
|
||||||
|
if (measuredFrames_ <= Benchmark::kFramesToSkip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timespec frameEndTime = {};
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime);
|
||||||
|
frameProcessTime_ += timeDiff(frameEndTime, frameStartTime_);
|
||||||
|
|
||||||
|
if (measuredFrames_ == Benchmark::kLastFrameToMeasure) {
|
||||||
|
const unsigned int measuredFrames = Benchmark::kLastFrameToMeasure -
|
||||||
|
Benchmark::kFramesToSkip;
|
||||||
|
LOG(Benchmark, Info)
|
||||||
|
<< "Processed " << measuredFrames
|
||||||
|
<< " frames in " << frameProcessTime_ / 1000 << "us, "
|
||||||
|
<< frameProcessTime_ / (1000 * measuredFrames)
|
||||||
|
<< " us/frame";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
|
@ -554,9 +554,6 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg,
|
||||||
lineBuffers_[i].resize(lineBufferLength_);
|
lineBuffers_[i].resize(lineBufferLength_);
|
||||||
}
|
}
|
||||||
|
|
||||||
measuredFrames_ = 0;
|
|
||||||
frameProcessTime_ = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,24 +743,9 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
inline int64_t timeDiff(timespec &after, timespec &before)
|
|
||||||
{
|
|
||||||
return (after.tv_sec - before.tv_sec) * 1000000000LL +
|
|
||||||
(int64_t)after.tv_nsec - (int64_t)before.tv_nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace */
|
|
||||||
|
|
||||||
void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)
|
void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)
|
||||||
{
|
{
|
||||||
timespec frameStartTime;
|
bench_.startFrame();
|
||||||
|
|
||||||
if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure) {
|
|
||||||
frameStartTime = {};
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<DmaSyncer> dmaSyncers;
|
std::vector<DmaSyncer> dmaSyncers;
|
||||||
for (const FrameBuffer::Plane &plane : input->planes())
|
for (const FrameBuffer::Plane &plane : input->planes())
|
||||||
|
@ -817,21 +799,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output
|
||||||
dmaSyncers.clear();
|
dmaSyncers.clear();
|
||||||
|
|
||||||
/* Measure before emitting signals */
|
/* Measure before emitting signals */
|
||||||
if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure &&
|
bench_.finishFrame();
|
||||||
++measuredFrames_ > DebayerCpu::kFramesToSkip) {
|
|
||||||
timespec frameEndTime = {};
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime);
|
|
||||||
frameProcessTime_ += timeDiff(frameEndTime, frameStartTime);
|
|
||||||
if (measuredFrames_ == DebayerCpu::kLastFrameToMeasure) {
|
|
||||||
const unsigned int measuredFrames = DebayerCpu::kLastFrameToMeasure -
|
|
||||||
DebayerCpu::kFramesToSkip;
|
|
||||||
LOG(Debayer, Info)
|
|
||||||
<< "Processed " << measuredFrames
|
|
||||||
<< " frames in " << frameProcessTime_ / 1000 << "us, "
|
|
||||||
<< frameProcessTime_ / (1000 * measuredFrames)
|
|
||||||
<< " us/frame";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Buffer ids are currently not used, so pass zeros as its parameter.
|
* Buffer ids are currently not used, so pass zeros as its parameter.
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <libcamera/base/object.h>
|
#include <libcamera/base/object.h>
|
||||||
|
|
||||||
|
#include "libcamera/internal/software_isp/benchmark.h"
|
||||||
#include "libcamera/internal/bayer_format.h"
|
#include "libcamera/internal/bayer_format.h"
|
||||||
#include "libcamera/internal/software_isp/swstats_cpu.h"
|
#include "libcamera/internal/software_isp/swstats_cpu.h"
|
||||||
|
|
||||||
|
@ -160,11 +161,7 @@ private:
|
||||||
unsigned int xShift_; /* Offset of 0/1 applied to window_.x */
|
unsigned int xShift_; /* Offset of 0/1 applied to window_.x */
|
||||||
bool enableInputMemcpy_;
|
bool enableInputMemcpy_;
|
||||||
bool swapRedBlueGains_;
|
bool swapRedBlueGains_;
|
||||||
unsigned int measuredFrames_;
|
Benchmark bench_;
|
||||||
int64_t frameProcessTime_;
|
|
||||||
/* Skip 30 frames for things to stabilize then measure 30 frames */
|
|
||||||
static constexpr unsigned int kFramesToSkip = 30;
|
|
||||||
static constexpr unsigned int kLastFrameToMeasure = 60;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -8,6 +8,7 @@ if not softisp_enabled
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libcamera_internal_sources += files([
|
libcamera_internal_sources += files([
|
||||||
|
'benchmark.cpp',
|
||||||
'debayer.cpp',
|
'debayer.cpp',
|
||||||
'debayer_cpu.cpp',
|
'debayer_cpu.cpp',
|
||||||
'software_isp.cpp',
|
'software_isp.cpp',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue