@@ -20,7 +20,7 @@ interface IPARkISP1Interface {
libcamera.IPACameraSensorInfo sensorInfo,
libcamera.ControlInfoMap sensorControls)
=> (int32 ret, libcamera.ControlInfoMap ipaControls);
- start() => (int32 ret);
+ start() => (int32 ret, libcamera.ControlList sensorControls);
stop();
configure(IPAConfigInfo configInfo,
@@ -191,6 +191,8 @@ struct IPAContext {
/* Interface to the Camera Helper */
std::unique_ptr<CameraSensorHelper> camHelper;
+
+ bool sensorControlsNeedSync;
};
} /* namespace ipa::rkisp1 */
@@ -55,7 +55,7 @@ public:
const IPACameraSensorInfo &sensorInfo,
const ControlInfoMap &sensorControls,
ControlInfoMap *ipaControls) override;
- int start() override;
+ int start(ControlList *sensorControls) override;
void stop() override;
int configure(const IPAConfigInfo &ipaConfig,
@@ -124,7 +124,7 @@ const ControlInfoMap::Map rkisp1Controls{
} /* namespace */
IPARkISP1::IPARkISP1()
- : context_({ {}, {}, {}, {}, { kMaxFrameContexts }, {}, {} })
+ : context_({ {}, {}, {}, {}, { kMaxFrameContexts }, {}, {}, false })
{
}
@@ -208,10 +208,19 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
return 0;
}
-int IPARkISP1::start()
+int IPARkISP1::start(ControlList *sensorControls)
{
- setControls(0);
+ if (context_.sensorControlsNeedSync) {
+ const auto &agc = context_.activeState.agc;
+ uint32_t exposure = agc.automatic.exposure;
+ uint32_t gain = context_.camHelper->gainCode(agc.automatic.gain);
+ *sensorControls = ControlList{ sensorControls_ };
+ sensorControls->set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure));
+ sensorControls->set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain));
+
+ context_.sensorControlsNeedSync = false;
+ }
return 0;
}
@@ -290,6 +299,8 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
return ret;
}
+ context_.sensorControlsNeedSync = true;
+
return 0;
}
@@ -943,6 +943,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
{
RkISP1CameraData *data = cameraData(camera);
utils::ScopeExitActions actions;
+ ControlList sensorControls;
int ret;
/* Allocate buffers for internal pipeline usage. */
@@ -951,7 +952,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
return ret;
actions += [&]() { freeBuffers(camera); };
- ret = data->ipa_->start();
+ ret = data->ipa_->start(&sensorControls);
if (ret) {
LOG(RkISP1, Error)
<< "Failed to start IPA " << camera->id();
@@ -961,6 +962,9 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
data->frame_ = 0;
+ data->sensor_->setControls(&sensorControls);
+ data->delayedCtrls_->reset();
+
if (!isRaw_) {
ret = param_->streamOn();
if (ret) {
When IPA AGC active state is initialized in configure() method, it may fall out of sync with actual sensor controls and initial values in the delayed controls. Fix this by sending updated controls to the pipeline handler on first start() after configure(). Also reset delayedCtrls_ on start to make it capture the updated control values. Signed-off-by: Mikhail Rudenko <mike.rudenko@gmail.com> --- include/libcamera/ipa/rkisp1.mojom | 2 +- src/ipa/rkisp1/ipa_context.h | 2 ++ src/ipa/rkisp1/rkisp1.cpp | 19 +++++++++++++++---- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 6 +++++- 4 files changed, 23 insertions(+), 6 deletions(-)