mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-12 23:09:45 +03:00
ipa: simple: Report exposure in metadata
Report exposure and gain in metadata. This is more complicated than it could be expected because the exposure value should be in microseconds but it's handled using V4L2_CID_EXPOSURE control, which doesn't specify the unit, see https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html. So the unit conversion is done in the way rkisp1 IPA uses. This requires getting and passing IPACameraSensorInfo around. To avoid naming confusion and to improve consistency with rkisp1 IPA, sensorCtrlInfoMap parameter is renamed to sensorControls. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
1375b07ede
commit
485a807dcb
5 changed files with 43 additions and 14 deletions
|
@ -16,7 +16,8 @@ interface IPASoftInterface {
|
||||||
init(libcamera.IPASettings settings,
|
init(libcamera.IPASettings settings,
|
||||||
libcamera.SharedFD fdStats,
|
libcamera.SharedFD fdStats,
|
||||||
libcamera.SharedFD fdParams,
|
libcamera.SharedFD fdParams,
|
||||||
libcamera.ControlInfoMap sensorCtrlInfoMap)
|
libcamera.IPACameraSensorInfo sensorInfo,
|
||||||
|
libcamera.ControlInfoMap sensorControls)
|
||||||
=> (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled);
|
=> (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled);
|
||||||
start() => (int32 ret);
|
start() => (int32 ret);
|
||||||
stop();
|
stop();
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
|
|
||||||
|
#include "control_ids.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
LOG_DEFINE_CATEGORY(IPASoftExposure)
|
LOG_DEFINE_CATEGORY(IPASoftExposure)
|
||||||
|
@ -97,10 +99,15 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
|
||||||
|
|
||||||
void Agc::process(IPAContext &context,
|
void Agc::process(IPAContext &context,
|
||||||
[[maybe_unused]] const uint32_t frame,
|
[[maybe_unused]] const uint32_t frame,
|
||||||
[[maybe_unused]] IPAFrameContext &frameContext,
|
IPAFrameContext &frameContext,
|
||||||
const SwIspStats *stats,
|
const SwIspStats *stats,
|
||||||
[[maybe_unused]] ControlList &metadata)
|
ControlList &metadata)
|
||||||
{
|
{
|
||||||
|
utils::Duration exposureTime =
|
||||||
|
context.configuration.agc.lineDuration * frameContext.sensor.exposure;
|
||||||
|
metadata.set(controls::ExposureTime, exposureTime.get<std::micro>());
|
||||||
|
metadata.set(controls::AnalogueGain, frameContext.sensor.gain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate Mean Sample Value (MSV) according to formula from:
|
* Calculate Mean Sample Value (MSV) according to formula from:
|
||||||
* https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf
|
* https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2024 Red Hat, Inc.
|
* Copyright (C) 2024-2025 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* Simple pipeline IPA Context
|
* Simple pipeline IPA Context
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include <libipa/fc_queue.h>
|
#include <libipa/fc_queue.h>
|
||||||
|
|
||||||
|
#include "core_ipa_interface.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
namespace ipa::soft {
|
namespace ipa::soft {
|
||||||
|
@ -27,6 +29,7 @@ struct IPASessionConfiguration {
|
||||||
struct {
|
struct {
|
||||||
int32_t exposureMin, exposureMax;
|
int32_t exposureMin, exposureMax;
|
||||||
double againMin, againMax, againMinStep;
|
double againMin, againMax, againMinStep;
|
||||||
|
utils::Duration lineDuration;
|
||||||
} agc;
|
} agc;
|
||||||
struct {
|
struct {
|
||||||
std::optional<uint8_t> level;
|
std::optional<uint8_t> level;
|
||||||
|
@ -83,6 +86,7 @@ struct IPAContext {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPACameraSensorInfo sensorInfo;
|
||||||
IPASessionConfiguration configuration;
|
IPASessionConfiguration configuration;
|
||||||
IPAActiveState activeState;
|
IPAActiveState activeState;
|
||||||
FCQueue<IPAFrameContext> frameContexts;
|
FCQueue<IPAFrameContext> frameContexts;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Simple Software Image Processing Algorithm module
|
* Simple Software Image Processing Algorithm module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
LOG_DEFINE_CATEGORY(IPASoft)
|
LOG_DEFINE_CATEGORY(IPASoft)
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
namespace ipa::soft {
|
namespace ipa::soft {
|
||||||
|
|
||||||
/* Maximum number of frame contexts to be held */
|
/* Maximum number of frame contexts to be held */
|
||||||
|
@ -50,7 +53,8 @@ public:
|
||||||
int init(const IPASettings &settings,
|
int init(const IPASettings &settings,
|
||||||
const SharedFD &fdStats,
|
const SharedFD &fdStats,
|
||||||
const SharedFD &fdParams,
|
const SharedFD &fdParams,
|
||||||
const ControlInfoMap &sensorInfoMap,
|
const IPACameraSensorInfo &sensorInfo,
|
||||||
|
const ControlInfoMap &sensorControls,
|
||||||
ControlInfoMap *ipaControls,
|
ControlInfoMap *ipaControls,
|
||||||
bool *ccmEnabled) override;
|
bool *ccmEnabled) override;
|
||||||
int configure(const IPAConfigInfo &configInfo) override;
|
int configure(const IPAConfigInfo &configInfo) override;
|
||||||
|
@ -89,7 +93,8 @@ IPASoftSimple::~IPASoftSimple()
|
||||||
int IPASoftSimple::init(const IPASettings &settings,
|
int IPASoftSimple::init(const IPASettings &settings,
|
||||||
const SharedFD &fdStats,
|
const SharedFD &fdStats,
|
||||||
const SharedFD &fdParams,
|
const SharedFD &fdParams,
|
||||||
const ControlInfoMap &sensorInfoMap,
|
const IPACameraSensorInfo &sensorInfo,
|
||||||
|
const ControlInfoMap &sensorControls,
|
||||||
ControlInfoMap *ipaControls,
|
ControlInfoMap *ipaControls,
|
||||||
bool *ccmEnabled)
|
bool *ccmEnabled)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +105,8 @@ int IPASoftSimple::init(const IPASettings &settings,
|
||||||
<< settings.sensorModel;
|
<< settings.sensorModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context_.sensorInfo = sensorInfo;
|
||||||
|
|
||||||
/* Load the tuning data file */
|
/* Load the tuning data file */
|
||||||
File file(settings.configurationFile);
|
File file(settings.configurationFile);
|
||||||
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||||
|
@ -173,12 +180,12 @@ int IPASoftSimple::init(const IPASettings &settings,
|
||||||
* Don't save the min and max control values yet, as e.g. the limits
|
* Don't save the min and max control values yet, as e.g. the limits
|
||||||
* for V4L2_CID_EXPOSURE depend on the configured sensor resolution.
|
* for V4L2_CID_EXPOSURE depend on the configured sensor resolution.
|
||||||
*/
|
*/
|
||||||
if (sensorInfoMap.find(V4L2_CID_EXPOSURE) == sensorInfoMap.end()) {
|
if (sensorControls.find(V4L2_CID_EXPOSURE) == sensorControls.end()) {
|
||||||
LOG(IPASoft, Error) << "Don't have exposure control";
|
LOG(IPASoft, Error) << "Don't have exposure control";
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sensorInfoMap.find(V4L2_CID_ANALOGUE_GAIN) == sensorInfoMap.end()) {
|
if (sensorControls.find(V4L2_CID_ANALOGUE_GAIN) == sensorControls.end()) {
|
||||||
LOG(IPASoft, Error) << "Don't have gain control";
|
LOG(IPASoft, Error) << "Don't have gain control";
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -198,6 +205,8 @@ int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
|
||||||
context_.activeState = {};
|
context_.activeState = {};
|
||||||
context_.frameContexts.clear();
|
context_.frameContexts.clear();
|
||||||
|
|
||||||
|
context_.configuration.agc.lineDuration =
|
||||||
|
context_.sensorInfo.minLineLength * 1.0s / context_.sensorInfo.pixelRate;
|
||||||
context_.configuration.agc.exposureMin = exposureInfo.min().get<int32_t>();
|
context_.configuration.agc.exposureMin = exposureInfo.min().get<int32_t>();
|
||||||
context_.configuration.agc.exposureMax = exposureInfo.max().get<int32_t>();
|
context_.configuration.agc.exposureMax = exposureInfo.max().get<int32_t>();
|
||||||
if (!context_.configuration.agc.exposureMin) {
|
if (!context_.configuration.agc.exposureMin) {
|
||||||
|
|
|
@ -133,12 +133,20 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
|
||||||
std::string ipaTuningFile =
|
std::string ipaTuningFile =
|
||||||
ipa_->configurationFile(sensor->model() + ".yaml", "uncalibrated.yaml");
|
ipa_->configurationFile(sensor->model() + ".yaml", "uncalibrated.yaml");
|
||||||
|
|
||||||
int ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() },
|
IPACameraSensorInfo sensorInfo{};
|
||||||
debayer_->getStatsFD(),
|
int ret = sensor->sensorInfo(&sensorInfo);
|
||||||
sharedParams_.fd(),
|
if (ret) {
|
||||||
sensor->controls(),
|
LOG(SoftwareIsp, Error) << "Camera sensor information not available";
|
||||||
ipaControls,
|
return;
|
||||||
&ccmEnabled_);
|
}
|
||||||
|
|
||||||
|
ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() },
|
||||||
|
debayer_->getStatsFD(),
|
||||||
|
sharedParams_.fd(),
|
||||||
|
sensorInfo,
|
||||||
|
sensor->controls(),
|
||||||
|
ipaControls,
|
||||||
|
&ccmEnabled_);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG(SoftwareIsp, Error) << "IPA init failed";
|
LOG(SoftwareIsp, Error) << "IPA init failed";
|
||||||
debayer_.reset();
|
debayer_.reset();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue