[libcamera-devel,v3,19/27] gst: libcamerasrc: Allocate and release buffers

Message ID 20200306202637.525587-20-nicolas@ndufresne.ca
State Accepted
Headers show
Series
  • GStreamer Element for libcamera
Related show

Commit Message

Nicolas Dufresne March 6, 2020, 8:26 p.m. UTC
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>

Setup the allocation and the release of buffers in the
element. We have one pooling GstAllocator that wraps the
FrameBufferAllocator and tracks the lifetime of FrameBuffer
objects. Then, for each pad we have a GstBufferPool object
which is only used to avoid re-allocating the GstBuffer
structure every time we push a buffer.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 src/gstreamer/gstlibcamerasrc.cpp | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Laurent Pinchart March 6, 2020, 8:55 p.m. UTC | #1
Hi Nicolas,

Thank you for the patch.

On Fri, Mar 06, 2020 at 03:26:29PM -0500, Nicolas Dufresne wrote:
> From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> 
> Setup the allocation and the release of buffers in the
> element. We have one pooling GstAllocator that wraps the
> FrameBufferAllocator and tracks the lifetime of FrameBuffer
> objects. Then, for each pad we have a GstBufferPool object
> which is only used to avoid re-allocating the GstBuffer
> structure every time we push a buffer.
> 
> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  src/gstreamer/gstlibcamerasrc.cpp | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> index 540a094..5ffc004 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -19,7 +19,9 @@
>  #include <libcamera/camera.h>
>  #include <libcamera/camera_manager.h>
>  
> +#include "gstlibcameraallocator.h"
>  #include "gstlibcamerapad.h"
> +#include "gstlibcamerapool.h"
>  #include "gstlibcamera-utils.h"
>  
>  using namespace libcamera;
> @@ -44,6 +46,7 @@ struct _GstLibcameraSrc {
>  	gchar *camera_name;
>  
>  	GstLibcameraSrcState *state;
> +	GstLibcameraAllocator *allocator;
>  };
>  
>  enum {
> @@ -221,6 +224,23 @@ gst_libcamera_src_task_enter(GstTask *task, GThread *thread, gpointer user_data)
>  		return;
>  	}
>  
> +	self->allocator = gst_libcamera_allocator_new(state->cam_);
> +	if (!self->allocator) {
> +		GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT,
> +				  ("Failed to allocate memory"),
> +				  ("gst_libcamera_allocator_new() failed."));
> +		gst_task_stop(task);
> +		return;
> +	}
> +
> +	for (gsize i = 0; i < state->srcpads_.size(); i++) {
> +		GstPad *srcpad = state->srcpads_[i];
> +		const StreamConfiguration &stream_cfg = state->config_->at(i);
> +		GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator,
> +								stream_cfg.stream());
> +		gst_libcamera_pad_set_pool(srcpad, pool);
> +	}
> +
>  done:
>  	switch (flow_ret) {
>  	case GST_FLOW_NOT_NEGOTIATED:
> @@ -236,8 +256,14 @@ static void
>  gst_libcamera_src_task_leave(GstTask *task, GThread *thread, gpointer user_data)
>  {
>  	GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);
> +	GstLibcameraSrcState *state = self->state;
>  
>  	GST_DEBUG_OBJECT(self, "Streaming thread is about to stop");
> +
> +	for (GstPad *srcpad : state->srcpads_)
> +		gst_libcamera_pad_set_pool(srcpad, NULL);
> +
> +	g_clear_object(&self->allocator);
>  }
>  
>  static void
> @@ -246,6 +272,8 @@ gst_libcamera_src_close(GstLibcameraSrc *self)
>  	GstLibcameraSrcState *state = self->state;
>  	gint ret;
>  
> +	GST_DEBUG_OBJECT(self, "Releasing resources");
> +
>  	ret = state->cam_->release();
>  	if (ret) {
>  		GST_ELEMENT_WARNING(self, RESOURCE, BUSY,
Laurent Pinchart March 6, 2020, 9 p.m. UTC | #2
Hi Nicolas,

On Fri, Mar 06, 2020 at 10:55:35PM +0200, Laurent Pinchart wrote:
> On Fri, Mar 06, 2020 at 03:26:29PM -0500, Nicolas Dufresne wrote:
> > From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> > 
> > Setup the allocation and the release of buffers in the
> > element. We have one pooling GstAllocator that wraps the
> > FrameBufferAllocator and tracks the lifetime of FrameBuffer
> > objects. Then, for each pad we have a GstBufferPool object
> > which is only used to avoid re-allocating the GstBuffer
> > structure every time we push a buffer.
> > 
> > Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> > ---
> >  src/gstreamer/gstlibcamerasrc.cpp | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> > 
> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> > index 540a094..5ffc004 100644
> > --- a/src/gstreamer/gstlibcamerasrc.cpp
> > +++ b/src/gstreamer/gstlibcamerasrc.cpp
> > @@ -19,7 +19,9 @@
> >  #include <libcamera/camera.h>
> >  #include <libcamera/camera_manager.h>
> >  
> > +#include "gstlibcameraallocator.h"
> >  #include "gstlibcamerapad.h"
> > +#include "gstlibcamerapool.h"
> >  #include "gstlibcamera-utils.h"
> >  
> >  using namespace libcamera;
> > @@ -44,6 +46,7 @@ struct _GstLibcameraSrc {
> >  	gchar *camera_name;
> >  
> >  	GstLibcameraSrcState *state;
> > +	GstLibcameraAllocator *allocator;
> >  };
> >  
> >  enum {
> > @@ -221,6 +224,23 @@ gst_libcamera_src_task_enter(GstTask *task, GThread *thread, gpointer user_data)
> >  		return;
> >  	}
> >  
> > +	self->allocator = gst_libcamera_allocator_new(state->cam_);
> > +	if (!self->allocator) {
> > +		GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT,
> > +				  ("Failed to allocate memory"),
> > +				  ("gst_libcamera_allocator_new() failed."));
> > +		gst_task_stop(task);
> > +		return;
> > +	}
> > +
> > +	for (gsize i = 0; i < state->srcpads_.size(); i++) {
> > +		GstPad *srcpad = state->srcpads_[i];
> > +		const StreamConfiguration &stream_cfg = state->config_->at(i);
> > +		GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator,
> > +								stream_cfg.stream());
> > +		gst_libcamera_pad_set_pool(srcpad, pool);
> > +	}
> > +
> >  done:
> >  	switch (flow_ret) {
> >  	case GST_FLOW_NOT_NEGOTIATED:
> > @@ -236,8 +256,14 @@ static void
> >  gst_libcamera_src_task_leave(GstTask *task, GThread *thread, gpointer user_data)
> >  {
> >  	GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);
> > +	GstLibcameraSrcState *state = self->state;
> >  
> >  	GST_DEBUG_OBJECT(self, "Streaming thread is about to stop");
> > +
> > +	for (GstPad *srcpad : state->srcpads_)
> > +		gst_libcamera_pad_set_pool(srcpad, NULL);

I forgot

s/NULL/nullptr/

This should be the last one :-)

> > +
> > +	g_clear_object(&self->allocator);
> >  }
> >  
> >  static void
> > @@ -246,6 +272,8 @@ gst_libcamera_src_close(GstLibcameraSrc *self)
> >  	GstLibcameraSrcState *state = self->state;
> >  	gint ret;
> >  
> > +	GST_DEBUG_OBJECT(self, "Releasing resources");
> > +
> >  	ret = state->cam_->release();
> >  	if (ret) {
> >  		GST_ELEMENT_WARNING(self, RESOURCE, BUSY,

Patch

diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 540a094..5ffc004 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -19,7 +19,9 @@ 
 #include <libcamera/camera.h>
 #include <libcamera/camera_manager.h>
 
+#include "gstlibcameraallocator.h"
 #include "gstlibcamerapad.h"
+#include "gstlibcamerapool.h"
 #include "gstlibcamera-utils.h"
 
 using namespace libcamera;
@@ -44,6 +46,7 @@  struct _GstLibcameraSrc {
 	gchar *camera_name;
 
 	GstLibcameraSrcState *state;
+	GstLibcameraAllocator *allocator;
 };
 
 enum {
@@ -221,6 +224,23 @@  gst_libcamera_src_task_enter(GstTask *task, GThread *thread, gpointer user_data)
 		return;
 	}
 
+	self->allocator = gst_libcamera_allocator_new(state->cam_);
+	if (!self->allocator) {
+		GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT,
+				  ("Failed to allocate memory"),
+				  ("gst_libcamera_allocator_new() failed."));
+		gst_task_stop(task);
+		return;
+	}
+
+	for (gsize i = 0; i < state->srcpads_.size(); i++) {
+		GstPad *srcpad = state->srcpads_[i];
+		const StreamConfiguration &stream_cfg = state->config_->at(i);
+		GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator,
+								stream_cfg.stream());
+		gst_libcamera_pad_set_pool(srcpad, pool);
+	}
+
 done:
 	switch (flow_ret) {
 	case GST_FLOW_NOT_NEGOTIATED:
@@ -236,8 +256,14 @@  static void
 gst_libcamera_src_task_leave(GstTask *task, GThread *thread, gpointer user_data)
 {
 	GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);
+	GstLibcameraSrcState *state = self->state;
 
 	GST_DEBUG_OBJECT(self, "Streaming thread is about to stop");
+
+	for (GstPad *srcpad : state->srcpads_)
+		gst_libcamera_pad_set_pool(srcpad, NULL);
+
+	g_clear_object(&self->allocator);
 }
 
 static void
@@ -246,6 +272,8 @@  gst_libcamera_src_close(GstLibcameraSrc *self)
 	GstLibcameraSrcState *state = self->state;
 	gint ret;
 
+	GST_DEBUG_OBJECT(self, "Releasing resources");
+
 	ret = state->cam_->release();
 	if (ret) {
 		GST_ELEMENT_WARNING(self, RESOURCE, BUSY,