[libcamera-devel,2/3] pipeline: uvcvideo: Cache supported formats in UVCCameraData
diff mbox series

Message ID 20220903181037.1406-3-laurent.pinchart@ideasonboard.com
State Accepted
Commit f98919307e411c57f24de7587b22ac90a7850bdc
Headers show
Series
  • libcamera: Fix crash with UVC cameras that expose no supported format
Related show

Commit Message

Laurent Pinchart Sept. 3, 2022, 6:10 p.m. UTC
Populate and cache the list of supported formats in
UVCCameraData::init(), to avoid repeating the operation every time
generateConfiguration() is called.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 44 ++++++++++----------
 1 file changed, 22 insertions(+), 22 deletions(-)

Comments

Kieran Bingham Sept. 6, 2022, 9:29 a.m. UTC | #1
Quoting Laurent Pinchart via libcamera-devel (2022-09-03 19:10:36)
> Populate and cache the list of supported formats in
> UVCCameraData::init(), to avoid repeating the operation every time
> generateConfiguration() is called.
> 

Furthermore, optimize the search for the largest supported size reported
by the device by determining this while processing the supported formats
to prevent searching the list twice.

(Or otherwise...)


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

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 44 ++++++++++----------
>  1 file changed, 22 insertions(+), 22 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> index 22b67faf309e..be0fbaea508a 100644
> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> @@ -50,6 +50,7 @@ public:
>  
>         std::unique_ptr<V4L2VideoDevice> video_;
>         Stream stream_;
> +       std::map<PixelFormat, std::vector<SizeRange>> formats_;
>  
>  private:
>         bool generateId();
> @@ -186,15 +187,7 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
>         if (roles.empty())
>                 return config;
>  
> -       V4L2VideoDevice::Formats v4l2Formats = data->video_->formats();
> -       std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
> -       for (const auto &format : v4l2Formats) {
> -               PixelFormat pixelFormat = format.first.toPixelFormat();
> -               if (pixelFormat.isValid())
> -                       deviceFormats[pixelFormat] = format.second;
> -       }
> -
> -       StreamFormats formats(deviceFormats);
> +       StreamFormats formats(data->formats_);
>         StreamConfiguration cfg(formats);
>  
>         cfg.pixelFormat = formats.pixelformats().front();
> @@ -445,6 +438,26 @@ int UVCCameraData::init(MediaDevice *media)
>                 return -EINVAL;
>         }
>  
> +       /*
> +        * Populate the map of supported formats, and infer the camera sensor
> +        * resolution from the largest size it advertises.
> +        */
> +       Size resolution;
> +       for (const auto &format : video_->formats()) {
> +               PixelFormat pixelFormat = format.first.toPixelFormat();
> +               if (!pixelFormat.isValid())
> +                       continue;
> +
> +               formats_[pixelFormat] = format.second;
> +
> +               const std::vector<SizeRange> &sizeRanges = format.second;
> +               for (const SizeRange &sizeRange : sizeRanges) {
> +                       if (sizeRange.max > resolution)
> +                               resolution = sizeRange.max;
> +               }
> +       }
> +
> +       /* Populate the camera properties. */
>         properties_.set(properties::Model, utils::toAscii(media->model()));
>  
>         /*
> @@ -475,19 +488,6 @@ int UVCCameraData::init(MediaDevice *media)
>  
>         properties_.set(properties::Location, location);
>  
> -       /*
> -        * Get the current format in order to initialize the sensor array
> -        * properties.
> -        */
> -       Size resolution;
> -       for (const auto &it : video_->formats()) {
> -               const std::vector<SizeRange> &sizeRanges = it.second;
> -               for (const SizeRange &sizeRange : sizeRanges) {
> -                       if (sizeRange.max > resolution)
> -                               resolution = sizeRange.max;
> -               }
> -       }
> -
>         properties_.set(properties::PixelArraySize, resolution);
>         properties_.set(properties::PixelArrayActiveAreas, { Rectangle(resolution) });
>  
> -- 
> Regards,
> 
> Laurent Pinchart
>

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 22b67faf309e..be0fbaea508a 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -50,6 +50,7 @@  public:
 
 	std::unique_ptr<V4L2VideoDevice> video_;
 	Stream stream_;
+	std::map<PixelFormat, std::vector<SizeRange>> formats_;
 
 private:
 	bool generateId();
@@ -186,15 +187,7 @@  CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
 	if (roles.empty())
 		return config;
 
-	V4L2VideoDevice::Formats v4l2Formats = data->video_->formats();
-	std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
-	for (const auto &format : v4l2Formats) {
-		PixelFormat pixelFormat = format.first.toPixelFormat();
-		if (pixelFormat.isValid())
-			deviceFormats[pixelFormat] = format.second;
-	}
-
-	StreamFormats formats(deviceFormats);
+	StreamFormats formats(data->formats_);
 	StreamConfiguration cfg(formats);
 
 	cfg.pixelFormat = formats.pixelformats().front();
@@ -445,6 +438,26 @@  int UVCCameraData::init(MediaDevice *media)
 		return -EINVAL;
 	}
 
+	/*
+	 * Populate the map of supported formats, and infer the camera sensor
+	 * resolution from the largest size it advertises.
+	 */
+	Size resolution;
+	for (const auto &format : video_->formats()) {
+		PixelFormat pixelFormat = format.first.toPixelFormat();
+		if (!pixelFormat.isValid())
+			continue;
+
+		formats_[pixelFormat] = format.second;
+
+		const std::vector<SizeRange> &sizeRanges = format.second;
+		for (const SizeRange &sizeRange : sizeRanges) {
+			if (sizeRange.max > resolution)
+				resolution = sizeRange.max;
+		}
+	}
+
+	/* Populate the camera properties. */
 	properties_.set(properties::Model, utils::toAscii(media->model()));
 
 	/*
@@ -475,19 +488,6 @@  int UVCCameraData::init(MediaDevice *media)
 
 	properties_.set(properties::Location, location);
 
-	/*
-	 * Get the current format in order to initialize the sensor array
-	 * properties.
-	 */
-	Size resolution;
-	for (const auto &it : video_->formats()) {
-		const std::vector<SizeRange> &sizeRanges = it.second;
-		for (const SizeRange &sizeRange : sizeRanges) {
-			if (sizeRange.max > resolution)
-				resolution = sizeRange.max;
-		}
-	}
-
 	properties_.set(properties::PixelArraySize, resolution);
 	properties_.set(properties::PixelArrayActiveAreas, { Rectangle(resolution) });