summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2020-12-15 10:16:33 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-12-16 03:46:00 +0200
commitf5e80e609c7cafd36d409692844ecba9741939b5 (patch)
treeea199d39dcd400f8068a64ad1e733670e97dfff3 /src/ipa
parentfdedaaf90272ac981ec0b10f1de0b6b89e0d3679 (diff)
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>
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp133
1 files changed, 66 insertions, 67 deletions
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 5f2e07fd..d087b07e 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -92,6 +92,8 @@ public:
private:
void setMode(const CameraSensorInfo &sensorInfo);
+ bool validateSensorControls();
+ bool validateIspControls();
void queueRequest(const ControlList &controls);
void returnEmbeddedBuffer(unsigned int bufferId);
void prepareISP(unsigned int bufferId);
@@ -290,6 +292,18 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
sensorCtrls_ = entityControls.at(0);
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. */
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
* 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)
{
- 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: "
<< 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 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
<< " (Shutter lines: " << exposureLines << ") Gain: "
<< 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)
{
- 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,
static_cast<int32_t>(dgStatus->digital_gain * 1000));
}
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;
+
for (int i = 0; i < 9; i++) {
ccm.ccm.ccm[i / 3][i % 3].den = 1000;
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)
{
- 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;
+
gamma.enabled = 1;
for (int i = 0; i < CONTRAST_NUM_POINTS; i++) {
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)
{
- 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;
+
blackLevel.enabled = 1;
blackLevel.black_level_r = blackLevelStatus->black_level_r;
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)
{
- if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_GEQ) == ispCtrls_.end()) {
- LOG(IPARPI, Error) << "Can't find geq control";
- return;
- }
-
bcm2835_isp_geq geq;
+
geq.enabled = 1;
geq.offset = geqStatus->offset;
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)
{
- if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DENOISE) == ispCtrls_.end()) {
- LOG(IPARPI, Error) << "Can't find denoise control";
- return;
- }
-
bcm2835_isp_denoise denoise;
+
denoise.enabled = 1;
denoise.constant = denoiseStatus->noise_constant;
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)
{
- if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_SHARPEN) == ispCtrls_.end()) {
- LOG(IPARPI, Error) << "Can't find sharpen control";
- return;
- }
-
bcm2835_isp_sharpen sharpen;
+
sharpen.enabled = 1;
sharpen.threshold.num = 1000 * sharpenStatus->threshold;
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)
{
- if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DPC) == ispCtrls_.end()) {
- LOG(IPARPI, Error) << "Can't find DPC control";
- return;
- }
-
bcm2835_isp_dpc dpc;
+
dpc.enabled = 1;
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)
{
- 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.
* Choose smallest cell size that won't exceed 63x48 cells.