libcamera: ipa: Pass a set of controls and return results from ipa::start()

This change allows controls passed into PipelineHandler::start to be
forwarded onto IPAInterface::start(). We also add a return channel if the
pipeline handler must action any of these controls, e.g. setting the
analogue gain or shutter speed in the sensor device.

The IPA interface wrapper isn't addressed as it will soon be replaced by
a new mechanism to handle IPC.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Naushir Patuck 2020-12-04 15:31:20 +00:00 committed by Laurent Pinchart
parent a62b35b8c0
commit 0238b9e080
15 changed files with 51 additions and 23 deletions

View file

@ -20,7 +20,8 @@ public:
~IPAContextWrapper();
int init(const IPASettings &settings) override;
int start() override;
int start(const IPAOperationData &data,
IPAOperationData *result) override;
void stop() override;
void configure(const CameraSensorInfo &sensorInfo,
const std::map<unsigned int, IPAStream> &streamConfig,

View file

@ -153,7 +153,8 @@ public:
virtual ~IPAInterface() = default;
virtual int init(const IPASettings &settings) = 0;
virtual int start() = 0;
virtual int start(const IPAOperationData &data,
IPAOperationData *result) = 0;
virtual void stop() = 0;
virtual void configure(const CameraSensorInfo &sensorInfo,

View file

@ -95,7 +95,9 @@ int IPAInterfaceWrapper::start(struct ipa_context *_ctx)
{
IPAInterfaceWrapper *ctx = static_cast<IPAInterfaceWrapper *>(_ctx);
return ctx->ipa_->start();
/* \todo Translate the data and result. */
IPAOperationData data = {};
return ctx->ipa_->start(data, nullptr);
}
void IPAInterfaceWrapper::stop(struct ipa_context *_ctx)

View file

@ -78,13 +78,14 @@ public:
}
int init(const IPASettings &settings) override;
int start() override { return 0; }
int start([[maybe_unused]] const IPAOperationData &data,
[[maybe_unused]] IPAOperationData *result) override { return 0; }
void stop() override {}
void configure(const CameraSensorInfo &sensorInfo,
const std::map<unsigned int, IPAStream> &streamConfig,
const std::map<unsigned int, const ControlInfoMap &> &entityControls,
const IPAOperationData &data,
const IPAOperationData &ipaConfig,
IPAOperationData *response) override;
void mapBuffers(const std::vector<IPABuffer> &buffers) override;
void unmapBuffers(const std::vector<unsigned int> &ids) override;

View file

@ -37,7 +37,8 @@ public:
{
return 0;
}
int start() override { return 0; }
int start([[maybe_unused]] const IPAOperationData &data,
[[maybe_unused]] IPAOperationData *result) override { return 0; }
void stop() override {}
void configure(const CameraSensorInfo &info,

View file

@ -34,7 +34,8 @@ public:
int init(const IPASettings &settings) override;
int start() override;
int start(const IPAOperationData &data,
IPAOperationData *result) override;
void stop() override;
void configure([[maybe_unused]] const CameraSensorInfo &sensorInfo,
@ -82,7 +83,8 @@ int IPAVimc::init(const IPASettings &settings)
return 0;
}
int IPAVimc::start()
int IPAVimc::start([[maybe_unused]] const IPAOperationData &data,
[[maybe_unused]] IPAOperationData *result)
{
trace(IPAOperationStart);

View file

@ -86,10 +86,11 @@ int IPAContextWrapper::init(const IPASettings &settings)
return 0;
}
int IPAContextWrapper::start()
int IPAContextWrapper::start(const IPAOperationData &data,
IPAOperationData *result)
{
if (intf_)
return intf_->start();
return intf_->start(data, result);
if (!ctx_)
return 0;

View file

@ -536,10 +536,17 @@ namespace libcamera {
/**
* \fn IPAInterface::start()
* \brief Start the IPA
* \param[in] data Protocol-specific data for the start operation
* \param[out] result Result of the start operation
*
* This method informs the IPA module that the camera is about to be started.
* The IPA module shall prepare any resources it needs to operate.
*
* The \a data and \a result parameters carry custom data passed by the
* pipeline handler to the IPA and back. The pipeline handler may set the \a
* result parameter to null if the IPA protocol doesn't need to pass a result
* back through the start() function.
*
* \return 0 on success or a negative error code otherwise
*/

View file

@ -752,7 +752,11 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
}
/* Start the IPA. */
ret = data->ipa_->start();
IPAOperationData ipaData = {};
IPAOperationData result = {};
if (controls)
ipaData.controls.emplace_back(*controls);
ret = data->ipa_->start(ipaData, &result);
if (ret) {
LOG(RPI, Error)
<< "Failed to start IPA for " << camera->id();
@ -1189,7 +1193,7 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
}
/* Ready the IPA - it must know about the sensor resolution. */
IPAOperationData result;
IPAOperationData result = {};
ipa_->configure(sensorInfo_, streamConfig, entityControls, ipaConfig,
&result);

View file

@ -842,7 +842,8 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c
if (ret)
return ret;
ret = data->ipa_->start();
IPAOperationData ipaData = {};
ret = data->ipa_->start(ipaData, nullptr);
if (ret) {
freeBuffers(camera);
LOG(RkISP1, Error)

View file

@ -322,7 +322,8 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] ControlList *con
if (ret < 0)
return ret;
ret = data->ipa_->start();
IPAOperationData ipaData = {};
ret = data->ipa_->start(ipaData, nullptr);
if (ret) {
data->video_->releaseBuffers();
return ret;

View file

@ -30,7 +30,8 @@ public:
{
return 0;
}
int start() override { return 0; }
int start([[maybe_unused]] const IPAOperationData &data,
[[maybe_unused]] IPAOperationData *result) override { return 0; }
void stop() override {}
void configure([[maybe_unused]] const CameraSensorInfo &sensorInfo,
[[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,

View file

@ -26,7 +26,8 @@ public:
IPAProxyThread(IPAModule *ipam);
int init(const IPASettings &settings) override;
int start() override;
int start(const IPAOperationData &data,
IPAOperationData *result) override;
void stop() override;
void configure(const CameraSensorInfo &sensorInfo,
@ -50,9 +51,9 @@ private:
ipa_ = ipa;
}
int start()
int start(const IPAOperationData &data, IPAOperationData *result)
{
return ipa_->start();
return ipa_->start(data, result);
}
void stop()
@ -111,12 +112,14 @@ int IPAProxyThread::init(const IPASettings &settings)
return 0;
}
int IPAProxyThread::start()
int IPAProxyThread::start(const IPAOperationData &data,
IPAOperationData *result)
{
running_ = true;
thread_.start();
return proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking);
return proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking,
data, result);
}
void IPAProxyThread::stop()

View file

@ -120,7 +120,8 @@ protected:
}
/* Test start of IPA module. */
ipa_->start();
IPAOperationData data = {};
ipa_->start(data, nullptr);
timer.start(1000);
while (timer.isRunning() && trace_ != IPAOperationStart)
dispatcher->processEvents();

View file

@ -56,7 +56,8 @@ public:
return 0;
}
int start() override
int start([[maybe_unused]] const IPAOperationData &data,
[[maybe_unused]] IPAOperationData *result) override
{
report(Op_start, TestPass);
return 0;
@ -376,7 +377,7 @@ protected:
return TestFail;
}
ret = INVOKE(start);
ret = INVOKE(start, ipaConfig, nullptr);
if (ret == TestFail) {
cerr << "Failed to run start()";
return TestFail;