[libcamera-devel,v4,04/31] libcamera: ipu3: Set stream configuration from sensor

Message ID 20190320163055.22056-5-jacopo@jmondi.org
State Superseded
Headers show
Series
  • libcamera: ipu3: Add ImgU support + multiple streams
Related show

Commit Message

Jacopo Mondi March 20, 2019, 4:30 p.m. UTC
Inspect all image sizes provided by the sensor and select the
biggest of them, associated with an image format code supported by the
CIO2 unit.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 47 +++++++++++++++++++---------
 1 file changed, 32 insertions(+), 15 deletions(-)

Comments

Laurent Pinchart March 21, 2019, 8:59 a.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Wed, Mar 20, 2019 at 05:30:28PM +0100, Jacopo Mondi wrote:
> Inspect all image sizes provided by the sensor and select the
> biggest of them, associated with an image format code supported by the
> CIO2 unit.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  src/libcamera/pipeline/ipu3/ipu3.cpp | 47 +++++++++++++++++++---------
>  1 file changed, 32 insertions(+), 15 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 2602f89617a3..1df074553fd1 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -5,6 +5,7 @@
>   * ipu3.cpp - Pipeline handler for Intel IPU3
>   */
>  
> +#include <iomanip>
>  #include <memory>
>  #include <vector>
>  
> @@ -74,6 +75,8 @@ private:
>  		Stream stream_;
>  	};
>  
> +	static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
> +
>  	IPU3CameraData *cameraData(const Camera *camera)
>  	{
>  		return static_cast<IPU3CameraData *>(
> @@ -106,26 +109,40 @@ std::map<Stream *, StreamConfiguration>
>  PipelineHandlerIPU3::streamConfiguration(Camera *camera,
>  					 std::set<Stream *> &streams)
>  {
> -	IPU3CameraData *data = cameraData(camera);
>  	std::map<Stream *, StreamConfiguration> configs;
> -	V4L2SubdeviceFormat format = {};
> +	IPU3CameraData *data = cameraData(camera);

Nitpicking, there's not need to reorder data and configs.

> +	V4L2Subdevice *sensor = data->sensor_;
> +	StreamConfiguration *config = &configs[&data->stream_];
> +	unsigned int bestSize = 0;
>  
> -	/*
> -	 * FIXME: As of now, return the image format reported by the sensor.
> -	 * In future good defaults should be provided for each stream.
> -	 */
> -	if (data->sensor_->getFormat(0, &format)) {
> -		LOG(IPU3, Error) << "Failed to create stream configurations";
> -		return configs;
> +	const FormatEnum formats = sensor->formats(0);

The const keyword isn't really needed.

> +	for (auto it = formats.begin(); it != formats.end(); ++it) {

	for (auto it : formats)

> +		int cio2Code = mediaBusToCIO2Format(it->first);
> +		if (cio2Code == -EINVAL)
> +			continue;
> +
> +		for (const SizeRange &range : it->second) {
> +			unsigned int frameSize = range.maxWidth
> +					       * range.maxHeight;
> +
> +			/*  Use the largest image size the sensor provides. */
> +			if (frameSize < bestSize)
> +				continue;
> +
> +			bestSize = frameSize;
> +
> +			config->width = range.maxWidth;
> +			config->height = range.maxHeight;
> +			config->pixelFormat = cio2Code;
> +		}
>  	}

The formats enumerated by the sensor shouldn't vary, you can do this
when creating the camera and cache the result.

>  
> -	StreamConfiguration config = {};
> -	config.width = format.width;
> -	config.height = format.height;
> -	config.pixelFormat = V4L2_PIX_FMT_IPU3_SGRBG10;
> -	config.bufferCount = 4;
> +	config->bufferCount = IPU3_BUFFER_COUNT;
>  
> -	configs[&data->stream_] = config;
> +	LOG(IPU3, Debug)
> +		<< "Stream format set to: " << config->width << "x"
> +		<< config->height << "- 0x" << std::hex << std::setfill('0')
> +		<< std::setw(4) << config->pixelFormat;

Shame we can't use the toString() helpers here.

>  
>  	return configs;
>  }

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 2602f89617a3..1df074553fd1 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -5,6 +5,7 @@ 
  * ipu3.cpp - Pipeline handler for Intel IPU3
  */
 
+#include <iomanip>
 #include <memory>
 #include <vector>
 
@@ -74,6 +75,8 @@  private:
 		Stream stream_;
 	};
 
+	static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
+
 	IPU3CameraData *cameraData(const Camera *camera)
 	{
 		return static_cast<IPU3CameraData *>(
@@ -106,26 +109,40 @@  std::map<Stream *, StreamConfiguration>
 PipelineHandlerIPU3::streamConfiguration(Camera *camera,
 					 std::set<Stream *> &streams)
 {
-	IPU3CameraData *data = cameraData(camera);
 	std::map<Stream *, StreamConfiguration> configs;
-	V4L2SubdeviceFormat format = {};
+	IPU3CameraData *data = cameraData(camera);
+	V4L2Subdevice *sensor = data->sensor_;
+	StreamConfiguration *config = &configs[&data->stream_];
+	unsigned int bestSize = 0;
 
-	/*
-	 * FIXME: As of now, return the image format reported by the sensor.
-	 * In future good defaults should be provided for each stream.
-	 */
-	if (data->sensor_->getFormat(0, &format)) {
-		LOG(IPU3, Error) << "Failed to create stream configurations";
-		return configs;
+	const FormatEnum formats = sensor->formats(0);
+	for (auto it = formats.begin(); it != formats.end(); ++it) {
+		int cio2Code = mediaBusToCIO2Format(it->first);
+		if (cio2Code == -EINVAL)
+			continue;
+
+		for (const SizeRange &range : it->second) {
+			unsigned int frameSize = range.maxWidth
+					       * range.maxHeight;
+
+			/*  Use the largest image size the sensor provides. */
+			if (frameSize < bestSize)
+				continue;
+
+			bestSize = frameSize;
+
+			config->width = range.maxWidth;
+			config->height = range.maxHeight;
+			config->pixelFormat = cio2Code;
+		}
 	}
 
-	StreamConfiguration config = {};
-	config.width = format.width;
-	config.height = format.height;
-	config.pixelFormat = V4L2_PIX_FMT_IPU3_SGRBG10;
-	config.bufferCount = 4;
+	config->bufferCount = IPU3_BUFFER_COUNT;
 
-	configs[&data->stream_] = config;
+	LOG(IPU3, Debug)
+		<< "Stream format set to: " << config->width << "x"
+		<< config->height << "- 0x" << std::hex << std::setfill('0')
+		<< std::setw(4) << config->pixelFormat;
 
 	return configs;
 }