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

Kieran Bingham kieran.bingham at ideasonboard.com
Tue Jul 14 16:08:58 CEST 2020


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 at 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)
> 

-- 
Regards
--
Kieran


More information about the libcamera-devel mailing list