diff options
Diffstat (limited to 'src/gstreamer/gstlibcameraallocator.cpp')
-rw-r--r-- | src/gstreamer/gstlibcameraallocator.cpp | 57 |
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 |