summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/ipa/raspberrypi.h3
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp42
-rw-r--r--src/libcamera/pipeline/raspberrypi/raspberrypi.cpp53
3 files changed, 56 insertions, 42 deletions
diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h
index 46ce7c28..a4937769 100644
--- a/include/libcamera/ipa/raspberrypi.h
+++ b/include/libcamera/ipa/raspberrypi.h
@@ -12,6 +12,8 @@
enum RPiConfigParameters {
RPI_IPA_CONFIG_LS_TABLE = (1 << 0),
+ RPI_IPA_CONFIG_STAGGERED_WRITE = (1 << 1),
+ RPI_IPA_CONFIG_SENSOR = (1 << 2),
};
enum RPiOperations {
@@ -20,7 +22,6 @@ enum RPiOperations {
RPI_IPA_ACTION_STATS_METADATA_COMPLETE,
RPI_IPA_ACTION_RUN_ISP,
RPI_IPA_ACTION_RUN_ISP_AND_DROP_FRAME,
- RPI_IPA_ACTION_SET_SENSOR_CONFIG,
RPI_IPA_ACTION_EMBEDDED_COMPLETE,
RPI_IPA_EVENT_SIGNAL_STAT_READY,
RPI_IPA_EVENT_SIGNAL_ISP_PREPARE,
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index b412260b..2fcbc782 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -94,7 +94,7 @@ private:
void reportMetadata();
bool parseEmbeddedData(unsigned int bufferId, struct DeviceStatus &deviceStatus);
void processStats(unsigned int bufferId);
- void applyAGC(const struct AgcStatus *agcStatus);
+ void applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls);
void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls);
void applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls);
void applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls);
@@ -196,6 +196,8 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
if (entityControls.empty())
return;
+ result->operation = 0;
+
unicam_ctrls_ = entityControls.at(0);
isp_ctrls_ = entityControls.at(1);
/* Setup a metadata ControlList to output metadata. */
@@ -217,13 +219,11 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
helper_->GetDelays(exposureDelay, gainDelay);
sensorMetadata = helper_->SensorEmbeddedDataPresent();
- IPAOperationData op;
- op.operation = RPI_IPA_ACTION_SET_SENSOR_CONFIG;
- op.data.push_back(gainDelay);
- op.data.push_back(exposureDelay);
- op.data.push_back(sensorMetadata);
+ result->data.push_back(gainDelay);
+ result->data.push_back(exposureDelay);
+ result->data.push_back(sensorMetadata);
- queueFrameAction.emit(0, op);
+ result->operation |= RPI_IPA_CONFIG_STAGGERED_WRITE;
}
/* Re-assemble camera mode using the sensor info. */
@@ -268,8 +268,13 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
/* SwitchMode may supply updated exposure/gain values to use. */
metadata.Get("agc.status", agcStatus);
- if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0)
- applyAGC(&agcStatus);
+ if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) {
+ ControlList ctrls(unicam_ctrls_);
+ applyAGC(&agcStatus, ctrls);
+ result->controls.push_back(ctrls);
+
+ result->operation |= RPI_IPA_CONFIG_SENSOR;
+ }
lastMode_ = mode_;
@@ -788,8 +793,15 @@ void IPARPi::processStats(unsigned int bufferId)
controller_.Process(statistics, &rpiMetadata_);
struct AgcStatus agcStatus;
- if (rpiMetadata_.Get("agc.status", agcStatus) == 0)
- applyAGC(&agcStatus);
+ if (rpiMetadata_.Get("agc.status", agcStatus) == 0) {
+ ControlList ctrls(unicam_ctrls_);
+ applyAGC(&agcStatus, ctrls);
+
+ IPAOperationData op;
+ op.operation = RPI_IPA_ACTION_V4L2_SET_STAGGERED;
+ op.controls.push_back(ctrls);
+ queueFrameAction.emit(0, op);
+ }
}
void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)
@@ -815,11 +827,8 @@ void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)
static_cast<int32_t>(awbStatus->gain_b * 1000));
}
-void IPARPi::applyAGC(const struct AgcStatus *agcStatus)
+void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
{
- IPAOperationData op;
- op.operation = RPI_IPA_ACTION_V4L2_SET_STAGGERED;
-
int32_t gain_code = helper_->GainCode(agcStatus->analogue_gain);
int32_t exposure_lines = helper_->ExposureLines(agcStatus->shutter_time);
@@ -838,11 +847,8 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus)
<< agcStatus->analogue_gain << " (Gain Code: "
<< gain_code << ")";
- ControlList ctrls(unicam_ctrls_);
ctrls.set(V4L2_CID_ANALOGUE_GAIN, gain_code);
ctrls.set(V4L2_CID_EXPOSURE, exposure_lines);
- op.controls.push_back(ctrls);
- queueFrameAction.emit(0, op);
}
void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls)
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index dfcc7506..c309ba42 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -821,7 +821,7 @@ int PipelineHandlerRPi::start(Camera *camera)
/*
* Write the last set of gain and exposure values to the camera before
* starting. First check that the staggered ctrl has been initialised
- * by the IPA action.
+ * by configure().
*/
ASSERT(data->staggeredCtrl_);
data->staggeredCtrl_.reset();
@@ -1169,15 +1169,36 @@ int RPiCameraData::configureIPA()
}
/* Ready the IPA - it must know about the sensor resolution. */
+ IPAOperationData result;
+
ipa_->configure(sensorInfo, streamConfig, entityControls, ipaConfig,
- nullptr);
+ &result);
+
+ if (result.operation & RPI_IPA_CONFIG_STAGGERED_WRITE) {
+ /*
+ * Setup our staggered control writer with the sensor default
+ * gain and exposure delays.
+ */
+ if (!staggeredCtrl_) {
+ staggeredCtrl_.init(unicam_[Unicam::Image].dev(),
+ { { V4L2_CID_ANALOGUE_GAIN, result.data[0] },
+ { V4L2_CID_EXPOSURE, result.data[1] } });
+ sensorMetadata_ = result.data[2];
+ }
- /* Configure the H/V flip controls based on the sensor rotation. */
- ControlList ctrls(unicam_[Unicam::Image].dev()->controls());
- int32_t rotation = sensor_->properties().get(properties::Rotation);
- ctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!rotation));
- ctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!rotation));
- unicam_[Unicam::Image].dev()->setControls(&ctrls);
+ /* Configure the H/V flip controls based on the sensor rotation. */
+ ControlList ctrls(unicam_[Unicam::Image].dev()->controls());
+ int32_t rotation = sensor_->properties().get(properties::Rotation);
+ ctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!rotation));
+ ctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!rotation));
+ unicam_[Unicam::Image].dev()->setControls(&ctrls);
+ }
+
+ if (result.operation & RPI_IPA_CONFIG_SENSOR) {
+ const ControlList &ctrls = result.controls[0];
+ if (!staggeredCtrl_.set(ctrls))
+ LOG(RPI, Error) << "V4L2 staggered set failed";
+ }
return 0;
}
@@ -1190,26 +1211,12 @@ void RPiCameraData::queueFrameAction(unsigned int frame, const IPAOperationData
*/
switch (action.operation) {
case RPI_IPA_ACTION_V4L2_SET_STAGGERED: {
- ControlList controls = action.controls[0];
+ const ControlList &controls = action.controls[0];
if (!staggeredCtrl_.set(controls))
LOG(RPI, Error) << "V4L2 staggered set failed";
goto done;
}
- case RPI_IPA_ACTION_SET_SENSOR_CONFIG: {
- /*
- * Setup our staggered control writer with the sensor default
- * gain and exposure delays.
- */
- if (!staggeredCtrl_) {
- staggeredCtrl_.init(unicam_[Unicam::Image].dev(),
- { { V4L2_CID_ANALOGUE_GAIN, action.data[0] },
- { V4L2_CID_EXPOSURE, action.data[1] } });
- sensorMetadata_ = action.data[2];
- }
- goto done;
- }
-
case RPI_IPA_ACTION_V4L2_SET_ISP: {
ControlList controls = action.controls[0];
isp_[Isp::Input].dev()->setControls(&controls);