From patchwork Wed Jan 16 13:59:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 250 Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3ED8160B2D for ; Wed, 16 Jan 2019 14:59:49 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id C5D81C0011; Wed, 16 Jan 2019 13:59:48 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Jan 2019 14:59:45 +0100 Message-Id: <20190116135949.2097-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116135949.2097-1-jacopo@jmondi.org> References: <20190116135949.2097-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/5] test: list-cameras: Make test output more verbose X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 13:59:49 -0000 Make the list-cameras test a little more verbose to better describe failures. While at there use the Test class defined TestStatus value as test exit codes, and skip the test if no camera gets registred. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- test/list-cameras.cpp | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/test/list-cameras.cpp b/test/list-cameras.cpp index e2026c9..c9dc199 100644 --- a/test/list-cameras.cpp +++ b/test/list-cameras.cpp @@ -7,6 +7,7 @@ #include +#include #include #include "test.h" @@ -14,27 +15,55 @@ using namespace std; using namespace libcamera; +/* + * List all cameras registered in the system, using the CameraManager. + * + * In order for the test to run successfully, a pipeline handler supporting + * the current test platform should be available in the library. + * Libcamera provides a platform-agnostic pipeline handler for the 'vimc' + * virtual media device, which can be used for testing purposes. + * + * The test tries to list all cameras registered in the system, if no + * camera is found the test is skipped. If the test gets skipped on a + * platform where a pipeline handler is known to be available, an error + * in camera enumeration might get unnoticed. + */ class ListTest : public Test { protected: int init() { cm = CameraManager::instance(); - cm->start(); + + int ret = cm->start(); + if (ret) { + cerr << "Failed to start the CameraManager" << endl; + return TestFail; + } return 0; } int run() { - unsigned int count = 0; + vector cameraList = cm->list(); + if (cameraList.empty()) { + cerr << "No cameras registered in the system: test skip" << endl + << "This might be expected if no pipeline handler supports the testing platform" << endl; + return TestSkip; + } + + for (auto name : cameraList) { + Camera *cam = cm->get(name); + if (!cam) { + cerr << "Failed to get camera '" << name << "' by name" << endl; + return TestFail; + } - for (auto name : cm->list()) { - cout << "- " << name << endl; - count++; + cout << "Found camera '" << cam->name() << "'" << endl; } - return count ? 0 : -ENODEV; + return TestPass; } void cleanup() From patchwork Wed Jan 16 13:59:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 251 Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 41EE860C98 for ; Wed, 16 Jan 2019 14:59:50 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 697D8C0011; Wed, 16 Jan 2019 13:59:49 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Jan 2019 14:59:46 +0100 Message-Id: <20190116135949.2097-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116135949.2097-1-jacopo@jmondi.org> References: <20190116135949.2097-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/5] libcamera: media_object: Add functions to entities X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 13:59:51 -0000 Media entities convey information about their main function in the 'function' field of 'struct media_v2_entity'. Store the main function in the MediaEntity function_ class member and provide a getter function for that. While at there update comments, keep the MediaPad description in sync with the MediaEntity one and remove a stale TODO entry. Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/include/media_object.h | 2 ++ src/libcamera/media_object.cpp | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h index 7fc4441..a10f7e1 100644 --- a/src/libcamera/include/media_object.h +++ b/src/libcamera/include/media_object.h @@ -84,6 +84,7 @@ class MediaEntity : public MediaObject { public: const std::string &name() const { return name_; } + unsigned int function() const { return function_; } unsigned int deviceMajor() const { return major_; } unsigned int deviceMinor() const { return minor_; } @@ -103,6 +104,7 @@ private: ~MediaEntity(); std::string name_; + unsigned int function_; std::string devnode_; unsigned int major_; unsigned int minor_; diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp index cb3af85..76dd326 100644 --- a/src/libcamera/media_object.cpp +++ b/src/libcamera/media_object.cpp @@ -166,7 +166,7 @@ MediaLink::MediaLink(const struct media_v2_link *link, MediaPad *source, * Pads are created from the information provided by the Media Controller API * in the media_v2_pad structure. They reference the entity() they belong to. * - * In addition to its graph id, every media graph pad is identified by an index + * In addition to its graph id, media graph pads are identified by an index * unique in the context of the entity the pad belongs to. * * A pad can be either a 'source' pad or a 'sink' pad. This information is @@ -242,11 +242,9 @@ void MediaPad::addLink(MediaLink *link) * Entities are created from the information provided by the Media Controller * API in the media_v2_entity structure. They reference the pads() they contain. * - * In addition to its graph id, every media graph entity is identified by a - * name() unique in the media device context. - * - * \todo Add support for associating a devnode to the entity when integrating - * with DeviceEnumerator. + * In addition to its graph id, media graph entities are identified by a + * name() unique in the media device context. They implement a function() and + * may expose a devnode(). */ /** @@ -255,6 +253,16 @@ void MediaPad::addLink(MediaLink *link) * \return The entity name */ +/** + * \fn MediaEntity::function() + * \brief Retrieve the entity's main function + * + * Media entity functions are expressed using the MEDIA_ENT_F_* macros + * defined by the Media Controller API. + * + * \return The entity's function + */ + /** * \fn MediaEntity::deviceMajor() * \brief Retrieve the major number of the interface associated with the entity @@ -336,7 +344,7 @@ MediaEntity::MediaEntity(MediaDevice *dev, const struct media_v2_entity *entity, unsigned int major, unsigned int minor) : MediaObject(dev, entity->id), name_(entity->name), - major_(major), minor_(minor) + function_(entity->function), major_(major), minor_(minor) { } From patchwork Wed Jan 16 13:59:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 252 Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E23AD60C9A for ; Wed, 16 Jan 2019 14:59:50 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 6E212C0008; Wed, 16 Jan 2019 13:59:50 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Jan 2019 14:59:47 +0100 Message-Id: <20190116135949.2097-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116135949.2097-1-jacopo@jmondi.org> References: <20190116135949.2097-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/5] libcamera: media_object: Set devnode in MediaEntity X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 13:59:51 -0000 The MediaEntity::setDeviceNode() function was designed to set the device node path associated with a MediaEntity. The function was there, but the devnode_ member field was never actually set. Fix this. While at there add a getter method for the devnode_ member as it will soon be used. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/include/media_object.h | 1 + src/libcamera/media_object.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h index a10f7e1..fad55a0 100644 --- a/src/libcamera/include/media_object.h +++ b/src/libcamera/include/media_object.h @@ -85,6 +85,7 @@ class MediaEntity : public MediaObject public: const std::string &name() const { return name_; } unsigned int function() const { return function_; } + const std::string &devnode() const { return devnode_; } unsigned int deviceMajor() const { return major_; } unsigned int deviceMinor() const { return minor_; } diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp index 76dd326..4e90443 100644 --- a/src/libcamera/media_object.cpp +++ b/src/libcamera/media_object.cpp @@ -263,6 +263,15 @@ void MediaPad::addLink(MediaLink *link) * \return The entity's function */ +/** + * \fn MediaEntity::devnode() + * \brief Retrieve the entity's device node path, if any + * + * \sa int MediaEntity::setDeviceNode(const std::string &devnode) + * + * \return The entity's device node path, or an empty string if it is not set + */ + /** * \fn MediaEntity::deviceMajor() * \brief Retrieve the major number of the interface associated with the entity @@ -330,6 +339,8 @@ int MediaEntity::setDeviceNode(const std::string &devnode) return ret; } + devnode_ = devnode; + return 0; } From patchwork Wed Jan 16 13:59:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 253 Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8005A60C9A for ; Wed, 16 Jan 2019 14:59:51 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 13AF2C0015; Wed, 16 Jan 2019 13:59:50 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Jan 2019 14:59:48 +0100 Message-Id: <20190116135949.2097-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116135949.2097-1-jacopo@jmondi.org> References: <20190116135949.2097-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/5] libcamera: pipeline: Allows more expressive names X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 13:59:51 -0000 Allow the registration of pipeline handlers with more expressive names than the pipeline handler factory class name. Result is the following: -DBG pipeline_handler.cpp:119 Registered pipeline handler "PipeHandlerVimc" -DBG pipeline_handler.cpp:119 Registered pipeline handler "PipelineHandlerIPU3" +DBG pipeline_handler.cpp:119 Registered pipeline handler "VIMC virtual driver pipeline handler" +DBG pipeline_handler.cpp:119 Registered pipeline handler "Intel IPU3 pipeline handler" Signed-off-by: Jacopo Mondi --- src/libcamera/include/pipeline_handler.h | 4 ++-- src/libcamera/pipeline/vimc.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index fdf8b8d..180f599 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -43,12 +43,12 @@ private: static std::map ®istry(); }; -#define REGISTER_PIPELINE_HANDLER(handler) \ +#define REGISTER_PIPELINE_HANDLER(handler, name) \ class handler##Factory : public PipelineHandlerFactory { \ public: \ handler##Factory() \ { \ - PipelineHandlerFactory::registerType(#handler, this); \ + PipelineHandlerFactory::registerType(name, this); \ } \ virtual PipelineHandler *create() { \ return new handler(); \ diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 720d9c2..21af902 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -88,6 +88,6 @@ bool PipeHandlerVimc::match(DeviceEnumerator *enumerator) return true; } -REGISTER_PIPELINE_HANDLER(PipeHandlerVimc); +REGISTER_PIPELINE_HANDLER(PipeHandlerVimc, "VIMC virtual driver pipeline handler"); } /* namespace libcamera */ From patchwork Wed Jan 16 13:59:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 254 Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 20D6D60C9C for ; Wed, 16 Jan 2019 14:59:52 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id A904DC0005; Wed, 16 Jan 2019 13:59:51 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 16 Jan 2019 14:59:49 +0100 Message-Id: <20190116135949.2097-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116135949.2097-1-jacopo@jmondi.org> References: <20190116135949.2097-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/5] libcamera: pipeline: Add Intel IPU3 pipeline X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 13:59:52 -0000 Add a pipeline handler for the Intel IPU3 device. The pipeline handler creates a Camera for each image sensor it finds to be connected to an IPU3 CSI-2 receiver, and enables the link between the two. Tested on Soraka, listing detected cameras on the system, verifying the pipeline handler gets matched and links properly enabled. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 263 ++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/meson.build | 3 + src/libcamera/pipeline/meson.build | 2 + 3 files changed, 268 insertions(+) create mode 100644 src/libcamera/pipeline/ipu3/ipu3.cpp create mode 100644 src/libcamera/pipeline/ipu3/meson.build diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp new file mode 100644 index 0000000..066e9da --- /dev/null +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipu3.cpp - Pipeline handler for Intel IPU3 + */ + +#include +#include + +#include + +#include "device_enumerator.h" +#include "log.h" +#include "media_device.h" +#include "pipeline_handler.h" + +namespace libcamera { + +class PipelineHandlerIPU3 : public PipelineHandler +{ +public: + PipelineHandlerIPU3(); + ~PipelineHandlerIPU3(); + + bool match(DeviceEnumerator *enumerator); + + unsigned int count(); + Camera *camera(unsigned int id) final; + +private: + MediaDevice *cio2_; + MediaDevice *imgu_; + + unsigned int numCameras_; + std::map camerasMap_; + + unsigned int registerCameras(); +}; + +PipelineHandlerIPU3::PipelineHandlerIPU3() + : cio2_(nullptr), imgu_(nullptr), numCameras_(0) +{ +} + +PipelineHandlerIPU3::~PipelineHandlerIPU3() +{ + if (cio2_) + cio2_->release(); + + if (imgu_) + imgu_->release(); + + for (auto map : camerasMap_) { + Camera *camera = map.second; + if (camera) + camera->put(); + } + + cio2_ = nullptr; + imgu_ = nullptr; + camerasMap_.clear(); +} + +unsigned int PipelineHandlerIPU3::count() +{ + return numCameras_; +} + +Camera *PipelineHandlerIPU3::camera(unsigned int id) +{ + if (id >= numCameras_) + return nullptr; + + /* + * The requested camera id does not match the key index used to store + * Camera instances in the 'camerasMap_' map. + * + * The 'id' argument represent the n-th valid cameras registered + * in the system, while the indexing key is the CSI-2 receiver index + * the camera sensor is associated to, and some receiver might have no + * camera sensor connected. + */ + for (auto it = camerasMap_.begin(); it != camerasMap_.end(); ++it, --id) { + if (id == 0) + return (*it).second; + } + + return nullptr; +} + +bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) +{ + DeviceMatch cio2_dm("ipu3-cio2"); + cio2_dm.add("ipu3-csi2 0"); + cio2_dm.add("ipu3-cio2 0"); + cio2_dm.add("ipu3-csi2 1"); + cio2_dm.add("ipu3-cio2 1"); + cio2_dm.add("ipu3-csi2 2"); + cio2_dm.add("ipu3-cio2 2"); + cio2_dm.add("ipu3-csi2 3"); + cio2_dm.add("ipu3-cio2 3"); + + DeviceMatch imgu_dm("ipu3-imgu"); + imgu_dm.add("ipu3-imgu 0"); + imgu_dm.add("ipu3-imgu 0 input"); + imgu_dm.add("ipu3-imgu 0 parameters"); + imgu_dm.add("ipu3-imgu 0 output"); + imgu_dm.add("ipu3-imgu 0 viewfinder"); + imgu_dm.add("ipu3-imgu 0 3a stat"); + imgu_dm.add("ipu3-imgu 1"); + imgu_dm.add("ipu3-imgu 1 input"); + imgu_dm.add("ipu3-imgu 1 parameters"); + imgu_dm.add("ipu3-imgu 1 output"); + imgu_dm.add("ipu3-imgu 1 viewfinder"); + imgu_dm.add("ipu3-imgu 1 3a stat"); + + cio2_ = enumerator->search(cio2_dm); + if (!cio2_) + return false; + + imgu_ = enumerator->search(imgu_dm); + if (!imgu_) + return false; + + /* + * It is safe to acquire both media devices at this point as + * DeviceEnumerator::search() skips the busy ones for us. + */ + cio2_->acquire(); + imgu_->acquire(); + + /* + * Disable all links that are enabled by default on CIO2, as camera + * creation enables all valid links it finds. + * + * Close the CIO2 media device after, as links are enabled and should + * not need to be changed after. + */ + if (cio2_->open()) + goto error_release_mdev; + + if (cio2_->disableLinks()) + goto error_close_cio2; + + numCameras_ = registerCameras(); + LOG(Debug) << "\"Intel IPU3\" pipeline handler initialized with " + << numCameras_ << " cameras registered"; + + cio2_->close(); + + return true; + +error_close_cio2: + cio2_->close(); + +error_release_mdev: + cio2_->release(); + imgu_->release(); + + return false; +} + +/* + * Cameras are created associating an image sensor (represented by a + * media entity with function MEDIA_ENT_F_CAM_SENSOR) to one of the four + * CIO2 CSI-2 receivers. + * + * Cameras are here created and stored in the member field 'camerasMap_' map, + * indexed by the id of the CSI-2 receiver they are connected, to maintain + * an ordering that does not depend on the device enumeration order. + * + * The function returns the number of cameras found in the system. + */ +unsigned int PipelineHandlerIPU3::registerCameras() +{ + const std::vector entities = cio2_->entities(); + unsigned int numCameras = 0; + struct { + unsigned int id; + MediaEntity *csi2; + } csi2Receivers[] = { + { 0, cio2_->getEntityByName("ipu3-csi2 0") }, + { 1, cio2_->getEntityByName("ipu3-csi2 1") }, + { 2, cio2_->getEntityByName("ipu3-csi2 2") }, + { 3, cio2_->getEntityByName("ipu3-csi2 3") }, + }; + + /* + * For each CSI-2 receiver on the IPU3, create a Camera if an + * image sensor is connected to it. + */ + for (auto csi2Receiver : csi2Receivers) { + MediaEntity *csi2 = csi2Receiver.csi2; + unsigned int id = csi2Receiver.id; + + /* + * This shall not happen, as the device enumerator matched + * all entities described in the cio2_dm DeviceMatch. + * + * As this check is basically free, better stay safe than sorry. + */ + if (!csi2) + continue; + + std::vector pads = csi2->pads(); + MediaPad *sink; + for (MediaPad *pad : pads) { + if (!(pad->flags() & MEDIA_PAD_FL_SINK)) + continue; + + /* IPU3 CSI-2 receivers have a single sink pad. */ + sink = pad; + break; + } + + std::vector links = sink->links(); + if (links.empty()) + continue; + + /* + * Verify that the receiver is connected to a sensor, enable + * the media link between the two, and create a Camera with + * a unique name. + * + * FIXME: This supports creating a single camera per CSI-2 receiver. + */ + for (MediaLink *link : links) { + /* Again, this shall not happen, but better stay safe. */ + if (!link->source()) + continue; + + MediaEntity *sensor = link->source()->entity(); + if (!sensor) + continue; + + if (sensor->function() != MEDIA_ENT_F_CAM_SENSOR) + continue; + + if (link->setEnabled(true)) + continue; + + std::size_t pos = sensor->name().find(" "); + std::string cameraName = sensor->name().substr(0, pos); + cameraName += " " + std::to_string(id); + + camerasMap_[id] = new Camera(cameraName); + + LOG(Info) << "Registered Camera[" << numCameras + << "] \"" << cameraName << "\"" + << " connected to CSI-2 receiver " << id; + + numCameras++; + break; + } + } + + return numCameras; +} + +REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3, "Intel IPU3 pipeline handler"); + +} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build new file mode 100644 index 0000000..0ab766a --- /dev/null +++ b/src/libcamera/pipeline/ipu3/meson.build @@ -0,0 +1,3 @@ +libcamera_sources += files([ + 'ipu3.cpp', +]) diff --git a/src/libcamera/pipeline/meson.build b/src/libcamera/pipeline/meson.build index 615ecd2..811c075 100644 --- a/src/libcamera/pipeline/meson.build +++ b/src/libcamera/pipeline/meson.build @@ -1,3 +1,5 @@ libcamera_sources += files([ 'vimc.cpp', ]) + +subdir('ipu3')