[libcamera-devel,v3,3/5] android: camera_device: Make CameraDevice a shared object

Message ID 20200817202629.4277-4-email@uajain.com
State Accepted
Headers show
Series
  • android: Camera hotplug support
Related show

Commit Message

Umang Jain Aug. 17, 2020, 8:26 p.m. UTC
CameraDevice needs to be wrapper into the std::shared_ptr instead
of std::unique_ptr to enable refcounting. The refcounting will help
us to support hotplug and hot-unplug CameraHalManager operations
in the subsequent commit.

Signed-off-by: Umang Jain <email@uajain.com>
---
 src/android/camera_device.cpp      | 15 +++++++++++++++
 src/android/camera_device.h        |  7 +++++--
 src/android/camera_hal_manager.cpp |  4 ++--
 src/android/camera_hal_manager.h   |  2 +-
 4 files changed, 23 insertions(+), 5 deletions(-)

Comments

Laurent Pinchart Aug. 19, 2020, 2:40 p.m. UTC | #1
Hi Umang,

Thank you for the patch.

On Mon, Aug 17, 2020 at 08:26:39PM +0000, Umang Jain wrote:
> CameraDevice needs to be wrapper into the std::shared_ptr instead
> of std::unique_ptr to enable refcounting. The refcounting will help
> us to support hotplug and hot-unplug CameraHalManager operations
> in the subsequent commit.
> 
> Signed-off-by: Umang Jain <email@uajain.com>
> ---
>  src/android/camera_device.cpp      | 15 +++++++++++++++
>  src/android/camera_device.h        |  7 +++++--
>  src/android/camera_hal_manager.cpp |  4 ++--
>  src/android/camera_hal_manager.h   |  2 +-
>  4 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index d918350..a79bb69 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -233,6 +233,21 @@ CameraDevice::~CameraDevice()
>  		delete it.second;
>  }
>  
> +std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
> +						    const std::shared_ptr<Camera> &cam)
> +{
> +	struct Deleter : std::default_delete<CameraDevice> {
> +		void operator()(CameraDevice *camera)
> +		{
> +			delete camera;
> +		}
> +	};

The reason we have a custom deleter for the Camera class is to allow
making the destructor private. The private destructor can't be accessed
from the default deleter, so we create a custom version inside this
member function of CameraDevice, which gives it access to the
destructor.

As this is internal to the HAL, making the destructor private is a bit
overkill in my opinion. You could simplify this function to

	CameraDevice *camera = new CameraDevice(id, cam);
	return std::shared_ptr<CameraDevice>(camera);

if you made the destructor public. The constructor can stay private.

With this changed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +
> +	CameraDevice *camera = new CameraDevice(id, cam);
> +
> +	return std::shared_ptr<CameraDevice>(camera, Deleter());
> +}
> +
>  /*
>   * Initialize the camera static information.
>   * This method is called before the camera device is opened.
> diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> index 7be9e11..b149043 100644
> --- a/src/android/camera_device.h
> +++ b/src/android/camera_device.h
> @@ -47,8 +47,8 @@ struct CameraStream {
>  class CameraDevice : protected libcamera::Loggable
>  {
>  public:
> -	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
> -	~CameraDevice();
> +	static std::shared_ptr<CameraDevice> create(unsigned int id,
> +						    const std::shared_ptr<libcamera::Camera> &cam);
>  
>  	int initialize();
>  
> @@ -72,6 +72,9 @@ protected:
>  	std::string logPrefix() const override;
>  
>  private:
> +	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
> +	~CameraDevice();
> +
>  	struct Camera3RequestDescriptor {
>  		Camera3RequestDescriptor(unsigned int frameNumber,
>  					 unsigned int numBuffers);
> diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp
> index 3d6d2b4..3a744af 100644
> --- a/src/android/camera_hal_manager.cpp
> +++ b/src/android/camera_hal_manager.cpp
> @@ -64,12 +64,12 @@ int CameraHalManager::init()
>  	 */
>  	unsigned int index = 0;
>  	for (auto &cam : cameraManager_->cameras()) {
> -		CameraDevice *camera = new CameraDevice(index, cam);
> +		std::shared_ptr<CameraDevice> camera = CameraDevice::create(index, cam);
>  		ret = camera->initialize();
>  		if (ret)
>  			continue;
>  
> -		cameras_.emplace_back(camera);
> +		cameras_.emplace_back(std::move(camera));
>  		++index;
>  	}
>  
> diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h
> index a582f04..3e34d63 100644
> --- a/src/android/camera_hal_manager.h
> +++ b/src/android/camera_hal_manager.h
> @@ -36,7 +36,7 @@ private:
>  	libcamera::CameraManager *cameraManager_;
>  
>  	const camera_module_callbacks_t *callbacks_;
> -	std::vector<std::unique_ptr<CameraDevice>> cameras_;
> +	std::vector<std::shared_ptr<CameraDevice>> cameras_;
>  };
>  
>  #endif /* __ANDROID_CAMERA_MANAGER_H__ */
Niklas Söderlund Aug. 20, 2020, 7:28 a.m. UTC | #2
Hi Umang,

Thanks for your patch.

On 2020-08-17 20:26:39 +0000, Umang Jain wrote:
> CameraDevice needs to be wrapper into the std::shared_ptr instead
> of std::unique_ptr to enable refcounting. The refcounting will help
> us to support hotplug and hot-unplug CameraHalManager operations
> in the subsequent commit.
> 
> Signed-off-by: Umang Jain <email@uajain.com>

With the comment about making the destructor public pointed out by 
Laurent fixed,

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>

> ---
>  src/android/camera_device.cpp      | 15 +++++++++++++++
>  src/android/camera_device.h        |  7 +++++--
>  src/android/camera_hal_manager.cpp |  4 ++--
>  src/android/camera_hal_manager.h   |  2 +-
>  4 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index d918350..a79bb69 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -233,6 +233,21 @@ CameraDevice::~CameraDevice()
>  		delete it.second;
>  }
>  
> +std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
> +						    const std::shared_ptr<Camera> &cam)
> +{
> +	struct Deleter : std::default_delete<CameraDevice> {
> +		void operator()(CameraDevice *camera)
> +		{
> +			delete camera;
> +		}
> +	};
> +
> +	CameraDevice *camera = new CameraDevice(id, cam);
> +
> +	return std::shared_ptr<CameraDevice>(camera, Deleter());
> +}
> +
>  /*
>   * Initialize the camera static information.
>   * This method is called before the camera device is opened.
> diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> index 7be9e11..b149043 100644
> --- a/src/android/camera_device.h
> +++ b/src/android/camera_device.h
> @@ -47,8 +47,8 @@ struct CameraStream {
>  class CameraDevice : protected libcamera::Loggable
>  {
>  public:
> -	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
> -	~CameraDevice();
> +	static std::shared_ptr<CameraDevice> create(unsigned int id,
> +						    const std::shared_ptr<libcamera::Camera> &cam);
>  
>  	int initialize();
>  
> @@ -72,6 +72,9 @@ protected:
>  	std::string logPrefix() const override;
>  
>  private:
> +	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
> +	~CameraDevice();
> +
>  	struct Camera3RequestDescriptor {
>  		Camera3RequestDescriptor(unsigned int frameNumber,
>  					 unsigned int numBuffers);
> diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp
> index 3d6d2b4..3a744af 100644
> --- a/src/android/camera_hal_manager.cpp
> +++ b/src/android/camera_hal_manager.cpp
> @@ -64,12 +64,12 @@ int CameraHalManager::init()
>  	 */
>  	unsigned int index = 0;
>  	for (auto &cam : cameraManager_->cameras()) {
> -		CameraDevice *camera = new CameraDevice(index, cam);
> +		std::shared_ptr<CameraDevice> camera = CameraDevice::create(index, cam);
>  		ret = camera->initialize();
>  		if (ret)
>  			continue;
>  
> -		cameras_.emplace_back(camera);
> +		cameras_.emplace_back(std::move(camera));
>  		++index;
>  	}
>  
> diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h
> index a582f04..3e34d63 100644
> --- a/src/android/camera_hal_manager.h
> +++ b/src/android/camera_hal_manager.h
> @@ -36,7 +36,7 @@ private:
>  	libcamera::CameraManager *cameraManager_;
>  
>  	const camera_module_callbacks_t *callbacks_;
> -	std::vector<std::unique_ptr<CameraDevice>> cameras_;
> +	std::vector<std::shared_ptr<CameraDevice>> cameras_;
>  };
>  
>  #endif /* __ANDROID_CAMERA_MANAGER_H__ */
> -- 
> 2.26.2
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index d918350..a79bb69 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -233,6 +233,21 @@  CameraDevice::~CameraDevice()
 		delete it.second;
 }
 
+std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
+						    const std::shared_ptr<Camera> &cam)
+{
+	struct Deleter : std::default_delete<CameraDevice> {
+		void operator()(CameraDevice *camera)
+		{
+			delete camera;
+		}
+	};
+
+	CameraDevice *camera = new CameraDevice(id, cam);
+
+	return std::shared_ptr<CameraDevice>(camera, Deleter());
+}
+
 /*
  * Initialize the camera static information.
  * This method is called before the camera device is opened.
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 7be9e11..b149043 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -47,8 +47,8 @@  struct CameraStream {
 class CameraDevice : protected libcamera::Loggable
 {
 public:
-	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
-	~CameraDevice();
+	static std::shared_ptr<CameraDevice> create(unsigned int id,
+						    const std::shared_ptr<libcamera::Camera> &cam);
 
 	int initialize();
 
@@ -72,6 +72,9 @@  protected:
 	std::string logPrefix() const override;
 
 private:
+	CameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);
+	~CameraDevice();
+
 	struct Camera3RequestDescriptor {
 		Camera3RequestDescriptor(unsigned int frameNumber,
 					 unsigned int numBuffers);
diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp
index 3d6d2b4..3a744af 100644
--- a/src/android/camera_hal_manager.cpp
+++ b/src/android/camera_hal_manager.cpp
@@ -64,12 +64,12 @@  int CameraHalManager::init()
 	 */
 	unsigned int index = 0;
 	for (auto &cam : cameraManager_->cameras()) {
-		CameraDevice *camera = new CameraDevice(index, cam);
+		std::shared_ptr<CameraDevice> camera = CameraDevice::create(index, cam);
 		ret = camera->initialize();
 		if (ret)
 			continue;
 
-		cameras_.emplace_back(camera);
+		cameras_.emplace_back(std::move(camera));
 		++index;
 	}
 
diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h
index a582f04..3e34d63 100644
--- a/src/android/camera_hal_manager.h
+++ b/src/android/camera_hal_manager.h
@@ -36,7 +36,7 @@  private:
 	libcamera::CameraManager *cameraManager_;
 
 	const camera_module_callbacks_t *callbacks_;
-	std::vector<std::unique_ptr<CameraDevice>> cameras_;
+	std::vector<std::shared_ptr<CameraDevice>> cameras_;
 };
 
 #endif /* __ANDROID_CAMERA_MANAGER_H__ */