ipa: raspberrypi: Only validate ISP and sensor control during configure
There is no need to validate all the ISP and sensor V4L2 control on every use. Simply validate them once during the IPA configuration, and fail if a required control is not available. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
fdedaaf902
commit
f5e80e609c
1 changed files with 66 additions and 67 deletions
|
@ -92,6 +92,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setMode(const CameraSensorInfo &sensorInfo);
|
void setMode(const CameraSensorInfo &sensorInfo);
|
||||||
|
bool validateSensorControls();
|
||||||
|
bool validateIspControls();
|
||||||
void queueRequest(const ControlList &controls);
|
void queueRequest(const ControlList &controls);
|
||||||
void returnEmbeddedBuffer(unsigned int bufferId);
|
void returnEmbeddedBuffer(unsigned int bufferId);
|
||||||
void prepareISP(unsigned int bufferId);
|
void prepareISP(unsigned int bufferId);
|
||||||
|
@ -290,6 +292,18 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
|
||||||
sensorCtrls_ = entityControls.at(0);
|
sensorCtrls_ = entityControls.at(0);
|
||||||
ispCtrls_ = entityControls.at(1);
|
ispCtrls_ = entityControls.at(1);
|
||||||
|
|
||||||
|
if (!validateSensorControls()) {
|
||||||
|
LOG(IPARPI, Error) << "Sensor control validation failed.";
|
||||||
|
result->operation = RPi::IPA_CONFIG_FAILED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validateIspControls()) {
|
||||||
|
LOG(IPARPI, Error) << "ISP control validation failed.";
|
||||||
|
result->operation = RPi::IPA_CONFIG_FAILED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup a metadata ControlList to output metadata. */
|
/* Setup a metadata ControlList to output metadata. */
|
||||||
libcameraMetadata_ = ControlList(controls::controls);
|
libcameraMetadata_ = ControlList(controls::controls);
|
||||||
|
|
||||||
|
@ -506,6 +520,51 @@ void IPARPi::reportMetadata()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IPARPi::validateSensorControls()
|
||||||
|
{
|
||||||
|
static const uint32_t ctrls[] = {
|
||||||
|
V4L2_CID_ANALOGUE_GAIN,
|
||||||
|
V4L2_CID_EXPOSURE
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto c : ctrls) {
|
||||||
|
if (sensorCtrls_.find(c) == sensorCtrls_.end()) {
|
||||||
|
LOG(IPARPI, Error) << "Unable to find sensor control "
|
||||||
|
<< utils::hex(c);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPARPi::validateIspControls()
|
||||||
|
{
|
||||||
|
static const uint32_t ctrls[] = {
|
||||||
|
V4L2_CID_RED_BALANCE,
|
||||||
|
V4L2_CID_BLUE_BALANCE,
|
||||||
|
V4L2_CID_DIGITAL_GAIN,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_CC_MATRIX,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_GAMMA,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_GEQ,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_DENOISE,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_SHARPEN,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_DPC,
|
||||||
|
V4L2_CID_USER_BCM2835_ISP_LENS_SHADING
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto c : ctrls) {
|
||||||
|
if (ispCtrls_.find(c) == ispCtrls_.end()) {
|
||||||
|
LOG(IPARPI, Error) << "Unable to find ISP control "
|
||||||
|
<< utils::hex(c);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converting between enums (used in the libcamera API) and the names that
|
* Converting between enums (used in the libcamera API) and the names that
|
||||||
* we use to identify different modes. Unfortunately, the conversion tables
|
* we use to identify different modes. Unfortunately, the conversion tables
|
||||||
|
@ -891,18 +950,6 @@ void IPARPi::processStats(unsigned int bufferId)
|
||||||
|
|
||||||
void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)
|
void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
const auto gainR = ispCtrls_.find(V4L2_CID_RED_BALANCE);
|
|
||||||
if (gainR == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find red gain control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto gainB = ispCtrls_.find(V4L2_CID_BLUE_BALANCE);
|
|
||||||
if (gainB == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find blue gain control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gain_r << " B: "
|
LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gain_r << " B: "
|
||||||
<< awbStatus->gain_b;
|
<< awbStatus->gain_b;
|
||||||
|
|
||||||
|
@ -917,16 +964,6 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
|
||||||
int32_t gainCode = helper_->GainCode(agcStatus->analogue_gain);
|
int32_t gainCode = helper_->GainCode(agcStatus->analogue_gain);
|
||||||
int32_t exposureLines = helper_->ExposureLines(agcStatus->shutter_time);
|
int32_t exposureLines = helper_->ExposureLines(agcStatus->shutter_time);
|
||||||
|
|
||||||
if (sensorCtrls_.find(V4L2_CID_ANALOGUE_GAIN) == sensorCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find analogue gain control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sensorCtrls_.find(V4L2_CID_EXPOSURE) == sensorCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find exposure control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(IPARPI, Debug) << "Applying AGC Exposure: " << agcStatus->shutter_time
|
LOG(IPARPI, Debug) << "Applying AGC Exposure: " << agcStatus->shutter_time
|
||||||
<< " (Shutter lines: " << exposureLines << ") Gain: "
|
<< " (Shutter lines: " << exposureLines << ") Gain: "
|
||||||
<< agcStatus->analogue_gain << " (Gain Code: "
|
<< agcStatus->analogue_gain << " (Gain Code: "
|
||||||
|
@ -938,23 +975,14 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
|
||||||
|
|
||||||
void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls)
|
void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_DIGITAL_GAIN) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find digital gain control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrls.set(V4L2_CID_DIGITAL_GAIN,
|
ctrls.set(V4L2_CID_DIGITAL_GAIN,
|
||||||
static_cast<int32_t>(dgStatus->digital_gain * 1000));
|
static_cast<int32_t>(dgStatus->digital_gain * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls)
|
void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_CC_MATRIX) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find CCM control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_custom_ccm ccm;
|
bcm2835_isp_custom_ccm ccm;
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
ccm.ccm.ccm[i / 3][i % 3].den = 1000;
|
ccm.ccm.ccm[i / 3][i % 3].den = 1000;
|
||||||
ccm.ccm.ccm[i / 3][i % 3].num = 1000 * ccmStatus->matrix[i];
|
ccm.ccm.ccm[i / 3][i % 3].num = 1000 * ccmStatus->matrix[i];
|
||||||
|
@ -970,12 +998,8 @@ void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls)
|
||||||
|
|
||||||
void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls)
|
void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_GAMMA) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find Gamma control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bcm2835_isp_gamma gamma;
|
struct bcm2835_isp_gamma gamma;
|
||||||
|
|
||||||
gamma.enabled = 1;
|
gamma.enabled = 1;
|
||||||
for (int i = 0; i < CONTRAST_NUM_POINTS; i++) {
|
for (int i = 0; i < CONTRAST_NUM_POINTS; i++) {
|
||||||
gamma.x[i] = contrastStatus->points[i].x;
|
gamma.x[i] = contrastStatus->points[i].x;
|
||||||
|
@ -989,12 +1013,8 @@ void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList
|
||||||
|
|
||||||
void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls)
|
void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find black level control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_black_level blackLevel;
|
bcm2835_isp_black_level blackLevel;
|
||||||
|
|
||||||
blackLevel.enabled = 1;
|
blackLevel.enabled = 1;
|
||||||
blackLevel.black_level_r = blackLevelStatus->black_level_r;
|
blackLevel.black_level_r = blackLevelStatus->black_level_r;
|
||||||
blackLevel.black_level_g = blackLevelStatus->black_level_g;
|
blackLevel.black_level_g = blackLevelStatus->black_level_g;
|
||||||
|
@ -1007,12 +1027,8 @@ void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, Co
|
||||||
|
|
||||||
void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls)
|
void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_GEQ) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find geq control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_geq geq;
|
bcm2835_isp_geq geq;
|
||||||
|
|
||||||
geq.enabled = 1;
|
geq.enabled = 1;
|
||||||
geq.offset = geqStatus->offset;
|
geq.offset = geqStatus->offset;
|
||||||
geq.slope.den = 1000;
|
geq.slope.den = 1000;
|
||||||
|
@ -1025,12 +1041,8 @@ void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls)
|
||||||
|
|
||||||
void IPARPi::applyDenoise(const struct SdnStatus *denoiseStatus, ControlList &ctrls)
|
void IPARPi::applyDenoise(const struct SdnStatus *denoiseStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DENOISE) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find denoise control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_denoise denoise;
|
bcm2835_isp_denoise denoise;
|
||||||
|
|
||||||
denoise.enabled = 1;
|
denoise.enabled = 1;
|
||||||
denoise.constant = denoiseStatus->noise_constant;
|
denoise.constant = denoiseStatus->noise_constant;
|
||||||
denoise.slope.num = 1000 * denoiseStatus->noise_slope;
|
denoise.slope.num = 1000 * denoiseStatus->noise_slope;
|
||||||
|
@ -1045,12 +1057,8 @@ void IPARPi::applyDenoise(const struct SdnStatus *denoiseStatus, ControlList &ct
|
||||||
|
|
||||||
void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls)
|
void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_SHARPEN) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find sharpen control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_sharpen sharpen;
|
bcm2835_isp_sharpen sharpen;
|
||||||
|
|
||||||
sharpen.enabled = 1;
|
sharpen.enabled = 1;
|
||||||
sharpen.threshold.num = 1000 * sharpenStatus->threshold;
|
sharpen.threshold.num = 1000 * sharpenStatus->threshold;
|
||||||
sharpen.threshold.den = 1000;
|
sharpen.threshold.den = 1000;
|
||||||
|
@ -1066,12 +1074,8 @@ void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList
|
||||||
|
|
||||||
void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls)
|
void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DPC) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find DPC control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bcm2835_isp_dpc dpc;
|
bcm2835_isp_dpc dpc;
|
||||||
|
|
||||||
dpc.enabled = 1;
|
dpc.enabled = 1;
|
||||||
dpc.strength = dpcStatus->strength;
|
dpc.strength = dpcStatus->strength;
|
||||||
|
|
||||||
|
@ -1082,11 +1086,6 @@ void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls)
|
||||||
|
|
||||||
void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls)
|
void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls)
|
||||||
{
|
{
|
||||||
if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING) == ispCtrls_.end()) {
|
|
||||||
LOG(IPARPI, Error) << "Can't find LS control";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Program lens shading tables into pipeline.
|
* Program lens shading tables into pipeline.
|
||||||
* Choose smallest cell size that won't exceed 63x48 cells.
|
* Choose smallest cell size that won't exceed 63x48 cells.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue