From 27cece6653e530c4dfd72a35d745e49460f02e54 Mon Sep 17 00:00:00 2001 From: Jaslo Ziska Date: Mon, 21 Oct 2024 18:45:33 +0200 Subject: gstreamer: Generate controls from control_ids_*.yaml files This commit implements gstreamer controls for the libcamera element by generating the controls from the control_ids_*.yaml files using a new gen-gst-controls.py script. The appropriate meson files are also changed to automatically run the script when building. The gen-gst-controls.py script works similar to the gen-controls.py script by parsing the control_ids_*.yaml files and generating C++ code for each exposed control. For the controls to be used as gstreamer properties the type for each control needs to be translated to the appropriate glib type and a GEnumValue is generated for each enum control. Then a g_object_install_property(), _get_property() and _set_property() function is generated for each control. The vendor controls get prefixed with "$vendor-" in the final gstreamer property name. The C++ code generated by the gen-gst-controls.py script is written into the template gstlibcamerasrc-controls.cpp.in file. The matching gstlibcamerasrc-controls.h header defines the GstCameraControls class which handles the installation of the gstreamer properties as well as keeping track of the control values and setting and getting the controls. The content of these functions is generated in the Python script. Finally the libcamerasrc element itself is edited to make use of the new GstCameraControls class. The way this works is by defining a PROP_LAST enum variant which is passed to the installProperties() function so the properties are defined with the appropriate offset. When getting or setting a property PROP_LAST is subtracted from the requested property to translate the control back into a libcamera::controls:: enum variant. Signed-off-by: Jaslo Ziska Reviewed-by: Nicolas Dufresne Signed-off-by: Kieran Bingham --- src/gstreamer/gstlibcamerasrc.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/gstreamer/gstlibcamerasrc.cpp') diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 40b787c8..8efa25f4 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -37,10 +37,11 @@ #include +#include "gstlibcamera-controls.h" +#include "gstlibcamera-utils.h" #include "gstlibcameraallocator.h" #include "gstlibcamerapad.h" #include "gstlibcamerapool.h" -#include "gstlibcamera-utils.h" using namespace libcamera; @@ -128,6 +129,7 @@ struct GstLibcameraSrcState { ControlList initControls_; guint group_id_; + GstCameraControls controls_; int queueRequest(); void requestCompleted(Request *request); @@ -153,6 +155,7 @@ struct _GstLibcameraSrc { enum { PROP_0, PROP_CAMERA_NAME, + PROP_LAST }; static void gst_libcamera_src_child_proxy_init(gpointer g_iface, @@ -183,6 +186,9 @@ int GstLibcameraSrcState::queueRequest() if (!request) return -ENOMEM; + /* Apply controls */ + controls_.applyControls(request); + std::unique_ptr wrap = std::make_unique(std::move(request)); @@ -226,6 +232,9 @@ GstLibcameraSrcState::requestCompleted(Request *request) { GLibLocker locker(&lock_); + + controls_.readMetadata(request); + wrap = std::move(queuedRequests_.front()); queuedRequests_.pop(); } @@ -408,6 +417,8 @@ gst_libcamera_src_open(GstLibcameraSrc *self) return false; } + self->state->controls_.setCamera(cam); + cam->requestCompleted.connect(self->state, &GstLibcameraSrcState::requestCompleted); /* No need to lock here, we didn't start our threads yet. */ @@ -722,6 +733,7 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, { GLibLocker lock(GST_OBJECT(object)); GstLibcameraSrc *self = GST_LIBCAMERA_SRC(object); + GstLibcameraSrcState *state = self->state; switch (prop_id) { case PROP_CAMERA_NAME: @@ -729,7 +741,8 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, self->camera_name = g_value_dup_string(value); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + if (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec)) + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } @@ -740,13 +753,15 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, { GLibLocker lock(GST_OBJECT(object)); GstLibcameraSrc *self = GST_LIBCAMERA_SRC(object); + GstLibcameraSrcState *state = self->state; switch (prop_id) { case PROP_CAMERA_NAME: g_value_set_string(value, self->camera_name); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + if (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec)) + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } @@ -947,6 +962,7 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + GstCameraControls::installProperties(object_class, PROP_LAST); } /* GstChildProxy implementation */ -- cgit v1.2.1