From 9ece9a15252acee40864039d050160d0ba670e40 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Tue, 4 Nov 2025 14:49:27 +0100 Subject: [PATCH] pipeline: imx8-isi: Delay ISI routes config to acquire() time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes behavior when calling 'cam -l' during a live stream from a camera in another process. Issue is that multiple process should be able to list (match procedure) the camera supported. But only the unique process that lock the media devices in order to be able to configure then start the pipeline should setup the routes, graphs, etc. Thus, the setRouting() is to be moved to a PipelineHandlerISI::acquireDevice() implementation to override the default Pipeline::acquireDevice() function. Fixes: 92df79112fb2 ("pipeline: imx8-isi: Add multicamera support") Signed-off-by: Andrei Gansari Signed-off-by: Antoine Bouyer Reviewed-by: Kieran Bingham Reviewed-by: Barnabás Pőcze Signed-off-by: Kieran Bingham --- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index de09431c..9550f546 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -117,6 +117,8 @@ protected: int queueRequestDevice(Camera *camera, Request *request) override; + bool acquireDevice(Camera *camera) override; + private: static constexpr Size kPreviewSize = { 1920, 1080 }; static constexpr Size kMinISISize = { 1, 1 }; @@ -143,6 +145,8 @@ private: std::unique_ptr crossbar_; std::vector pipes_; + + V4L2Subdevice::Routing routing_ = {}; }; /* ----------------------------------------------------------------------------- @@ -950,6 +954,19 @@ int PipelineHandlerISI::queueRequestDevice(Camera *camera, Request *request) return 0; } +bool PipelineHandlerISI::acquireDevice([[maybe_unused]] Camera *camera) +{ + if (useCount() > 0) + return true; + + /* Enable routing for all available sensors once */ + int ret = crossbar_->setRouting(&routing_, V4L2Subdevice::ActiveFormat); + if (ret) + return false; + + return true; +} + bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) { DeviceMatch dm("mxc-isi"); @@ -1034,7 +1051,6 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) unsigned int numSinks = 0; const unsigned int xbarFirstSource = crossbar_->entity()->pads().size() - pipes_.size(); const unsigned int maxStreams = pipes_.size() / cameraCount; - V4L2Subdevice::Routing routing = {}; for (MediaPad *pad : crossbar_->entity()->pads()) { unsigned int sink = numSinks; @@ -1104,7 +1120,7 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) /* Add routes to the crossbar switch routing table. */ for (unsigned i = 0; i < data->streams_.size(); i++) { unsigned int sourcePad = xbarFirstSource + data->xbarSourceOffset_ + i; - routing.emplace_back(V4L2Subdevice::Stream{ data->xbarSink_, 0 }, + routing_.emplace_back(V4L2Subdevice::Stream{ data->xbarSink_, 0 }, V4L2Subdevice::Stream{ sourcePad, 0 }, V4L2_SUBDEV_ROUTE_FL_ACTIVE); } @@ -1116,10 +1132,6 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) numCameras++; } - ret = crossbar_->setRouting(&routing, V4L2Subdevice::ActiveFormat); - if (ret) - return false; - return numCameras > 0; }