summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcamera/pipeline')
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp93
-rw-r--r--src/libcamera/pipeline/raspberrypi/raspberrypi.cpp257
-rw-r--r--src/libcamera/pipeline/raspberrypi/rpi_stream.cpp6
-rw-r--r--src/libcamera/pipeline/raspberrypi/rpi_stream.h5
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp75
-rw-r--r--src/libcamera/pipeline/vimc/vimc.cpp10
6 files changed, 211 insertions, 235 deletions
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 61f7bf43..3e6b88af 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -14,7 +14,8 @@
#include <libcamera/camera.h>
#include <libcamera/control_ids.h>
#include <libcamera/formats.h>
-#include <libcamera/ipa/ipu3.h>
+#include <libcamera/ipa/ipu3_ipa_interface.h>
+#include <libcamera/ipa/ipu3_ipa_proxy.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
@@ -77,8 +78,11 @@ public:
std::unique_ptr<DelayedControls> delayedCtrls_;
IPU3Frames frameInfos_;
+ std::unique_ptr<ipa::ipu3::IPAProxyIPU3> ipa_;
+
private:
- void queueFrameAction(unsigned int id, const IPAOperationData &op);
+ void queueFrameAction(unsigned int id,
+ const ipa::ipu3::IPU3Action &action);
};
class IPU3CameraConfiguration : public CameraConfiguration
@@ -609,18 +613,12 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera)
for (const std::unique_ptr<FrameBuffer> &buffer : imgu->paramBuffers_) {
buffer->setCookie(ipaBufferId++);
- ipaBuffers_.push_back({
- .id = buffer->cookie(),
- .planes = buffer->planes()
- });
+ ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());
}
for (const std::unique_ptr<FrameBuffer> &buffer : imgu->statBuffers_) {
buffer->setCookie(ipaBufferId++);
- ipaBuffers_.push_back({
- .id = buffer->cookie(),
- .planes = buffer->planes()
- });
+ ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());
}
data->ipa_->mapBuffers(ipaBuffers_);
@@ -650,16 +648,10 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera)
int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *controls)
{
+ std::map<uint32_t, ControlInfoMap> entityControls;
IPU3CameraData *data = cameraData(camera);
CIO2Device *cio2 = &data->cio2_;
ImgUDevice *imgu = data->imgu_;
-
- CameraSensorInfo sensorInfo = {};
- std::map<unsigned int, IPAStream> streamConfig;
- std::map<unsigned int, const ControlInfoMap &> entityControls;
- IPAOperationData ipaConfig;
- IPAOperationData result = {};
-
int ret;
/* Allocate buffers for internal pipeline usage. */
@@ -667,8 +659,7 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *con
if (ret)
return ret;
- IPAOperationData ipaData = {};
- ret = data->ipa_->start(ipaData, nullptr);
+ ret = data->ipa_->start();
if (ret)
goto error;
@@ -684,24 +675,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *con
if (ret)
goto error;
- /* Inform IPA of stream configuration and sensor controls. */
- ret = data->cio2_.sensor()->sensorInfo(&sensorInfo);
- if (ret)
- goto error;
-
- streamConfig[0] = {
- .pixelFormat = data->outStream_.configuration().pixelFormat,
- .size = data->outStream_.configuration().size,
- };
- streamConfig[1] = {
- .pixelFormat = data->vfStream_.configuration().pixelFormat,
- .size = data->vfStream_.configuration().size,
- };
-
entityControls.emplace(0, data->cio2_.sensor()->controls());
-
- data->ipa_->configure(sensorInfo, streamConfig, entityControls,
- ipaConfig, &result);
+ data->ipa_->configure(entityControls);
return 0;
@@ -751,11 +726,11 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
info->rawBuffer = rawBuffer;
- IPAOperationData op;
- op.operation = IPU3_IPA_EVENT_PROCESS_CONTROLS;
- op.data = { info->id };
- op.controls = { request->controls() };
- data->ipa_->processEvent(op);
+ ipa::ipu3::IPU3Event ev;
+ ev.op = ipa::ipu3::EventProcessControls;
+ ev.frame = info->id;
+ ev.controls = request->controls();
+ data->ipa_->processEvent(ev);
return 0;
}
@@ -1048,7 +1023,7 @@ int PipelineHandlerIPU3::registerCameras()
int IPU3CameraData::loadIPA()
{
- ipa_ = IPAManager::createIPA(pipe_, 1, 1);
+ ipa_ = IPAManager::createIPA<ipa::ipu3::IPAProxyIPU3>(pipe_, 1, 1);
if (!ipa_)
return -ENOENT;
@@ -1060,15 +1035,15 @@ int IPU3CameraData::loadIPA()
}
void IPU3CameraData::queueFrameAction(unsigned int id,
- const IPAOperationData &action)
+ const ipa::ipu3::IPU3Action &action)
{
- switch (action.operation) {
- case IPU3_IPA_ACTION_SET_SENSOR_CONTROLS: {
- const ControlList &controls = action.controls[0];
+ switch (action.op) {
+ case ipa::ipu3::ActionSetSensorControls: {
+ const ControlList &controls = action.controls;
delayedCtrls_->push(controls);
break;
}
- case IPU3_IPA_ACTION_PARAM_FILLED: {
+ case ipa::ipu3::ActionParamFilled: {
IPU3Frames::Info *info = frameInfos_.find(id);
if (!info)
break;
@@ -1090,13 +1065,13 @@ void IPU3CameraData::queueFrameAction(unsigned int id,
break;
}
- case IPU3_IPA_ACTION_METADATA_READY: {
+ case ipa::ipu3::ActionMetadataReady: {
IPU3Frames::Info *info = frameInfos_.find(id);
if (!info)
break;
Request *request = info->request;
- request->metadata() = action.controls[0];
+ request->metadata() = action.controls;
info->metadataProcessed = true;
if (frameInfos_.tryComplete(info))
pipe_->completeRequest(request);
@@ -1104,7 +1079,7 @@ void IPU3CameraData::queueFrameAction(unsigned int id,
break;
}
default:
- LOG(IPU3, Error) << "Unknown action " << action.operation;
+ LOG(IPU3, Error) << "Unknown action " << action.op;
break;
}
}
@@ -1172,10 +1147,11 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
if (request->findBuffer(&rawStream_))
pipe_->completeBuffer(request, buffer);
- IPAOperationData op;
- op.operation = IPU3_IPA_EVENT_FILL_PARAMS;
- op.data = { info->id, info->paramBuffer->cookie() };
- ipa_->processEvent(op);
+ ipa::ipu3::IPU3Event ev;
+ ev.op = ipa::ipu3::EventFillParams;
+ ev.frame = info->id;
+ ev.bufferId = info->paramBuffer->cookie();
+ ipa_->processEvent(ev);
}
void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
@@ -1202,10 +1178,11 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer)
return;
}
- IPAOperationData op;
- op.operation = IPU3_IPA_EVENT_STAT_READY;
- op.data = { info->id, info->statBuffer->cookie() };
- ipa_->processEvent(op);
+ ipa::ipu3::IPU3Event ev;
+ ev.op = ipa::ipu3::EventStatReady;
+ ev.frame = info->id;
+ ev.bufferId = info->statBuffer->cookie();
+ ipa_->processEvent(ev);
}
REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3)
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index e4764681..15aa600e 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -18,10 +18,13 @@
#include <libcamera/file_descriptor.h>
#include <libcamera/formats.h>
#include <libcamera/ipa/raspberrypi.h>
+#include <libcamera/ipa/raspberrypi_ipa_interface.h>
+#include <libcamera/ipa/raspberrypi_ipa_proxy.h>
#include <libcamera/logging.h>
#include <libcamera/property_ids.h>
#include <libcamera/request.h>
+#include <linux/bcm2835-isp.h>
#include <linux/videodev2.h>
#include "libcamera/internal/bayer_format.h"
@@ -146,7 +149,11 @@ public:
int loadIPA();
int configureIPA(const CameraConfiguration *config);
- void queueFrameAction(unsigned int frame, const IPAOperationData &action);
+ void statsMetadataComplete(uint32_t bufferId, const ControlList &controls);
+ void runIsp(uint32_t bufferId);
+ void embeddedComplete(uint32_t bufferId);
+ void setIsp(const ControlList &controls);
+ void setDelayedControls(const ControlList &controls);
/* bufferComplete signal handlers. */
void unicamBufferDequeue(FrameBuffer *buffer);
@@ -159,6 +166,8 @@ public:
void handleState();
void applyScalerCrop(const ControlList &controls);
+ std::unique_ptr<ipa::rpi::IPAProxyRPi> ipa_;
+
std::unique_ptr<CameraSensor> sensor_;
/* Array of Unicam and ISP device streams and associated buffers/streams. */
RPi::Device<Unicam, 2> unicam_;
@@ -751,7 +760,7 @@ int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stre
return ret;
}
-int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *controls)
+int PipelineHandlerRPi::start(Camera *camera, ControlList *controls)
{
RPiCameraData *data = cameraData(camera);
int ret;
@@ -769,30 +778,20 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
data->applyScalerCrop(*controls);
/* Start the IPA. */
- IPAOperationData ipaData = {};
- IPAOperationData result = {};
- if (controls) {
- ipaData.operation = RPi::IPA_CONFIG_STARTUP_CTRLS;
- ipaData.controls.emplace_back(*controls);
- }
- ret = data->ipa_->start(ipaData, &result);
- if (ret) {
- LOG(RPI, Error)
- << "Failed to start IPA for " << camera->id();
- stop(camera);
- return ret;
- }
+ ipa::rpi::StartControls ipaData;
+ ipa::rpi::StartControls result;
+ if (controls)
+ ipaData.controls = *controls;
+ data->ipa_->start(ipaData, &result);
/* Apply any gain/exposure settings that the IPA may have passed back. */
- if (result.operation & RPi::IPA_RESULT_SENSOR_CTRLS) {
- ControlList &ctrls = result.controls[0];
+ if (!result.controls.empty()) {
+ ControlList &ctrls = result.controls;
data->unicam_[Unicam::Image].dev()->setControls(&ctrls);
}
- if (result.operation & RPi::IPA_RESULT_DROP_FRAMES) {
- /* Configure the number of dropped frames required on startup. */
- data->dropFrameCount_ = result.data[0];
- }
+ /* Configure the number of dropped frames required on startup. */
+ data->dropFrameCount_ = result.dropFrameCount;
/* We need to set the dropFrameCount_ before queueing buffers. */
ret = queueAllBuffers(camera);
@@ -1115,8 +1114,8 @@ int PipelineHandlerRPi::prepareBuffers(Camera *camera)
* Pass the stats and embedded data buffers to the IPA. No other
* buffers need to be passed.
*/
- mapBuffers(camera, data->isp_[Isp::Stats].getBuffers(), RPi::BufferMask::STATS);
- mapBuffers(camera, data->unicam_[Unicam::Embedded].getBuffers(), RPi::BufferMask::EMBEDDED_DATA);
+ mapBuffers(camera, data->isp_[Isp::Stats].getBuffers(), ipa::rpi::MaskStats);
+ mapBuffers(camera, data->unicam_[Unicam::Embedded].getBuffers(), ipa::rpi::MaskEmbeddedData);
return 0;
}
@@ -1133,8 +1132,8 @@ void PipelineHandlerRPi::mapBuffers(Camera *camera, const RPi::BufferMap &buffer
* handler and the IPA.
*/
for (auto const &it : buffers) {
- ipaBuffers.push_back({ .id = mask | it.first,
- .planes = it.second->planes() });
+ ipaBuffers.push_back(IPABuffer(mask | it.first,
+ it.second->planes()));
data->ipaBuffers_.insert(mask | it.first);
}
@@ -1165,15 +1164,18 @@ void RPiCameraData::frameStarted(uint32_t sequence)
int RPiCameraData::loadIPA()
{
- ipa_ = IPAManager::createIPA(pipe_, 1, 1);
+ ipa_ = IPAManager::createIPA<ipa::rpi::IPAProxyRPi>(pipe_, 1, 1);
+
if (!ipa_)
return -ENOENT;
- ipa_->queueFrameAction.connect(this, &RPiCameraData::queueFrameAction);
+ ipa_->statsMetadataComplete.connect(this, &RPiCameraData::statsMetadataComplete);
+ ipa_->runIsp.connect(this, &RPiCameraData::runIsp);
+ ipa_->embeddedComplete.connect(this, &RPiCameraData::embeddedComplete);
+ ipa_->setIsp.connect(this, &RPiCameraData::setIsp);
+ ipa_->setDelayedControls.connect(this, &RPiCameraData::setDelayedControls);
- IPASettings settings{
- .configurationFile = ipa_->configurationFile(sensor_->model() + ".json")
- };
+ IPASettings settings(ipa_->configurationFile(sensor_->model() + ".json"));
return ipa_->init(settings);
}
@@ -1185,8 +1187,8 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
static_cast<const RPiCameraConfiguration *>(config);
std::map<unsigned int, IPAStream> streamConfig;
- std::map<unsigned int, const ControlInfoMap &> entityControls;
- IPAOperationData ipaConfig = {};
+ std::map<unsigned int, ControlInfoMap> entityControls;
+ ipa::rpi::ConfigInput ipaConfig;
/* Get the device format to pass to the IPA. */
V4L2DeviceFormat sensorFormat;
@@ -1195,10 +1197,9 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
unsigned int i = 0;
for (auto const &stream : isp_) {
if (stream.isExternal()) {
- streamConfig[i++] = {
- .pixelFormat = stream.configuration().pixelFormat,
- .size = stream.configuration().size
- };
+ streamConfig[i++] = IPAStream(
+ stream.configuration().pixelFormat,
+ stream.configuration().size);
}
}
@@ -1206,17 +1207,20 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
entityControls.emplace(1, isp_[Isp::Input].dev()->controls());
/* Always send the user transform to the IPA. */
- ipaConfig.data = { static_cast<unsigned int>(config->transform) };
+ ipaConfig.transform = static_cast<unsigned int>(config->transform);
/* Allocate the lens shading table via dmaHeap and pass to the IPA. */
if (!lsTable_.isValid()) {
- lsTable_ = dmaHeap_.alloc("ls_grid", RPi::MaxLsGridSize);
+ lsTable_ = dmaHeap_.alloc("ls_grid", ipa::rpi::MaxLsGridSize);
if (!lsTable_.isValid())
return -ENOMEM;
/* Allow the IPA to mmap the LS table via the file descriptor. */
- ipaConfig.operation = RPi::IPA_CONFIG_LS_TABLE;
- ipaConfig.data.push_back(static_cast<unsigned int>(lsTable_.fd()));
+ /*
+ * \todo Investigate if mapping the lens shading table buffer
+ * could be handled with mapBuffers().
+ */
+ ipaConfig.lsTableHandle = lsTable_;
}
/* We store the CameraSensorInfo for digital zoom calculations. */
@@ -1227,35 +1231,34 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
}
/* Ready the IPA - it must know about the sensor resolution. */
- IPAOperationData result = {};
+ ipa::rpi::ConfigOutput result;
ipa_->configure(sensorInfo_, streamConfig, entityControls, ipaConfig,
- &result);
+ &result, &ret);
- if (result.operation & RPi::IPA_RESULT_CONFIG_FAILED) {
+ if (ret < 0) {
LOG(RPI, Error) << "IPA configuration failed!";
return -EPIPE;
}
- unsigned int resultIdx = 0;
- if (result.operation & RPi::IPA_RESULT_SENSOR_PARAMS) {
+ if (result.params & ipa::rpi::ConfigStaggeredWrite) {
/*
* Setup our delayed control writer with the sensor default
* gain and exposure delays.
*/
std::unordered_map<uint32_t, unsigned int> delays = {
- { V4L2_CID_ANALOGUE_GAIN, result.data[resultIdx++] },
- { V4L2_CID_EXPOSURE, result.data[resultIdx++] },
- { V4L2_CID_VBLANK, result.data[resultIdx++] }
+ { V4L2_CID_ANALOGUE_GAIN, result.sensorConfig.gainDelay },
+ { V4L2_CID_EXPOSURE, result.sensorConfig.exposureDelay },
+ { V4L2_CID_VBLANK, result.sensorConfig.vblank }
};
delayedCtrls_ = std::make_unique<DelayedControls>(unicam_[Unicam::Image].dev(), delays);
- sensorMetadata_ = result.data[resultIdx++];
+ sensorMetadata_ = result.sensorConfig.sensorMetadata;
}
- if (result.operation & RPi::IPA_RESULT_SENSOR_CTRLS) {
- ControlList &ctrls = result.controls[0];
+ if (!result.controls.empty()) {
+ ControlList &ctrls = result.controls;
unicam_[Unicam::Image].dev()->setControls(&ctrls);
}
@@ -1275,90 +1278,86 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
return 0;
}
-void RPiCameraData::queueFrameAction([[maybe_unused]] unsigned int frame,
- const IPAOperationData &action)
+void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList &controls)
{
+ if (state_ == State::Stopped)
+ handleState();
+
+ FrameBuffer *buffer = isp_[Isp::Stats].getBuffers().at(bufferId);
+
+ handleStreamBuffer(buffer, &isp_[Isp::Stats]);
+
+ /* Fill the Request metadata buffer with what the IPA has provided */
+ Request *request = requestQueue_.front();
+ request->metadata() = std::move(controls);
+
/*
- * The following actions can be handled when the pipeline handler is in
- * a stopped state.
+ * Also update the ScalerCrop in the metadata with what we actually
+ * used. But we must first rescale that from ISP (camera mode) pixels
+ * back into sensor native pixels.
+ *
+ * Sending this information on every frame may be helpful.
*/
- switch (action.operation) {
- case RPi::IPA_ACTION_SET_DELAYED_CTRLS: {
- const ControlList &controls = action.controls[0];
- if (!delayedCtrls_->push(controls))
- LOG(RPI, Error) << "Failed to set delayed controls";
- goto done;
+ if (updateScalerCrop_) {
+ updateScalerCrop_ = false;
+ scalerCrop_ = ispCrop_.scaledBy(sensorInfo_.analogCrop.size(),
+ sensorInfo_.outputSize);
+ scalerCrop_.translateBy(sensorInfo_.analogCrop.topLeft());
}
+ request->metadata().set(controls::ScalerCrop, scalerCrop_);
- case RPi::IPA_ACTION_V4L2_SET_ISP: {
- ControlList controls = action.controls[0];
- isp_[Isp::Input].dev()->setControls(&controls);
- goto done;
- }
- }
+ state_ = State::IpaComplete;
- if (state_ == State::Stopped)
- goto done;
+ handleState();
+}
- /*
- * The following actions must not be handled when the pipeline handler
- * is in a stopped state.
- */
- switch (action.operation) {
- case RPi::IPA_ACTION_STATS_METADATA_COMPLETE: {
- unsigned int bufferId = action.data[0];
- FrameBuffer *buffer = isp_[Isp::Stats].getBuffers().at(bufferId);
+void RPiCameraData::runIsp(uint32_t bufferId)
+{
+ if (state_ == State::Stopped)
+ handleState();
- handleStreamBuffer(buffer, &isp_[Isp::Stats]);
+ FrameBuffer *buffer = unicam_[Unicam::Image].getBuffers().at(bufferId);
- /* Fill the Request metadata buffer with what the IPA has provided */
- Request *request = requestQueue_.front();
- request->metadata() = std::move(action.controls[0]);
+ LOG(RPI, Debug) << "Input re-queue to ISP, buffer id " << bufferId
+ << ", timestamp: " << buffer->metadata().timestamp;
- /*
- * Also update the ScalerCrop in the metadata with what we actually
- * used. But we must first rescale that from ISP (camera mode) pixels
- * back into sensor native pixels.
- *
- * Sending this information on every frame may be helpful.
- */
- if (updateScalerCrop_) {
- updateScalerCrop_ = false;
- scalerCrop_ = ispCrop_.scaledBy(sensorInfo_.analogCrop.size(),
- sensorInfo_.outputSize);
- scalerCrop_.translateBy(sensorInfo_.analogCrop.topLeft());
- }
- request->metadata().set(controls::ScalerCrop, scalerCrop_);
+ isp_[Isp::Input].queueBuffer(buffer);
+ ispOutputCount_ = 0;
+ handleState();
+}
- state_ = State::IpaComplete;
- break;
- }
+void RPiCameraData::embeddedComplete(uint32_t bufferId)
+{
+ if (state_ == State::Stopped)
+ handleState();
- case RPi::IPA_ACTION_EMBEDDED_COMPLETE: {
- unsigned int bufferId = action.data[0];
- FrameBuffer *buffer = unicam_[Unicam::Embedded].getBuffers().at(bufferId);
- handleStreamBuffer(buffer, &unicam_[Unicam::Embedded]);
- break;
- }
+ FrameBuffer *buffer = unicam_[Unicam::Embedded].getBuffers().at(bufferId);
+ handleStreamBuffer(buffer, &unicam_[Unicam::Embedded]);
+ handleState();
+}
- case RPi::IPA_ACTION_RUN_ISP: {
- unsigned int bufferId = action.data[0];
- FrameBuffer *buffer = unicam_[Unicam::Image].getBuffers().at(bufferId);
+void RPiCameraData::setIsp(const ControlList &controls)
+{
+ ControlList ctrls = controls;
- LOG(RPI, Debug) << "Input re-queue to ISP, buffer id " << bufferId
- << ", timestamp: " << buffer->metadata().timestamp;
+ Span<const uint8_t> s =
+ ctrls.get(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING).data();
+ bcm2835_isp_lens_shading ls =
+ *reinterpret_cast<const bcm2835_isp_lens_shading *>(s.data());
+ ls.dmabuf = lsTable_.fd();
- isp_[Isp::Input].queueBuffer(buffer);
- ispOutputCount_ = 0;
- break;
- }
+ ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ls),
+ sizeof(ls) });
+ ctrls.set(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING, c);
- default:
- LOG(RPI, Error) << "Unknown action " << action.operation;
- break;
- }
+ isp_[Isp::Input].dev()->setControls(&ctrls);
+ handleState();
+}
-done:
+void RPiCameraData::setDelayedControls(const ControlList &controls)
+{
+ if (!delayedCtrls_->push(controls))
+ LOG(RPI, Error) << "V4L2 staggered set failed";
handleState();
}
@@ -1456,10 +1455,7 @@ void RPiCameraData::ispOutputDequeue(FrameBuffer *buffer)
* application until after the IPA signals so.
*/
if (stream == &isp_[Isp::Stats]) {
- IPAOperationData op;
- op.operation = RPi::IPA_EVENT_SIGNAL_STAT_READY;
- op.data = { RPi::BufferMask::STATS | static_cast<unsigned int>(index) };
- ipa_->processEvent(op);
+ ipa_->signalStatReady(ipa::rpi::MaskStats | static_cast<unsigned int>(index));
} else {
/* Any other ISP output can be handed back to the application now. */
handleStreamBuffer(buffer, stream);
@@ -1563,7 +1559,7 @@ void RPiCameraData::handleExternalBuffer(FrameBuffer *buffer, RPi::Stream *strea
{
unsigned int id = stream->getBufferId(buffer);
- if (!(id & RPi::BufferMask::EXTERNAL_BUFFER))
+ if (!(id & ipa::rpi::MaskExternalBuffer))
return;
/* Stop the Stream object from tracking the buffer. */
@@ -1663,7 +1659,6 @@ void RPiCameraData::applyScalerCrop(const ControlList &controls)
void RPiCameraData::tryRunPipeline()
{
FrameBuffer *bayerBuffer, *embeddedBuffer;
- IPAOperationData op;
/* If any of our request or buffer queues are empty, we cannot proceed. */
if (state_ != State::Idle || requestQueue_.empty() ||
@@ -1684,9 +1679,7 @@ void RPiCameraData::tryRunPipeline()
* queue the ISP output buffer listed in the request to start the HW
* pipeline.
*/
- op.operation = RPi::IPA_EVENT_QUEUE_REQUEST;
- op.controls = { request->controls() };
- ipa_->processEvent(op);
+ ipa_->signalQueueRequest(request->controls());
/* Set our state to say the pipeline is active. */
state_ = State::Busy;
@@ -1694,14 +1687,14 @@ void RPiCameraData::tryRunPipeline()
unsigned int bayerId = unicam_[Unicam::Image].getBufferId(bayerBuffer);
unsigned int embeddedId = unicam_[Unicam::Embedded].getBufferId(embeddedBuffer);
- LOG(RPI, Debug) << "Signalling RPi::IPA_EVENT_SIGNAL_ISP_PREPARE:"
+ LOG(RPI, Debug) << "Signalling signalIspPrepare:"
<< " Bayer buffer id: " << bayerId
<< " Embedded buffer id: " << embeddedId;
- op.operation = RPi::IPA_EVENT_SIGNAL_ISP_PREPARE;
- op.data = { RPi::BufferMask::EMBEDDED_DATA | embeddedId,
- RPi::BufferMask::BAYER_DATA | bayerId };
- ipa_->processEvent(op);
+ ipa::rpi::ISPConfig ispPrepare;
+ ispPrepare.embeddedbufferId = ipa::rpi::MaskEmbeddedData | embeddedId;
+ ispPrepare.bayerbufferId = ipa::rpi::MaskBayerData | bayerId;
+ ipa_->signalIspPrepare(ispPrepare);
}
bool RPiCameraData::findMatchingBuffers(FrameBuffer *&bayerBuffer, FrameBuffer *&embeddedBuffer)
diff --git a/src/libcamera/pipeline/raspberrypi/rpi_stream.cpp b/src/libcamera/pipeline/raspberrypi/rpi_stream.cpp
index 3a5dadab..496dd36f 100644
--- a/src/libcamera/pipeline/raspberrypi/rpi_stream.cpp
+++ b/src/libcamera/pipeline/raspberrypi/rpi_stream.cpp
@@ -6,6 +6,8 @@
*/
#include "rpi_stream.h"
+#include <libcamera/ipa/raspberrypi_ipa_interface.h>
+
#include "libcamera/internal/log.h"
namespace libcamera {
@@ -70,7 +72,7 @@ int Stream::getBufferId(FrameBuffer *buffer) const
void Stream::setExternalBuffer(FrameBuffer *buffer)
{
- bufferMap_.emplace(RPi::BufferMask::EXTERNAL_BUFFER | id_.get(), buffer);
+ bufferMap_.emplace(ipa::rpi::MaskExternalBuffer | id_.get(), buffer);
}
void Stream::removeExternalBuffer(FrameBuffer *buffer)
@@ -78,7 +80,7 @@ void Stream::removeExternalBuffer(FrameBuffer *buffer)
int id = getBufferId(buffer);
/* Ensure we have this buffer in the stream, and it is marked external. */
- ASSERT(id != -1 && (id & RPi::BufferMask::EXTERNAL_BUFFER));
+ ASSERT(id != -1 && (id & ipa::rpi::MaskExternalBuffer));
bufferMap_.erase(id);
}
diff --git a/src/libcamera/pipeline/raspberrypi/rpi_stream.h b/src/libcamera/pipeline/raspberrypi/rpi_stream.h
index 0b502f64..701110d0 100644
--- a/src/libcamera/pipeline/raspberrypi/rpi_stream.h
+++ b/src/libcamera/pipeline/raspberrypi/rpi_stream.h
@@ -13,6 +13,7 @@
#include <vector>
#include <libcamera/ipa/raspberrypi.h>
+#include <libcamera/ipa/raspberrypi_ipa_interface.h>
#include <libcamera/stream.h>
#include "libcamera/internal/v4l2_videodevice.h"
@@ -31,13 +32,13 @@ class Stream : public libcamera::Stream
{
public:
Stream()
- : id_(RPi::BufferMask::ID)
+ : id_(ipa::rpi::MaskID)
{
}
Stream(const char *name, MediaEntity *dev, bool importOnly = false)
: external_(false), importOnly_(importOnly), name_(name),
- dev_(std::make_unique<V4L2VideoDevice>(dev)), id_(RPi::BufferMask::ID)
+ dev_(std::make_unique<V4L2VideoDevice>(dev)), id_(ipa::rpi::MaskID)
{
}
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 7cb89eb0..a794501a 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -18,7 +18,9 @@
#include <libcamera/camera.h>
#include <libcamera/control_ids.h>
#include <libcamera/formats.h>
-#include <libcamera/ipa/rkisp1.h>
+#include <libcamera/ipa/core_ipa_interface.h>
+#include <libcamera/ipa/rkisp1_ipa_interface.h>
+#include <libcamera/ipa/rkisp1_ipa_proxy.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
@@ -96,9 +98,11 @@ public:
RkISP1MainPath *mainPath_;
RkISP1SelfPath *selfPath_;
+ std::unique_ptr<ipa::rkisp1::IPAProxyRkISP1> ipa_;
+
private:
void queueFrameAction(unsigned int frame,
- const IPAOperationData &action);
+ const ipa::rkisp1::RkISP1Action &action);
void metadataReady(unsigned int frame, const ControlList &metadata);
};
@@ -298,7 +302,7 @@ RkISP1FrameInfo *RkISP1Frames::find(Request *request)
int RkISP1CameraData::loadIPA()
{
- ipa_ = IPAManager::createIPA(pipe_, 1, 1);
+ ipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe_, 1, 1);
if (!ipa_)
return -ENOENT;
@@ -311,15 +315,15 @@ int RkISP1CameraData::loadIPA()
}
void RkISP1CameraData::queueFrameAction(unsigned int frame,
- const IPAOperationData &action)
+ const ipa::rkisp1::RkISP1Action &action)
{
- switch (action.operation) {
- case RKISP1_IPA_ACTION_V4L2_SET: {
- const ControlList &controls = action.controls[0];
+ switch (action.op) {
+ case ipa::rkisp1::ActionV4L2Set: {
+ const ControlList &controls = action.controls;
delayedCtrls_->push(controls);
break;
}
- case RKISP1_IPA_ACTION_PARAM_FILLED: {
+ case ipa::rkisp1::ActionParamFilled: {
PipelineHandlerRkISP1 *pipe = static_cast<PipelineHandlerRkISP1 *>(pipe_);
RkISP1FrameInfo *info = frameInfo_.find(frame);
if (!info)
@@ -336,11 +340,11 @@ void RkISP1CameraData::queueFrameAction(unsigned int frame,
break;
}
- case RKISP1_IPA_ACTION_METADATA:
- metadataReady(frame, action.controls[0]);
+ case ipa::rkisp1::ActionMetadata:
+ metadataReady(frame, action.controls);
break;
default:
- LOG(RkISP1, Error) << "Unknown action " << action.operation;
+ LOG(RkISP1, Error) << "Unknown action " << action.op;
break;
}
}
@@ -612,16 +616,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
for (const StreamConfiguration &cfg : *config) {
if (cfg.stream() == &data->mainPathStream_) {
ret = mainPath_.configure(cfg, format);
- streamConfig[0] = {
- .pixelFormat = cfg.pixelFormat,
- .size = cfg.size,
- };
+ streamConfig[0] = IPAStream(cfg.pixelFormat,
+ cfg.size);
} else {
ret = selfPath_.configure(cfg, format);
- streamConfig[1] = {
- .pixelFormat = cfg.pixelFormat,
- .size = cfg.size,
- };
+ streamConfig[1] = IPAStream(cfg.pixelFormat,
+ cfg.size);
}
if (ret)
@@ -650,12 +650,10 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
ret = 0;
}
- std::map<unsigned int, const ControlInfoMap &> entityControls;
+ std::map<uint32_t, ControlInfoMap> entityControls;
entityControls.emplace(0, data->sensor_->controls());
- IPAOperationData ipaConfig;
- data->ipa_->configure(sensorInfo, streamConfig, entityControls,
- ipaConfig, nullptr);
+ data->ipa_->configure(sensorInfo, streamConfig, entityControls);
return 0;
}
@@ -695,15 +693,15 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
for (std::unique_ptr<FrameBuffer> &buffer : paramBuffers_) {
buffer->setCookie(ipaBufferId++);
- data->ipaBuffers_.push_back({ .id = buffer->cookie(),
- .planes = buffer->planes() });
+ data->ipaBuffers_.emplace_back(buffer->cookie(),
+ buffer->planes());
availableParamBuffers_.push(buffer.get());
}
for (std::unique_ptr<FrameBuffer> &buffer : statBuffers_) {
buffer->setCookie(ipaBufferId++);
- data->ipaBuffers_.push_back({ .id = buffer->cookie(),
- .planes = buffer->planes() });
+ data->ipaBuffers_.emplace_back(buffer->cookie(),
+ buffer->planes());
availableStatBuffers_.push(buffer.get());
}
@@ -757,8 +755,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c
if (ret)
return ret;
- IPAOperationData ipaData = {};
- ret = data->ipa_->start(ipaData, nullptr);
+ ret = data->ipa_->start();
if (ret) {
freeBuffers(camera);
LOG(RkISP1, Error)
@@ -853,11 +850,12 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
if (!info)
return -ENOENT;
- IPAOperationData op;
- op.operation = RKISP1_IPA_EVENT_QUEUE_REQUEST;
- op.data = { data->frame_, info->paramBuffer->cookie() };
- op.controls = { request->controls() };
- data->ipa_->processEvent(op);
+ ipa::rkisp1::RkISP1Event ev;
+ ev.op = ipa::rkisp1::EventQueueRequest;
+ ev.frame = data->frame_;
+ ev.bufferId = info->paramBuffer->cookie();
+ ev.controls = request->controls();
+ data->ipa_->processEvent(ev);
data->frame_++;
@@ -1088,10 +1086,11 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
if (data->frame_ <= buffer->metadata().sequence)
data->frame_ = buffer->metadata().sequence + 1;
- IPAOperationData op;
- op.operation = RKISP1_IPA_EVENT_SIGNAL_STAT_BUFFER;
- op.data = { info->frame, info->statBuffer->cookie() };
- data->ipa_->processEvent(op);
+ ipa::rkisp1::RkISP1Event ev;
+ ev.op = ipa::rkisp1::EventSignalStatBuffer;
+ ev.frame = info->frame;
+ ev.bufferId = info->statBuffer->cookie();
+ data->ipa_->processEvent(ev);
}
REGISTER_PIPELINE_HANDLER(PipelineHandlerRkISP1)
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 36325ffb..78b47916 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -34,6 +34,9 @@
#include "libcamera/internal/v4l2_subdevice.h"
#include "libcamera/internal/v4l2_videodevice.h"
+#include <libcamera/ipa/vimc_ipa_interface.h>
+#include <libcamera/ipa/vimc_ipa_proxy.h>
+
namespace libcamera {
LOG_DEFINE_CATEGORY(VIMC)
@@ -56,6 +59,8 @@ public:
std::unique_ptr<V4L2VideoDevice> video_;
std::unique_ptr<V4L2VideoDevice> raw_;
Stream stream_;
+
+ std::unique_ptr<ipa::vimc::IPAProxyVimc> ipa_;
};
class VimcCameraConfiguration : public CameraConfiguration
@@ -311,8 +316,7 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] ControlList *con
if (ret < 0)
return ret;
- IPAOperationData ipaData = {};
- ret = data->ipa_->start(ipaData, nullptr);
+ ret = data->ipa_->start();
if (ret) {
data->video_->releaseBuffers();
return ret;
@@ -418,7 +422,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)
std::unique_ptr<VimcCameraData> data = std::make_unique<VimcCameraData>(this, media);
- data->ipa_ = IPAManager::createIPA(this, 0, 0);
+ data->ipa_ = IPAManager::createIPA<ipa::vimc::IPAProxyVimc>(this, 0, 0);
if (data->ipa_ != nullptr) {
std::string conf = data->ipa_->configurationFile("vimc.conf");
data->ipa_->init(IPASettings{ conf });