[{"id":36438,"web_url":"https://patchwork.libcamera.org/comment/36438/","msgid":"<176131088501.127060.10225509952554706243@isaac-ThinkPad-T16-Gen-2>","date":"2025-10-24T13:01:25","subject":"Re: [PATCH v2 02/35] libcamera: pipeline: utilise shared MediaDevice\n\tpointers","submitter":{"id":215,"url":"https://patchwork.libcamera.org/api/people/215/","name":"Isaac Scott","email":"isaac.scott@ideasonboard.com"},"content":"Hi Stefan,\n\nThank you for the patch!\n\nQuoting Stefan Klug (2025-10-23 15:48:03)\n> From: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> Adapt the PipelineHandler::acquireMediaDevice() support function to\n> return a shared pointer instead of the underlying raw pointer.\n> \n> Propagate this update to all pipeline handlers that use the MediaDevice\n> and store a std::shared_ptr<MediaDevice> accordingly.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> ---\n>  include/libcamera/internal/pipeline_handler.h      |  8 ++++----\n>  src/libcamera/pipeline/imx8-isi/imx8-isi.cpp       |  2 +-\n>  src/libcamera/pipeline/ipu3/cio2.cpp               |  2 +-\n>  src/libcamera/pipeline/ipu3/cio2.h                 |  2 +-\n>  src/libcamera/pipeline/ipu3/imgu.cpp               |  3 ++-\n>  src/libcamera/pipeline/ipu3/imgu.h                 |  4 ++--\n>  src/libcamera/pipeline/ipu3/ipu3.cpp               |  4 ++--\n>  src/libcamera/pipeline/mali-c55/mali-c55.cpp       |  2 +-\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp           |  2 +-\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.cpp      |  2 +-\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.h        |  2 +-\n>  .../pipeline/rpi/common/pipeline_base.cpp          |  6 ++++--\n>  src/libcamera/pipeline/rpi/common/pipeline_base.h  |  9 ++++++---\n>  src/libcamera/pipeline/rpi/pisp/pisp.cpp           | 10 ++++++----\n>  src/libcamera/pipeline/rpi/vc4/vc4.cpp             | 13 +++++++++----\n>  src/libcamera/pipeline/simple/simple.cpp           | 13 +++++++------\n>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp       |  6 +++---\n>  src/libcamera/pipeline/vimc/vimc.cpp               |  6 +++---\n>  src/libcamera/pipeline_handler.cpp                 | 14 ++++++++------\n>  test/delayed_controls.cpp                          |  2 +-\n>  test/libtest/buffer_source.cpp                     |  2 +-\n>  21 files changed, 65 insertions(+), 49 deletions(-)\n> \n> diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\n> index e89d6a33e398..0b25cffb44e5 100644\n> --- a/include/libcamera/internal/pipeline_handler.h\n> +++ b/include/libcamera/internal/pipeline_handler.h\n> @@ -38,8 +38,8 @@ public:\n>         virtual ~PipelineHandler();\n>  \n>         virtual bool match(DeviceEnumerator *enumerator) = 0;\n> -       MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator,\n> -                                       const DeviceMatch &dm);\n> +       std::shared_ptr<MediaDevice> acquireMediaDevice(DeviceEnumerator *enumerator,\n> +                                                       const DeviceMatch &dm);\n>  \n>         bool acquire(Camera *camera);\n>         void release(Camera *camera);\n> @@ -72,7 +72,7 @@ public:\n>  \n>  protected:\n>         void registerCamera(std::shared_ptr<Camera> camera);\n> -       void hotplugMediaDevice(MediaDevice *media);\n> +       void hotplugMediaDevice(std::shared_ptr<MediaDevice> media);\n>  \n>         virtual int queueRequestDevice(Camera *camera, Request *request) = 0;\n>         virtual void stopDevice(Camera *camera) = 0;\n> @@ -86,7 +86,7 @@ protected:\n>  private:\n>         void unlockMediaDevices();\n>  \n> -       void mediaDeviceDisconnected(MediaDevice *media);\n> +       void mediaDeviceDisconnected(std::shared_ptr<MediaDevice> media);\n>         virtual void disconnect();\n>  \n>         void doQueueRequest(Request *request);\n> diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> index de09431cb9b9..3f414676ec28 100644\n> --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> @@ -139,7 +139,7 @@ private:\n>  \n>         void bufferReady(FrameBuffer *buffer);\n>  \n> -       MediaDevice *isiDev_;\n> +       std::shared_ptr<MediaDevice> isiDev_;\n\nReviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>\n\n>  \n>         std::unique_ptr<V4L2Subdevice> crossbar_;\n>         std::vector<Pipe> pipes_;\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> index aa544d7b0303..ebbd424c56ea 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> @@ -112,7 +112,7 @@ std::vector<SizeRange> CIO2Device::sizes(const PixelFormat &format) const\n>   * \\return 0 on success or a negative error code otherwise\n>   * \\retval -ENODEV No supported image sensor is connected to this CIO2 instance\n>   */\n> -int CIO2Device::init(const MediaDevice *media, unsigned int index)\n> +int CIO2Device::init(std::shared_ptr<const MediaDevice> media, unsigned int index)\n>  {\n>         int ret;\n>  \n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> index 3aa3a1ca8ef8..d844cb7ae831 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.h\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -38,7 +38,7 @@ public:\n>         std::vector<PixelFormat> formats() const;\n>         std::vector<SizeRange> sizes(const PixelFormat &format) const;\n>  \n> -       int init(const MediaDevice *media, unsigned int index);\n> +       int init(std::shared_ptr<const MediaDevice> media, unsigned int index);\n>         int configure(const Size &size, const Transform &transform,\n>                       V4L2DeviceFormat *outputFormat);\n>  \n> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp\n> index 7be780913fae..391e000f6e12 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.cpp\n> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp\n> @@ -330,7 +330,8 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)\n>   *\n>   * \\return 0 on success or a negative error code otherwise\n>   */\n> -int ImgUDevice::init(MediaDevice *media, unsigned int index)\n> +int ImgUDevice::init(std::shared_ptr<libcamera::MediaDevice> media,\n> +                    unsigned int index)\n>  {\n>         int ret;\n>  \n> diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h\n> index fa508316b301..272f861f98c4 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.h\n> +++ b/src/libcamera/pipeline/ipu3/imgu.h\n> @@ -64,7 +64,7 @@ public:\n>                 Size viewfinder;\n>         };\n>  \n> -       int init(MediaDevice *media, unsigned int index);\n> +       int init(std::shared_ptr<MediaDevice> media, unsigned int index);\n>  \n>         PipeConfig calculatePipeConfig(Pipe *pipe);\n>  \n> @@ -118,7 +118,7 @@ private:\n>                                  V4L2DeviceFormat *outputFormat);\n>  \n>         std::string name_;\n> -       MediaDevice *media_;\n> +       std::shared_ptr<MediaDevice> media_;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index d6b7edcb5a7f..695762c750f8 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -164,8 +164,8 @@ private:\n>  \n>         ImgUDevice imgu0_;\n>         ImgUDevice imgu1_;\n> -       MediaDevice *cio2MediaDev_;\n> -       MediaDevice *imguMediaDev_;\n> +       std::shared_ptr<MediaDevice> cio2MediaDev_;\n> +       std::shared_ptr<MediaDevice> imguMediaDev_;\n>  \n>         std::vector<IPABuffer> ipaBuffers_;\n>  };\n> diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> index 38bdc6138ed1..434b2d5e8a5f 100644\n> --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> @@ -682,7 +682,7 @@ private:\n>         bool registerTPGCamera(MediaLink *link);\n>         bool registerSensorCamera(MediaLink *link);\n>  \n> -       MediaDevice *media_;\n> +       std::shared_ptr<MediaDevice> media_;\n>         std::unique_ptr<V4L2Subdevice> isp_;\n>         std::unique_ptr<V4L2VideoDevice> stats_;\n>         std::unique_ptr<V4L2VideoDevice> params_;\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index ecd13831539f..959cdb41fe7e 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -218,7 +218,7 @@ private:\n>  \n>         int updateControls(RkISP1CameraData *data);\n>  \n> -       MediaDevice *media_;\n> +       std::shared_ptr<MediaDevice> media_;\n>         std::unique_ptr<V4L2Subdevice> isp_;\n>         std::unique_ptr<V4L2VideoDevice> param_;\n>         std::unique_ptr<V4L2VideoDevice> stat_;\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> index d318bea92446..8d5298c04833 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> @@ -64,7 +64,7 @@ RkISP1Path::RkISP1Path(const char *name, const Span<const PixelFormat> &formats,\n>  {\n>  }\n>  \n> -bool RkISP1Path::init(MediaDevice *media)\n> +bool RkISP1Path::init(std::shared_ptr<MediaDevice> media)\n>  {\n>         std::string resizer = std::string(\"rkisp1_resizer_\") + name_ + \"path\";\n>         std::string video = std::string(\"rkisp1_\") + name_ + \"path\";\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> index 0b60c499ac64..0c68e9eb99af 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> @@ -37,7 +37,7 @@ public:\n>         RkISP1Path(const char *name, const Span<const PixelFormat> &formats,\n>                    const Size &minResolution, const Size &maxResolution);\n>  \n> -       bool init(MediaDevice *media);\n> +       bool init(std::shared_ptr<MediaDevice> media);\n>  \n>         int setEnabled(bool enable) { return link_->setEnabled(enable); }\n>         bool isEnabled() const { return link_->flags() & MEDIA_LNK_FL_ENABLED; }\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> index c209aa596311..9d65dc83573b 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> @@ -786,8 +786,10 @@ int PipelineHandlerBase::queueRequestDevice(Camera *camera, Request *request)\n>  }\n>  \n>  int PipelineHandlerBase::registerCamera(std::unique_ptr<RPi::CameraData> &cameraData,\n> -                                       MediaDevice *frontend, const std::string &frontendName,\n> -                                       MediaDevice *backend, MediaEntity *sensorEntity)\n> +                                       std::shared_ptr<MediaDevice> frontend,\n> +                                       const std::string &frontendName,\n> +                                       std::shared_ptr<MediaDevice> backend,\n> +                                       MediaEntity *sensorEntity)\n>  {\n>         CameraData *data = cameraData.get();\n>         int ret;\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> index 4bce4ec4f978..15628259afc6 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> @@ -224,13 +224,16 @@ public:\n>  \n>  protected:\n>         int registerCamera(std::unique_ptr<RPi::CameraData> &cameraData,\n> -                          MediaDevice *frontent, const std::string &frontendName,\n> -                          MediaDevice *backend, MediaEntity *sensorEntity);\n> +                          std::shared_ptr<MediaDevice> frontend,\n> +                          const std::string &frontendName,\n> +                          std::shared_ptr<MediaDevice> backend,\n> +                          MediaEntity *sensorEntity);\n>  \n>         void mapBuffers(Camera *camera, const BufferMap &buffers, unsigned int mask);\n>  \n>         virtual int platformRegister(std::unique_ptr<CameraData> &cameraData,\n> -                                    MediaDevice *unicam, MediaDevice *isp) = 0;\n> +                                    std::shared_ptr<MediaDevice> unicam,\n> +                                    std::shared_ptr<MediaDevice> isp) = 0;\n>  \n>  private:\n>         CameraData *cameraData(Camera *camera)\n> diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> index 082724c5a0fb..77acd2f64092 100644\n> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> @@ -866,7 +866,8 @@ private:\n>  \n>         int prepareBuffers(Camera *camera) override;\n>         int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,\n> -                            MediaDevice *cfe, MediaDevice *isp) override;\n> +                            std::shared_ptr<MediaDevice> cfe,\n> +                            std::shared_ptr<MediaDevice> isp) override;\n>  };\n>  \n>  bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)\n> @@ -884,7 +885,7 @@ bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)\n>                 cfe.add(\"rp1-cfe-fe-image0\");\n>                 cfe.add(\"rp1-cfe-fe-stats\");\n>                 cfe.add(\"rp1-cfe-fe-config\");\n> -               MediaDevice *cfeDevice = acquireMediaDevice(enumerator, cfe);\n> +               std::shared_ptr<MediaDevice> cfeDevice = acquireMediaDevice(enumerator, cfe);\n>  \n>                 if (!cfeDevice) {\n>                         LOG(RPI, Debug) << \"Unable to acquire a CFE instance\";\n> @@ -900,7 +901,7 @@ bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)\n>                 isp.add(\"pispbe-tdn_input\");\n>                 isp.add(\"pispbe-stitch_output\");\n>                 isp.add(\"pispbe-stitch_input\");\n> -               MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp);\n> +               std::shared_ptr<MediaDevice> ispDevice = acquireMediaDevice(enumerator, isp);\n>  \n>                 if (!ispDevice) {\n>                         LOG(RPI, Debug) << \"Unable to acquire ISP instance\";\n> @@ -1065,7 +1066,8 @@ int PipelineHandlerPiSP::prepareBuffers(Camera *camera)\n>  }\n>  \n>  int PipelineHandlerPiSP::platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,\n> -                                         MediaDevice *cfe, MediaDevice *isp)\n> +                                         std::shared_ptr<MediaDevice> cfe,\n> +                                         std::shared_ptr<MediaDevice> isp)\n>  {\n>         PiSPCameraData *data = static_cast<PiSPCameraData *>(cameraData.get());\n>         int ret;\n> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> index 99d43bd0a2f5..f0cb99d59e74 100644\n> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> @@ -5,6 +5,8 @@\n>   * Pipeline handler for VC4-based Raspberry Pi devices\n>   */\n>  \n> +#include <memory>\n> +\n>  #include <linux/bcm2835-isp.h>\n>  #include <linux/v4l2-controls.h>\n>  #include <linux/videodev2.h>\n> @@ -158,7 +160,8 @@ private:\n>  \n>         int prepareBuffers(Camera *camera) override;\n>         int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,\n> -                            MediaDevice *unicam, MediaDevice *isp) override;\n> +                            std::shared_ptr<MediaDevice> unicam,\n> +                            std::shared_ptr<MediaDevice> isp) override;\n>  };\n>  \n>  bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)\n> @@ -173,7 +176,7 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)\n>          */\n>         for (unsigned int i = 0; i < numUnicamDevices; i++) {\n>                 DeviceMatch unicam(\"unicam\");\n> -               MediaDevice *unicamDevice = acquireMediaDevice(enumerator, unicam);\n> +               std::shared_ptr<MediaDevice> unicamDevice = acquireMediaDevice(enumerator, unicam);\n>  \n>                 if (!unicamDevice) {\n>                         LOG(RPI, Debug) << \"Unable to acquire a Unicam instance\";\n> @@ -181,7 +184,7 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)\n>                 }\n>  \n>                 DeviceMatch isp(\"bcm2835-isp\");\n> -               MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp);\n> +               std::shared_ptr<MediaDevice> ispDevice = acquireMediaDevice(enumerator, isp);\n>  \n>                 if (!ispDevice) {\n>                         LOG(RPI, Debug) << \"Unable to acquire ISP instance\";\n> @@ -303,7 +306,9 @@ int PipelineHandlerVc4::prepareBuffers(Camera *camera)\n>         return 0;\n>  }\n>  \n> -int PipelineHandlerVc4::platformRegister(std::unique_ptr<RPi::CameraData> &cameraData, MediaDevice *unicam, MediaDevice *isp)\n> +int PipelineHandlerVc4::platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,\n> +                                        std::shared_ptr<MediaDevice> unicam,\n> +                                        std::shared_ptr<MediaDevice> isp)\n>  {\n>         Vc4CameraData *data = static_cast<Vc4CameraData *>(cameraData.get());\n>  \n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index 7b0783cdbc32..1183be9a6b07 100644\n> --- a/src/libcamera/pipeline/simple/simple.cpp\n> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> @@ -413,7 +413,7 @@ public:\n>  \n>         V4L2VideoDevice *video(const MediaEntity *entity);\n>         V4L2Subdevice *subdev(const MediaEntity *entity);\n> -       MediaDevice *converter() { return converter_; }\n> +       MediaDevice *converter() { return converter_.get(); }\n>         bool swIspEnabled() const { return swIspEnabled_; }\n>  \n>  protected:\n> @@ -434,7 +434,8 @@ private:\n>                 return static_cast<SimpleCameraData *>(camera->_d());\n>         }\n>  \n> -       bool matchDevice(MediaDevice *media, const SimplePipelineInfo &info,\n> +       bool matchDevice(std::shared_ptr<MediaDevice> media,\n> +                        const SimplePipelineInfo &info,\n>                          DeviceEnumerator *enumerator);\n>  \n>         std::vector<MediaEntity *> locateSensors(MediaDevice *media);\n> @@ -445,7 +446,7 @@ private:\n>  \n>         std::map<const MediaEntity *, EntityData> entities_;\n>  \n> -       MediaDevice *converter_;\n> +       std::shared_ptr<MediaDevice> converter_;\n>         bool swIspEnabled_;\n>  };\n>  \n> @@ -1684,7 +1685,7 @@ int SimplePipelineHandler::resetRoutingTable(V4L2Subdevice *subdev)\n>         return 0;\n>  }\n>  \n> -bool SimplePipelineHandler::matchDevice(MediaDevice *media,\n> +bool SimplePipelineHandler::matchDevice(std::shared_ptr<MediaDevice> media,\n>                                         const SimplePipelineInfo &info,\n>                                         DeviceEnumerator *enumerator)\n>  {\n> @@ -1715,7 +1716,7 @@ bool SimplePipelineHandler::matchDevice(MediaDevice *media,\n>         }\n>  \n>         /* Locate the sensors. */\n> -       std::vector<MediaEntity *> sensors = locateSensors(media);\n> +       std::vector<MediaEntity *> sensors = locateSensors(media.get());\n>         if (sensors.empty()) {\n>                 LOG(SimplePipeline, Info) << \"No sensor found for \" << media->deviceNode();\n>                 return false;\n> @@ -1833,7 +1834,7 @@ bool SimplePipelineHandler::matchDevice(MediaDevice *media,\n>  \n>  bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)\n>  {\n> -       MediaDevice *media;\n> +       std::shared_ptr<MediaDevice> media;\n>  \n>         for (const SimplePipelineInfo &inf : supportedDevices) {\n>                 DeviceMatch dm(inf.driver);\n> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> index 4b5816dfdde0..034f9c39d3e9 100644\n> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> @@ -46,7 +46,7 @@ public:\n>         {\n>         }\n>  \n> -       int init(MediaDevice *media);\n> +       int init(std::shared_ptr<MediaDevice> media);\n>         void addControl(uint32_t cid, const ControlInfo &v4l2info,\n>                         ControlInfoMap::Map *ctrls);\n>         void imageBufferReady(FrameBuffer *buffer);\n> @@ -466,7 +466,7 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request)\n>  \n>  bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)\n>  {\n> -       MediaDevice *media;\n> +       std::shared_ptr<MediaDevice> media;\n>         DeviceMatch dm(\"uvcvideo\");\n>  \n>         media = acquireMediaDevice(enumerator, dm);\n> @@ -508,7 +508,7 @@ void PipelineHandlerUVC::releaseDevice(Camera *camera)\n>         data->video_->close();\n>  }\n>  \n> -int UVCCameraData::init(MediaDevice *media)\n> +int UVCCameraData::init(std::shared_ptr<MediaDevice> media)\n>  {\n>         int ret;\n>  \n> diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\n> index 5022101505a1..fdb92b4a82d9 100644\n> --- a/src/libcamera/pipeline/vimc/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc/vimc.cpp\n> @@ -49,7 +49,7 @@ LOG_DEFINE_CATEGORY(VIMC)\n>  class VimcCameraData : public Camera::Private\n>  {\n>  public:\n> -       VimcCameraData(PipelineHandler *pipe, MediaDevice *media)\n> +       VimcCameraData(PipelineHandler *pipe, std::shared_ptr<MediaDevice> media)\n>                 : Camera::Private(pipe), media_(media)\n>         {\n>         }\n> @@ -59,7 +59,7 @@ public:\n>         void imageBufferReady(FrameBuffer *buffer);\n>         void paramsComputed(unsigned int id, const Flags<ipa::vimc::TestFlag> flags);\n>  \n> -       MediaDevice *media_;\n> +       std::shared_ptr<MediaDevice> media_;\n>         std::unique_ptr<CameraSensor> sensor_;\n>         std::unique_ptr<V4L2Subdevice> debayer_;\n>         std::unique_ptr<V4L2Subdevice> scaler_;\n> @@ -479,7 +479,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)\n>         dm.add(\"RGB/YUV Input\");\n>         dm.add(\"Scaler\");\n>  \n> -       MediaDevice *media = acquireMediaDevice(enumerator, dm);\n> +       std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm);\n>         if (!media)\n>                 return false;\n>  \n> diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\n> index e5f9e55c9783..825b8767fe3b 100644\n> --- a/src/libcamera/pipeline_handler.cpp\n> +++ b/src/libcamera/pipeline_handler.cpp\n> @@ -129,10 +129,12 @@ PipelineHandler::~PipelineHandler()\n>   *\n>   * \\context This function shall be called from the CameraManager thread.\n>   *\n> - * \\return A pointer to the matching MediaDevice, or nullptr if no match is found\n> + * \\return A shared pointer to the matching MediaDevice, or nullptr if no match\n> + * is found\n>   */\n> -MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,\n> -                                                const DeviceMatch &dm)\n> +std::shared_ptr<MediaDevice>\n> +PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,\n> +                                   const DeviceMatch &dm)\n>  {\n>         std::shared_ptr<MediaDevice> media = enumerator->search(dm);\n>         if (!media)\n> @@ -143,7 +145,7 @@ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,\n>  \n>         mediaDevices_.push_back(media);\n>  \n> -       return media.get();\n> +       return media;\n>  }\n>  \n>  /**\n> @@ -725,7 +727,7 @@ void PipelineHandler::registerCamera(std::shared_ptr<Camera> camera)\n>   * handler gets notified and automatically disconnects all the cameras it has\n>   * registered without requiring any manual intervention.\n>   */\n> -void PipelineHandler::hotplugMediaDevice(MediaDevice *media)\n> +void PipelineHandler::hotplugMediaDevice(std::shared_ptr<MediaDevice> media)\n>  {\n>         media->disconnected.connect(this, [this, media] { mediaDeviceDisconnected(media); });\n>  }\n> @@ -733,7 +735,7 @@ void PipelineHandler::hotplugMediaDevice(MediaDevice *media)\n>  /**\n>   * \\brief Slot for the MediaDevice disconnected signal\n>   */\n> -void PipelineHandler::mediaDeviceDisconnected(MediaDevice *media)\n> +void PipelineHandler::mediaDeviceDisconnected(std::shared_ptr<MediaDevice> media)\n>  {\n>         media->disconnected.disconnect(this);\n>  \n> diff --git a/test/delayed_controls.cpp b/test/delayed_controls.cpp\n> index 7bd30e7aead8..b305be48aafc 100644\n> --- a/test/delayed_controls.cpp\n> +++ b/test/delayed_controls.cpp\n> @@ -47,7 +47,7 @@ protected:\n>                         return TestSkip;\n>                 }\n>  \n> -               dev_ = V4L2VideoDevice::fromEntityName(media_.get(), \"vivid-000-vid-cap\");\n> +               dev_ = V4L2VideoDevice::fromEntityName(media_, \"vivid-000-vid-cap\");\n>                 if (dev_->open()) {\n>                         cerr << \"Failed to open video device\" << endl;\n>                         return TestFail;\n> diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp\n> index dde11f365e43..19b25fed50a0 100644\n> --- a/test/libtest/buffer_source.cpp\n> +++ b/test/libtest/buffer_source.cpp\n> @@ -52,7 +52,7 @@ int BufferSource::allocate(const StreamConfiguration &config)\n>                 return TestSkip;\n>         }\n>  \n> -       std::unique_ptr<V4L2VideoDevice> video = V4L2VideoDevice::fromEntityName(media_.get(), videoDeviceName);\n> +       std::unique_ptr<V4L2VideoDevice> video = V4L2VideoDevice::fromEntityName(media_, videoDeviceName);\n>         if (!video) {\n>                 std::cout << \"Failed to get video device from entity \"\n>                           << videoDeviceName << std::endl;\n> -- \n> 2.48.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6F443C3259\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Oct 2025 13:01:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id ACB2E60978;\n\tFri, 24 Oct 2025 15:01:29 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0244260964\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Oct 2025 15:01:27 +0200 (CEST)","from thinkpad.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 452691AA6;\n\tFri, 24 Oct 2025 14:59:42 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Xs7DPA2r\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761310782;\n\tbh=4LCASz8IP6yJZ1OTDCKcIjVX9K96uGr5thUuJ23M8YY=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=Xs7DPA2rE/Jm/ebLLDXVot/EXf5ZWWqOY0xQgEDo1dO/8FW5+St61kR2clGs2cGZf\n\tDMlDgOYJiIChrWkWFTTkPQC4DoRpxCgTsdRg2F5xjxXGYPRut4wmOvN1rDWZZyD4Fz\n\tibztu4HGnB1mRi0McASjvvbH4yI5B1FLfvy9Z9Rg=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251023144841.403689-3-stefan.klug@ideasonboard.com>","References":"<20251023144841.403689-1-stefan.klug@ideasonboard.com>\n\t<20251023144841.403689-3-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v2 02/35] libcamera: pipeline: utilise shared MediaDevice\n\tpointers","From":"Isaac Scott <isaac.scott@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 24 Oct 2025 14:01:25 +0100","Message-ID":"<176131088501.127060.10225509952554706243@isaac-ThinkPad-T16-Gen-2>","User-Agent":"alot/0.10","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]