[libcamera-devel,v4,4/7] libcamera: Add user Transform to CameraConfiguration

Message ID 20200828144110.17303-5-david.plowman@raspberrypi.com
State Accepted
Headers show
Series
  • 2D transforms
Related show

Commit Message

David Plowman Aug. 28, 2020, 2:41 p.m. UTC
Add a field to the CameraConfiguration (including the necessary
documentation) to represent a 2D transform requested by the
application. All pipeline handlers are amended to coerce this to the
Identity, marking the configuration as "adjusted" if something
different had been requested.

Pipeline handlers that support Transforms can be amended subsequently.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/camera.h                       |  3 +++
 src/libcamera/camera.cpp                         | 16 +++++++++++++++-
 src/libcamera/pipeline/ipu3/ipu3.cpp             |  5 +++++
 .../pipeline/raspberrypi/raspberrypi.cpp         |  5 +++++
 src/libcamera/pipeline/rkisp1/rkisp1.cpp         |  5 +++++
 src/libcamera/pipeline/simple/simple.cpp         |  5 +++++
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp     |  5 +++++
 src/libcamera/pipeline/vimc/vimc.cpp             |  5 +++++
 8 files changed, 48 insertions(+), 1 deletion(-)

Comments

Kieran Bingham Aug. 28, 2020, 3:33 p.m. UTC | #1
Hi David,

On 28/08/2020 15:41, David Plowman wrote:
> Add a field to the CameraConfiguration (including the necessary
> documentation) to represent a 2D transform requested by the
> application. All pipeline handlers are amended to coerce this to the
> Identity, marking the configuration as "adjusted" if something
> different had been requested.
> 
> Pipeline handlers that support Transforms can be amended subsequently.
> 
> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

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

> ---
>  include/libcamera/camera.h                       |  3 +++
>  src/libcamera/camera.cpp                         | 16 +++++++++++++++-
>  src/libcamera/pipeline/ipu3/ipu3.cpp             |  5 +++++
>  .../pipeline/raspberrypi/raspberrypi.cpp         |  5 +++++
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp         |  5 +++++
>  src/libcamera/pipeline/simple/simple.cpp         |  5 +++++
>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp     |  5 +++++
>  src/libcamera/pipeline/vimc/vimc.cpp             |  5 +++++
>  8 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
> index 272c12c..a2ee4e7 100644
> --- a/include/libcamera/camera.h
> +++ b/include/libcamera/camera.h
> @@ -17,6 +17,7 @@
>  #include <libcamera/request.h>
>  #include <libcamera/signal.h>
>  #include <libcamera/stream.h>
> +#include <libcamera/transform.h>
>  
>  namespace libcamera {
>  
> @@ -61,6 +62,8 @@ public:
>  	bool empty() const;
>  	std::size_t size() const;
>  
> +	Transform transform;
> +
>  protected:
>  	CameraConfiguration();
>  
> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
> index 4a9c19c..b547ffe 100644
> --- a/src/libcamera/camera.cpp
> +++ b/src/libcamera/camera.cpp
> @@ -93,7 +93,7 @@ LOG_DECLARE_CATEGORY(Camera)
>   * \brief Create an empty camera configuration
>   */
>  CameraConfiguration::CameraConfiguration()
> -	: config_({})
> +	: transform(Transform::Identity), config_({})
>  {
>  }
>  
> @@ -250,6 +250,20 @@ std::size_t CameraConfiguration::size() const
>  	return config_.size();
>  }
>  
> +/**
> + * \var CameraConfiguration::transform
> + * \brief User-specified transform to be applied to the image
> + *
> + * The transform is a user-specified 2D plane transform that will be applied
> + * to the camera images by the processing pipeline before being handed to
> + * the application. This is subsequent to any transform that is already
> + * required to fix up any platform-defined rotation.
> + *
> + * The usual 2D plane transforms are allowed here (horizontal/vertical
> + * flips, multiple of 90-degree rotations etc.), but the validate() function
> + * may adjust this field at its discretion if the selection is not supported.
> + */
> +
>  /**
>   * \var CameraConfiguration::config_
>   * \brief The vector of stream configurations
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 2d881fe..22b8825 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -138,6 +138,11 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/* Cap the number of entries to the available streams. */
>  	if (config_.size() > IPU3_MAX_STREAMS) {
>  		config_.resize(IPU3_MAX_STREAMS);
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index 7aace71..dc36f53 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -400,6 +400,11 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/*
>  	 * Configure the H/V flip controls based on the sensor rotation. We do
>  	 * this here so that the sensor has the correct Bayer format that will
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index 4d89aab..6f53a1d 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -478,6 +478,11 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/* Cap the number of entries to the available streams. */
>  	if (config_.size() > 1) {
>  		config_.resize(1);
> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
> index eb72e3b..10223a9 100644
> --- a/src/libcamera/pipeline/simple/simple.cpp
> +++ b/src/libcamera/pipeline/simple/simple.cpp
> @@ -438,6 +438,11 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/* Cap the number of entries to the available streams. */
>  	if (config_.size() > 1) {
>  		config_.resize(1);
> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> index bafe6f1..ba0efc8 100644
> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> @@ -109,6 +109,11 @@ CameraConfiguration::Status UVCCameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/* Cap the number of entries to the available streams. */
>  	if (config_.size() > 1) {
>  		config_.resize(1);
> diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
> index d192670..fc8085f 100644
> --- a/src/libcamera/pipeline/vimc/vimc.cpp
> +++ b/src/libcamera/pipeline/vimc/vimc.cpp
> @@ -130,6 +130,11 @@ CameraConfiguration::Status VimcCameraConfiguration::validate()
>  	if (config_.empty())
>  		return Invalid;
>  
> +	if (transform != Transform::Identity) {
> +		transform = Transform::Identity;
> +		status = Adjusted;
> +	}
> +
>  	/* Cap the number of entries to the available streams. */
>  	if (config_.size() > 1) {
>  		config_.resize(1);
>

Patch

diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 272c12c..a2ee4e7 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -17,6 +17,7 @@ 
 #include <libcamera/request.h>
 #include <libcamera/signal.h>
 #include <libcamera/stream.h>
+#include <libcamera/transform.h>
 
 namespace libcamera {
 
@@ -61,6 +62,8 @@  public:
 	bool empty() const;
 	std::size_t size() const;
 
+	Transform transform;
+
 protected:
 	CameraConfiguration();
 
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 4a9c19c..b547ffe 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -93,7 +93,7 @@  LOG_DECLARE_CATEGORY(Camera)
  * \brief Create an empty camera configuration
  */
 CameraConfiguration::CameraConfiguration()
-	: config_({})
+	: transform(Transform::Identity), config_({})
 {
 }
 
@@ -250,6 +250,20 @@  std::size_t CameraConfiguration::size() const
 	return config_.size();
 }
 
+/**
+ * \var CameraConfiguration::transform
+ * \brief User-specified transform to be applied to the image
+ *
+ * The transform is a user-specified 2D plane transform that will be applied
+ * to the camera images by the processing pipeline before being handed to
+ * the application. This is subsequent to any transform that is already
+ * required to fix up any platform-defined rotation.
+ *
+ * The usual 2D plane transforms are allowed here (horizontal/vertical
+ * flips, multiple of 90-degree rotations etc.), but the validate() function
+ * may adjust this field at its discretion if the selection is not supported.
+ */
+
 /**
  * \var CameraConfiguration::config_
  * \brief The vector of stream configurations
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 2d881fe..22b8825 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -138,6 +138,11 @@  CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > IPU3_MAX_STREAMS) {
 		config_.resize(IPU3_MAX_STREAMS);
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index 7aace71..dc36f53 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -400,6 +400,11 @@  CameraConfiguration::Status RPiCameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/*
 	 * Configure the H/V flip controls based on the sensor rotation. We do
 	 * this here so that the sensor has the correct Bayer format that will
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 4d89aab..6f53a1d 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -478,6 +478,11 @@  CameraConfiguration::Status RkISP1CameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > 1) {
 		config_.resize(1);
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index eb72e3b..10223a9 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -438,6 +438,11 @@  CameraConfiguration::Status SimpleCameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > 1) {
 		config_.resize(1);
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index bafe6f1..ba0efc8 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -109,6 +109,11 @@  CameraConfiguration::Status UVCCameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > 1) {
 		config_.resize(1);
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index d192670..fc8085f 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -130,6 +130,11 @@  CameraConfiguration::Status VimcCameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
+	if (transform != Transform::Identity) {
+		transform = Transform::Identity;
+		status = Adjusted;
+	}
+
 	/* Cap the number of entries to the available streams. */
 	if (config_.size() > 1) {
 		config_.resize(1);