[libcamera-devel,v1] gstreamer: Added virtual functions needed to support request pads
diff mbox series

Message ID 20210607170100.797671-1-vedantparanjape160201@gmail.com
State Superseded
Headers show
Series
  • [libcamera-devel,v1] gstreamer: Added virtual functions needed to support request pads
Related show

Commit Message

Vedant Paranjape June 7, 2021, 5:01 p.m. UTC
Using request pads needs virtual functions to create new request pads and
release the allocated pads.

It defines the functions gst_libcamera_src_request_new_pad() and
gst_libcamera_src_release_pad() which handle, creating and releasing
request pads. It also assigned these functions to their callback
handlers in GstLibcameraSrcClass.

This doesn't enable request pad support in gstreamer element. This is
one of the series of changes needed to make it work.

Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
---
 src/gstreamer/gstlibcamerasrc.cpp | 53 +++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

Comments

Nicolas Dufresne June 8, 2021, 11:54 a.m. UTC | #1
p.s. Add RFC in front of PATCH for in progress work.

Le lundi 07 juin 2021 à 22:31 +0530, Vedant Paranjape a écrit :
> Using request pads needs virtual functions to create new request pads and
> release the allocated pads.
> 
> It defines the functions gst_libcamera_src_request_new_pad() and
> gst_libcamera_src_release_pad() which handle, creating and releasing
> request pads. It also assigned these functions to their callback
> handlers in GstLibcameraSrcClass.
> 
> This doesn't enable request pad support in gstreamer element. This is
> one of the series of changes needed to make it work.
> 
> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
> ---
>  src/gstreamer/gstlibcamerasrc.cpp | 53 +++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
> 
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> index ccc61590..f0a4fbf0 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -640,6 +640,57 @@ 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;
> +
> +	pad = gst_pad_new_from_template(templ, name);
> +	if (G_IS_INITIALLY_UNOWNED (pad))

This is not needed, as it's always true for pads.

> +	{
> +		g_object_ref_sink(pad);
> +	}
> +	
> +	{
> +		GLibLocker lock(GST_OBJECT(self->state));
> +		self->state->srcpads_.push_back((GstPad*)g_object_ref(&pad));

Oops, & in front of pad will send a GstPad** to object_ref, the memory will
likely be corrupted after that.

> +	}
> +
> +	if (!gst_element_add_pad(element, pad))
> +	{
> +		GST_ELEMENT_ERROR (element, STREAM, FAILED,
> +			("Internal data stream error."), ("Could not add pad to element"));
> +		{
> +			GLibLocker lock(GST_OBJECT(self->state));
> +			self->state->srcpads_.pop_back();

This virtual function could be called concurrently, so you cannot assume that
it's the first one.

> +		}
> +		return NULL;		
> +	}
> +
> +	return (GstPad*)g_steal_pointer(&pad);

Use reinterpret_cast.

> +}
> +
> +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->state));
> +		auto iterator = std::find(self->state->srcpads_.begin(), self->state->srcpads_.end(), pad);
> +		if (iterator != self->state->srcpads_.end())

There is in C++ nicer way to iterate vectors. Perhaps have a look at other code.

> +		{
> +			g_object_unref(self->state->srcpads_[std::distance(self->state->srcpads_.begin(), iterator)]);
> +			self->state->srcpads_.erase(iterator);
> +		}
> +	}
> +	gst_element_remove_pad(element, pad);
> +}
> +
>  static void
>  gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
>  {
> @@ -650,6 +701,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,

Patch
diff mbox series

diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index ccc61590..f0a4fbf0 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -640,6 +640,57 @@  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;
+
+	pad = gst_pad_new_from_template(templ, name);
+	if (G_IS_INITIALLY_UNOWNED (pad))
+	{
+		g_object_ref_sink(pad);
+	}
+	
+	{
+		GLibLocker lock(GST_OBJECT(self->state));
+		self->state->srcpads_.push_back((GstPad*)g_object_ref(&pad));
+	}
+
+	if (!gst_element_add_pad(element, pad))
+	{
+		GST_ELEMENT_ERROR (element, STREAM, FAILED,
+			("Internal data stream error."), ("Could not add pad to element"));
+		{
+			GLibLocker lock(GST_OBJECT(self->state));
+			self->state->srcpads_.pop_back();
+		}
+		return NULL;		
+	}
+
+	return (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->state));
+		auto iterator = std::find(self->state->srcpads_.begin(), self->state->srcpads_.end(), pad);
+		if (iterator != self->state->srcpads_.end())
+		{
+			g_object_unref(self->state->srcpads_[std::distance(self->state->srcpads_.begin(), iterator)]);
+			self->state->srcpads_.erase(iterator);
+		}
+	}
+	gst_element_remove_pad(element, pad);
+}
+
 static void
 gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
 {
@@ -650,6 +701,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,