[libcamera-devel] [PATCH v6] gstreamer: Added virtual functions needed to support request pads
Nicolas Dufresne
nicolas at ndufresne.ca
Wed Jun 23 22:36:12 CEST 2021
Le samedi 19 juin 2021 à 00:02 +0530, Vedant Paranjape a écrit :
> This patch adds support for using request pads in libcamerasrc Gst
> Element. It allows a user to request multiple streams if the platform
> supports multistream output using libcamera.
>
> This was tested on Raspberry Pi 4B+ with a camera connected to CSI port.
> It can be tested by running the following command
>
> gst-launch-1.0 libcamerasrc camera-name="<camera-name-here>" name=src src.src ! queue ! videoconvert ! autovideosink src.src_0 ! queue ! videoconvert ! autovideosink
>
> Signed-off-by: Vedant Paranjape <vedantparanjape160201 at gmail.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> ---
> src/gstreamer/gstlibcamerasrc.cpp | 53 ++++++++++++++++++++++++++++++-
> 1 file changed, 52 insertions(+), 1 deletion(-)
>
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> index ccc61590..ea53c2b5 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -361,10 +361,12 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
> GST_DEBUG_OBJECT(self, "Streaming thread has started");
>
> guint group_id = gst_util_group_id_next();
> + gint stream_id_num = 0;
> StreamRoles roles;
> for (GstPad *srcpad : state->srcpads_) {
> /* Create stream-id and push stream-start. */
> - g_autofree gchar *stream_id = gst_pad_create_stream_id(srcpad, GST_ELEMENT(self), nullptr);
> + g_autofree gchar *stream_id_intermediate = g_strdup_printf("%i%i", group_id, stream_id_num++);
> + g_autofree gchar *stream_id = gst_pad_create_stream_id(srcpad, GST_ELEMENT(self), stream_id_intermediate);
> GstEvent *event = gst_event_new_stream_start(stream_id);
> gst_event_set_group_id(event, group_id);
> gst_pad_push_event(srcpad, event);
> @@ -640,6 +642,53 @@ gst_libcamera_src_init(GstLibcameraSrc *self)
> self->state = state;
> }
>
> +static GstPad *
> +gst_libcamera_src_request_new_pad(GstElement *element, GstPadTemplate *templ,
> + const gchar *name, [[maybe_unused]] const GstCaps *caps)
> +{
> + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(element);
> + g_autoptr(GstPad) pad = NULL;
> +
> + GST_DEBUG_OBJECT(self, "new request pad created");
> +
> + pad = gst_pad_new_from_template(templ, name);
> + g_object_ref_sink(pad);
> +
> + if (gst_element_add_pad(element, pad)) {
> + GLibLocker lock(GST_OBJECT(self));
> + self->state->srcpads_.push_back(reinterpret_cast<GstPad *>(g_object_ref(pad)));
> + } else {
> + GST_ELEMENT_ERROR(element, STREAM, FAILED,
> + ("Internal data stream error."),
> + ("Could not add pad to element"));
> + return NULL;
> + }
> +
> + return reinterpret_cast<GstPad *>(g_steal_pointer(&pad));
> +}
> +
> +static void
> +gst_libcamera_src_release_pad(GstElement *element, GstPad *pad)
> +{
> + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(element);
> +
> + GST_DEBUG_OBJECT(self, "Pad %" GST_PTR_FORMAT " being released", pad);
> +
> + {
> + GLibLocker lock(GST_OBJECT(self));
> + std::vector<GstPad *> &pads = self->state->srcpads_;
> + auto begin_iterator = pads.begin();
> + auto end_iterator = pads.end();
> + auto pad_iterator = std::find(begin_iterator, end_iterator, pad);
> +
> + if (pad_iterator != end_iterator) {
> + g_object_unref(*pad_iterator);
> + pads.erase(pad_iterator);
> + }
> + }
> + gst_element_remove_pad(element, pad);
> +}
> +
> static void
> gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
> {
> @@ -650,6 +699,8 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
> object_class->get_property = gst_libcamera_src_get_property;
> object_class->finalize = gst_libcamera_src_finalize;
>
> + element_class->request_new_pad = gst_libcamera_src_request_new_pad;
> + element_class->release_pad = gst_libcamera_src_release_pad;
> element_class->change_state = gst_libcamera_src_change_state;
>
> gst_element_class_set_metadata(element_class,
More information about the libcamera-devel
mailing list