[libcamera-devel] [PATCH/RFC 11/12] libcamera: pipeline: uvcvideo: Validate format in UVCCameraConfiguration::validate()
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat May 18 01:10:58 CEST 2019
Hi Niklas,
Thank you for the patch.
On Sat, May 18, 2019 at 02:06:20AM +0300, Laurent Pinchart wrote:
> From: Niklas Söderlund <niklas.soderlund at ragnatech.se>
>
> Validate and potentially adjust the requested format with a list of
> discrete formats retrieved from the video device.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> src/libcamera/pipeline/uvcvideo.cpp | 44 ++++++++++++++++++++++++-----
> 1 file changed, 37 insertions(+), 7 deletions(-)
>
> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
> index 286d19b0af01..e02d5b19e82a 100644
> --- a/src/libcamera/pipeline/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo.cpp
> @@ -37,6 +37,7 @@ public:
>
> V4L2Device *video_;
> Stream stream_;
> + StreamFormats formats_;
> };
>
> class UVCCameraConfiguration : public CameraConfiguration
> @@ -45,6 +46,7 @@ public:
> UVCCameraConfiguration();
>
> Status validate() override;
> + StreamFormats formats;
You can instead store a pointer to the UVCCameraData in
UVCCameraConfiguration (see the IPU3 or RkISP1 pipeline handlers to see
how this should be done), and access the formats from there.
> };
>
> class PipelineHandlerUVC : public PipelineHandler
> @@ -96,21 +98,42 @@ CameraConfiguration::Status UVCCameraConfiguration::validate()
>
> StreamConfiguration &cfg = config_[0];
>
> - /* \todo: Validate the configuration against the device capabilities. */
> const unsigned int pixelFormat = cfg.pixelFormat;
> const Size size = cfg.size;
> + const unsigned int bufferCount = cfg.bufferCount;
>
> cfg.pixelFormat = V4L2_PIX_FMT_YUYV;
> - cfg.size = { 640, 480 };
> + if (cfg.pixelFormat != pixelFormat) {
> + LOG(UVC, Debug)
> + << "Adjusting pixel format from " << pixelFormat
> + << " to " << cfg.pixelFormat;
> + status = Adjusted;
> + }
We shouldn't hardcode the format to YUYV but instead support any pixel
format supported by the camera (or at the very least both YUYV and
MJPEG).
>
> - if (cfg.pixelFormat != pixelFormat || cfg.size != size) {
> + const std::vector<Size> &formatSizes = formats.sizes(cfg.pixelFormat);
> + cfg.size = formatSizes.front();
> + for (const Size &formatsSize : formatSizes) {
> + if (formatsSize <= size)
> + cfg.size = formatsSize;
> +
> + if (formatsSize == size)
> + break;
> + }
> +
> + if (cfg.size != size) {
> LOG(UVC, Debug)
> - << "Adjusting configuration from " << cfg.toString()
> - << " to " << cfg.size.toString() << "-YUYV";
> + << "Adjusting size from " << size.toString()
> + << " to " << cfg.size.toString();
> status = Adjusted;
> }
>
> - cfg.bufferCount = 4;
> + if (bufferCount < 4) {
> + cfg.bufferCount = 4;
> + LOG(UVC, Debug)
> + << "Adjusting buffer count from " << bufferCount
> + << " to " << cfg.bufferCount;
> + status = Adjusted;
> + }
I've left this out for now, with a \todo in one of the patches to decide
on how to handle buffers count adjustement. Let's not mix it with this
patc.
>
> return status;
> }
> @@ -123,7 +146,10 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)
> CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
> const StreamRoles &roles)
> {
> - CameraConfiguration *config = new UVCCameraConfiguration();
> + UVCCameraData *data = cameraData(camera);
> + UVCCameraConfiguration *config = new UVCCameraConfiguration();
> +
> + config->formats = data->formats_;
>
> if (!roles.empty()) {
> StreamConfiguration cfg{};
Should we pick a default configuration based on the enumerated formats ?
> @@ -242,6 +268,10 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
> if (data->video_->open())
> return false;
>
> + data->formats_ = StreamFormats(data->video_->enumerateFrameSizes({ V4L2_PIX_FMT_YUYV }));
No need for the StreamFormats(), is there ?
> + for (const Size &size : data->formats_.sizes(V4L2_PIX_FMT_YUYV))
> + LOG(UVC, Info) << size.toString();
This should be debug messages. Or if you think they're useful as info
messages, should we print all resolutions on a single line ?
> +
> data->video_->bufferReady.connect(data.get(), &UVCCameraData::bufferReady);
>
> /* Create and register the camera. */
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list