diff options
-rw-r--r-- | src/libcamera/include/pipeline_handler.h | 4 | ||||
-rw-r--r-- | src/libcamera/pipeline/ipu3/ipu3.cpp | 30 | ||||
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1.cpp | 16 | ||||
-rw-r--r-- | src/libcamera/pipeline/uvcvideo.cpp | 25 | ||||
-rw-r--r-- | src/libcamera/pipeline/vimc.cpp | 20 | ||||
-rw-r--r-- | src/libcamera/pipeline_handler.cpp | 32 |
6 files changed, 59 insertions, 68 deletions
diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 5830e531..8e6a136d 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -22,6 +22,7 @@ class Camera; class CameraConfiguration; class CameraManager; class DeviceEnumerator; +class DeviceMatch; class MediaDevice; class PipelineHandler; class Request; @@ -53,6 +54,8 @@ public: virtual ~PipelineHandler(); virtual bool match(DeviceEnumerator *enumerator) = 0; + MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator, + const DeviceMatch &dm); virtual CameraConfiguration streamConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) = 0; @@ -84,6 +87,7 @@ private: void mediaDeviceDisconnected(MediaDevice *media); virtual void disconnect(); + std::vector<std::shared_ptr<MediaDevice>> mediaDevices_; std::vector<std::weak_ptr<Camera>> cameras_; std::map<const Camera *, std::unique_ptr<CameraData>> cameraData_; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 8a6a0e27..75a70e66 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -149,7 +149,6 @@ class PipelineHandlerIPU3 : public PipelineHandler { public: PipelineHandlerIPU3(CameraManager *manager); - ~PipelineHandlerIPU3(); CameraConfiguration streamConfiguration(Camera *camera, @@ -201,8 +200,8 @@ private: ImgUDevice imgu0_; ImgUDevice imgu1_; - std::shared_ptr<MediaDevice> cio2MediaDev_; - std::shared_ptr<MediaDevice> imguMediaDev_; + MediaDevice *cio2MediaDev_; + MediaDevice *imguMediaDev_; }; PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager) @@ -210,15 +209,6 @@ PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager) { } -PipelineHandlerIPU3::~PipelineHandlerIPU3() -{ - if (cio2MediaDev_) - cio2MediaDev_->release(); - - if (imguMediaDev_) - imguMediaDev_->release(); -} - CameraConfiguration PipelineHandlerIPU3::streamConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) @@ -614,20 +604,14 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) imgu_dm.add("ipu3-imgu 1 viewfinder"); imgu_dm.add("ipu3-imgu 1 3a stat"); - cio2MediaDev_ = enumerator->search(cio2_dm); + cio2MediaDev_ = acquireMediaDevice(enumerator, cio2_dm); if (!cio2MediaDev_) return false; - if (!cio2MediaDev_->acquire()) - return false; - - imguMediaDev_ = enumerator->search(imgu_dm); + imguMediaDev_ = acquireMediaDevice(enumerator, imgu_dm); if (!imguMediaDev_) return false; - if (!imguMediaDev_->acquire()) - return false; - /* * Disable all links that are enabled by default on CIO2, as camera * creation enables all valid links it finds. @@ -682,11 +666,11 @@ int PipelineHandlerIPU3::registerCameras() { int ret; - ret = imgu0_.init(imguMediaDev_.get(), 0); + ret = imgu0_.init(imguMediaDev_, 0); if (ret) return ret; - ret = imgu1_.init(imguMediaDev_.get(), 1); + ret = imgu1_.init(imguMediaDev_, 1); if (ret) return ret; @@ -705,7 +689,7 @@ int PipelineHandlerIPU3::registerCameras() }; CIO2Device *cio2 = &data->cio2_; - ret = cio2->init(cio2MediaDev_.get(), id); + ret = cio2->init(cio2MediaDev_, id); if (ret) continue; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index b94d742d..b395405c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -81,7 +81,7 @@ private: int createCamera(MediaEntity *sensor); void bufferReady(Buffer *buffer); - std::shared_ptr<MediaDevice> media_; + MediaDevice *media_; V4L2Subdevice *dphy_; V4L2Subdevice *isp_; V4L2Device *video_; @@ -100,9 +100,6 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1() delete video_; delete isp_; delete dphy_; - - if (media_) - media_->release(); } /* ----------------------------------------------------------------------------- @@ -355,24 +352,21 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) dm.add("rkisp1-input-params"); dm.add("rockchip-sy-mipi-dphy"); - media_ = enumerator->search(dm); + media_ = acquireMediaDevice(enumerator, dm); if (!media_) return false; - media_->acquire(); - /* Create the V4L2 subdevices we will need. */ - dphy_ = V4L2Subdevice::fromEntityName(media_.get(), - "rockchip-sy-mipi-dphy"); + dphy_ = V4L2Subdevice::fromEntityName(media_, "rockchip-sy-mipi-dphy"); if (dphy_->open() < 0) return false; - isp_ = V4L2Subdevice::fromEntityName(media_.get(), "rkisp1-isp-subdev"); + isp_ = V4L2Subdevice::fromEntityName(media_, "rkisp1-isp-subdev"); if (isp_->open() < 0) return false; /* Locate and open the capture video node. */ - video_ = V4L2Device::fromEntityName(media_.get(), "rkisp1_mainpath"); + video_ = V4L2Device::fromEntityName(media_, "rkisp1_mainpath"); if (video_->open() < 0) return false; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index e40b052f..351712cf 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -24,7 +24,6 @@ class PipelineHandlerUVC : public PipelineHandler { public: PipelineHandlerUVC(CameraManager *manager); - ~PipelineHandlerUVC(); CameraConfiguration streamConfiguration(Camera *camera, @@ -69,19 +68,11 @@ private: return static_cast<UVCCameraData *>( PipelineHandler::cameraData(camera)); } - - std::shared_ptr<MediaDevice> media_; }; PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) - : PipelineHandler(manager), media_(nullptr) -{ -} - -PipelineHandlerUVC::~PipelineHandlerUVC() + : PipelineHandler(manager) { - if (media_) - media_->release(); } CameraConfiguration @@ -177,19 +168,17 @@ int PipelineHandlerUVC::queueRequest(Camera *camera, Request *request) bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { + MediaDevice *media; DeviceMatch dm("uvcvideo"); - media_ = enumerator->search(dm); - if (!media_) - return false; - - if (!media_->acquire()) + media = acquireMediaDevice(enumerator, dm); + if (!media) return false; std::unique_ptr<UVCCameraData> data = utils::make_unique<UVCCameraData>(this); /* Locate and open the default video node. */ - for (MediaEntity *entity : media_->entities()) { + for (MediaEntity *entity : media->entities()) { if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { data->video_ = new V4L2Device(entity); break; @@ -208,11 +197,11 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) /* Create and register the camera. */ std::set<Stream *> streams{ &data->stream_ }; - std::shared_ptr<Camera> camera = Camera::create(this, media_->model(), streams); + std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams); registerCamera(std::move(camera), std::move(data)); /* Enable hot-unplug notifications. */ - hotplugMediaDevice(media_.get()); + hotplugMediaDevice(media); return true; } diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 7b6ebd4c..737d6df6 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -24,7 +24,6 @@ class PipelineHandlerVimc : public PipelineHandler { public: PipelineHandlerVimc(CameraManager *manager); - ~PipelineHandlerVimc(); CameraConfiguration streamConfiguration(Camera *camera, @@ -69,19 +68,11 @@ private: return static_cast<VimcCameraData *>( PipelineHandler::cameraData(camera)); } - - std::shared_ptr<MediaDevice> media_; }; PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager) - : PipelineHandler(manager), media_(nullptr) -{ -} - -PipelineHandlerVimc::~PipelineHandlerVimc() + : PipelineHandler(manager) { - if (media_) - media_->release(); } CameraConfiguration @@ -189,17 +180,14 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) dm.add("RGB/YUV Input"); dm.add("Scaler"); - media_ = enumerator->search(dm); - if (!media_) - return false; - - if (!media_->acquire()) + MediaDevice *media = acquireMediaDevice(enumerator, dm); + if (!media) return false; std::unique_ptr<VimcCameraData> data = utils::make_unique<VimcCameraData>(this); /* Locate and open the capture video node. */ - data->video_ = new V4L2Device(media_->getEntityByName("Raw Capture 1")); + data->video_ = new V4L2Device(media->getEntityByName("Raw Capture 1")); if (data->video_->open()) return false; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 4ecd6c49..c92ee782 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -11,6 +11,7 @@ #include <libcamera/camera.h> #include <libcamera/camera_manager.h> +#include "device_enumerator.h" #include "log.h" #include "media_device.h" #include "utils.h" @@ -116,6 +117,8 @@ PipelineHandler::PipelineHandler(CameraManager *manager) PipelineHandler::~PipelineHandler() { + for (std::shared_ptr<MediaDevice> media : mediaDevices_) + media->release(); }; /** @@ -150,6 +153,35 @@ PipelineHandler::~PipelineHandler() */ /** + * \brief Search and acquire a MediDevice matching a device pattern + * \param[in] enumerator Enumerator containing all media devices in the system + * \param[in] dm Device match pattern + * + * Search the device \a enumerator for an available media device matching the + * device match pattern \a dm. Matching media device that have previously been + * acquired by MediaDevice::acquire() are not considered. If a match is found, + * the media device is acquired and returned. The caller shall not release the + * device explicitly, it will be automatically released when the pipeline + * handler is destroyed. + * + * \return A pointer to the matching MediaDevice, or nullptr if no match is found + */ +MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, + const DeviceMatch &dm) +{ + std::shared_ptr<MediaDevice> media = enumerator->search(dm); + if (!media) + return nullptr; + + if (!media->acquire()) + return nullptr; + + mediaDevices_.push_back(media); + + return media.get(); +} + +/** * \fn PipelineHandler::streamConfiguration() * \brief Retrieve a group of stream configurations for a specified camera * \param[in] camera The camera to fetch default configuration from |