summaryrefslogtreecommitdiff
path: root/src/gstreamer/gstlibcameraallocator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gstreamer/gstlibcameraallocator.cpp')
-rw-r--r--src/gstreamer/gstlibcameraallocator.cpp57
1 files changed, 39 insertions, 18 deletions
diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
index 1d5959c0..d4492d99 100644
--- a/src/gstreamer/gstlibcameraallocator.cpp
+++ b/src/gstreamer/gstlibcameraallocator.cpp
@@ -3,11 +3,13 @@
* Copyright (C) 2020, Collabora Ltd.
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
*
- * gstlibcameraallocator.cpp - GStreamer Custom Allocator
+ * GStreamer Custom Allocator
*/
#include "gstlibcameraallocator.h"
+#include <utility>
+
#include <libcamera/camera.h>
#include <libcamera/framebuffer_allocator.h>
#include <libcamera/stream.h>
@@ -52,8 +54,10 @@ FrameWrap::FrameWrap(GstAllocator *allocator, FrameBuffer *buffer,
outstandingPlanes_(0)
{
for (const FrameBuffer::Plane &plane : buffer->planes()) {
- GstMemory *mem = gst_fd_allocator_alloc(allocator, plane.fd.fd(), plane.length,
+ GstMemory *mem = gst_fd_allocator_alloc(allocator, plane.fd.get(),
+ plane.offset + plane.length,
GST_FD_MEMORY_FLAG_DONT_CLOSE);
+ gst_memory_resize(mem, plane.offset, plane.length);
gst_mini_object_set_qdata(GST_MINI_OBJECT(mem), getQuark(), this, nullptr);
GST_MINI_OBJECT(mem)->dispose = gst_libcamera_allocator_release;
g_object_unref(mem->allocator);
@@ -70,7 +74,7 @@ FrameWrap::~FrameWrap()
}
}
-GQuark FrameWrap::getQuark(void)
+GQuark FrameWrap::getQuark()
{
static gsize frame_quark = 0;
@@ -98,25 +102,33 @@ struct _GstLibcameraAllocator {
* FrameWrap.
*/
GHashTable *pools;
+ /*
+ * The camera manager represents the library, which needs to be kept
+ * alive until all the memory has been released.
+ */
+ std::shared_ptr<CameraManager> *cm_ptr;
};
G_DEFINE_TYPE(GstLibcameraAllocator, gst_libcamera_allocator,
- GST_TYPE_DMABUF_ALLOCATOR);
+ GST_TYPE_DMABUF_ALLOCATOR)
static gboolean
gst_libcamera_allocator_release(GstMiniObject *mini_object)
{
GstMemory *mem = GST_MEMORY_CAST(mini_object);
GstLibcameraAllocator *self = GST_LIBCAMERA_ALLOCATOR(mem->allocator);
- GLibLocker lock(GST_OBJECT(self));
- auto *frame = reinterpret_cast<FrameWrap *>(gst_mini_object_get_qdata(mini_object, FrameWrap::getQuark()));
- gst_memory_ref(mem);
+ {
+ GLibLocker lock(GST_OBJECT(self));
+ auto *frame = reinterpret_cast<FrameWrap *>(gst_mini_object_get_qdata(mini_object, FrameWrap::getQuark()));
- if (frame->releasePlane()) {
- auto *pool = reinterpret_cast<GQueue *>(g_hash_table_lookup(self->pools, frame->stream_));
- g_return_val_if_fail(pool, TRUE);
- g_queue_push_tail(pool, frame);
+ gst_memory_ref(mem);
+
+ if (frame->releasePlane()) {
+ auto *pool = reinterpret_cast<GQueue *>(g_hash_table_lookup(self->pools, frame->stream_));
+ g_return_val_if_fail(pool, TRUE);
+ g_queue_push_tail(pool, frame);
+ }
}
/* Keep last in case we are holding on the last allocator ref. */
@@ -168,6 +180,9 @@ gst_libcamera_allocator_finalize(GObject *object)
delete self->fb_allocator;
+ /* Keep last. */
+ delete self->cm_ptr;
+
G_OBJECT_CLASS(gst_libcamera_allocator_parent_class)->finalize(object);
}
@@ -183,17 +198,23 @@ gst_libcamera_allocator_class_init(GstLibcameraAllocatorClass *klass)
}
GstLibcameraAllocator *
-gst_libcamera_allocator_new(std::shared_ptr<Camera> camera)
+gst_libcamera_allocator_new(std::shared_ptr<Camera> camera,
+ CameraConfiguration *config_)
{
- auto *self = GST_LIBCAMERA_ALLOCATOR(g_object_new(GST_TYPE_LIBCAMERA_ALLOCATOR,
- nullptr));
+ g_autoptr(GstLibcameraAllocator) self = GST_LIBCAMERA_ALLOCATOR(g_object_new(GST_TYPE_LIBCAMERA_ALLOCATOR,
+ nullptr));
+ gint ret;
+
+ self->cm_ptr = new std::shared_ptr<CameraManager>(gst_libcamera_get_camera_manager(ret));
+ if (ret)
+ return nullptr;
self->fb_allocator = new FrameBufferAllocator(camera);
- for (Stream *stream : camera->streams()) {
- gint ret;
+ for (StreamConfiguration &streamCfg : *config_) {
+ Stream *stream = streamCfg.stream();
ret = self->fb_allocator->allocate(stream);
- if (ret == 0)
+ if (ret <= 0)
return nullptr;
GQueue *pool = g_queue_new();
@@ -207,7 +228,7 @@ gst_libcamera_allocator_new(std::shared_ptr<Camera> camera)
g_hash_table_insert(self->pools, stream, pool);
}
- return self;
+ return std::exchange(self, nullptr);
}
bool