[PATCH v4 3/3] libcamera: pipeline: rkisp1: Convert to use MediaPipeline
Stefan Klug
stefan.klug at ideasonboard.com
Thu Apr 3 12:34:56 CEST 2025
On Wed, Apr 02, 2025 at 04:39:18PM +0900, Paul Elder wrote:
> From: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> Use the new MediaPipeline to manage and identify all sensors connected
> to complex pipelines that can connect to the CSI2 receiver before the
> ISP.
>
> This can include chained multiplexors that supply multiple cameras, so
> make use of the MediaDevice::locateEntities to search for all cameras
> and construct a pipeline for each.
>
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> Reviewed-by: Umang Jain <umang.jain at ideasonboard.com>
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> src/libcamera/pipeline/rkisp1/rkisp1.cpp | 86 +++++++++---------------
> 1 file changed, 32 insertions(+), 54 deletions(-)
Nice when that code gets shorter :-)
Acked-by: Stefan Klug <stefan.klug at ideasonboard.com>
>
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index 52633fe3cb85..705615b86b0c 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -42,6 +42,7 @@
> #include "libcamera/internal/framebuffer.h"
> #include "libcamera/internal/ipa_manager.h"
> #include "libcamera/internal/media_device.h"
> +#include "libcamera/internal/media_pipeline.h"
> #include "libcamera/internal/pipeline_handler.h"
> #include "libcamera/internal/v4l2_subdevice.h"
> #include "libcamera/internal/v4l2_videodevice.h"
> @@ -116,6 +117,11 @@ public:
>
> ControlInfoMap ipaControls_;
>
> + /*
> + * All entities in the pipeline, from the camera sensor to the RKISP1.
> + */
> + MediaPipeline pipe_;
> +
> private:
> void paramsComputed(unsigned int frame, unsigned int bytesused);
> void setSensorControls(unsigned int frame,
> @@ -180,8 +186,7 @@ private:
> friend RkISP1CameraConfiguration;
> friend RkISP1Frames;
>
> - int initLinks(Camera *camera, const CameraSensor *sensor,
> - const RkISP1CameraConfiguration &config);
> + int initLinks(Camera *camera, const RkISP1CameraConfiguration &config);
> int createCamera(MediaEntity *sensor);
> void tryCompleteRequest(RkISP1FrameInfo *info);
> void imageBufferReady(FrameBuffer *buffer);
> @@ -199,7 +204,6 @@ private:
> std::unique_ptr<V4L2Subdevice> isp_;
> std::unique_ptr<V4L2VideoDevice> param_;
> std::unique_ptr<V4L2VideoDevice> stat_;
> - std::unique_ptr<V4L2Subdevice> csi_;
>
> bool hasSelfPath_;
> bool isRaw_;
> @@ -223,8 +227,6 @@ private:
> std::queue<FrameBuffer *> availableStatBuffers_;
>
> Camera *activeCamera_;
> -
> - const MediaPad *ispSink_;
> };
>
> RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)
> @@ -798,7 +800,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
> CameraSensor *sensor = data->sensor_.get();
> int ret;
>
> - ret = initLinks(camera, sensor, *config);
> + ret = initLinks(camera, *config);
> if (ret)
> return ret;
>
> @@ -821,12 +823,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
>
> LOG(RkISP1, Debug) << "Sensor configured with " << format;
>
> - if (csi_) {
> - ret = csi_->setFormat(0, &format);
> - if (ret < 0)
> - return ret;
> - }
> + /* Propagate format through the internal media pipeline up to the ISP */
> + ret = data->pipe_.configure(sensor, &format);
> + if (ret < 0)
> + return ret;
>
> + LOG(RkISP1, Debug) << "Configuring ISP with : " << format;
> ret = isp_->setFormat(0, &format);
> if (ret < 0)
> return ret;
> @@ -1201,7 +1203,6 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
> */
>
> int PipelineHandlerRkISP1::initLinks(Camera *camera,
> - const CameraSensor *sensor,
> const RkISP1CameraConfiguration &config)
> {
> RkISP1CameraData *data = cameraData(camera);
> @@ -1212,31 +1213,16 @@ int PipelineHandlerRkISP1::initLinks(Camera *camera,
> return ret;
>
> /*
> - * Configure the sensor links: enable the link corresponding to this
> - * camera.
> + * Configure the sensor links: enable the links corresponding to this
> + * pipeline all the way up to the ISP, through any connected CSI receiver.
> */
> - for (MediaLink *link : ispSink_->links()) {
> - if (link->source()->entity() != sensor->entity())
> - continue;
> -
> - LOG(RkISP1, Debug)
> - << "Enabling link from sensor '"
> - << link->source()->entity()->name()
> - << "' to ISP";
> -
> - ret = link->setEnabled(true);
> - if (ret < 0)
> - return ret;
> - }
> -
> - if (csi_) {
> - MediaLink *link = isp_->entity()->getPadByIndex(0)->links().at(0);
> -
> - ret = link->setEnabled(true);
> - if (ret < 0)
> - return ret;
> + ret = data->pipe_.initLinks();
> + if (ret) {
> + LOG(RkISP1, Error) << "Failed to set up pipe links";
> + return ret;
> }
>
> + /* Configure the paths after the ISP */
> for (const StreamConfiguration &cfg : config) {
> if (cfg.stream() == &data->mainPathStream_)
> ret = data->mainPath_->setEnabled(true);
> @@ -1312,6 +1298,13 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
> std::make_unique<RkISP1CameraData>(this, &mainPath_,
> hasSelfPath_ ? &selfPath_ : nullptr);
>
> + /* Identify the pipeline path between the sensor and the rkisp1_isp */
> + ret = data->pipe_.init(sensor, "rkisp1_isp");
> + if (ret) {
> + LOG(RkISP1, Error) << "Failed to identify path from sensor to sink";
> + return ret;
> + }
> +
> data->sensor_ = CameraSensorFactoryBase::create(sensor);
> if (!data->sensor_)
> return -ENODEV;
> @@ -1347,6 +1340,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
> const std::string &id = data->sensor_->id();
> std::shared_ptr<Camera> camera =
> Camera::create(std::move(data), id, streams);
> +
> registerCamera(std::move(camera));
>
> return 0;
> @@ -1354,8 +1348,6 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
>
> bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> {
> - const MediaPad *pad;
> -
> DeviceMatch dm("rkisp1");
> dm.add("rkisp1_isp");
> dm.add("rkisp1_resizer_mainpath");
> @@ -1380,22 +1372,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> if (isp_->open() < 0)
> return false;
>
> - /* Locate and open the optional CSI-2 receiver. */
> - ispSink_ = isp_->entity()->getPadByIndex(0);
> - if (!ispSink_ || ispSink_->links().empty())
> - return false;
> -
> - pad = ispSink_->links().at(0)->source();
> - if (pad->entity()->function() == MEDIA_ENT_F_VID_IF_BRIDGE) {
> - csi_ = std::make_unique<V4L2Subdevice>(pad->entity());
> - if (csi_->open() < 0)
> - return false;
> -
> - ispSink_ = csi_->entity()->getPadByIndex(0);
> - if (!ispSink_)
> - return false;
> - }
> -
> /* Locate and open the stats and params video nodes. */
> stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats");
> if (stat_->open() < 0)
> @@ -1446,8 +1422,10 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> * camera instance for each of them.
> */
> bool registered = false;
> - for (MediaLink *link : ispSink_->links()) {
> - if (!createCamera(link->source()->entity()))
> +
> + for (MediaEntity *entity : media_->locateEntities(MEDIA_ENT_F_CAM_SENSOR)) {
> + LOG(RkISP1, Debug) << "Identified " << entity->name();
> + if (!createCamera(entity))
> registered = true;
> }
>
> --
> 2.47.2
>
More information about the libcamera-devel
mailing list