summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp209
1 files changed, 152 insertions, 57 deletions
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index fef4fa81..28e99129 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -135,7 +135,8 @@ public:
V4L2VideoDevice *selfPathVideo)
: CameraData(pipe), sensor_(nullptr), frame_(0),
frameInfo_(pipe), mainPathVideo_(mainPathVideo),
- selfPathVideo_(selfPathVideo)
+ selfPathVideo_(selfPathVideo), mainPathActive_(false),
+ selfPathActive_(false)
{
}
@@ -147,6 +148,7 @@ public:
int loadIPA();
Stream mainPathStream_;
+ Stream selfPathStream_;
CameraSensor *sensor_;
unsigned int frame_;
std::vector<IPABuffer> ipaBuffers_;
@@ -156,6 +158,9 @@ public:
V4L2VideoDevice *mainPathVideo_;
V4L2VideoDevice *selfPathVideo_;
+ bool mainPathActive_;
+ bool selfPathActive_;
+
private:
void queueFrameAction(unsigned int frame,
const IPAOperationData &action);
@@ -612,7 +617,6 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
RkISP1CameraConfiguration *config =
static_cast<RkISP1CameraConfiguration *>(c);
RkISP1CameraData *data = cameraData(camera);
- StreamConfiguration &cfg = config->at(0);
CameraSensor *sensor = data->sensor_;
int ret;
@@ -654,37 +658,63 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
LOG(RkISP1, Debug) << "ISP output pad configured with " << format.toString();
- ret = mainPathResizer_->setFormat(0, &format);
- if (ret < 0)
- return ret;
+ data->mainPathActive_ = false;
+ data->selfPathActive_ = false;
+ for (const StreamConfiguration &cfg : *config) {
+ V4L2SubdeviceFormat ispFormat = format;
+ V4L2Subdevice *resizer;
+ V4L2VideoDevice *video;
+
+ if (cfg.stream() == &data->mainPathStream_) {
+ resizer = mainPathResizer_;
+ video = mainPathVideo_;
+ data->mainPathActive_ = true;
+ } else {
+ resizer = selfPathResizer_;
+ video = selfPathVideo_;
+ data->selfPathActive_ = true;
+ }
+
+ ret = resizer->setFormat(0, &ispFormat);
+ if (ret < 0)
+ return ret;
- LOG(RkISP1, Debug) << "Resizer input pad configured with " << format.toString();
+ const char *name = resizer == mainPathResizer_ ? "main" : "self";
- format.size = cfg.size;
+ LOG(RkISP1, Debug)
+ << "Configured " << name << " resizer input pad with "
+ << ispFormat.toString();
- LOG(RkISP1, Debug) << "Configuring resizer output pad with " << format.toString();
+ ispFormat.size = cfg.size;
- ret = mainPathResizer_->setFormat(1, &format);
- if (ret < 0)
- return ret;
+ LOG(RkISP1, Debug)
+ << "Configuring " << name << " resizer output pad with "
+ << ispFormat.toString();
- LOG(RkISP1, Debug) << "Resizer output pad configured with " << format.toString();
+ ret = resizer->setFormat(1, &ispFormat);
+ if (ret < 0)
+ return ret;
- const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat);
- V4L2DeviceFormat outputFormat = {};
- outputFormat.fourcc = mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat);
- outputFormat.size = cfg.size;
- outputFormat.planesCount = info.numPlanes();
+ LOG(RkISP1, Debug)
+ << "Configured " << name << " resizer output pad with "
+ << ispFormat.toString();
- ret = mainPathVideo_->setFormat(&outputFormat);
- if (ret)
- return ret;
+ const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat);
+ V4L2DeviceFormat outputFormat = {};
+ outputFormat.fourcc = video->toV4L2PixelFormat(cfg.pixelFormat);
+ outputFormat.size = cfg.size;
+ outputFormat.planesCount = info.numPlanes();
- if (outputFormat.size != cfg.size ||
- outputFormat.fourcc != mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat)) {
- LOG(RkISP1, Error)
- << "Unable to configure capture in " << cfg.toString();
- return -EINVAL;
+ ret = video->setFormat(&outputFormat);
+ if (ret)
+ return ret;
+
+ if (outputFormat.size != cfg.size ||
+ outputFormat.fourcc != video->toV4L2PixelFormat(cfg.pixelFormat)) {
+ LOG(RkISP1, Error)
+ << "Unable to configure capture in " << cfg.toString();
+ return -EINVAL;
+ }
}
V4L2DeviceFormat paramFormat = {};
@@ -699,34 +729,53 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
if (ret)
return ret;
- cfg.setStream(&data->mainPathStream_);
-
return 0;
}
int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
+ RkISP1CameraData *data = cameraData(camera);
unsigned int count = stream->configuration().bufferCount;
- return mainPathVideo_->exportBuffers(count, buffers);
+
+ if (stream == &data->mainPathStream_)
+ return mainPathVideo_->exportBuffers(count, buffers);
+ else if (stream == &data->selfPathStream_)
+ return selfPathVideo_->exportBuffers(count, buffers);
+
+ return -EINVAL;
}
int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
{
RkISP1CameraData *data = cameraData(camera);
- unsigned int count = data->mainPathStream_.configuration().bufferCount;
unsigned int ipaBufferId = 1;
int ret;
- ret = mainPathVideo_->importBuffers(count);
- if (ret < 0)
- goto error;
+ unsigned int maxCount = std::max({
+ data->mainPathStream_.configuration().bufferCount,
+ data->selfPathStream_.configuration().bufferCount,
+ });
+
+ if (data->mainPathActive_) {
+ ret = mainPathVideo_->importBuffers(
+ data->mainPathStream_.configuration().bufferCount);
+ if (ret < 0)
+ goto error;
+ }
- ret = param_->allocateBuffers(count, &paramBuffers_);
+ if (data->selfPathActive_) {
+ ret = selfPathVideo_->importBuffers(
+ data->selfPathStream_.configuration().bufferCount);
+ if (ret < 0)
+ goto error;
+ }
+
+ ret = param_->allocateBuffers(maxCount, &paramBuffers_);
if (ret < 0)
goto error;
- ret = stat_->allocateBuffers(count, &statBuffers_);
+ ret = stat_->allocateBuffers(maxCount, &statBuffers_);
if (ret < 0)
goto error;
@@ -752,6 +801,7 @@ error:
paramBuffers_.clear();
statBuffers_.clear();
mainPathVideo_->releaseBuffers();
+ selfPathVideo_->releaseBuffers();
return ret;
}
@@ -785,6 +835,9 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
if (mainPathVideo_->releaseBuffers())
LOG(RkISP1, Error) << "Failed to release main path buffers";
+ if (selfPathVideo_->releaseBuffers())
+ LOG(RkISP1, Error) << "Failed to release self path buffers";
+
return 0;
}
@@ -827,15 +880,47 @@ int PipelineHandlerRkISP1::start(Camera *camera)
return ret;
}
- ret = mainPathVideo_->streamOn();
- if (ret) {
- param_->streamOff();
- stat_->streamOff();
- data->ipa_->stop();
- freeBuffers(camera);
+ std::map<unsigned int, IPAStream> streamConfig;
- LOG(RkISP1, Error)
- << "Failed to start camera " << camera->id();
+ if (data->mainPathActive_) {
+ ret = mainPathVideo_->streamOn();
+ if (ret) {
+ param_->streamOff();
+ stat_->streamOff();
+ data->ipa_->stop();
+ freeBuffers(camera);
+
+ LOG(RkISP1, Error)
+ << "Failed to start main path " << camera->id();
+ return ret;
+ }
+
+ streamConfig[0] = {
+ .pixelFormat = data->mainPathStream_.configuration().pixelFormat,
+ .size = data->mainPathStream_.configuration().size,
+ };
+ }
+
+ if (data->selfPathActive_) {
+ ret = selfPathVideo_->streamOn();
+ if (ret) {
+ if (data->mainPathActive_)
+ mainPathVideo_->streamOff();
+
+ param_->streamOff();
+ stat_->streamOff();
+ data->ipa_->stop();
+ freeBuffers(camera);
+
+ LOG(RkISP1, Error)
+ << "Failed to start self path " << camera->id();
+ return ret;
+ }
+
+ streamConfig[1] = {
+ .pixelFormat = data->selfPathStream_.configuration().pixelFormat,
+ .size = data->selfPathStream_.configuration().size,
+ };
}
activeCamera_ = camera;
@@ -850,12 +935,6 @@ int PipelineHandlerRkISP1::start(Camera *camera)
ret = 0;
}
- std::map<unsigned int, IPAStream> streamConfig;
- streamConfig[0] = {
- .pixelFormat = data->mainPathStream_.configuration().pixelFormat,
- .size = data->mainPathStream_.configuration().size,
- };
-
std::map<unsigned int, const ControlInfoMap &> entityControls;
entityControls.emplace(0, data->sensor_->controls());
@@ -871,20 +950,31 @@ void PipelineHandlerRkISP1::stop(Camera *camera)
RkISP1CameraData *data = cameraData(camera);
int ret;
- ret = mainPathVideo_->streamOff();
- if (ret)
- LOG(RkISP1, Warning)
- << "Failed to stop camera " << camera->id();
+ if (data->selfPathActive_) {
+ ret = selfPathVideo_->streamOff();
+ if (ret)
+ LOG(RkISP1, Warning)
+ << "Failed to stop self path for "
+ << camera->id();
+ }
+
+ if (data->mainPathActive_) {
+ ret = mainPathVideo_->streamOff();
+ if (ret)
+ LOG(RkISP1, Warning)
+ << "Failed to stop main path for "
+ << camera->id();
+ }
ret = stat_->streamOff();
if (ret)
LOG(RkISP1, Warning)
- << "Failed to stop statistics " << camera->id();
+ << "Failed to stop statistics for " << camera->id();
ret = param_->streamOff();
if (ret)
LOG(RkISP1, Warning)
- << "Failed to stop parameters " << camera->id();
+ << "Failed to stop parameters for " << camera->id();
data->ipa_->stop();
@@ -955,11 +1045,16 @@ int PipelineHandlerRkISP1::initLinks(const Camera *camera,
}
for (const StreamConfiguration &cfg : config) {
- if (cfg.stream() != &data->mainPathStream_)
+ MediaLink *link;
+ if (cfg.stream() == &data->mainPathStream_)
+ link = media_->link("rkisp1_isp", 2,
+ "rkisp1_resizer_mainpath", 0);
+ else if (cfg.stream() == &data->selfPathStream_)
+ link = media_->link("rkisp1_isp", 2,
+ "rkisp1_resizer_selfpath", 0);
+ else
return -EINVAL;
- MediaLink *link = media_->link("rkisp1_isp", 2,
- "rkisp1_resizer_mainpath", 0);
if (!link)
return -ENODEV;