gstreamer: Added virtual functions needed to support request pads
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> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
committed by
Paul Elder
parent
e4e3af642e
commit
53a0d80af0
@@ -361,10 +361,12 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
|
|||||||
GST_DEBUG_OBJECT(self, "Streaming thread has started");
|
GST_DEBUG_OBJECT(self, "Streaming thread has started");
|
||||||
|
|
||||||
guint group_id = gst_util_group_id_next();
|
guint group_id = gst_util_group_id_next();
|
||||||
|
gint stream_id_num = 0;
|
||||||
StreamRoles roles;
|
StreamRoles roles;
|
||||||
for (GstPad *srcpad : state->srcpads_) {
|
for (GstPad *srcpad : state->srcpads_) {
|
||||||
/* Create stream-id and push stream-start. */
|
/* 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);
|
GstEvent *event = gst_event_new_stream_start(stream_id);
|
||||||
gst_event_set_group_id(event, group_id);
|
gst_event_set_group_id(event, group_id);
|
||||||
gst_pad_push_event(srcpad, event);
|
gst_pad_push_event(srcpad, event);
|
||||||
@@ -640,6 +642,53 @@ gst_libcamera_src_init(GstLibcameraSrc *self)
|
|||||||
self->state = state;
|
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
|
static void
|
||||||
gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
|
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->get_property = gst_libcamera_src_get_property;
|
||||||
object_class->finalize = gst_libcamera_src_finalize;
|
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;
|
element_class->change_state = gst_libcamera_src_change_state;
|
||||||
|
|
||||||
gst_element_class_set_metadata(element_class,
|
gst_element_class_set_metadata(element_class,
|
||||||
|
|||||||
Reference in New Issue
Block a user