[v3] libcamerasrc: Report camera properties as device properties
diff mbox series

Message ID 20250704053424.23718-1-uajain@igalia.com
State New
Headers show
Series
  • [v3] libcamerasrc: Report camera properties as device properties
Related show

Commit Message

Umang Jain July 4, 2025, 5:34 a.m. UTC
Iterate over all libcamera camera properties and report them as
device properties. The values are reported as strings, including the ones
which enum types, for better readability.

Signed-off-by: Umang Jain <uajain@igalia.com>
---
Changes in v3:
- Iterate over all camera properties and report everything.
---
 src/gstreamer/gstlibcameraprovider.cpp | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Comments

Laurent Pinchart July 4, 2025, 9:46 a.m. UTC | #1
Hi Umang,

Thank you for the patch.

On Fri, Jul 04, 2025 at 11:04:24AM +0530, Umang Jain wrote:
> Iterate over all libcamera camera properties and report them as
> device properties. The values are reported as strings, including the ones
> which enum types, for better readability.
> 
> Signed-off-by: Umang Jain <uajain@igalia.com>
> ---
> Changes in v3:
> - Iterate over all camera properties and report everything.
> ---
>  src/gstreamer/gstlibcameraprovider.cpp | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp
> index 5da96ea3..237baeb2 100644
> --- a/src/gstreamer/gstlibcameraprovider.cpp
> +++ b/src/gstreamer/gstlibcameraprovider.cpp
> @@ -12,6 +12,7 @@
>  
>  #include <libcamera/camera.h>
>  #include <libcamera/camera_manager.h>
> +#include <libcamera/property_ids.h>
>  
>  #include "gstlibcamerasrc.h"
>  #include "gstlibcamera-utils.h"
> @@ -130,6 +131,7 @@ gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)
>  {
>  	static const std::array roles{ StreamRole::VideoRecording };
>  	g_autoptr(GstCaps) caps = gst_caps_new_empty();
> +	g_autoptr(GstStructure) props = gst_structure_new_empty("camera-properties");

You can move this just before the for loop below.

>  	const gchar *name = camera->id().c_str();
>  
>  	std::unique_ptr<CameraConfiguration> config = camera->generateConfiguration(roles);
> @@ -144,12 +146,34 @@ gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)
>  			gst_caps_append(caps, sub_caps);
>  	}
>  
> +	for (const auto &[key, value] : camera->properties()) {
> +		const ControlId *id = properties::properties.at(key);
> +
> +		g_autoptr(GString) prop_str = g_string_new("api.libcamera.");
> +		g_string_append(prop_str, id->name().c_str());
> +
> +		/* Use string names for enum values for better readability */

s/readability/readability./

> +		if (value.type() == ControlTypeInteger32) {
> +			int32_t val = value.get<int32_t>();
> +			const auto &it = id->enumerators().find(val);
> +			if (it != id->enumerators().end()) {
> +				gst_structure_set(props, prop_str->str, G_TYPE_STRING,
> +						  it->second.c_str(), nullptr);
> +				continue;
> +			}
> +		}
> +
> +		gst_structure_set(props, prop_str->str, G_TYPE_STRING,
> +				  value.toString().c_str(), nullptr);

Instead of using a libcamera-specific internal string representation of
the value, it should be converted to native GStreamer types. Numerical
properties should use a numerical type, rectangles should be converted
to the native GStreamer representation, ...

Nicolas, any opinion on this ?

> +	}
> +
>  	return GST_DEVICE(g_object_new(GST_TYPE_LIBCAMERA_DEVICE,
>  				       /* \todo Use a unique identifier instead of camera name. */
>  				       "name", name,
>  				       "display-name", name,
>  				       "caps", caps,
>  				       "device-class", "Source/Video",
> +				       "properties", props,
>  				       nullptr));
>  }
>

Patch
diff mbox series

diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp
index 5da96ea3..237baeb2 100644
--- a/src/gstreamer/gstlibcameraprovider.cpp
+++ b/src/gstreamer/gstlibcameraprovider.cpp
@@ -12,6 +12,7 @@ 
 
 #include <libcamera/camera.h>
 #include <libcamera/camera_manager.h>
+#include <libcamera/property_ids.h>
 
 #include "gstlibcamerasrc.h"
 #include "gstlibcamera-utils.h"
@@ -130,6 +131,7 @@  gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)
 {
 	static const std::array roles{ StreamRole::VideoRecording };
 	g_autoptr(GstCaps) caps = gst_caps_new_empty();
+	g_autoptr(GstStructure) props = gst_structure_new_empty("camera-properties");
 	const gchar *name = camera->id().c_str();
 
 	std::unique_ptr<CameraConfiguration> config = camera->generateConfiguration(roles);
@@ -144,12 +146,34 @@  gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)
 			gst_caps_append(caps, sub_caps);
 	}
 
+	for (const auto &[key, value] : camera->properties()) {
+		const ControlId *id = properties::properties.at(key);
+
+		g_autoptr(GString) prop_str = g_string_new("api.libcamera.");
+		g_string_append(prop_str, id->name().c_str());
+
+		/* Use string names for enum values for better readability */
+		if (value.type() == ControlTypeInteger32) {
+			int32_t val = value.get<int32_t>();
+			const auto &it = id->enumerators().find(val);
+			if (it != id->enumerators().end()) {
+				gst_structure_set(props, prop_str->str, G_TYPE_STRING,
+						  it->second.c_str(), nullptr);
+				continue;
+			}
+		}
+
+		gst_structure_set(props, prop_str->str, G_TYPE_STRING,
+				  value.toString().c_str(), nullptr);
+	}
+
 	return GST_DEVICE(g_object_new(GST_TYPE_LIBCAMERA_DEVICE,
 				       /* \todo Use a unique identifier instead of camera name. */
 				       "name", name,
 				       "display-name", name,
 				       "caps", caps,
 				       "device-class", "Source/Video",
+				       "properties", props,
 				       nullptr));
 }