gstreamer: allocator: Ensure camera manager stay alive

Without the camera manager, it is not possible to cleanly delete the
FrameBufferAllocator object. Keep the camera manager alive until all the
memory object have been released.

A shared_ptr to the CameraManager is introduced which is itself stored
as a plain pointer and allocated and released explicitly. When more
than one C++ member is required, this can be refactored to use a new C++
class, but the struct _GstLibcameraAllocator is allocated and freed by
glib, so it does not have automatic destruction presently.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=211
[Kieran: Update test framework to remove expected test fail]
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Nicolas Dufresne 2024-03-05 10:30:56 -05:00 committed by Kieran Bingham
parent d267fd6d89
commit 0c9862d6e3
2 changed files with 16 additions and 3 deletions

View file

@ -100,6 +100,11 @@ 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,
@ -173,6 +178,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);
}
@ -193,11 +201,17 @@ gst_libcamera_allocator_new(std::shared_ptr<Camera> camera,
{
auto *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) {
g_object_unref(self);
return nullptr;
}
self->fb_allocator = new FrameBufferAllocator(camera);
for (StreamConfiguration &streamCfg : *config_) {
Stream *stream = streamCfg.stream();
gint ret;
ret = self->fb_allocator->allocate(stream);
if (ret == 0)

View file

@ -8,8 +8,7 @@ gstreamer_tests = [
{'name': 'single_stream_test', 'sources': ['gstreamer_single_stream_test.cpp']},
{'name': 'multi_stream_test', 'sources': ['gstreamer_multi_stream_test.cpp']},
{'name': 'device_provider_test', 'sources': ['gstreamer_device_provider_test.cpp']},
{'name': 'memory_lifetime_test', 'sources': ['gstreamer_memory_lifetime_test.cpp'],
'should_fail': true},
{'name': 'memory_lifetime_test', 'sources': ['gstreamer_memory_lifetime_test.cpp']},
]
gstreamer_dep = dependency('gstreamer-1.0', required : true)
gstapp_dep = dependency('gstreamer-app-1.0', required : true)