[libcamera-devel,4/9] libcamera: pipeline: vivid: Generate and validate StreamConfigurations

Message ID 20200713132451.2944673-5-kieran.bingham@ideasonboard.com
State Awaiting Upstream
Headers show
Series
  • Introduce a new PipelineHandler
Related show

Commit Message

Kieran Bingham July 13, 2020, 1:24 p.m. UTC
Implement the support for Generating and Validating the streams the
Camera can provide.

Vivid is a simple case with only a single stream.

Test the configurations can be generated and reported with cam -I:

"""
LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./src/cam/cam -c 1 -I
[232:02:09.633067174] [2882911]  INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home//libcamera/build-vivid/src/ipa' to the IPA search path
[232:02:09.633332451] [2882911]  WARN IPAManager ipa_manager.cpp:147 No IPA found in '/usr/local/lib/x86_64-linux-gnu/libcamera'
[232:02:09.633373414] [2882911]  INFO Camera camera_manager.cpp:283 libcamera v0.0.11+714-d1ebd889-dirty
Using camera vivid
0: 1280x720-BGR888
 * Pixelformat: NV21 (320x180)-(3840x2160)/(+0,+0)
  - 320x180
  - 640x360
  - 640x480
  - 1280x720
  - 1920x1080
  - 3840x2160
 * Pixelformat: NV12 (320x180)-(3840x2160)/(+0,+0)
  - 320x180
  - 640x360
  - 640x480
  - 1280x720
  - 1920x1080
  - 3840x2160
 * Pixelformat: BGRA8888 (320x180)-(3840x2160)/(+0,+0)
  - 320x180
  - 640x360
  - 640x480
  - 1280x720
  - 1920x1080
  - 3840x2160
 * Pixelformat: RGBA8888 (320x180)-(3840x2160)/(+0,+0)
  - 320x180
  - 640x360
  - 640x480
  - 1280x720
  - 1920x1080
  - 3840x2160

"""

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/libcamera/pipeline/vivid/vivid.cpp | 74 +++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

Comments

Kieran Bingham July 14, 2020, 2:08 p.m. UTC | #1
Hi Kieran,

On 13/07/2020 14:24, Kieran Bingham wrote:
> Implement the support for Generating and Validating the streams the
> Camera can provide.
> 
> Vivid is a simple case with only a single stream.
> 
> Test the configurations can be generated and reported with cam -I:
> 
> """
> LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./src/cam/cam -c 1 -I
> [232:02:09.633067174] [2882911]  INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home//libcamera/build-vivid/src/ipa' to the IPA search path
> [232:02:09.633332451] [2882911]  WARN IPAManager ipa_manager.cpp:147 No IPA found in '/usr/local/lib/x86_64-linux-gnu/libcamera'
> [232:02:09.633373414] [2882911]  INFO Camera camera_manager.cpp:283 libcamera v0.0.11+714-d1ebd889-dirty
> Using camera vivid
> 0: 1280x720-BGR888
>  * Pixelformat: NV21 (320x180)-(3840x2160)/(+0,+0)
>   - 320x180
>   - 640x360
>   - 640x480
>   - 1280x720
>   - 1920x1080
>   - 3840x2160
>  * Pixelformat: NV12 (320x180)-(3840x2160)/(+0,+0)
>   - 320x180
>   - 640x360
>   - 640x480
>   - 1280x720
>   - 1920x1080
>   - 3840x2160
>  * Pixelformat: BGRA8888 (320x180)-(3840x2160)/(+0,+0)
>   - 320x180
>   - 640x360
>   - 640x480
>   - 1280x720
>   - 1920x1080
>   - 3840x2160
>  * Pixelformat: RGBA8888 (320x180)-(3840x2160)/(+0,+0)
>   - 320x180
>   - 640x360
>   - 640x480
>   - 1280x720
>   - 1920x1080
>   - 3840x2160
> 
> """
> 
> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>  src/libcamera/pipeline/vivid/vivid.cpp | 74 +++++++++++++++++++++++++-
>  1 file changed, 73 insertions(+), 1 deletion(-)
> 
> diff --git a/src/libcamera/pipeline/vivid/vivid.cpp b/src/libcamera/pipeline/vivid/vivid.cpp
> index a8922ce70ed4..9e95bae8bc30 100644
> --- a/src/libcamera/pipeline/vivid/vivid.cpp
> +++ b/src/libcamera/pipeline/vivid/vivid.cpp
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <libcamera/camera.h>
> +#include <libcamera/formats.h>
>  
>  #include "libcamera/internal/device_enumerator.h"
>  #include "libcamera/internal/log.h"
> @@ -63,8 +64,50 @@ public:
>  	int queueRequestDevice(Camera *camera, Request *request) override;
>  
>  	bool match(DeviceEnumerator *enumerator) override;
> +
> +private:
> +	int processControls(VividCameraData *data, Request *request);
> +
> +	VividCameraData *cameraData(const Camera *camera)
> +	{
> +		return static_cast<VividCameraData *>(
> +			PipelineHandler::cameraData(camera));
> +	}
>  };
>  
> +VividCameraConfiguration::VividCameraConfiguration()
> +	: CameraConfiguration()
> +{
> +}

Is it odd / necessary to create the constructor for the
CameraConfiguration here, I expect the CameraConfiguration constructor
would be called anyway, so we could remove this constructor...

On the other hand perhaps it's helpful to have it here as part of the
skeleton for developers adding their own more complicated components...

> +
> +CameraConfiguration::Status VividCameraConfiguration::validate()
> +{
> +	Status status = Valid;
> +
> +	if (config_.empty())
> +		return Invalid;
> +
> +	/* Cap the number of entries to the available streams. */
> +	if (config_.size() > 1) {
> +		config_.resize(1);
> +		status = Adjusted;
> +	}
> +
> +	StreamConfiguration &cfg = config_[0];
> +
> +	/* Adjust the pixel format. */
> +	const std::vector<libcamera::PixelFormat> formats = cfg.formats().pixelformats();
> +	if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {
> +		cfg.pixelFormat = cfg.formats().pixelformats()[0];
> +		LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString();
> +		status = Adjusted;
> +	}
> +
> +	cfg.bufferCount = 4;
> +
> +	return status;
> +}
> +
>  PipelineHandlerVivid::PipelineHandlerVivid(CameraManager *manager)
>  	: PipelineHandler(manager)
>  {
> @@ -73,7 +116,36 @@ PipelineHandlerVivid::PipelineHandlerVivid(CameraManager *manager)
>  CameraConfiguration *PipelineHandlerVivid::generateConfiguration(Camera *camera,
>  								 const StreamRoles &roles)
>  {
> -	return nullptr;
> +	CameraConfiguration *config = new VividCameraConfiguration();
> +	VividCameraData *data = cameraData(camera);
> +
> +	if (roles.empty())
> +		return config;
> +
> +	std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
> +		data->video_->formats();
> +	std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
> +	std::transform(v4l2Formats.begin(), v4l2Formats.end(),
> +		       std::inserter(deviceFormats, deviceFormats.begin()),
> +		       [&](const decltype(v4l2Formats)::value_type &format) {
> +			       return decltype(deviceFormats)::value_type{
> +				       format.first.toPixelFormat(),
> +				       format.second
> +			       };
> +		       });
> +
> +	StreamFormats formats(deviceFormats);
> +	StreamConfiguration cfg(formats);
> +
> +	cfg.pixelFormat = formats::BGR888;
> +	cfg.size = { 1280, 720 };
> +	cfg.bufferCount = 4;
> +
> +	config->addConfiguration(cfg);
> +
> +	config->validate();
> +
> +	return config;
>  }
>  
>  int PipelineHandlerVivid::configure(Camera *camera, CameraConfiguration *config)
>

Patch

diff --git a/src/libcamera/pipeline/vivid/vivid.cpp b/src/libcamera/pipeline/vivid/vivid.cpp
index a8922ce70ed4..9e95bae8bc30 100644
--- a/src/libcamera/pipeline/vivid/vivid.cpp
+++ b/src/libcamera/pipeline/vivid/vivid.cpp
@@ -6,6 +6,7 @@ 
  */
 
 #include <libcamera/camera.h>
+#include <libcamera/formats.h>
 
 #include "libcamera/internal/device_enumerator.h"
 #include "libcamera/internal/log.h"
@@ -63,8 +64,50 @@  public:
 	int queueRequestDevice(Camera *camera, Request *request) override;
 
 	bool match(DeviceEnumerator *enumerator) override;
+
+private:
+	int processControls(VividCameraData *data, Request *request);
+
+	VividCameraData *cameraData(const Camera *camera)
+	{
+		return static_cast<VividCameraData *>(
+			PipelineHandler::cameraData(camera));
+	}
 };
 
+VividCameraConfiguration::VividCameraConfiguration()
+	: CameraConfiguration()
+{
+}
+
+CameraConfiguration::Status VividCameraConfiguration::validate()
+{
+	Status status = Valid;
+
+	if (config_.empty())
+		return Invalid;
+
+	/* Cap the number of entries to the available streams. */
+	if (config_.size() > 1) {
+		config_.resize(1);
+		status = Adjusted;
+	}
+
+	StreamConfiguration &cfg = config_[0];
+
+	/* Adjust the pixel format. */
+	const std::vector<libcamera::PixelFormat> formats = cfg.formats().pixelformats();
+	if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {
+		cfg.pixelFormat = cfg.formats().pixelformats()[0];
+		LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString();
+		status = Adjusted;
+	}
+
+	cfg.bufferCount = 4;
+
+	return status;
+}
+
 PipelineHandlerVivid::PipelineHandlerVivid(CameraManager *manager)
 	: PipelineHandler(manager)
 {
@@ -73,7 +116,36 @@  PipelineHandlerVivid::PipelineHandlerVivid(CameraManager *manager)
 CameraConfiguration *PipelineHandlerVivid::generateConfiguration(Camera *camera,
 								 const StreamRoles &roles)
 {
-	return nullptr;
+	CameraConfiguration *config = new VividCameraConfiguration();
+	VividCameraData *data = cameraData(camera);
+
+	if (roles.empty())
+		return config;
+
+	std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
+		data->video_->formats();
+	std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
+	std::transform(v4l2Formats.begin(), v4l2Formats.end(),
+		       std::inserter(deviceFormats, deviceFormats.begin()),
+		       [&](const decltype(v4l2Formats)::value_type &format) {
+			       return decltype(deviceFormats)::value_type{
+				       format.first.toPixelFormat(),
+				       format.second
+			       };
+		       });
+
+	StreamFormats formats(deviceFormats);
+	StreamConfiguration cfg(formats);
+
+	cfg.pixelFormat = formats::BGR888;
+	cfg.size = { 1280, 720 };
+	cfg.bufferCount = 4;
+
+	config->addConfiguration(cfg);
+
+	config->validate();
+
+	return config;
 }
 
 int PipelineHandlerVivid::configure(Camera *camera, CameraConfiguration *config)