[libcamera-devel] [PATCH v1] gstreamer: Added virtual functions needed to support request pads

Nicolas Dufresne nicolas at ndufresne.ca
Tue Jun 8 13:54:32 CEST 2021


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 at 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,




More information about the libcamera-devel mailing list