[libcamera-devel,v1,1/2] pipeline: raspberrypi: Move sensor entity detection out of registerCamera()
diff mbox series

Message ID 20211201115711.1017822-2-naush@raspberrypi.com
State Superseded
Headers show
Series
  • Raspberry Pi: Add video mux and bridge support
Related show

Commit Message

Naushir Patuck Dec. 1, 2021, 11:57 a.m. UTC
Enumerate the sensor device entities in PipelineHandlerRPi::match() and loop
over PipelineHandlerRPi::registerCamera() for each sensor found. This will
allow the pipeline handler to register multiple cameras attached to a single
Unicam instance with a Video Mux device.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 .../pipeline/raspberrypi/raspberrypi.cpp      | 35 +++++++++++--------
 1 file changed, 20 insertions(+), 15 deletions(-)

Comments

Kieran Bingham Dec. 8, 2021, 12:14 p.m. UTC | #1
Quoting Naushir Patuck (2021-12-01 11:57:10)
> Enumerate the sensor device entities in PipelineHandlerRPi::match() and loop
> over PipelineHandlerRPi::registerCamera() for each sensor found. This will
> allow the pipeline handler to register multiple cameras attached to a single
> Unicam instance with a Video Mux device.
> 
> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>

This sounds like a really interesting use case/demonstration of how MC
exposes the hardware to userspace to do something useful with it. Even
before personally I'd struggled with the extra complexitys that MC
brings, so I'm glad to be seeing some of the 'benefits' it
facilitates...

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> ---
>  .../pipeline/raspberrypi/raspberrypi.cpp      | 35 +++++++++++--------
>  1 file changed, 20 insertions(+), 15 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index e31fa3b23859..811160490f5c 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -314,7 +314,7 @@ private:
>                 return static_cast<RPiCameraData *>(camera->_d());
>         }
>  
> -       int registerCamera(MediaDevice *unicam, MediaDevice *isp);
> +       int registerCamera(MediaDevice *unicam, MediaDevice *isp, MediaEntity *sensorEntity);
>         int queueAllBuffers(Camera *camera);
>         int prepareBuffers(Camera *camera);
>         void freeBuffers(Camera *camera);
> @@ -1009,16 +1009,28 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
>                 return false;
>         }
>  
> -       int ret = registerCamera(unicamDevice, ispDevice);
> -       if (ret) {
> -               LOG(RPI, Error) << "Failed to register camera: " << ret;
> -               return false;
> +       /*
> +        * The loop below is used to register multiple cameras behind one or more
> +        * video mux devices that are attaced to a particular Unicam instance.
> +        * Obviously these cameras cannot be used simultaneously.
> +        */
> +       unsigned int numCameras = 0;
> +       for (MediaEntity *entity : unicamDevice->entities()) {
> +               if (entity->function() != MEDIA_ENT_F_CAM_SENSOR)
> +                       continue;
> +
> +               int ret = registerCamera(unicamDevice, ispDevice, entity);
> +               if (ret)
> +                       LOG(RPI, Error) << "Failed to register camera "
> +                                       << entity->name() << ": " << ret;
> +               else
> +                       numCameras++;
>         }
>  
> -       return true;
> +       return !!numCameras;
>  }
>  
> -int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp)
> +int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, MediaEntity *sensorEntity)
>  {
>         std::unique_ptr<RPiCameraData> data = std::make_unique<RPiCameraData>(this);
>  
> @@ -1059,14 +1071,7 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp)
>         data->isp_[Isp::Output1].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
>         data->isp_[Isp::Stats].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
>  
> -       /* Identify the sensor. */
> -       for (MediaEntity *entity : unicam->entities()) {
> -               if (entity->function() == MEDIA_ENT_F_CAM_SENSOR) {
> -                       data->sensor_ = std::make_unique<CameraSensor>(entity);
> -                       break;
> -               }
> -       }
> -
> +       data->sensor_ = std::make_unique<CameraSensor>(sensorEntity);
>         if (!data->sensor_)
>                 return -EINVAL;
>  
> -- 
> 2.25.1
>

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index e31fa3b23859..811160490f5c 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -314,7 +314,7 @@  private:
 		return static_cast<RPiCameraData *>(camera->_d());
 	}
 
-	int registerCamera(MediaDevice *unicam, MediaDevice *isp);
+	int registerCamera(MediaDevice *unicam, MediaDevice *isp, MediaEntity *sensorEntity);
 	int queueAllBuffers(Camera *camera);
 	int prepareBuffers(Camera *camera);
 	void freeBuffers(Camera *camera);
@@ -1009,16 +1009,28 @@  bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
 		return false;
 	}
 
-	int ret = registerCamera(unicamDevice, ispDevice);
-	if (ret) {
-		LOG(RPI, Error) << "Failed to register camera: " << ret;
-		return false;
+	/*
+	 * The loop below is used to register multiple cameras behind one or more
+	 * video mux devices that are attaced to a particular Unicam instance.
+	 * Obviously these cameras cannot be used simultaneously.
+	 */
+	unsigned int numCameras = 0;
+	for (MediaEntity *entity : unicamDevice->entities()) {
+		if (entity->function() != MEDIA_ENT_F_CAM_SENSOR)
+			continue;
+
+		int ret = registerCamera(unicamDevice, ispDevice, entity);
+		if (ret)
+			LOG(RPI, Error) << "Failed to register camera "
+					<< entity->name() << ": " << ret;
+		else
+			numCameras++;
 	}
 
-	return true;
+	return !!numCameras;
 }
 
-int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp)
+int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, MediaEntity *sensorEntity)
 {
 	std::unique_ptr<RPiCameraData> data = std::make_unique<RPiCameraData>(this);
 
@@ -1059,14 +1071,7 @@  int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp)
 	data->isp_[Isp::Output1].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
 	data->isp_[Isp::Stats].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
 
-	/* Identify the sensor. */
-	for (MediaEntity *entity : unicam->entities()) {
-		if (entity->function() == MEDIA_ENT_F_CAM_SENSOR) {
-			data->sensor_ = std::make_unique<CameraSensor>(entity);
-			break;
-		}
-	}
-
+	data->sensor_ = std::make_unique<CameraSensor>(sensorEntity);
 	if (!data->sensor_)
 		return -EINVAL;