Message ID | 20210618183218.449146-1-vedantparanjape160201@gmail.com |
---|---|
State | Accepted |
Commit | 53a0d80af0f9983d6bc0d54b0e85403a08721488 |
Headers | show |
Series |
|
Related | show |
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@gmail.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@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,
Hi Vedant, On Sat, Jun 19, 2021 at 12:02:18AM +0530, Vedant Paranjape wrote: > 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@gmail.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.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, > -- > 2.25.1 >
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,
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@gmail.com> --- src/gstreamer/gstlibcamerasrc.cpp | 53 ++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-)