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");
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user